diff --git a/lib/compiler-singlepass/src/codegen_x64.rs b/lib/compiler-singlepass/src/codegen_x64.rs index bd02ddc2a4a..9d5fe93b522 100644 --- a/lib/compiler-singlepass/src/codegen_x64.rs +++ b/lib/compiler-singlepass/src/codegen_x64.rs @@ -5388,6 +5388,8 @@ impl<'a> FuncGen<'a> { let vmcaller_checked_anyfunc_func_ptr = self.vmoffsets.vmcaller_checked_anyfunc_func_ptr() as usize; + let vmcaller_checked_anyfunc_vmctx = + self.vmoffsets.vmcaller_checked_anyfunc_vmctx() as usize; self.emit_call_sysv( |this| { @@ -5403,6 +5405,14 @@ impl<'a> FuncGen<'a> { this.trap_table .offset_to_code .insert(offset, TrapCode::StackOverflow); + + // We set the context pointer + this.assembler.emit_mov( + Size::S64, + Location::Memory(GPR::RAX, vmcaller_checked_anyfunc_vmctx as i32), + Machine::get_param_location(0), + ); + this.assembler.emit_call_location(Location::Memory( GPR::RAX, vmcaller_checked_anyfunc_func_ptr as i32, diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs new file mode 100644 index 00000000000..508ec0fee7a --- /dev/null +++ b/tests/compilers/issues.rs @@ -0,0 +1,78 @@ +//! This file is mainly to assure specific issues are working well +use anyhow::Result; +use wasmer::*; + +/// Corruption of WasmerEnv when using call indirect. +/// +/// Note: this one is specific to Singlepass, but we want to test in all +/// available compilers. +/// +/// https://github.com/wasmerio/wasmer/issues/2329 +#[compiler_test(issues)] +fn issue_2329(mut config: crate::Config) -> Result<()> { + let store = config.store(); + + #[derive(Clone, Default, WasmerEnv)] + pub struct Env { + #[wasmer(export)] + memory: LazyInit, + } + + impl Env { + pub fn new() -> Self { + Self { + memory: LazyInit::new(), + } + } + } + + pub fn read_memory(env: &Env, guest_ptr: u32) -> u32 { + dbg!(env.memory_ref()); + dbg!(guest_ptr); + 0 + } + + let wat = r#" + (module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func)) + (type (;2;) (func (param i32 i32) (result i32))) + (import "env" "__read_memory" (func $__read_memory (type 0))) + (func $read_memory (type 1) + (drop + (call $_ZN5other8dispatch17h053cb34ef5d0d7b0E + (i32.const 1) + (i32.const 2))) + (drop + (call $__read_memory + (i32.const 1)))) + (func $_ZN5other8dispatch17h053cb34ef5d0d7b0E (type 2) (param i32 i32) (result i32) + (call_indirect (type 0) + (local.get 1) + (local.get 0))) + (table (;0;) 2 2 funcref) + (memory (;0;) 16) + (global (;0;) (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "read_memory" (func $read_memory)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2)) + (elem (;0;) (i32.const 1) func $__read_memory)) + "#; + let module = Module::new(&store, wat)?; + let env = Env::new(); + let imports: ImportObject = imports! { + "env" => { + "__read_memory" => Function::new_native_with_env( + &store, + env.clone(), + read_memory + ), + } + }; + let instance = Instance::new(&module, &imports)?; + instance.exports.get_function("read_memory")?.call(&[])?; + Ok(()) +} diff --git a/tests/compilers/main.rs b/tests/compilers/main.rs index b80a13e482c..5b85deb0382 100644 --- a/tests/compilers/main.rs +++ b/tests/compilers/main.rs @@ -7,6 +7,7 @@ extern crate compiler_test_derive; mod config; mod imports; +mod issues; mod metering; mod middlewares; // mod multi_value_imports;