Skip to content

Commit

Permalink
Merge pull request #2494 from wasmerio/fix-issue-2329
Browse files Browse the repository at this point in the history
Fix Singlepass function environment in indirect calls
  • Loading branch information
syrusakbary authored Jul 29, 2021
2 parents 223ceb8 + 9ecedc3 commit e567bb7
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
10 changes: 10 additions & 0 deletions lib/compiler-singlepass/src/codegen_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -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,
Expand Down
78 changes: 78 additions & 0 deletions tests/compilers/issues.rs
Original file line number Diff line number Diff line change
@@ -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<Memory>,
}

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(())
}
1 change: 1 addition & 0 deletions tests/compilers/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern crate compiler_test_derive;

mod config;
mod imports;
mod issues;
mod metering;
mod middlewares;
// mod multi_value_imports;
Expand Down

0 comments on commit e567bb7

Please sign in to comment.