This commit adds lots of plumbing to get the type section from the
module linking proposal plumbed all the way through to the `wasmtime`
crate and the `wasmtime-c-api` crate. This isn't all that useful right
now because Wasmtime doesn't support imported/exported
modules/instances, but this is all necessary groundwork to getting that
exported at some point. I've added some light tests but I suspect the
bulk of the testing will come in a future commit.
One major change in this commit is that `SignatureIndex` no longer
follows type type index space in a wasm module. Instead a new
`TypeIndex` type is used to track that. Function signatures, still
indexed by `SignatureIndex`, are then packed together tightly.
* Validate modules while translating
This commit is a change to cranelift-wasm to validate each function body
as it is translated. Additionally top-level module translation functions
will perform module validation. This commit builds on changes in
wasmparser to perform module validation interwtwined with parsing and
translation. This will be necessary for future wasm features such as
module linking where the type behind a function index, for example, can
be far away in another module. Additionally this also brings a nice
benefit where parsing the binary only happens once (instead of having an
up-front serial validation step) and validation can happen in parallel
for each function.
Most of the changes in this commit are plumbing to make sure everything
lines up right. The major functional change here is that module
compilation should be faster by validating in parallel (or skipping
function validation entirely in the case of a cache hit). Otherwise from
a user-facing perspective nothing should be that different.
This commit does mean that cranelift's translation now inherently
validates the input wasm module. This means that the Spidermonkey
integration of cranelift-wasm will also be validating the function as
it's being translated with cranelift. The associated PR for wasmparser
(bytecodealliance/wasmparser#62) provides the necessary tools to create
a `FuncValidator` for Gecko, but this is something I'll want careful
review for before landing!
* Read function operators until EOF
This way we can let the validator take care of any issues with
mismatched `end` instructions and/or trailing operators/bytes.
`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`.
This should be more efficient than using a `VMExternRef` that points at a
`VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic
allocation, and some reference counting.
Note that the null function reference is *NOT* a null pointer; it is a
`VMCallerCheckedAnyfunc` that has a null `func_ptr` member.
Part of #929
* Allow different Cranelift IR types to be used for different Wasm reference
types.
* Do not assume that all Wasm reference types are always a Cranelift IR
reference type. For example, `funcref`s might not need GC in some
implementations, and can therefore be represented with a pointer rather than a
reference type.
* Compute instance exports on demand.
Instead having instances eagerly compute a Vec of Externs, and bumping
the refcount for each Extern, compute Externs on demand.
This also enables `Instance::get_export` to avoid doing a linear search.
This also means that the closure returned by `get0` and friends now
holds an `InstanceHandle` to dynamically hold the instance live rather
than being scoped to a lifetime.
* Compute module imports and exports on demand too.
And compute Extern::ty on demand too.
* Add a utility function for computing an ExternType.
* Add a utility function for looking up a function's signature.
* Add a utility function for computing the ValType of a Global.
* Rename wasmtime_environ::Export to EntityIndex.
This helps differentiate it from other Export types in the tree, and
describes what it is.
* Fix a typo in a comment.
* Simplify module imports and exports.
* Make `Instance::exports` return the export names.
This significantly simplifies the public API, as it's relatively common
to need the names, and this avoids the need to do a zip with
`Module::exports`.
This also changes `ImportType` and `ExportType` to have public members
instead of private members and accessors, as I find that simplifies the
usage particularly in cases where there are temporary instances.
* Remove `Instance::module`.
This doesn't quite remove `Instance`'s `module` member, it gets a step
closer.
* Use a InstanceHandle utility function.
* Don't consume self in the `Func::get*` methods.
Instead, just create a closure containing the instance handle and the
export for them to call.
* Use `ExactSizeIterator` to avoid needing separate `num_*` methods.
* Rename `Extern::func()` etc. to `into_func()` etc.
* Revise examples to avoid using `nth`.
* Add convenience methods to instance for getting specific extern types.
* Use the convenience functions in more tests and examples.
* Avoid cloning strings for `ImportType` and `ExportType`.
* Remove more obviated clone() calls.
* Simplify `Func`'s closure state.
* Make wasmtime::Export's fields private.
This makes them more consistent with ExportType.
* Fix compilation error.
* Make a lifetime parameter explicit, and use better lifetime names.
Instead of 'me, use 'instance and 'module to make it clear what the
lifetime is.
* More lifetime cleanups.
* rename PassiveElemIndex to ElemIndex and same for PassiveDataIndex (#1411)
* rename PassiveDataIndex to DataIndex
* rename PassiveElemIndex to ElemIndex
* Apply renamings to wasmtime as well
* Run rustfmt
Co-authored-by: csmoe <csmoe@msn.com>
* Manually rename BasicBlock to BlockPredecessor
BasicBlock is a pair of (Ebb, Inst) that is used to represent the
basic block subcomponent of an Ebb that is a predecessor to an Ebb.
Eventually we will be able to remove this struct, but for now it
makes sense to give it a non-conflicting name so that we can start
to transition Ebb to represent a basic block.
I have not updated any comments that refer to BasicBlock, as
eventually we will remove BlockPredecessor and replace with Block,
which is a basic block, so the comments will become correct.
* Manually rename SSABuilder block types to avoid conflict
SSABuilder has its own Block and BlockData types. These along with
associated identifier will cause conflicts in a later commit, so
they are renamed to be more verbose here.
* Automatically rename 'Ebb' to 'Block' in *.rs
* Automatically rename 'EBB' to 'block' in *.rs
* Automatically rename 'ebb' to 'block' in *.rs
* Automatically rename 'extended basic block' to 'basic block' in *.rs
* Automatically rename 'an basic block' to 'a basic block' in *.rs
* Manually update comment for `Block`
`Block`'s wikipedia article required an update.
* Automatically rename 'an `Block`' to 'a `Block`' in *.rs
* Automatically rename 'extended_basic_block' to 'basic_block' in *.rs
* Automatically rename 'ebb' to 'block' in *.clif
* Manually rename clif constant that contains 'ebb' as substring to avoid conflict
* Automatically rename filecheck uses of 'EBB' to 'BB'
'regex: EBB' -> 'regex: BB'
'$EBB' -> '$BB'
* Automatically rename 'EBB' 'Ebb' to 'block' in *.clif
* Automatically rename 'an block' to 'a block' in *.clif
* Fix broken testcase when function name length increases
Test function names are limited to 16 characters. This causes
the new longer name to be truncated and fail a filecheck test. An
outdated comment was also fixed.
* cranelift-wasm: replace `WasmTypesMap` with `ModuleTranslationState`
The `ModuleTranslationState` contains information decoded from the Wasm module
that must be referenced during each Wasm function's translation.
This is only for data that is maintained by `cranelift-wasm` itself, as opposed
to being maintained by the embedder. Data that is maintained by the embedder is
represented with `ModuleEnvironment`.
A `ModuleTranslationState` is returned by `translate_module`, and can then be
used when translating functions from that module.
* cranelift-wasm: rename `TranslationState` to `FuncTranslationState`
To disambiguate a bit with the new `ModuleTranslationState`.
* cranelift-wasm: Reorganize the internal `state` module into submodules
One module for the `ModuleTranslationState` and another for the
`FuncTranslationState`.
* cranelift-wasm: replace `FuncTranslator` with methods on `ModuleTranslationState`
`FuncTranslator` was two methods that always took ownership of `self`, so it
didn't really make sense as an object as opposed to two different functions, or
in this case methods on the object that actually persists for a longer time.
I think this improves ergonomics nicely.
Before:
```rust
let module_translation = translate_module(...)?;
for body in func_bodies {
let mut translator = FuncTranslator::new();
translator.translate(body, ...)?;
}
```
After:
```rust
let module_translation = translate_module(...)?;
for body in func_bodies {
module_translation.translate_func(body, ...)?;
}
```
Note that this commit does not remove `FuncTranslator`. It still exists, but is
just a wrapper over the `ModuleTranslationState` methods, and it is marked
deprecated, so that downstream users get a heads up. This should make the
transition easier.
* Revert "cranelift-wasm: replace `FuncTranslator` with methods on `ModuleTranslationState`"
This reverts commit 075f9ae933bcaae39348b61287c8f78a4009340d.
This commit introduces initial support for multi-value Wasm. Wasm blocks and
calls can now take and return an arbitrary number of values.
The encoding for multi-value blocks means that we need to keep the contents of
the "Types" section around when translating function bodies. To do this, we
introduce a `WasmTypesMap` type that maps the type indices to their parameters
and returns, construct it when parsing the "Types" section, and shepherd it
through a bunch of functions and methods when translating function bodies.
This patch restricts the `Err(..)` return from `blocktype_to_type` to be
`Err(..)` only in the case where it really is an error to continue. The three
use points of `blocktype_to_type` are changed to check for an `Err(..)` rather
than silently ignoring it. There are also cosmetic changes to `type_to_type`
and `tabletype_to_type`.
When compiling wasm_lua_binarytrees, this reduces the number of blocks
allocated by CL by 1.9%. Instruction count falls by 0.1%.
Details:
* `type_to_type` and `tabletype_to_type`:
- Added the function name in the failure message
- No functional change for non-error cases
- Push the `Ok(..)` to expression leaves, where it really applies. This
corrects the misleading impression that, in the case of an unsupported
type, the function returns `Ok` wrapped around whatever
`wasm_unsupported` returns. It doesn't do that, but it certainly reads
like that. This assumes that the LLVM backend will do tail merging, so
the generated code will be unchanged.
* `blocktype_to_type`:
- Change return type from `WasmResult<ir::Type>` to `WasmResult<Option<ir::Type>>`
- Manually inline the call to `type_to_type`, to make this function easier
to read.
- For the non-error case: map `TypeOrFuncType::Type(Type::EmptyBlockType)`
to `Ok(None)` rather than `Err(..)`, since that's what all the call sites
expect - For the error cases, add the function name in the failure
messages
* cranelift-wasm/src/code_translator.rs
- For the three uses of `blocktype_to_type`, use `?` to detect failures and
drop out immediately, meaning that the code will no longer silently ignore
errors.
* [wasm] return a WasmResult from `declare_table_elements`
This method in particular needs to accommodate failure because any table index other than zero is
currently invalid.
* [wasm] additional failure handling improvements
- Adds `WasmResult<()>` as the return type for most of the `ModuleEnvironment` methods that
previously returned nothing.
- Replaces some panics with `WasmError::Unsupported` now that the methods can return a result.
- Adds a `wasm_unsupported!()` macro for early returns with a formatted unsupported message.