You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

572 lines
19 KiB

//! Helper script to publish the wasmtime and cranelift suites of crates
//!
//! See documentation in `docs/contributing-release-process.md` for more
//! information, but in a nutshell:
//!
//! * `./publish bump` - bump crate versions in-tree
//! * `./publish verify` - verify crates can be published to crates.io
//! * `./publish publish` - actually publish crates to crates.io
use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::thread;
use std::time::Duration;
// note that this list must be topologically sorted by dependencies
const CRATES_TO_PUBLISH: &[&str] = &[
// cranelift
"cranelift-isle",
"cranelift-entity",
Remove `wasmtime-environ`'s dependency on `cranelift-codegen` (#3199) * Move `CompiledFunction` into wasmtime-cranelift This commit moves the `wasmtime_environ::CompiledFunction` type into the `wasmtime-cranelift` crate. This type has lots of Cranelift-specific pieces of compilation and doesn't need to be generated by all Wasmtime compilers. This replaces the usage in the `Compiler` trait with a `Box<Any>` type that each compiler can select. Each compiler must still produce a `FunctionInfo`, however, which is shared information we'll deserialize for each module. The `wasmtime-debug` crate is also folded into the `wasmtime-cranelift` crate as a result of this commit. One possibility was to move the `CompiledFunction` commit into its own crate and have `wasmtime-debug` depend on that, but since `wasmtime-debug` is Cranelift-specific at this time it didn't seem like it was too too necessary to keep it separate. If `wasmtime-debug` supports other backends in the future we can recreate a new crate, perhaps with it refactored to not depend on Cranelift. * Move wasmtime_environ::reference_type This now belongs in wasmtime-cranelift and nowhere else * Remove `Type` reexport in wasmtime-environ One less dependency on `cranelift-codegen`! * Remove `types` reexport from `wasmtime-environ` Less cranelift! * Remove `SourceLoc` from wasmtime-environ Change the `srcloc`, `start_srcloc`, and `end_srcloc` fields to a custom `FilePos` type instead of `ir::SourceLoc`. These are only used in a few places so there's not much to lose from an extra abstraction for these leaf use cases outside of cranelift. * Remove wasmtime-environ's dep on cranelift's `StackMap` This commit "clones" the `StackMap` data structure in to `wasmtime-environ` to have an independent representation that that chosen by Cranelift. This allows Wasmtime to decouple this runtime dependency of stack map information and let the two evolve independently, if necessary. An alternative would be to refactor cranelift's implementation into a separate crate and have wasmtime depend on that but it seemed a bit like overkill to do so and easier to clone just a few lines for this. * Define code offsets in wasmtime-environ with `u32` Don't use Cranelift's `binemit::CodeOffset` alias to define this field type since the `wasmtime-environ` crate will be losing the `cranelift-codegen` dependency soon. * Commit to using `cranelift-entity` in Wasmtime This commit removes the reexport of `cranelift-entity` from the `wasmtime-environ` crate and instead directly depends on the `cranelift-entity` crate in all referencing crates. The original reason for the reexport was to make cranelift version bumps easier since it's less versions to change, but nowadays we have a script to do that. Otherwise this encourages crates to use whatever they want from `cranelift-entity` since we'll always depend on the whole crate. It's expected that the `cranelift-entity` crate will continue to be a lean crate in dependencies and suitable for use at both runtime and compile time. Consequently there's no need to avoid its usage in Wasmtime at runtime, since "remove Cranelift at compile time" is primarily about the `cranelift-codegen` crate. * Remove most uses of `cranelift-codegen` in `wasmtime-environ` There's only one final use remaining, which is the reexport of `TrapCode`, which will get handled later. * Limit the glob-reexport of `cranelift_wasm` This commit removes the glob reexport of `cranelift-wasm` from the `wasmtime-environ` crate. This is intended to explicitly define what we're reexporting and is a transitionary step to curtail the amount of dependencies taken on `cranelift-wasm` throughout the codebase. For example some functions used by debuginfo mapping are better imported directly from the crate since they're Cranelift-specific. Note that this is intended to be a temporary state affairs, soon this reexport will be gone entirely. Additionally this commit reduces imports from `cranelift_wasm` and also primarily imports from `crate::wasm` within `wasmtime-environ` to get a better sense of what's imported from where and what will need to be shared. * Extract types from cranelift-wasm to cranelift-wasm-types This commit creates a new crate called `cranelift-wasm-types` and extracts type definitions from the `cranelift-wasm` crate into this new crate. The purpose of this crate is to be a shared definition of wasm types that can be shared both by compilers (like Cranelift) as well as wasm runtimes (e.g. Wasmtime). This new `cranelift-wasm-types` crate doesn't depend on `cranelift-codegen` and is the final step in severing the unconditional dependency from Wasmtime to `cranelift-codegen`. The final refactoring in this commit is to then reexport this crate from `wasmtime-environ`, delete the `cranelift-codegen` dependency, and then update all `use` paths to point to these new types. The main change of substance here is that the `TrapCode` enum is mirrored from Cranelift into this `cranelift-wasm-types` crate. While this unfortunately results in three definitions (one more which is non-exhaustive in Wasmtime itself) it's hopefully not too onerous and ideally something we can patch up in the future. * Get lightbeam compiling * Remove unnecessary dependency * Fix compile with uffd * Update publish script * Fix more uffd tests * Rename cranelift-wasm-types to wasmtime-types This reflects the purpose a bit more where it's types specifically intended for Wasmtime and its support. * Fix publish script
3 years ago
"wasmtime-types",
"cranelift-bforest",
"cranelift-codegen-shared",
"cranelift-codegen-meta",
"cranelift-egraph",
egraph-based midend: draw the rest of the owl (productionized). (#4953) * egraph-based midend: draw the rest of the owl. * Rename `egg` submodule of cranelift-codegen to `egraph`. * Apply some feedback from @jsharp during code walkthrough. * Remove recursion from find_best_node by doing a single pass. Rather than recursively computing the lowest-cost node for a given eclass and memoizing the answer at each eclass node, we can do a single forward pass; because every eclass node refers only to earlier nodes, this is sufficient. The behavior may slightly differ from the earlier behavior because we cannot short-circuit costs to zero once a node is elaborated; but in practice this should not matter. * Make elaboration non-recursive. Use an explicit stack instead (with `ElabStackEntry` entries, alongside a result stack). * Make elaboration traversal of the domtree non-recursive/stack-safe. * Work analysis logic in Cranelift-side egraph glue into a general analysis framework in cranelift-egraph. * Apply static recursion limit to rule application. * Fix aarch64 wrt dynamic-vector support -- broken rebase. * Topo-sort cranelift-egraph before cranelift-codegen in publish script, like the comment instructs me to! * Fix multi-result call testcase. * Include `cranelift-egraph` in `PUBLISHED_CRATES`. * Fix atomic_rmw: not really a load. * Remove now-unnecessary PartialOrd/Ord derivations. * Address some code-review comments. * Review feedback. * Review feedback. * No overlap in mid-end rules, because we are defining a multi-constructor. * rustfmt * Review feedback. * Review feedback. * Review feedback. * Review feedback. * Remove redundant `mut`. * Add comment noting what rules can do. * Review feedback. * Clarify comment wording. * Update `has_memory_fence_semantics`. * Apply @jameysharp's improved loop-level computation. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix suggestion commit. * Fix off-by-one in new loop-nest analysis. * Review feedback. * Review feedback. * Review feedback. * Use `Default`, not `std::default::Default`, as per @fitzgen Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> * Apply @fitzgen's comment elaboration to a doc-comment. Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> * Add stat for hitting the rewrite-depth limit. * Some code motion in split prelude to make the diff a little clearer wrt `main`. * Take @jameysharp's suggested `try_into()` usage for blockparam indices. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Take @jameysharp's suggestion to avoid double-match on load op. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix suggestion (add import). * Review feedback. * Fix stack_load handling. * Remove redundant can_store case. * Take @jameysharp's suggested improvement to FuncEGraph::build() logic Co-authored-by: Jamey Sharp <jamey@minilop.net> * Tweaks to FuncEGraph::build() on top of suggestion. * Take @jameysharp's suggested clarified condition Co-authored-by: Jamey Sharp <jamey@minilop.net> * Clean up after suggestion (unused variable). * Fix loop analysis. * loop level asserts * Revert constant-space loop analysis -- edge cases were incorrect, so let's go with the simple thing for now. * Take @jameysharp's suggestion re: result_tys Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix up after suggestion * Take @jameysharp's suggestion to use fold rather than reduce Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fixup after suggestion * Take @jameysharp's suggestion to remove elaborate_eclass_use's return value. * Clarifying comment in terminator insts. Co-authored-by: Jamey Sharp <jamey@minilop.net> Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
2 years ago
"cranelift-codegen",
"cranelift-reader",
"cranelift-serde",
"cranelift-module",
"cranelift-frontend",
"cranelift-wasm",
"cranelift-native",
"cranelift-object",
"cranelift-interpreter",
"cranelift",
Flush Icache on AArch64 Windows (#4997) * cranelift: Add FlushInstructionCache for AArch64 on Windows This was previously done on #3426 for linux. * wasmtime: Add FlushInstructionCache for AArch64 on Windows This was previously done on #3426 for linux. * cranelift: Add MemoryUse flag to JIT Memory Manager This allows us to keep the icache flushing code self-contained and not leak implementation details. This also changes the windows icache flushing code to only flush pages that were previously unflushed. * Add jit-icache-coherence crate * cranelift: Use `jit-icache-coherence` * wasmtime: Use `jit-icache-coherence` * jit-icache-coherence: Make rustix feature additive Mutually exclusive features cause issues. * wasmtime: Remove rustix from wasmtime-jit We now use it via jit-icache-coherence * Rename wasmtime-jit-icache-coherency crate * Use cfg-if in wasmtime-jit-icache-coherency crate * Use inline instead of inline(always) * Add unsafe marker to clear_cache * Conditionally compile all rustix operations membarrier does not exist on MacOS * Publish `wasmtime-jit-icache-coherence` * Remove explicit windows check This is implied by the target_os = "windows" above * cranelift: Remove len != 0 check This is redundant as it is done in non_protected_allocations_iter * Comment cleanups Thanks @akirilov-arm! * Make clear_cache safe * Rename pipeline_flush to pipeline_flush_mt * Revert "Make clear_cache safe" This reverts commit 21165d81c9030ed9b291a1021a367214d2942c90. * More docs! * Fix pipeline_flush reference on clear_cache * Update more docs! * Move pipeline flush after `mprotect` calls Technically the `clear_cache` operation is a lie in AArch64, so move the pipeline flush after the `mprotect` calls so that it benefits from the implicit cache cleaning done by it. * wasmtime: Remove rustix backend from icache crate * wasmtime: Use libc for macos * wasmtime: Flush icache on all arch's for windows * wasmtime: Add flags to membarrier call
2 years ago
"wasmtime-jit-icache-coherence",
"cranelift-jit",
// wiggle
"wiggle-generate",
"wiggle-macro",
Initial skeleton for Winch (#4907) * Initial skeleton for Winch This commit introduces the initial skeleton for Winch, the "baseline" compiler. This skeleton contains mostly setup code for the ISA, ABI, registers, and compilation environment abstractions. It also includes the calculation of function local slots. As of this commit, the structure of these abstractions looks like the following: +------------------------+ | v +----------+ +-----+ +-----------+-----+-----------------+ | Compiler | --> | ISA | --> | Registers | ABI | Compilation Env | +----------+ +-----+ +-----------+-----+-----------------+ | ^ +------------------------------+ * Compilation environment will hold a reference to the function data * Add basic documentation to the ABI trait * Enable x86 and arm64 in cranelift-codegen * Add reg_name function for x64 * Introduce the concept of a MacroAssembler and Assembler This commit introduces the concept of a MacroAsesembler and Assembler. The MacroAssembler trait will provide a high enough interface across architectures so that each ISA implementation can use their own low-level Assembler implementation to fulfill the interface. Each Assembler will provide a 1-1 mapping to each ISA instruction. As of this commit, only a partial debug implementation is provided for the x64 Assembler. * Add a newtype over PReg Adds a newtype `Reg` over regalloc2::PReg; this ensures that Winch will operate only on the concept of `Reg`. This change is temporary until we have the necessary machinery to share a common Reg abstraction via `cranelift_asm` * Improvements to local calcuation - Add `LocalSlot::addressed_from_sp` - Use `u32` for local slot and local sizes calculation * Add helper methods to ABIArg Adds helper methods to retrieve register and type information from the argument * Make locals_size public in frame * Improve x64 register naming depending on size * Add new methods to the masm interface This commit introduces the ability for the MacroAssembler to reserve stack space, get the address of a given local and perform a stack store based on the concept of `Operand`s. There are several motivating factors to introduce the concept of an Operand: - Make the translation between Winch and Cranelift easier; - Make dispatching from the MacroAssembler to the underlying Assembler - easier by minimizing the amount of functions that we need to define - in order to satisfy the store/load combinations This commit also introduces the concept of a memory address, which essentially describes the addressing modes; as of this commit only one addressing mode is supported. We'll also need to verify that this structure will play nicely with arm64. * Blank masm implementation for arm64 * Implementation of reserve_stack, local_address, store and fp_offset for x64 * Implement function prologue and argument register spilling * Add structopt and wat * Fix debug instruction formatting * Make TargetISA trait publicly accessible * Modify the MacroAssembler finalize siganture to return a slice of strings * Introduce a simple CLI for Winch To be able to compile Wasm programs with Winch independently. Mostly meant for testing / debugging * Fix bug in x64 assembler mov_rm * Remove unused import * Move the stack slot calculation to the Frame This commit moves the calculation of the stack slots to the frame handler abstraction and also includes the calculation of the limits for the function defined locals, which will be used to zero the locals that are not associated to function arguments * Add i32 and i64 constructors to local slots * Introduce the concept of DefinedLocalsRange This commit introduces `DefinedLocalsRange` to track the stack offset at which the function-defined locals start and end; this is later used to zero-out that stack region * Add constructors for int and float registers * Add a placeholder stack implementation * Add a regset abstraction to track register availability Adds a bit set abstraction to track register availability for register allocation. The bit set has no specific knowledge about physical registers, it works on the register's hardware encoding as the source of truth. Each RegSet is expected to be created with the universe of allocatable registers per ISA when starting the compilation of a particular function. * Add an abstraction over register and immediate This is meant to be used as the source for stores. * Add a way to zero local slots and an initial skeletion of regalloc This commit introduces `zero_local_slots` to the MacroAssembler; which ensures that function defined locals are zeroed out when starting the function body. The algorithm divides the defined function locals stack range into 8 byte slots and stores a zero at each address. This process relies on register allocation if the amount of slots that need to be initialized is greater than 1. In such case, the next available register is requested to the register set and it's used to store a 0, which is then stored at every local slot * Update to wasmparser 0.92 * Correctly track if the regset has registers available * Add a result entry to the ABI signature This commuit introduces ABIResult as part of the ABISignature; this struct will track how function results are stored; initially it will consiste of a single register that will be requested to the register allocator at the end of the function; potentially causing a spill * Move zero local slots and add more granular methods to the masm This commit removes zeroing local slots from the MacroAssembler and instead adds more granular methods to it (e.g `zero`, `add`). This allows for better code sharing since most of the work done by the algorithm for zeroing slots will be the same in all targets, except for the binary emissions pieces, which is what gets delegated to the masm * Use wasmparser's visitor API and add initial support for const and add This commit adds initial support for the I32Const and I32 instructions; this involves adding a minimum for register allocation. Note that some regalloc pieces are still incomplete, since for the current set of supported instructions they are not needed. * Make the ty field public in Local * Add scratch_reg to the abi * Add a method to get a particular local from the Frame * Split the compilation environment abstraction This commit splits the compilation environment into two more concise abstractions: 1. CodeGen: the main abstraction for code generation 2. CodeGenContext: abstraction that shares the common pieces for compilation; these pieces are shared between the code generator and the register allocator * Add `push` and `load` to the MacroAssembler * Remove dead code warnings for unused paths * Map ISA features to cranelift-codegen ISA features * Apply formatting * Fix Cargo.toml after a bad rebase * Add component-compiler feature * Use clap instead of structopt * Add winch to publish.rs script * Minor formatting * Add tests to RegSet and fix two bugs when freeing and checking for register availability * Add tests to Stack * Free source register after a non-constant i32 add * Improve comments - Remove unneeded comments - And improve some of the TODO items * Update default features * Drop the ABI generic param and pass the word_size information directly To avoid dealing with dead code warnings this commit passes the word size information directly, since it's the only piece of information needed from the ABI by Codegen until now * Remove dead code This piece of code will be put back once we start integrating Winch with Wasmtime * Remove unused enum variant This variant doesn't get constructed; it should be added back once a backend is added and not enabled by default or when Winch gets integrated into Wasmtime * Fix unused code in regset tests * Update spec testsuite * Switch the visitor pattern for a simpler operator match This commit removes the usage of wasmparser's visitor pattern and instead defaults to a simpler operator matching approach. This removes the complexity of having to define all the visitor trait functions at once. * Use wasmparser's Visitor trait with a different macro strategy This commit puts back wasmparser's Visitor trait, with a sigle; simpler macro, only used for unsupported operators. * Restructure Winch This commit restuructures Winch's parts. It divides the initial approach into three main crates: `winch-codegen`,`wasmtime-winch` and `winch-tools`. `wasmtime-winch` is reponsible for the Wasmtime-Winch integration. `winch-codegen` is solely responsible for code generation. `winch-tools` is CLI tool to compile Wasm programs, mainly for testing purposes. * Refactor zero local slots This commit moves the logic of zeroing local slots from the codegen module into a method with a default implementation in the MacroAssembler trait: `zero_mem_range`. The refactored implementation is very similar to the previous implementation with the only difference that it doesn't allocates a general-purpose register; it instead uses the register allocator to retrieve the scratch register and uses this register to unroll the series of zero stores. * Tie the codegen creation to the ISA ABI This commit makes the relationship between the ISA ABI and the codegen explicit. This allows us to pass down ABI-specific bit and pieces to the codegeneration. In this case the only concrete piece that we need is the ABI word size. * Mark winch as publishable directory * Revamp winch docs This commit ensures that all the code comments in Winch are compliant with the syle used in the rest of Wasmtime's codebase. It also imptoves, generally the quality of the comments in some modules. * Panic when using multi-value when the target is aarch64 Similar to x64, this commit ensures that the abi signature of the current function doesn't use multi-value returns * Document the usage of directives * Use endianness instead of endianess in the ISA trait * Introduce a three-argument form in the MacroAssembler This commit introduces the usage of three-argument form for the MacroAssembler interface. This allows for a natural mapping for architectures like aarch64. In the case of x64, the implementation can simply restrict the implementation asserting for equality in two of the arguments of defaulting to a differnt set of instructions. As of this commit, the implementation of `add` panics if the destination and the first source arguments are not equal; internally the x64 assembler implementation will ensure that all the allowed combinations of `add` are satisfied. The reason for panicking and not emitting a `mov` followed by an `add` for example is simply because register allocation happens right before calling `add`, which ensures any register-to-register moves, if needed. This implementation will evolve in the future and this panic will be lifted if needed. * Improve the documentation for the MacroAssembler. Documents the usage of three-arg form and the intention around the high-level interface. * Format comments in remaining modules * Clean up Cargo.toml for winch pieces This commit adds missing fields to each of Winch's Cargo.toml. * Use `ModuleTranslation::get_types()` to derive the function type * Assert that start range is always word-size aligned
2 years ago
// winch
"winch-codegen",
"winch",
// wasmtime
"wasmtime-asm-macros",
support dynamic function calls in component model (#4442) * support dynamic function calls in component model This addresses #4310, introducing a new `component::values::Val` type for representing component values dynamically, as well as `component::types::Type` for representing the corresponding interface types. It also adds a `call` method to `component::func::Func`, which takes a slice of `Val`s as parameters and returns a `Result<Val>` representing the result. Note that I've moved `post_return` and `call_raw` from `TypedFunc` to `Func` since there was nothing specific to `TypedFunc` about them, and I wanted to reuse them. The code in both is unchanged beyond the trivial tweaks to make them fit in their new home. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * order variants and match cases more consistently Signed-off-by: Joel Dice <joel.dice@fermyon.com> * implement lift for String, Box<str>, etc. This also removes the redundant `store` parameter from `Type::load`. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * implement code review feedback This fixes a few issues: - Bad offset calculation when lowering - Missing variant padding - Style issues regarding `types::Handle` - Missed opportunities to reuse `Lift` and `Lower` impls It also adds forwarding `Lift` impls for `Box<[T]>`, `Vec<T>`, etc. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * move `new_*` methods to specific `types` structs Per review feedback, I've moved `Type::new_record` to `Record::new_val` and added a `Type::unwrap_record` method; likewise for the other kinds of types. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * make tuple, option, and expected type comparisons recursive These types should compare as equal across component boundaries as long as their type parameters are equal. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * improve error diagnostic in `Type::check` We now distinguish between more failure cases to provide an informative error message. Signed-off-by: Joel Dice <joel.dice@fermyon.com> * address review feedback - Remove `WasmStr::to_str_from_memory` and `WasmList::get_from_memory` - add `try_new` methods to various `values` types - avoid using `ExactSizeIterator::len` where we can't trust it - fix over-constrained bounds on forwarded `ComponentType` impls Signed-off-by: Joel Dice <joel.dice@fermyon.com> * rearrange code per review feedback - Move functions from `types` to `values` module so we can make certain struct fields private - Rename `try_new` to just `new` Signed-off-by: Joel Dice <joel.dice@fermyon.com> * remove special-case equality test for tuples, options, and expecteds Instead, I've added a FIXME comment and will open an issue to do recursive structural equality testing. Signed-off-by: Joel Dice <joel.dice@fermyon.com>
2 years ago
"wasmtime-component-util",
"wasmtime-wit-bindgen",
"wasmtime-component-macro",
"wasmtime-jit-debug",
Implement support for `async` functions in Wasmtime (#2434) * Implement support for `async` functions in Wasmtime This is an implementation of [RFC 2] in Wasmtime which is to support `async`-defined host functions. At a high level support is added by executing WebAssembly code that might invoke an asynchronous host function on a separate native stack. When the host function's future is not ready we switch back to the main native stack to continue execution. There's a whole bunch of details in this commit, and it's a bit much to go over them all here in this commit message. The most important changes here are: * A new `wasmtime-fiber` crate has been written to manage the low-level details of stack-switching. Unixes use `mmap` to allocate a stack and Windows uses the native fibers implementation. We'll surely want to refactor this to move stack allocation elsewhere in the future. Fibers are intended to be relatively general with a lot of type paremters to fling values back and forth across suspension points. The whole crate is a giant wad of `unsafe` unfortunately and involves handwritten assembly with custom dwarf CFI directives to boot. Definitely deserves a close eye in review! * The `Store` type has two new methods -- `block_on` and `on_fiber` which bridge between the async and non-async worlds. Lots of unsafe fiddly bits here as we're trying to communicate context pointers between disparate portions of the code. Extra eyes and care in review is greatly appreciated. * The APIs for binding `async` functions are unfortunately pretty ugly in `Func`. This is mostly due to language limitations and compiler bugs (I believe) in Rust. Instead of `Func::wrap` we have a `Func::wrapN_async` family of methods, and we've also got a whole bunch of `Func::getN_async` methods now too. It may be worth rethinking the API of `Func` to try to make the documentation page actually grok'able. This isn't super heavily tested but the various test should suffice for engaging hopefully nearly all the infrastructure in one form or another. This is just the start though! [RFC 2]: https://github.com/bytecodealliance/rfcs/pull/2 * Add wasmtime-fiber to publish script * Save vector/float registers on ARM too. * Fix a typo * Update lock file * Implement periodically yielding with fuel consumption This commit implements APIs on `Store` to periodically yield execution of futures through the consumption of fuel. When fuel runs out a future's execution is yielded back to the caller, and then upon resumption fuel is re-injected. The goal of this is to allow cooperative multi-tasking with futures. * Fix compile without async * Save/restore the frame pointer in fiber switching Turns out this is another caller-saved register! * Simplify x86_64 fiber asm Take a leaf out of aarch64's playbook and don't have extra memory to load/store these arguments, instead leverage how `wasmtime_fiber_switch` already loads a bunch of data into registers which we can then immediately start using on a fiber's start without any extra memory accesses. * Add x86 support to wasmtime-fiber * Add ARM32 support to fiber crate * Make fiber build file probing more flexible * Use CreateFiberEx on Windows * Remove a stray no-longer-used trait declaration * Don't reach into `Caller` internals * Tweak async fuel to eventually run out. With fuel it's probably best to not provide any way to inject infinite fuel. * Fix some typos * Cleanup asm a bit * Use a shared header file to deduplicate some directives * Guarantee hidden visibility for functions * Enable gc-sections on macOS x86_64 * Add `.type` annotations for ARM * Update lock file * Fix compile error * Review comments
4 years ago
"wasmtime-fiber",
"wasmtime-environ",
"wasmtime-runtime",
winch: Refactoring wasmtime compiler integration pieces to share more between Cranelift and Winch (#5944) * Enable the native target by default in winch Match cranelift-codegen's build script where if no architecture is explicitly enabled then the host architecture is implicitly enabled. * Refactor Cranelift's ISA builder to share more with Winch This commit refactors the `Builder` type to have a type parameter representing the finished ISA with Cranelift and Winch having their own typedefs for `Builder` to represent their own builders. The intention is to use this shared functionality to produce more shared code between the two codegen backends. * Moving compiler shared components to a separate crate * Restore native flag inference in compiler building This fixes an oversight from the previous commits to use `cranelift-native` to infer flags for the native host when using default settings with Wasmtime. * Move `Compiler::page_size_align` into wasmtime-environ The `cranelift-codegen` crate doesn't need this and winch wants the same implementation, so shuffle it around so everyone has access to it. * Fill out `Compiler::{flags, isa_flags}` for Winch These are easy enough to plumb through with some shared code for Wasmtime. * Plumb the `is_branch_protection_enabled` flag for Winch Just forwarding an isa-specific setting accessor. * Moving executable creation to shared compiler crate * Adding builder back in and removing from shared crate * Refactoring the shared pieces for the `CompilerBuilder` I decided to move a couple things around from Alex's initial changes. Instead of having the shared builder do everything, I went back to having each compiler have a distinct builder implementation. I refactored most of the flag setting logic into a single shared location, so we can still reduce the amount of code duplication. With them being separate, we don't need to maintain things like `LinkOpts` which Winch doesn't currently use. We also have an avenue to error when certain flags are sent to Winch if we don't support them. I'm hoping this will make things more maintainable as we build out Winch. I'm still unsure about keeping everything shared in a single crate (`cranelift_shared`). It's starting to feel like this crate is doing too much, which makes it difficult to name. There does seem to be a need for two distinct abstraction: creating the final executable and the handling of shared/ISA flags when building the compiler. I could make them into two separate crates, but there doesn't seem to be enough there yet to justify it. * Documentation updates, and renaming the finish method * Adding back in a default temporarily to pass tests, and removing some unused imports * Fixing winch tests with wrong method name * Removing unused imports from codegen shared crate * Apply documentation formatting updates Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com> * Adding back in cranelift_native flag inferring * Adding new shared crate to publish list * Adding write feature to pass cargo check --------- Co-authored-by: Alex Crichton <alex@alexcrichton.com> Co-authored-by: Saúl Cabrera <saulecabrera@gmail.com>
2 years ago
"wasmtime-cranelift-shared",
"wasmtime-cranelift",
"wasmtime-jit",
"wasmtime-cache",
Initial skeleton for Winch (#4907) * Initial skeleton for Winch This commit introduces the initial skeleton for Winch, the "baseline" compiler. This skeleton contains mostly setup code for the ISA, ABI, registers, and compilation environment abstractions. It also includes the calculation of function local slots. As of this commit, the structure of these abstractions looks like the following: +------------------------+ | v +----------+ +-----+ +-----------+-----+-----------------+ | Compiler | --> | ISA | --> | Registers | ABI | Compilation Env | +----------+ +-----+ +-----------+-----+-----------------+ | ^ +------------------------------+ * Compilation environment will hold a reference to the function data * Add basic documentation to the ABI trait * Enable x86 and arm64 in cranelift-codegen * Add reg_name function for x64 * Introduce the concept of a MacroAssembler and Assembler This commit introduces the concept of a MacroAsesembler and Assembler. The MacroAssembler trait will provide a high enough interface across architectures so that each ISA implementation can use their own low-level Assembler implementation to fulfill the interface. Each Assembler will provide a 1-1 mapping to each ISA instruction. As of this commit, only a partial debug implementation is provided for the x64 Assembler. * Add a newtype over PReg Adds a newtype `Reg` over regalloc2::PReg; this ensures that Winch will operate only on the concept of `Reg`. This change is temporary until we have the necessary machinery to share a common Reg abstraction via `cranelift_asm` * Improvements to local calcuation - Add `LocalSlot::addressed_from_sp` - Use `u32` for local slot and local sizes calculation * Add helper methods to ABIArg Adds helper methods to retrieve register and type information from the argument * Make locals_size public in frame * Improve x64 register naming depending on size * Add new methods to the masm interface This commit introduces the ability for the MacroAssembler to reserve stack space, get the address of a given local and perform a stack store based on the concept of `Operand`s. There are several motivating factors to introduce the concept of an Operand: - Make the translation between Winch and Cranelift easier; - Make dispatching from the MacroAssembler to the underlying Assembler - easier by minimizing the amount of functions that we need to define - in order to satisfy the store/load combinations This commit also introduces the concept of a memory address, which essentially describes the addressing modes; as of this commit only one addressing mode is supported. We'll also need to verify that this structure will play nicely with arm64. * Blank masm implementation for arm64 * Implementation of reserve_stack, local_address, store and fp_offset for x64 * Implement function prologue and argument register spilling * Add structopt and wat * Fix debug instruction formatting * Make TargetISA trait publicly accessible * Modify the MacroAssembler finalize siganture to return a slice of strings * Introduce a simple CLI for Winch To be able to compile Wasm programs with Winch independently. Mostly meant for testing / debugging * Fix bug in x64 assembler mov_rm * Remove unused import * Move the stack slot calculation to the Frame This commit moves the calculation of the stack slots to the frame handler abstraction and also includes the calculation of the limits for the function defined locals, which will be used to zero the locals that are not associated to function arguments * Add i32 and i64 constructors to local slots * Introduce the concept of DefinedLocalsRange This commit introduces `DefinedLocalsRange` to track the stack offset at which the function-defined locals start and end; this is later used to zero-out that stack region * Add constructors for int and float registers * Add a placeholder stack implementation * Add a regset abstraction to track register availability Adds a bit set abstraction to track register availability for register allocation. The bit set has no specific knowledge about physical registers, it works on the register's hardware encoding as the source of truth. Each RegSet is expected to be created with the universe of allocatable registers per ISA when starting the compilation of a particular function. * Add an abstraction over register and immediate This is meant to be used as the source for stores. * Add a way to zero local slots and an initial skeletion of regalloc This commit introduces `zero_local_slots` to the MacroAssembler; which ensures that function defined locals are zeroed out when starting the function body. The algorithm divides the defined function locals stack range into 8 byte slots and stores a zero at each address. This process relies on register allocation if the amount of slots that need to be initialized is greater than 1. In such case, the next available register is requested to the register set and it's used to store a 0, which is then stored at every local slot * Update to wasmparser 0.92 * Correctly track if the regset has registers available * Add a result entry to the ABI signature This commuit introduces ABIResult as part of the ABISignature; this struct will track how function results are stored; initially it will consiste of a single register that will be requested to the register allocator at the end of the function; potentially causing a spill * Move zero local slots and add more granular methods to the masm This commit removes zeroing local slots from the MacroAssembler and instead adds more granular methods to it (e.g `zero`, `add`). This allows for better code sharing since most of the work done by the algorithm for zeroing slots will be the same in all targets, except for the binary emissions pieces, which is what gets delegated to the masm * Use wasmparser's visitor API and add initial support for const and add This commit adds initial support for the I32Const and I32 instructions; this involves adding a minimum for register allocation. Note that some regalloc pieces are still incomplete, since for the current set of supported instructions they are not needed. * Make the ty field public in Local * Add scratch_reg to the abi * Add a method to get a particular local from the Frame * Split the compilation environment abstraction This commit splits the compilation environment into two more concise abstractions: 1. CodeGen: the main abstraction for code generation 2. CodeGenContext: abstraction that shares the common pieces for compilation; these pieces are shared between the code generator and the register allocator * Add `push` and `load` to the MacroAssembler * Remove dead code warnings for unused paths * Map ISA features to cranelift-codegen ISA features * Apply formatting * Fix Cargo.toml after a bad rebase * Add component-compiler feature * Use clap instead of structopt * Add winch to publish.rs script * Minor formatting * Add tests to RegSet and fix two bugs when freeing and checking for register availability * Add tests to Stack * Free source register after a non-constant i32 add * Improve comments - Remove unneeded comments - And improve some of the TODO items * Update default features * Drop the ABI generic param and pass the word_size information directly To avoid dealing with dead code warnings this commit passes the word size information directly, since it's the only piece of information needed from the ABI by Codegen until now * Remove dead code This piece of code will be put back once we start integrating Winch with Wasmtime * Remove unused enum variant This variant doesn't get constructed; it should be added back once a backend is added and not enabled by default or when Winch gets integrated into Wasmtime * Fix unused code in regset tests * Update spec testsuite * Switch the visitor pattern for a simpler operator match This commit removes the usage of wasmparser's visitor pattern and instead defaults to a simpler operator matching approach. This removes the complexity of having to define all the visitor trait functions at once. * Use wasmparser's Visitor trait with a different macro strategy This commit puts back wasmparser's Visitor trait, with a sigle; simpler macro, only used for unsupported operators. * Restructure Winch This commit restuructures Winch's parts. It divides the initial approach into three main crates: `winch-codegen`,`wasmtime-winch` and `winch-tools`. `wasmtime-winch` is reponsible for the Wasmtime-Winch integration. `winch-codegen` is solely responsible for code generation. `winch-tools` is CLI tool to compile Wasm programs, mainly for testing purposes. * Refactor zero local slots This commit moves the logic of zeroing local slots from the codegen module into a method with a default implementation in the MacroAssembler trait: `zero_mem_range`. The refactored implementation is very similar to the previous implementation with the only difference that it doesn't allocates a general-purpose register; it instead uses the register allocator to retrieve the scratch register and uses this register to unroll the series of zero stores. * Tie the codegen creation to the ISA ABI This commit makes the relationship between the ISA ABI and the codegen explicit. This allows us to pass down ABI-specific bit and pieces to the codegeneration. In this case the only concrete piece that we need is the ABI word size. * Mark winch as publishable directory * Revamp winch docs This commit ensures that all the code comments in Winch are compliant with the syle used in the rest of Wasmtime's codebase. It also imptoves, generally the quality of the comments in some modules. * Panic when using multi-value when the target is aarch64 Similar to x64, this commit ensures that the abi signature of the current function doesn't use multi-value returns * Document the usage of directives * Use endianness instead of endianess in the ISA trait * Introduce a three-argument form in the MacroAssembler This commit introduces the usage of three-argument form for the MacroAssembler interface. This allows for a natural mapping for architectures like aarch64. In the case of x64, the implementation can simply restrict the implementation asserting for equality in two of the arguments of defaulting to a differnt set of instructions. As of this commit, the implementation of `add` panics if the destination and the first source arguments are not equal; internally the x64 assembler implementation will ensure that all the allowed combinations of `add` are satisfied. The reason for panicking and not emitting a `mov` followed by an `add` for example is simply because register allocation happens right before calling `add`, which ensures any register-to-register moves, if needed. This implementation will evolve in the future and this panic will be lifted if needed. * Improve the documentation for the MacroAssembler. Documents the usage of three-arg form and the intention around the high-level interface. * Format comments in remaining modules * Clean up Cargo.toml for winch pieces This commit adds missing fields to each of Winch's Cargo.toml. * Use `ModuleTranslation::get_types()` to derive the function type * Assert that start range is always word-size aligned
2 years ago
"wasmtime-winch",
"wasmtime",
// wasi-common/wiggle
"wiggle",
"wasi-common",
"wasi-cap-std-sync",
"wasi-tokio",
// other misc wasmtime crates
"wasmtime-wasi",
"wasmtime-wasi-crypto",
wasi-threads: an initial implementation (#5484) This commit includes a set of changes that add initial support for `wasi-threads` to Wasmtime: * feat: remove mutability from the WasiCtx Table This patch adds interior mutability to the WasiCtx Table and the Table elements. Major pain points: * `File` only needs `RwLock<cap_std::fs::File>` to implement `File::set_fdflags()` on Windows, because of [1] * Because `File` needs a `RwLock` and `RwLock*Guard` cannot be hold across an `.await`, The `async` from `async fn num_ready_bytes(&self)` had to be removed * Because `File` needs a `RwLock` and `RwLock*Guard` cannot be dereferenced in `pollable`, the signature of `fn pollable(&self) -> Option<rustix::fd::BorrowedFd>` changed to `fn pollable(&self) -> Option<Arc<dyn AsFd + '_>>` [1] https://github.com/bytecodealliance/system-interface/blob/da238e324e752033f315f09c082ad9ce35d42696/src/fs/fd_flags.rs#L210-L217 * wasi-threads: add an initial implementation This change is a first step toward implementing `wasi-threads` in Wasmtime. We may find that it has some missing pieces, but the core functionality is there: when `wasi::thread_spawn` is called by a running WebAssembly module, a function named `wasi_thread_start` is found in the module's exports and called in a new instance. The shared memory of the original instance is reused in the new instance. This new WASI proposal is in its early stages and details are still being hashed out in the [spec] and [wasi-libc] repositories. Due to its experimental state, the `wasi-threads` functionality is hidden behind both a compile-time and runtime flag: one must build with `--features wasi-threads` but also run the Wasmtime CLI with `--wasm-features threads` and `--wasi-modules experimental-wasi-threads`. One can experiment with `wasi-threads` by running: ```console $ cargo run --features wasi-threads -- \ --wasm-features threads --wasi-modules experimental-wasi-threads \ <a threads-enabled module> ``` Threads-enabled Wasm modules are not yet easy to build. Hopefully this is resolved soon, but in the meantime see the use of `THREAD_MODEL=posix` in the [wasi-libc] repository for some clues on what is necessary. Wiggle complicates things by requiring the Wasm memory to be exported with a certain name and `wasi-threads` also expects that memory to be imported; this build-time obstacle can be overcome with the `--import-memory --export-memory` flags only available in the latest Clang tree. Due to all of this, the included tests are written directly in WAT--run these with: ```console $ cargo test --features wasi-threads -p wasmtime-cli -- cli_tests ``` [spec]: https://github.com/WebAssembly/wasi-threads [wasi-libc]: https://github.com/WebAssembly/wasi-libc This change does not protect the WASI implementations themselves from concurrent access. This is already complete in previous commits or left for future commits in certain cases (e.g., wasi-nn). * wasi-threads: factor out process exit logic As is being discussed [elsewhere], either calling `proc_exit` or trapping in any thread should halt execution of all threads. The Wasmtime CLI already has logic for adapting a WebAssembly error code to a code expected in each OS. This change factors out this logic to a new function, `maybe_exit_on_error`, for use within the `wasi-threads` implementation. This will work reasonably well for CLI users of Wasmtime + `wasi-threads`, but embedders will want something better in the future: when a `wasi-threads` threads fails, they may not want their application to exit. Handling this is tricky, because it will require cancelling the threads spawned by the `wasi-threads` implementation, something that is not trivial to do in Rust. With this change, we defer that work until later in order to provide a working implementation of `wasi-threads` for experimentation. [elsewhere]: https://github.com/WebAssembly/wasi-threads/pull/17 * review: work around `fd_fdstat_set_flags` In order to make progress with wasi-threads, this change temporarily works around limitations induced by `wasi-common`'s `fd_fdstat_set_flags` to allow `&mut self` use in the implementation. Eventual resolution is tracked in https://github.com/bytecodealliance/wasmtime/issues/5643. This change makes several related helper functions (e.g., `set_fdflags`) take `&mut self` as well. * test: use `wait`/`notify` to improve `threads.wat` test Previously, the test simply executed in a loop for some hardcoded number of iterations. This changes uses `wait` and `notify` and atomic operations to keep track of when the spawned threads are done and join on the main thread appropriately. * various fixes and tweaks due to the PR review --------- Signed-off-by: Harald Hoyer <harald@profian.com> Co-authored-by: Harald Hoyer <harald@profian.com> Co-authored-by: Alex Crichton <alex@alexcrichton.com>
2 years ago
"wasmtime-wasi-nn",
"wasmtime-wasi-threads",
"wasmtime-wast",
"wasmtime-cli-flags",
"wasmtime-explorer",
"wasmtime-cli",
];
Adjust dependency directives between crates (#3420) * Adjust dependency directives between crates This commit is a preparation for the release process for Wasmtime. The specific changes here are to delineate which crates are "public", and all version requirements on non-public crates will now be done with `=A.B.C` version requirements instead of today's `A.B.C` version requirements. The purpose for doing this is to assist with patch releases that might happen in the future. Patch releases of wasmtime are already required to not break the APIs of "public" crates, but no such guarantee is given about "internal" crates. This means that a patch release runs the risk, for example, of breaking an internal API. In doing so though we would also need to release a new major version of the internal crate, but we wouldn't have a great hole in the number scheme of major versions to do so. By using `=A.B.C` requirements for internal crates it means we can safely ignore strict semver-compatibility between releases of internal crates for patch releases, since the only consumers of the crate will be the corresponding patch release of the `wasmtime` crate itself (or other public crates). The `publish.rs` script has been updated with a check to verify that dependencies on internal crates are all specified with an `=` dependency, and dependnecies on all public crates are without a `=` dependency. This will hopefully make it so we don't have to worry about what to use where, we just let CI tell us what to do. Using this modification all version dependency declarations have been updated. Note that some crates were adjusted to simply remove their `version` requirement in cases such as the crate wasn't published anyway (`publish = false` was specified) or it's in the `dev-dependencies` section which doesn't need version specifiers for path dependencies. * Switch to normal sever deps for cranelift dependencies These crates will now all be considered "public" where in patch releases they will be guaranteed to not have breaking changes.
3 years ago
// Anything **not** mentioned in this array is required to have an `=a.b.c`
// dependency requirement on it to enable breaking api changes even in "patch"
// releases since everything not mentioned here is just an organizational detail
// that no one else should rely on.
const PUBLIC_CRATES: &[&str] = &[
// just here to appease the script because these are submodules of this
// repository.
"wasi-crypto",
"witx",
// these are actually public crates which we cannot break the API of in
// patch releases.
"wasmtime",
"wasmtime-wasi",
"wasmtime-wasi-crypto",
wasi-threads: an initial implementation (#5484) This commit includes a set of changes that add initial support for `wasi-threads` to Wasmtime: * feat: remove mutability from the WasiCtx Table This patch adds interior mutability to the WasiCtx Table and the Table elements. Major pain points: * `File` only needs `RwLock<cap_std::fs::File>` to implement `File::set_fdflags()` on Windows, because of [1] * Because `File` needs a `RwLock` and `RwLock*Guard` cannot be hold across an `.await`, The `async` from `async fn num_ready_bytes(&self)` had to be removed * Because `File` needs a `RwLock` and `RwLock*Guard` cannot be dereferenced in `pollable`, the signature of `fn pollable(&self) -> Option<rustix::fd::BorrowedFd>` changed to `fn pollable(&self) -> Option<Arc<dyn AsFd + '_>>` [1] https://github.com/bytecodealliance/system-interface/blob/da238e324e752033f315f09c082ad9ce35d42696/src/fs/fd_flags.rs#L210-L217 * wasi-threads: add an initial implementation This change is a first step toward implementing `wasi-threads` in Wasmtime. We may find that it has some missing pieces, but the core functionality is there: when `wasi::thread_spawn` is called by a running WebAssembly module, a function named `wasi_thread_start` is found in the module's exports and called in a new instance. The shared memory of the original instance is reused in the new instance. This new WASI proposal is in its early stages and details are still being hashed out in the [spec] and [wasi-libc] repositories. Due to its experimental state, the `wasi-threads` functionality is hidden behind both a compile-time and runtime flag: one must build with `--features wasi-threads` but also run the Wasmtime CLI with `--wasm-features threads` and `--wasi-modules experimental-wasi-threads`. One can experiment with `wasi-threads` by running: ```console $ cargo run --features wasi-threads -- \ --wasm-features threads --wasi-modules experimental-wasi-threads \ <a threads-enabled module> ``` Threads-enabled Wasm modules are not yet easy to build. Hopefully this is resolved soon, but in the meantime see the use of `THREAD_MODEL=posix` in the [wasi-libc] repository for some clues on what is necessary. Wiggle complicates things by requiring the Wasm memory to be exported with a certain name and `wasi-threads` also expects that memory to be imported; this build-time obstacle can be overcome with the `--import-memory --export-memory` flags only available in the latest Clang tree. Due to all of this, the included tests are written directly in WAT--run these with: ```console $ cargo test --features wasi-threads -p wasmtime-cli -- cli_tests ``` [spec]: https://github.com/WebAssembly/wasi-threads [wasi-libc]: https://github.com/WebAssembly/wasi-libc This change does not protect the WASI implementations themselves from concurrent access. This is already complete in previous commits or left for future commits in certain cases (e.g., wasi-nn). * wasi-threads: factor out process exit logic As is being discussed [elsewhere], either calling `proc_exit` or trapping in any thread should halt execution of all threads. The Wasmtime CLI already has logic for adapting a WebAssembly error code to a code expected in each OS. This change factors out this logic to a new function, `maybe_exit_on_error`, for use within the `wasi-threads` implementation. This will work reasonably well for CLI users of Wasmtime + `wasi-threads`, but embedders will want something better in the future: when a `wasi-threads` threads fails, they may not want their application to exit. Handling this is tricky, because it will require cancelling the threads spawned by the `wasi-threads` implementation, something that is not trivial to do in Rust. With this change, we defer that work until later in order to provide a working implementation of `wasi-threads` for experimentation. [elsewhere]: https://github.com/WebAssembly/wasi-threads/pull/17 * review: work around `fd_fdstat_set_flags` In order to make progress with wasi-threads, this change temporarily works around limitations induced by `wasi-common`'s `fd_fdstat_set_flags` to allow `&mut self` use in the implementation. Eventual resolution is tracked in https://github.com/bytecodealliance/wasmtime/issues/5643. This change makes several related helper functions (e.g., `set_fdflags`) take `&mut self` as well. * test: use `wait`/`notify` to improve `threads.wat` test Previously, the test simply executed in a loop for some hardcoded number of iterations. This changes uses `wait` and `notify` and atomic operations to keep track of when the spawned threads are done and join on the main thread appropriately. * various fixes and tweaks due to the PR review --------- Signed-off-by: Harald Hoyer <harald@profian.com> Co-authored-by: Harald Hoyer <harald@profian.com> Co-authored-by: Alex Crichton <alex@alexcrichton.com>
2 years ago
"wasmtime-wasi-nn",
"wasmtime-wasi-threads",
Adjust dependency directives between crates (#3420) * Adjust dependency directives between crates This commit is a preparation for the release process for Wasmtime. The specific changes here are to delineate which crates are "public", and all version requirements on non-public crates will now be done with `=A.B.C` version requirements instead of today's `A.B.C` version requirements. The purpose for doing this is to assist with patch releases that might happen in the future. Patch releases of wasmtime are already required to not break the APIs of "public" crates, but no such guarantee is given about "internal" crates. This means that a patch release runs the risk, for example, of breaking an internal API. In doing so though we would also need to release a new major version of the internal crate, but we wouldn't have a great hole in the number scheme of major versions to do so. By using `=A.B.C` requirements for internal crates it means we can safely ignore strict semver-compatibility between releases of internal crates for patch releases, since the only consumers of the crate will be the corresponding patch release of the `wasmtime` crate itself (or other public crates). The `publish.rs` script has been updated with a check to verify that dependencies on internal crates are all specified with an `=` dependency, and dependnecies on all public crates are without a `=` dependency. This will hopefully make it so we don't have to worry about what to use where, we just let CI tell us what to do. Using this modification all version dependency declarations have been updated. Note that some crates were adjusted to simply remove their `version` requirement in cases such as the crate wasn't published anyway (`publish = false` was specified) or it's in the `dev-dependencies` section which doesn't need version specifiers for path dependencies. * Switch to normal sever deps for cranelift dependencies These crates will now all be considered "public" where in patch releases they will be guaranteed to not have breaking changes.
3 years ago
"wasmtime-cli",
// all cranelift crates are considered "public" in that they can't
// have breaking API changes in patch releases
"cranelift-entity",
"cranelift-bforest",
"cranelift-codegen-shared",
"cranelift-codegen-meta",
egraph-based midend: draw the rest of the owl (productionized). (#4953) * egraph-based midend: draw the rest of the owl. * Rename `egg` submodule of cranelift-codegen to `egraph`. * Apply some feedback from @jsharp during code walkthrough. * Remove recursion from find_best_node by doing a single pass. Rather than recursively computing the lowest-cost node for a given eclass and memoizing the answer at each eclass node, we can do a single forward pass; because every eclass node refers only to earlier nodes, this is sufficient. The behavior may slightly differ from the earlier behavior because we cannot short-circuit costs to zero once a node is elaborated; but in practice this should not matter. * Make elaboration non-recursive. Use an explicit stack instead (with `ElabStackEntry` entries, alongside a result stack). * Make elaboration traversal of the domtree non-recursive/stack-safe. * Work analysis logic in Cranelift-side egraph glue into a general analysis framework in cranelift-egraph. * Apply static recursion limit to rule application. * Fix aarch64 wrt dynamic-vector support -- broken rebase. * Topo-sort cranelift-egraph before cranelift-codegen in publish script, like the comment instructs me to! * Fix multi-result call testcase. * Include `cranelift-egraph` in `PUBLISHED_CRATES`. * Fix atomic_rmw: not really a load. * Remove now-unnecessary PartialOrd/Ord derivations. * Address some code-review comments. * Review feedback. * Review feedback. * No overlap in mid-end rules, because we are defining a multi-constructor. * rustfmt * Review feedback. * Review feedback. * Review feedback. * Review feedback. * Remove redundant `mut`. * Add comment noting what rules can do. * Review feedback. * Clarify comment wording. * Update `has_memory_fence_semantics`. * Apply @jameysharp's improved loop-level computation. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix suggestion commit. * Fix off-by-one in new loop-nest analysis. * Review feedback. * Review feedback. * Review feedback. * Use `Default`, not `std::default::Default`, as per @fitzgen Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> * Apply @fitzgen's comment elaboration to a doc-comment. Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com> * Add stat for hitting the rewrite-depth limit. * Some code motion in split prelude to make the diff a little clearer wrt `main`. * Take @jameysharp's suggested `try_into()` usage for blockparam indices. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Take @jameysharp's suggestion to avoid double-match on load op. Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix suggestion (add import). * Review feedback. * Fix stack_load handling. * Remove redundant can_store case. * Take @jameysharp's suggested improvement to FuncEGraph::build() logic Co-authored-by: Jamey Sharp <jamey@minilop.net> * Tweaks to FuncEGraph::build() on top of suggestion. * Take @jameysharp's suggested clarified condition Co-authored-by: Jamey Sharp <jamey@minilop.net> * Clean up after suggestion (unused variable). * Fix loop analysis. * loop level asserts * Revert constant-space loop analysis -- edge cases were incorrect, so let's go with the simple thing for now. * Take @jameysharp's suggestion re: result_tys Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fix up after suggestion * Take @jameysharp's suggestion to use fold rather than reduce Co-authored-by: Jamey Sharp <jamey@minilop.net> * Fixup after suggestion * Take @jameysharp's suggestion to remove elaborate_eclass_use's return value. * Clarifying comment in terminator insts. Co-authored-by: Jamey Sharp <jamey@minilop.net> Co-authored-by: Nick Fitzgerald <fitzgen@gmail.com>
2 years ago
"cranelift-egraph",
Adjust dependency directives between crates (#3420) * Adjust dependency directives between crates This commit is a preparation for the release process for Wasmtime. The specific changes here are to delineate which crates are "public", and all version requirements on non-public crates will now be done with `=A.B.C` version requirements instead of today's `A.B.C` version requirements. The purpose for doing this is to assist with patch releases that might happen in the future. Patch releases of wasmtime are already required to not break the APIs of "public" crates, but no such guarantee is given about "internal" crates. This means that a patch release runs the risk, for example, of breaking an internal API. In doing so though we would also need to release a new major version of the internal crate, but we wouldn't have a great hole in the number scheme of major versions to do so. By using `=A.B.C` requirements for internal crates it means we can safely ignore strict semver-compatibility between releases of internal crates for patch releases, since the only consumers of the crate will be the corresponding patch release of the `wasmtime` crate itself (or other public crates). The `publish.rs` script has been updated with a check to verify that dependencies on internal crates are all specified with an `=` dependency, and dependnecies on all public crates are without a `=` dependency. This will hopefully make it so we don't have to worry about what to use where, we just let CI tell us what to do. Using this modification all version dependency declarations have been updated. Note that some crates were adjusted to simply remove their `version` requirement in cases such as the crate wasn't published anyway (`publish = false` was specified) or it's in the `dev-dependencies` section which doesn't need version specifiers for path dependencies. * Switch to normal sever deps for cranelift dependencies These crates will now all be considered "public" where in patch releases they will be guaranteed to not have breaking changes.
3 years ago
"cranelift-codegen",
"cranelift-reader",
"cranelift-serde",
"cranelift-module",
"cranelift-frontend",
"cranelift-wasm",
"cranelift-native",
"cranelift-object",
"cranelift-interpreter",
"cranelift",
"cranelift-jit",
// This is a dependency of cranelift crates and as a result can't break in
// patch releases as well
"wasmtime-types",
];
const C_HEADER_PATH: &str = "./crates/c-api/include/wasmtime.h";
struct Workspace {
version: String,
}
struct Crate {
manifest: PathBuf,
name: String,
version: String,
publish: bool,
}
fn main() {
let mut crates = Vec::new();
let root = read_crate(None, "./Cargo.toml".as_ref());
let ws = Workspace {
version: root.version.clone(),
};
crates.push(root);
find_crates("crates".as_ref(), &ws, &mut crates);
find_crates("cranelift".as_ref(), &ws, &mut crates);
Initial skeleton for Winch (#4907) * Initial skeleton for Winch This commit introduces the initial skeleton for Winch, the "baseline" compiler. This skeleton contains mostly setup code for the ISA, ABI, registers, and compilation environment abstractions. It also includes the calculation of function local slots. As of this commit, the structure of these abstractions looks like the following: +------------------------+ | v +----------+ +-----+ +-----------+-----+-----------------+ | Compiler | --> | ISA | --> | Registers | ABI | Compilation Env | +----------+ +-----+ +-----------+-----+-----------------+ | ^ +------------------------------+ * Compilation environment will hold a reference to the function data * Add basic documentation to the ABI trait * Enable x86 and arm64 in cranelift-codegen * Add reg_name function for x64 * Introduce the concept of a MacroAssembler and Assembler This commit introduces the concept of a MacroAsesembler and Assembler. The MacroAssembler trait will provide a high enough interface across architectures so that each ISA implementation can use their own low-level Assembler implementation to fulfill the interface. Each Assembler will provide a 1-1 mapping to each ISA instruction. As of this commit, only a partial debug implementation is provided for the x64 Assembler. * Add a newtype over PReg Adds a newtype `Reg` over regalloc2::PReg; this ensures that Winch will operate only on the concept of `Reg`. This change is temporary until we have the necessary machinery to share a common Reg abstraction via `cranelift_asm` * Improvements to local calcuation - Add `LocalSlot::addressed_from_sp` - Use `u32` for local slot and local sizes calculation * Add helper methods to ABIArg Adds helper methods to retrieve register and type information from the argument * Make locals_size public in frame * Improve x64 register naming depending on size * Add new methods to the masm interface This commit introduces the ability for the MacroAssembler to reserve stack space, get the address of a given local and perform a stack store based on the concept of `Operand`s. There are several motivating factors to introduce the concept of an Operand: - Make the translation between Winch and Cranelift easier; - Make dispatching from the MacroAssembler to the underlying Assembler - easier by minimizing the amount of functions that we need to define - in order to satisfy the store/load combinations This commit also introduces the concept of a memory address, which essentially describes the addressing modes; as of this commit only one addressing mode is supported. We'll also need to verify that this structure will play nicely with arm64. * Blank masm implementation for arm64 * Implementation of reserve_stack, local_address, store and fp_offset for x64 * Implement function prologue and argument register spilling * Add structopt and wat * Fix debug instruction formatting * Make TargetISA trait publicly accessible * Modify the MacroAssembler finalize siganture to return a slice of strings * Introduce a simple CLI for Winch To be able to compile Wasm programs with Winch independently. Mostly meant for testing / debugging * Fix bug in x64 assembler mov_rm * Remove unused import * Move the stack slot calculation to the Frame This commit moves the calculation of the stack slots to the frame handler abstraction and also includes the calculation of the limits for the function defined locals, which will be used to zero the locals that are not associated to function arguments * Add i32 and i64 constructors to local slots * Introduce the concept of DefinedLocalsRange This commit introduces `DefinedLocalsRange` to track the stack offset at which the function-defined locals start and end; this is later used to zero-out that stack region * Add constructors for int and float registers * Add a placeholder stack implementation * Add a regset abstraction to track register availability Adds a bit set abstraction to track register availability for register allocation. The bit set has no specific knowledge about physical registers, it works on the register's hardware encoding as the source of truth. Each RegSet is expected to be created with the universe of allocatable registers per ISA when starting the compilation of a particular function. * Add an abstraction over register and immediate This is meant to be used as the source for stores. * Add a way to zero local slots and an initial skeletion of regalloc This commit introduces `zero_local_slots` to the MacroAssembler; which ensures that function defined locals are zeroed out when starting the function body. The algorithm divides the defined function locals stack range into 8 byte slots and stores a zero at each address. This process relies on register allocation if the amount of slots that need to be initialized is greater than 1. In such case, the next available register is requested to the register set and it's used to store a 0, which is then stored at every local slot * Update to wasmparser 0.92 * Correctly track if the regset has registers available * Add a result entry to the ABI signature This commuit introduces ABIResult as part of the ABISignature; this struct will track how function results are stored; initially it will consiste of a single register that will be requested to the register allocator at the end of the function; potentially causing a spill * Move zero local slots and add more granular methods to the masm This commit removes zeroing local slots from the MacroAssembler and instead adds more granular methods to it (e.g `zero`, `add`). This allows for better code sharing since most of the work done by the algorithm for zeroing slots will be the same in all targets, except for the binary emissions pieces, which is what gets delegated to the masm * Use wasmparser's visitor API and add initial support for const and add This commit adds initial support for the I32Const and I32 instructions; this involves adding a minimum for register allocation. Note that some regalloc pieces are still incomplete, since for the current set of supported instructions they are not needed. * Make the ty field public in Local * Add scratch_reg to the abi * Add a method to get a particular local from the Frame * Split the compilation environment abstraction This commit splits the compilation environment into two more concise abstractions: 1. CodeGen: the main abstraction for code generation 2. CodeGenContext: abstraction that shares the common pieces for compilation; these pieces are shared between the code generator and the register allocator * Add `push` and `load` to the MacroAssembler * Remove dead code warnings for unused paths * Map ISA features to cranelift-codegen ISA features * Apply formatting * Fix Cargo.toml after a bad rebase * Add component-compiler feature * Use clap instead of structopt * Add winch to publish.rs script * Minor formatting * Add tests to RegSet and fix two bugs when freeing and checking for register availability * Add tests to Stack * Free source register after a non-constant i32 add * Improve comments - Remove unneeded comments - And improve some of the TODO items * Update default features * Drop the ABI generic param and pass the word_size information directly To avoid dealing with dead code warnings this commit passes the word size information directly, since it's the only piece of information needed from the ABI by Codegen until now * Remove dead code This piece of code will be put back once we start integrating Winch with Wasmtime * Remove unused enum variant This variant doesn't get constructed; it should be added back once a backend is added and not enabled by default or when Winch gets integrated into Wasmtime * Fix unused code in regset tests * Update spec testsuite * Switch the visitor pattern for a simpler operator match This commit removes the usage of wasmparser's visitor pattern and instead defaults to a simpler operator matching approach. This removes the complexity of having to define all the visitor trait functions at once. * Use wasmparser's Visitor trait with a different macro strategy This commit puts back wasmparser's Visitor trait, with a sigle; simpler macro, only used for unsupported operators. * Restructure Winch This commit restuructures Winch's parts. It divides the initial approach into three main crates: `winch-codegen`,`wasmtime-winch` and `winch-tools`. `wasmtime-winch` is reponsible for the Wasmtime-Winch integration. `winch-codegen` is solely responsible for code generation. `winch-tools` is CLI tool to compile Wasm programs, mainly for testing purposes. * Refactor zero local slots This commit moves the logic of zeroing local slots from the codegen module into a method with a default implementation in the MacroAssembler trait: `zero_mem_range`. The refactored implementation is very similar to the previous implementation with the only difference that it doesn't allocates a general-purpose register; it instead uses the register allocator to retrieve the scratch register and uses this register to unroll the series of zero stores. * Tie the codegen creation to the ISA ABI This commit makes the relationship between the ISA ABI and the codegen explicit. This allows us to pass down ABI-specific bit and pieces to the codegeneration. In this case the only concrete piece that we need is the ABI word size. * Mark winch as publishable directory * Revamp winch docs This commit ensures that all the code comments in Winch are compliant with the syle used in the rest of Wasmtime's codebase. It also imptoves, generally the quality of the comments in some modules. * Panic when using multi-value when the target is aarch64 Similar to x64, this commit ensures that the abi signature of the current function doesn't use multi-value returns * Document the usage of directives * Use endianness instead of endianess in the ISA trait * Introduce a three-argument form in the MacroAssembler This commit introduces the usage of three-argument form for the MacroAssembler interface. This allows for a natural mapping for architectures like aarch64. In the case of x64, the implementation can simply restrict the implementation asserting for equality in two of the arguments of defaulting to a differnt set of instructions. As of this commit, the implementation of `add` panics if the destination and the first source arguments are not equal; internally the x64 assembler implementation will ensure that all the allowed combinations of `add` are satisfied. The reason for panicking and not emitting a `mov` followed by an `add` for example is simply because register allocation happens right before calling `add`, which ensures any register-to-register moves, if needed. This implementation will evolve in the future and this panic will be lifted if needed. * Improve the documentation for the MacroAssembler. Documents the usage of three-arg form and the intention around the high-level interface. * Format comments in remaining modules * Clean up Cargo.toml for winch pieces This commit adds missing fields to each of Winch's Cargo.toml. * Use `ModuleTranslation::get_types()` to derive the function type * Assert that start range is always word-size aligned
2 years ago
find_crates("winch".as_ref(), &ws, &mut crates);
let pos = CRATES_TO_PUBLISH
.iter()
.enumerate()
.map(|(i, c)| (*c, i))
.collect::<HashMap<_, _>>();
crates.sort_by_key(|krate| pos.get(&krate.name[..]));
match &env::args().nth(1).expect("must have one argument")[..] {
name @ "bump" | name @ "bump-patch" => {
for krate in crates.iter() {
bump_version(&krate, &crates, name == "bump-patch");
}
// update C API version in wasmtime.h
update_capi_version();
// update the lock file
assert!(Command::new("cargo")
.arg("fetch")
.status()
.unwrap()
.success());
}
"publish" => {
// We have so many crates to publish we're frequently either
// rate-limited or we run into issues where crates can't publish
// successfully because they're waiting on the index entries of
// previously-published crates to propagate. This means we try to
// publish in a loop and we remove crates once they're successfully
// published. Failed-to-publish crates get enqueued for another try
// later on.
for _ in 0..10 {
crates.retain(|krate| !publish(krate));
if crates.is_empty() {
break;
}
println!(
"{} crates failed to publish, waiting for a bit to retry",
crates.len(),
);
thread::sleep(Duration::from_secs(40));
}
assert!(crates.is_empty(), "failed to publish all crates");
println!("");
println!("===================================================================");
println!("");
println!("Don't forget to push a git tag for this release!");
println!("");
println!(" $ git tag vX.Y.Z");
println!(" $ git push git@github.com:bytecodealliance/wasmtime.git vX.Y.Z");
}
"verify" => {
verify(&crates);
}
s => panic!("unknown command: {}", s),
}
}
fn find_crates(dir: &Path, ws: &Workspace, dst: &mut Vec<Crate>) {
if dir.join("Cargo.toml").exists() {
let krate = read_crate(Some(ws), &dir.join("Cargo.toml"));
if !krate.publish || CRATES_TO_PUBLISH.iter().any(|c| krate.name == *c) {
dst.push(krate);
} else {
panic!("failed to find {:?} in whitelist or blacklist", krate.name);
}
}
for entry in dir.read_dir().unwrap() {
let entry = entry.unwrap();
if entry.file_type().unwrap().is_dir() {
find_crates(&entry.path(), ws, dst);
}
}
}
fn read_crate(ws: Option<&Workspace>, manifest: &Path) -> Crate {
let mut name = None;
let mut version = None;
let mut publish = true;
for line in fs::read_to_string(manifest).unwrap().lines() {
if name.is_none() && line.starts_with("name = \"") {
name = Some(
line.replace("name = \"", "")
.replace("\"", "")
.trim()
.to_string(),
);
}
if version.is_none() && line.starts_with("version = \"") {
version = Some(
line.replace("version = \"", "")
.replace("\"", "")
.trim()
.to_string(),
);
}
if let Some(ws) = ws {
if version.is_none() && line.starts_with("version.workspace = true") {
version = Some(ws.version.clone());
}
}
if line.starts_with("publish = false") {
publish = false;
}
}
let name = name.unwrap();
let version = version.unwrap();
if ["witx", "witx-cli", "wasi-crypto"].contains(&&name[..]) {
publish = false;
}
Crate {
manifest: manifest.to_path_buf(),
name,
version,
publish,
}
}
fn bump_version(krate: &Crate, crates: &[Crate], patch: bool) {
let contents = fs::read_to_string(&krate.manifest).unwrap();
let next_version = |krate: &Crate| -> String {
if CRATES_TO_PUBLISH.contains(&&krate.name[..]) {
bump(&krate.version, patch)
} else {
krate.version.clone()
}
};
let mut new_manifest = String::new();
let mut is_deps = false;
for line in contents.lines() {
let mut rewritten = false;
if !is_deps && line.starts_with("version =") {
if CRATES_TO_PUBLISH.contains(&&krate.name[..]) {
println!(
"bump `{}` {} => {}",
krate.name,
krate.version,
next_version(krate),
);
new_manifest.push_str(&line.replace(&krate.version, &next_version(krate)));
rewritten = true;
}
}
is_deps = if line.starts_with("[") {
line.contains("dependencies")
} else {
is_deps
};
for other in crates {
// If `other` isn't a published crate then it's not going to get a
// bumped version so we don't need to update anything in the
// manifest.
if !other.publish {
continue;
}
if !is_deps || !line.starts_with(&format!("{} ", other.name)) {
continue;
}
if !line.contains(&other.version) {
Adjust dependency directives between crates (#3420) * Adjust dependency directives between crates This commit is a preparation for the release process for Wasmtime. The specific changes here are to delineate which crates are &#34;public&#34;, and all version requirements on non-public crates will now be done with `=A.B.C` version requirements instead of today&#39;s `A.B.C` version requirements. The purpose for doing this is to assist with patch releases that might happen in the future. Patch releases of wasmtime are already required to not break the APIs of &#34;public&#34; crates, but no such guarantee is given about &#34;internal&#34; crates. This means that a patch release runs the risk, for example, of breaking an internal API. In doing so though we would also need to release a new major version of the internal crate, but we wouldn&#39;t have a great hole in the number scheme of major versions to do so. By using `=A.B.C` requirements for internal crates it means we can safely ignore strict semver-compatibility between releases of internal crates for patch releases, since the only consumers of the crate will be the corresponding patch release of the `wasmtime` crate itself (or other public crates). The `publish.rs` script has been updated with a check to verify that dependencies on internal crates are all specified with an `=` dependency, and dependnecies on all public crates are without a `=` dependency. This will hopefully make it so we don&#39;t have to worry about what to use where, we just let CI tell us what to do. Using this modification all version dependency declarations have been updated. Note that some crates were adjusted to simply remove their `version` requirement in cases such as the crate wasn&#39;t published anyway (`publish = false` was specified) or it&#39;s in the `dev-dependencies` section which doesn&#39;t need version specifiers for path dependencies. * Switch to normal sever deps for cranelift dependencies These crates will now all be considered &#34;public&#34; where in patch releases they will be guaranteed to not have breaking changes.
3 years ago
if !line.contains("version =") || !krate.publish {
continue;
}
panic!(
"{:?} has a dep on {} but doesn't list version {}",
krate.manifest, other.name, other.version
);
}
Adjust dependency directives between crates (#3420) * Adjust dependency directives between crates This commit is a preparation for the release process for Wasmtime. The specific changes here are to delineate which crates are &#34;public&#34;, and all version requirements on non-public crates will now be done with `=A.B.C` version requirements instead of today&#39;s `A.B.C` version requirements. The purpose for doing this is to assist with patch releases that might happen in the future. Patch releases of wasmtime are already required to not break the APIs of &#34;public&#34; crates, but no such guarantee is given about &#34;internal&#34; crates. This means that a patch release runs the risk, for example, of breaking an internal API. In doing so though we would also need to release a new major version of the internal crate, but we wouldn&#39;t have a great hole in the number scheme of major versions to do so. By using `=A.B.C` requirements for internal crates it means we can safely ignore strict semver-compatibility between releases of internal crates for patch releases, since the only consumers of the crate will be the corresponding patch release of the `wasmtime` crate itself (or other public crates). The `publish.rs` script has been updated with a check to verify that dependencies on internal crates are all specified with an `=` dependency, and dependnecies on all public crates are without a `=` dependency. This will hopefully make it so we don&#39;t have to worry about what to use where, we just let CI tell us what to do. Using this modification all version dependency declarations have been updated. Note that some crates were adjusted to simply remove their `version` requirement in cases such as the crate wasn&#39;t published anyway (`publish = false` was specified) or it&#39;s in the `dev-dependencies` section which doesn&#39;t need version specifiers for path dependencies. * Switch to normal sever deps for cranelift dependencies These crates will now all be considered &#34;public&#34; where in patch releases they will be guaranteed to not have breaking changes.
3 years ago
if krate.publish {
if PUBLIC_CRATES.contains(&other.name.as_str()) {
assert!(
!line.contains("\"="),
"{} should not have an exact version requirement on {}",
krate.name,
other.name
);
} else {
assert!(
line.contains("\"="),
"{} should have an exact version requirement on {}",
krate.name,
other.name
);
}
}
rewritten = true;
new_manifest.push_str(&line.replace(&other.version, &next_version(other)));
break;
}
if !rewritten {
new_manifest.push_str(line);
}
new_manifest.push_str("\n");
}
fs::write(&krate.manifest, new_manifest).unwrap();
}
fn update_capi_version() {
let version = read_crate(None, "./Cargo.toml".as_ref()).version;
let mut iter = version.split('.').map(|s| s.parse::<u32>().unwrap());
let major = iter.next().expect("major version");
let minor = iter.next().expect("minor version");
let patch = iter.next().expect("patch version");
let mut new_header = String::new();
let contents = fs::read_to_string(C_HEADER_PATH).unwrap();
for line in contents.lines() {
if line.starts_with("#define WASMTIME_VERSION \"") {
new_header.push_str(&format!("#define WASMTIME_VERSION \"{version}\""));
} else if line.starts_with("#define WASMTIME_VERSION_MAJOR") {
new_header.push_str(&format!("#define WASMTIME_VERSION_MAJOR {major}"));
} else if line.starts_with("#define WASMTIME_VERSION_MINOR") {
new_header.push_str(&format!("#define WASMTIME_VERSION_MINOR {minor}"));
} else if line.starts_with("#define WASMTIME_VERSION_PATCH") {
new_header.push_str(&format!("#define WASMTIME_VERSION_PATCH {patch}"));
} else {
new_header.push_str(line);
}
new_header.push_str("\n");
}
fs::write(&C_HEADER_PATH, new_header).unwrap();
}
/// Performs a major version bump increment on the semver version `version`.
///
/// This function will perform a semver-major-version bump on the `version`
/// specified. This is used to calculate the next version of a crate in this
/// repository since we're currently making major version bumps for all our
/// releases. This may end up getting tweaked as we stabilize crates and start
/// doing more minor/patch releases, but for now this should do the trick.
fn bump(version: &str, patch_bump: bool) -> String {
let mut iter = version.split('.').map(|s| s.parse::<u32>().unwrap());
let major = iter.next().expect("major version");
let minor = iter.next().expect("minor version");
let patch = iter.next().expect("patch version");
if patch_bump {
return format!("{}.{}.{}", major, minor, patch + 1);
}
if major != 0 {
format!("{}.0.0", major + 1)
} else if minor != 0 {
format!("0.{}.0", minor + 1)
} else {
format!("0.0.{}", patch + 1)
}
}
fn publish(krate: &Crate) -> bool {
if !CRATES_TO_PUBLISH.iter().any(|s| *s == krate.name) {
return true;
}
// First make sure the crate isn't already published at this version. This
// script may be re-run and there's no need to re-attempt previous work.
let output = Command::new("curl")
.arg(&format!("https://crates.io/api/v1/crates/{}", krate.name))
.output()
.expect("failed to invoke `curl`");
if output.status.success()
&& String::from_utf8_lossy(&output.stdout)
.contains(&format!("\"newest_version\":\"{}\"", krate.version))
{
println!(
"skip publish {} because {} is latest version",
krate.name, krate.version,
);
return true;
}
let status = Command::new("cargo")
.arg("publish")
.current_dir(krate.manifest.parent().unwrap())
.arg("--no-verify")
.status()
.expect("failed to run cargo");
if !status.success() {
println!("FAIL: failed to publish `{}`: {}", krate.name, status);
return false;
}
// After we've published then make sure that the `wasmtime-publish` group is
// added to this crate for future publications. If it's already present
// though we can skip the `cargo owner` modification.
let output = Command::new("curl")
.arg(&format!(
"https://crates.io/api/v1/crates/{}/owners",
krate.name
))
.output()
.expect("failed to invoke `curl`");
if output.status.success()
&& String::from_utf8_lossy(&output.stdout).contains("wasmtime-publish")
{
println!(
"wasmtime-publish already listed as an owner of {}",
krate.name
);
return true;
}
// Note that the status is ignored here. This fails most of the time because
// the owner is already set and present, so we only want to add this to
// crates which haven't previously been published.
let status = Command::new("cargo")
.arg("owner")
.arg("-a")
.arg("github:bytecodealliance:wasmtime-publish")
.arg(&krate.name)
.status()
.expect("failed to run cargo");
if !status.success() {
panic!(
"FAIL: failed to add wasmtime-publish as owner `{}`: {}",
krate.name, status
);
}
true
}
// Verify the current tree is publish-able to crates.io. The intention here is
// that we'll run `cargo package` on everything which verifies the build as-if
// it were published to crates.io. This requires using an incrementally-built
// directory registry generated from `cargo vendor` because the versions
// referenced from `Cargo.toml` may not exist on crates.io.
fn verify(crates: &[Crate]) {
verify_capi();
drop(fs::remove_dir_all(".cargo"));
drop(fs::remove_dir_all("vendor"));
let vendor = Command::new("cargo")
.arg("vendor")
.stderr(Stdio::inherit())
.output()
.unwrap();
assert!(vendor.status.success());
fs::create_dir_all(".cargo").unwrap();
fs::write(".cargo/config.toml", vendor.stdout).unwrap();
// Vendor witx which wasn't vendored because it's a path dependency, but
// it'll need to be in our directory registry for crates that depend on it.
let witx = crates
.iter()
.find(|c| c.name == "witx" && c.manifest.iter().any(|p| p == "wasi-common"))
.unwrap();
verify_and_vendor(&witx);
// Vendor wasi-crypto which is also a path dependency
let wasi_crypto = crates.iter().find(|c| c.name == "wasi-crypto").unwrap();
verify_and_vendor(&wasi_crypto);
for krate in crates {
if !krate.publish {
continue;
}
verify_and_vendor(&krate);
}
fn verify_and_vendor(krate: &Crate) {
let mut cmd = Command::new("cargo");
cmd.arg("package")
.arg("--manifest-path")
.arg(&krate.manifest)
.env("CARGO_TARGET_DIR", "./target");
if krate.name == "witx" || krate.name.contains("wasi-nn") {
cmd.arg("--no-verify");
}
let status = cmd.status().unwrap();
assert!(status.success(), "failed to verify {:?}", &krate.manifest);
let tar = Command::new("tar")
.arg("xf")
.arg(format!(
"../target/package/{}-{}.crate",
krate.name, krate.version
))
.current_dir("./vendor")
.status()
.unwrap();
assert!(tar.success());
fs::write(
format!(
"./vendor/{}-{}/.cargo-checksum.json",
krate.name, krate.version
),
"{\"files\":{}}",
)
.unwrap();
}
fn verify_capi() {
let version = read_crate(None, "./Cargo.toml".as_ref()).version;
let mut iter = version.split('.').map(|s| s.parse::<u32>().unwrap());
let major = iter.next().expect("major version");
let minor = iter.next().expect("minor version");
let patch = iter.next().expect("patch version");
let mut count = 0;
let contents = fs::read_to_string(C_HEADER_PATH).unwrap();
for line in contents.lines() {
if line.starts_with(&format!("#define WASMTIME_VERSION \"{version}\"")) {
count += 1;
} else if line.starts_with(&format!("#define WASMTIME_VERSION_MAJOR {major}")) {
count += 1;
} else if line.starts_with(&format!("#define WASMTIME_VERSION_MINOR {minor}")) {
count += 1;
} else if line.starts_with(&format!("#define WASMTIME_VERSION_PATCH {patch}")) {
count += 1;
}
}
assert!(
count == 4,
"invalid version macros in {}, should match \"{}\"",
C_HEADER_PATH,
version
);
}
}