|
|
|
//! 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",
|
|
|
|
"cranelift-codegen",
|
|
|
|
"cranelift-reader",
|
|
|
|
"cranelift-serde",
|
|
|
|
"cranelift-module",
|
|
|
|
"cranelift-frontend",
|
|
|
|
"cranelift-wasm",
|
|
|
|
"cranelift-native",
|
|
|
|
"cranelift-object",
|
|
|
|
"cranelift-interpreter",
|
|
|
|
"cranelift",
|
|
|
|
"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",
|
|
|
|
"wasmtime-fiber",
|
|
|
|
"wasmtime-environ",
|
|
|
|
"wasmtime-runtime",
|
|
|
|
"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",
|
|
|
|
];
|
|
|
|
|
|
|
|
// 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",
|
|
|
|
"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",
|
|
|
|
"cranelift-egraph",
|
|
|
|
"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) {
|
|
|
|
if !line.contains("version =") || !krate.publish {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
panic!(
|
|
|
|
"{:?} has a dep on {} but doesn't list version {}",
|
|
|
|
krate.manifest, other.name, other.version
|
|
|
|
);
|
|
|
|
}
|
|
|
|
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
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|