forked from mirrors/gecko-dev
Bug 1677452 - Update Cranelift to firefox85 / dcc52ba3f69d3de7cdbd787b936825d9c61e3c27 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
This commit is contained in:
parent
842f9f30b0
commit
f28cf588c0
13 changed files with 56 additions and 52 deletions
10
Cargo.toml
10
Cargo.toml
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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))))))');
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)/);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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()) })
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -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)?;
|
||||
|
|
@ -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],
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue