diff --git a/lib/compiler/src/engine/resolver.rs b/lib/compiler/src/engine/resolver.rs index e4699370bd0..58b595075c2 100644 --- a/lib/compiler/src/engine/resolver.rs +++ b/lib/compiler/src/engine/resolver.rs @@ -64,7 +64,7 @@ fn get_runtime_size(context: &StoreObjects, extern_: &VMExtern) -> Option { pub fn resolve_imports( module: &ModuleInfo, imports: &[VMExtern], - context: &StoreObjects, + context: &mut StoreObjects, finished_dynamic_function_trampolines: &BoxedSlice, memory_styles: &PrimaryMap, _table_styles: &PrimaryMap, @@ -104,14 +104,22 @@ pub fn resolve_imports( } match *resolved { VMExtern::Function(handle) => { - let f = handle.get(context); + let f = handle.get_mut(context); let address = match f.kind { VMFunctionKind::Dynamic => { // If this is a dynamic imported function, // the address of the function is the address of the // reverse trampoline. let index = FunctionIndex::new(function_imports.len()); - finished_dynamic_function_trampolines[index].0 as *mut VMFunctionBody as _ + let ptr = finished_dynamic_function_trampolines[index].0 + as *mut VMFunctionBody as _; + // The logic is currently handling the "resolution" of dynamic imported functions at instantiation time. + // However, ideally it should be done even before then, as you may have dynamic imported functions that + // are linked at runtime and not instantiation time. And those will not work properly with the current logic. + // Ideally, this logic should be done directly in the `wasmer-vm` crate. + // TODO (@syrusakbary): Get rid of `VMFunctionKind` + unsafe { f.anyfunc.as_ptr().as_mut() }.func_ptr = ptr; + ptr } VMFunctionKind::Static => unsafe { f.anyfunc.as_ptr().as_ref().func_ptr }, }; diff --git a/tests/compilers/imports.rs b/tests/compilers/imports.rs index a14273dd4ff..265495d618e 100644 --- a/tests/compilers/imports.rs +++ b/tests/compilers/imports.rs @@ -13,8 +13,11 @@ use wasmer::Type as ValueType; use wasmer::*; fn get_module(store: &Store) -> Result { + // Note: this module is also used to test indirect calls to imported + // functions, do not remove the call_indirect instruction let wat = r#" - (import "host" "0" (func)) + (type (func)) + (import "host" "0" (func $host_func_0 (type 0))) (import "host" "1" (func (param i32) (result i32))) (import "host" "2" (func (param i32) (param i64))) (import "host" "3" (func (param i32 i64 i32 f32 f64))) @@ -22,7 +25,9 @@ fn get_module(store: &Store) -> Result { (export "memory" (memory $mem)) (func $foo - call 0 + i32.const 1 + call_indirect (type 0) + i32.const 0 call 1 i32.const 1 @@ -37,6 +42,8 @@ fn get_module(store: &Store) -> Result { f64.const 500 call 3 ) + (table 2 2 funcref) + (elem (i32.const 1) func $host_func_0) (start $foo) "#;