We weren't previously keeping track of quite the right information for whether
an `if .. else .. end`'s following block was reachable or not. It should be
reachable if the head is reachable and either the consequent or alternative end
reachable (and therefore fall through to the following block) or do an early
`br_if` to it.
This commit rejiggers `ControlStackFrame::If` to keep track of reachability at
the end of the consequent (we don't need to keep track of it at the end of the
alternative, since that is simply `state.reachable`) and adds Wasm tests for
every reachability situation we can encounter with `if .. else .. end`.
Fixes#1132
* 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 fixes a bug where at the end of an `if..else..end`'s consequent
block, we would sometimes erroneously jump to the `else` block instead of to the
following destination block. Not good!
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.
Only i16x8 and i32x4 are encoded in this commit mainly because i8x16 and i64x2 do not have simple encodings in x86. i64x2 is not required by the SIMD spec and there is discussion (https://github.com/WebAssembly/simd/pull/98#issuecomment-530092217) about removing i8x16.
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.
By default, constants added by SIMD's v128.const will be typed as I8x16 in CLIF. This type must be changed to the appropriate vector type before use to satisfy cranelift's type checking. To do this, we track what SSA values are created by v128.const and convert them with a raw_bitcast immediately before use in the currently implemented SIMD instructions.
-Add resumable_trap, safepoint, isnull, and null instructions
-Add Stackmap struct and StackmapSink trait
Co-authored-by: Mir Ahmed <mirahmed753@gmail.com>
Co-authored-by: Dan Gohman <sunfish@mozilla.com>
* [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.