Skip to content

Commit

Permalink
Bug 1677452 - Update Cranelift to firefox85 / dcc52ba3f69d3de7cdbd787…
Browse files Browse the repository at this point in the history
…b936825d9c61e3c27 and wasmparser to 0.67: Part 1 - hash and API changes. r=lth.

This updates the relevant CL and wasmparser versions:

* wasmparser 0.67

* Cranelift/wasmtime to dcc52ba3f69d3de7cdbd787b936825d9c61e3c27
  on branch firefox85 at https://github.com/mozilla-spidermonkey/wasmtime

It also includes the following changes needed to track CL/wasmparser ABI changes:

* test suite: track improvements to validation-failure expected outputs.

* wasm/cranelift/src/bindings/mod.rs, ModuleEnvironment::signature: track
  CL-side changes towards module-linking support.

* wasm/cranelift/src/wasm2clif.rs: FuncEnvironment::translate_memory_copy:
  track CL-side changes for supporting multiple memories.

Differential Revision: https://phabricator.services.mozilla.com/D97587
  • Loading branch information
julian-seward1 committed Nov 19, 2020
1 parent 842f9f3 commit f28cf58
Show file tree
Hide file tree
Showing 13 changed files with 56 additions and 52 deletions.
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,11 @@ failure = { git = "https://github.com/badboy/failure", rev = "64af847bc5fdcb6d24
failure_derive = { git = "https://github.com/badboy/failure", rev = "64af847bc5fdcb6d2438bec8a6030812a80519a5" }

[patch.crates-io.cranelift-codegen]
git = "https://github.com/bytecodealliance/wasmtime"
rev = "e22e2c3722f2fbccd3c8d3230119fa04c332c69c"
git = "https://github.com/mozilla-spidermonkey/wasmtime"
rev = "dcc52ba3f69d3de7cdbd787b936825d9c61e3c27"
branch = "firefox85"

[patch.crates-io.cranelift-wasm]
git = "https://github.com/bytecodealliance/wasmtime"
rev = "e22e2c3722f2fbccd3c8d3230119fa04c332c69c"
git = "https://github.com/mozilla-spidermonkey/wasmtime"
rev = "dcc52ba3f69d3de7cdbd787b936825d9c61e3c27"
branch = "firefox85"
15 changes: 1 addition & 14 deletions js/src/jit-test/lib/wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,9 @@ function wasmCompilationShouldFail(bin, compile_error_regex) {
}
}

function typeToCraneliftName(ty) {
switch(ty) {
case 'externref':
return 'ExternRef';
case 'funcref':
return 'FuncRef';
default:
return ty.toUpperCase();
}
}

function mismatchError(actual, expect) {
let actualCL = typeToCraneliftName(actual);
let expectCL = typeToCraneliftName(expect);
var str = `(type mismatch: expression has type ${actual} but expected ${expect})|` +
`(type mismatch: expected Some\\(${expectCL}\\), found Some\\(${actualCL}\\))`;
`(type mismatch: expected ${expect}, found ${actual}\)`;
return RegExp(str);
}

Expand Down
16 changes: 8 additions & 8 deletions js/src/jit-test/tests/wasm/control-flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ wasmFullPass(`(module
assertEq(counter, 0);

// "if" doesn't return an expression value
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 42) (i32.const 0))))', /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 42) (i32.const 0))))', /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 42) (drop (i32.const 0)))))', emptyStackError);
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 1) (i32.const 0) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 1) (i32.const 0) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);
wasmFailValidateText('(module (func (result i32) (if (result i32) (i32.const 1) (drop (i32.const 0)) (if (i32.const 1) (drop (i32.const 1))))))', emptyStackError);
wasmFailValidateText('(module (func (if (result i32) (i32.const 1) (i32.const 0) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText('(module (func (if (result i32) (i32.const 1) (i32.const 0) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);
wasmFailValidateText('(module (func (if (result i32) (i32.const 1) (i32.const 0) (if (i32.const 1) (drop (i32.const 1))))))', emptyStackError);
wasmFailValidateText('(module (func (if (i32.const 1) (drop (i32.const 0)) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText('(module (func (if (i32.const 1) (drop (i32.const 0)) (if (result i32) (i32.const 1) (i32.const 1)))))', /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);
wasmEvalText('(module (func (if (i32.const 1) (drop (i32.const 0)) (if (i32.const 1) (drop (i32.const 1))))))');

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -315,7 +315,7 @@ wasmFailValidateText('(module (func (result i32) (br 0 (f32.const 42))))', misma
wasmFailValidateText('(module (func (result i32) (block (br 0))))', emptyStackError);
wasmFailValidateText('(module (func (result i32) (block (result f32) (br 0 (f32.const 42)))))', mismatchError("f32", "i32"));

wasmFailValidateText(`(module (func (param i32) (result i32) (block (if (result i32) (local.get 0) (br 0 (i32.const 42))))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText(`(module (func (param i32) (result i32) (block (if (result i32) (local.get 0) (br 0 (i32.const 42))))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);
wasmFailValidateText(`(module (func (param i32) (result i32) (block (result i32) (if (local.get 0) (drop (i32.const 42))) (br 0 (f32.const 42)))) (export "" (func 0)))`, mismatchError("f32", "i32"));

wasmFullPass('(module (func (result i32) (br 0 (i32.const 42)) (i32.const 13)) (export "run" (func 0)))', 42);
Expand All @@ -328,7 +328,7 @@ var f = wasmEvalText(`(module (func (param i32) (result i32) (block (result i32)
assertEq(f(0), 43);
assertEq(f(1), 43);

wasmFailValidateText(`(module (func (param i32) (result i32) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 42))) (i32.const 43))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText(`(module (func (param i32) (result i32) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 42))) (i32.const 43))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);

var f = wasmEvalText(`(module (func (param i32) (result i32) (block (result i32) (if (local.get 0) (br 1 (i32.const 42))) (i32.const 43))) (export "" (func 0)))`).exports[""];
assertEq(f(0), 43);
Expand All @@ -344,7 +344,7 @@ var f = wasmEvalText(`(module (func (param i32) (result i32) (block (result i32)
assertEq(f(0), 43);
assertEq(f(1), 43);

wasmFailValidateText(`(module (func (param i32) (result i32) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 42))) (br 0 (i32.const 43)))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText(`(module (func (param i32) (result i32) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 42))) (br 0 (i32.const 43)))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);

var f = wasmEvalText(`(module (func (param i32) (result i32) (if (local.get 0) (br 1 (i32.const 42))) (br 0 (i32.const 43))) (export "" (func 0)))`).exports[""];
assertEq(f(0), 43);
Expand All @@ -366,7 +366,7 @@ var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const
assertEq(f(0), 0);
assertEq(f(1), 0);

wasmFailValidateText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 99))) (i32.const -1)))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected Some\(I32\) but nothing on stack)/);
wasmFailValidateText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (result i32) (if (result i32) (local.get 0) (br 0 (i32.const 99))) (i32.const -1)))) (export "" (func 0)))`, /(if without else with a result value)|(type mismatch: expected i32 but nothing on stack)/);

var f = wasmEvalText(`(module (func (param i32) (result i32) (i32.add (i32.const 1) (block (result i32) (if (local.get 0) (br 1 (i32.const 99))) (i32.const -1)))) (export "" (func 0)))`).exports[""];
assertEq(f(0), 0);
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit-test/tests/wasm/float.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ wasmFailValidateText('(module (func (param i32) (result i32) (f32.sqrt (local.ge
wasmFailValidateText('(module (func (param i32) (result f64) (f64.sqrt (local.get 0))))', mismatchError("i32", "f64"));
wasmFailValidateText('(module (func (param f64) (result i32) (f64.sqrt (local.get 0))))', mismatchError("f64", "i32"));
wasmFailValidateText('(module (func (param i32) (result i32) (f64.sqrt (local.get 0))))', mismatchError("i32", "f64"));
wasmFailValidateText('(module (func (f32.sqrt (nop))))', /(popping value from empty stack)|(type mismatch: expected Some\(F32\) but nothing on stack)/);
wasmFailValidateText('(module (func (f32.sqrt (nop))))', /(popping value from empty stack)|(type mismatch: expected f32 but nothing on stack)/);

wasmFailValidateText('(module (func (param i32) (param f32) (result f32) (f32.add (local.get 0) (local.get 1))))', mismatchError("i32", "f32"));
wasmFailValidateText('(module (func (param f32) (param i32) (result f32) (f32.add (local.get 0) (local.get 1))))', mismatchError("i32", "f32"));
Expand Down
4 changes: 2 additions & 2 deletions js/src/jit-test/tests/wasm/passive-segs-boundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ mem_test("(memory.init 1 (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
// init: too few args
mem_test("(memory.init 1 (i32.const 1) (i32.const 1))", "",
WebAssembly.CompileError,
/(popping value from empty stack)|(expected Some\(I32\) but nothing on stack)/);
/(popping value from empty stack)|(expected i32 but nothing on stack)/);

// invalid argument types
{
Expand Down Expand Up @@ -372,7 +372,7 @@ tab_test("(table.init 1 (i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1))
// init: too few args
tab_test("(table.init 1 (i32.const 1) (i32.const 1))", "",
WebAssembly.CompileError,
/(popping value from empty stack)|(expected Some\(I32\) but nothing on stack)/);
/(popping value from empty stack)|(expected i32 but nothing on stack)/);

// invalid argument types
{
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ checkMiscPrefixed([0x13], true); // table.size+1, which is currently unas
)`;
assertErrorMessage(() => wasmEvalText(text1),
WebAssembly.CompileError,
/(popping value from empty stack)|(expected Some\(I32\) but nothing on stack)/);
/(popping value from empty stack)|(expected i32 but nothing on stack)/);
let text2 =
`(module
(memory (export "memory") 1 1)
Expand Down
8 changes: 4 additions & 4 deletions js/src/jit-test/tests/wasm/ref-types/tables-fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ assertErrorMessage(() => wasmEvalText(
(table.fill $t (i32.const 0) (ref.null extern) (f64.const 0))
))`),
WebAssembly.CompileError,
/(type mismatch: expression has type f64 but expected i32)|(type mismatch: expected Some\(I32\), found Some\(F64\))/);
/(type mismatch: expression has type f64 but expected i32)|(type mismatch: expected i32, found f64)/);

assertErrorMessage(() => wasmEvalText(
`(module
Expand All @@ -184,7 +184,7 @@ assertErrorMessage(() => wasmEvalText(
(table.fill $t (i32.const 0) (f32.const 0) (i32.const 0))
))`),
WebAssembly.CompileError,
/(type mismatch: expression has type f32 but expected externref)|(type mismatch: expected Some\(ExternRef\), found Some\(F32\))/);
/(type mismatch: expression has type f32 but expected externref)|(type mismatch: expected externref, found f32)/);

assertErrorMessage(() => wasmEvalText(
`(module
Expand All @@ -193,7 +193,7 @@ assertErrorMessage(() => wasmEvalText(
(table.fill $t (i64.const 0) (ref.null extern) (i32.const 0))
))`),
WebAssembly.CompileError,
/(type mismatch: expression has type i64 but expected i32)|(type mismatch: expected Some\(I32\), found Some\(I64\))/);
/(type mismatch: expression has type i64 but expected i32)|(type mismatch: expected i32, found i64)/);

assertErrorMessage(() => wasmEvalText(
`(module
Expand All @@ -211,4 +211,4 @@ assertErrorMessage(() => wasmEvalText(
(table.fill (i32.const 0) (local.get $v) (i32.const 0)))
)`),
WebAssembly.CompileError,
/(expression has type externref but expected funcref)|(type mismatch: expected Some\(FuncRef\), found Some\(ExternRef\))/);
/(expression has type externref but expected funcref)|(type mismatch: expected funcref, found externref)/);
4 changes: 2 additions & 2 deletions js/src/jit-test/tests/wasm/ref-types/tables-generalized.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
(func (export "set_ref") (param i32) (param externref)
(table.set (local.get 0) (local.get 1))))`)),
WebAssembly.CompileError,
/(type mismatch: expression has type externref but expected funcref)|(type mismatch: expected Some\(FuncRef\), found Some\(ExternRef\))/);
/(type mismatch: expression has type externref but expected funcref)|(type mismatch: expected funcref, found externref)/);

// table.set with non-i32 index - fails validation

Expand Down Expand Up @@ -360,7 +360,7 @@ assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
(func (export "grow2") (param i32) (param externref) (result i32)
(table.grow (local.get 1) (local.get 0))))`)),
WebAssembly.CompileError,
/(type mismatch: expression has type externref but expected funcref)|(type mismatch: expected Some\(FuncRef\), found Some\(ExternRef\))/);
/(type mismatch: expression has type externref but expected funcref)|(type mismatch: expected funcref, found externref)/);

// Special case for private tables without a maximum

Expand Down
2 changes: 1 addition & 1 deletion js/src/jit-test/tests/wasm/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

wasmFailValidateText('(module (func (select (i32.const 0) (i32.const 0) (f32.const 0))))', mismatchError("f32", "i32"));

wasmFailValidateText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" (func 0)))', /(select operand types must match)|(type mismatch: expected Some\(F32\), found Some\(I32\))/);
wasmFailValidateText('(module (func (select (i32.const 0) (f32.const 0) (i32.const 0))) (export "" (func 0)))', /(select operand types must match)|(type mismatch: expected f32, found i32)/);
wasmFailValidateText('(module (func (select (block ) (i32.const 0) (i32.const 0))) (export "" (func 0)))', emptyStackError);
wasmFailValidateText('(module (func (select (return) (i32.const 0) (i32.const 0))) (export "" (func 0)))', unusedValuesError);
assertEq(wasmEvalText('(module (func (drop (select (return) (i32.const 0) (i32.const 0)))) (export "" (func 0)))').exports[""](), undefined);
Expand Down
5 changes: 3 additions & 2 deletions js/src/wasm/cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ name = "baldrdash"
# cranelift-wasm to pinned commits. If you want to update Cranelift in Gecko,
# you should update the following $TOP_LEVEL/Cargo.toml file: look for the
# revision (rev) hashes of both cranelift dependencies (codegen and wasm).
cranelift-codegen = { version = "0.67.0", default-features = false }
cranelift-wasm = { version = "0.67.0" }
cranelift-codegen = { version = "0.68.0", default-features = false }
cranelift-wasm = { version = "0.68.0" }
log = { version = "0.4.6", default-features = false, features = ["release_max_level_info"] }
env_logger = "0.8"
smallvec = "1.0"
wasmparser = { version = "0.67" }

[build-dependencies]
bindgen = {version = "0.53", default-features = false} # disable `logging` to reduce code size
Expand Down
17 changes: 14 additions & 3 deletions js/src/wasm/cranelift/src/bindings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
use cranelift_codegen::ir::{self, InstBuilder, SourceLoc};
use cranelift_codegen::isa;

use cranelift_wasm::{wasmparser, FuncIndex, GlobalIndex, SignatureIndex, TableIndex, WasmResult};
use cranelift_wasm::{wasmparser, FuncIndex, GlobalIndex, SignatureIndex, TableIndex, TypeIndex,
WasmResult};

use crate::compile;
use crate::utils::BasicError;
Expand Down Expand Up @@ -284,8 +285,18 @@ impl<'a> ModuleEnvironment<'a> {
pub fn func_is_import(&self, func_index: FuncIndex) -> bool {
unsafe { low_level::env_func_is_import(self.env, func_index.index()) }
}
pub fn signature(&self, sig_index: SignatureIndex) -> FuncTypeWithId {
FuncTypeWithId::new(unsafe { low_level::env_signature(self.env, sig_index.index()) })
pub fn signature(&self, type_index: TypeIndex) -> FuncTypeWithId {
// This function takes `TypeIndex` rather than the `SignatureIndex` that one
// might expect. Why? https://github.com/bytecodealliance/wasmtime/pull/2115
// introduces two new types to the type section as viewed by Cranelift. This is
// in support of the module linking proposal. So now a type index (for
// Cranelift) can refer to a func, module, or instance type. When the type index
// refers to a func type, it can also be used to get the signature index which
// can be used to get the ir::Signature for that func type. For us, Cranelift is
// only used with function types so we can just assume type index and signature
// index are 1:1. If and when we come to support the module linking proposal,
// this will need to be revisited.
FuncTypeWithId::new(unsafe { low_level::env_signature(self.env, type_index.index()) })
}
pub fn table(&self, table_index: TableIndex) -> TableDesc {
TableDesc(unsafe { low_level::env_table(self.env, table_index.index()) })
Expand Down
5 changes: 0 additions & 5 deletions js/src/wasm/cranelift/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,11 +338,6 @@ impl<'a> Relocations<'a> {
}

impl<'a> RelocSink for Relocations<'a> {
/// Add a relocation referencing a block at the current offset.
fn reloc_block(&mut self, _at: CodeOffset, _reloc: Reloc, _block_offset: CodeOffset) {
unimplemented!("block relocations NYI");
}

/// Add a relocation referencing an external symbol at the current offset.
fn reloc_external(
&mut self,
Expand Down
18 changes: 13 additions & 5 deletions js/src/wasm/cranelift/src/wasm2clif.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use cranelift_codegen::isa::{CallConv, TargetFrontendConfig, TargetIsa};
use cranelift_codegen::packed_option::PackedOption;
use cranelift_wasm::{
FuncEnvironment, FuncIndex, FunctionBuilder, GlobalIndex, GlobalVariable, MemoryIndex,
ReturnMode, SignatureIndex, TableIndex, TargetEnvironment, WasmError, WasmResult,
ReturnMode, TableIndex, TargetEnvironment, WasmError, WasmResult, TypeIndex
};

use crate::bindings::{self, GlobalDesc, SymbolicAddress};
Expand Down Expand Up @@ -825,7 +825,7 @@ impl<'static_env, 'module_env> FuncEnvironment for TransEnv<'static_env, 'module
fn make_indirect_sig(
&mut self,
func: &mut ir::Function,
index: SignatureIndex,
index: TypeIndex,
) -> WasmResult<ir::SigRef> {
let wsig = self.module_env.signature(index);
let mut sigdata = init_sig_from_wsig(self.static_env.call_conv(), &wsig)?;
Expand Down Expand Up @@ -890,7 +890,7 @@ impl<'static_env, 'module_env> FuncEnvironment for TransEnv<'static_env, 'module
mut pos: FuncCursor,
table_index: TableIndex,
table: ir::Table,
sig_index: SignatureIndex,
sig_index: TypeIndex,
sig_ref: ir::SigRef,
callee: ir::Value,
call_args: &[ir::Value],
Expand Down Expand Up @@ -1095,12 +1095,20 @@ impl<'static_env, 'module_env> FuncEnvironment for TransEnv<'static_env, 'module
fn translate_memory_copy(
&mut self,
mut pos: FuncCursor,
_index: MemoryIndex,
heap: ir::Heap,
_src_index: MemoryIndex,
src_heap: ir::Heap,
_dst_index: MemoryIndex,
dst_heap: ir::Heap,
dst: ir::Value,
src: ir::Value,
len: ir::Value,
) -> WasmResult<()> {
if src_heap != dst_heap {
return Err(WasmError::Unsupported(
"memory_copy between different heaps is not supported".to_string(),
));
}
let heap = src_heap;
let heap_gv = pos.func.heaps[heap].base;
let mem_base = pos.ins().global_value(POINTER_TYPE, heap_gv);

Expand Down

0 comments on commit f28cf58

Please sign in to comment.