diff --git a/lib/runtime-core/src/backing.rs b/lib/runtime-core/src/backing.rs index ff21e9195..d413ef00e 100644 --- a/lib/runtime-core/src/backing.rs +++ b/lib/runtime-core/src/backing.rs @@ -15,7 +15,7 @@ use crate::{ }, vm, }; -use std::{fmt::Debug, slice}; +use std::{fmt::Debug, ptr, slice}; pub const INTERNALS_SIZE: usize = 256; @@ -384,7 +384,7 @@ impl LocalBacking { LocalOrImport::Import(imported_func_index) => { let vm::ImportedFunc { func, vmctx } = imports.vm_functions[imported_func_index]; - (func, vmctx) + (func, vmctx as _) } }; @@ -417,7 +417,7 @@ impl LocalBacking { LocalOrImport::Import(imported_func_index) => { let vm::ImportedFunc { func, vmctx } = imports.vm_functions[imported_func_index]; - (func, vmctx) + (func, vmctx as _) } }; @@ -541,6 +541,15 @@ impl ImportBacking { } } +impl Drop for ImportBacking { + fn drop(&mut self) { + for (_imported_func_index, imported_func) in (*self.vm_functions).iter_mut() { + let _: Box = unsafe { Box::from_raw(imported_func.vmctx) }; + imported_func.vmctx = ptr::null_mut(); + } + } +} + fn import_functions( module: &ModuleInner, imports: &ImportObject, @@ -564,6 +573,7 @@ fn import_functions( let import = imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); + dbg!(vmctx); match import { Some(Export::Function { func, @@ -573,9 +583,16 @@ fn import_functions( if *expected_sig == *signature { functions.push(vm::ImportedFunc { func: func.inner(), - vmctx: match ctx { - Context::External(ctx) => ctx, - Context::Internal => vmctx, + vmctx: { + let _ = match ctx { + Context::External(ctx) => ctx, + Context::Internal => vmctx, + }; + + Box::into_raw(Box::new(vm::FuncCtx { + vmctx, + func_env: ptr::null_mut(), + })) }, }); } else { diff --git a/lib/runtime-core/src/instance.rs b/lib/runtime-core/src/instance.rs index 85e9f8f76..2716e272a 100644 --- a/lib/runtime-core/src/instance.rs +++ b/lib/runtime-core/src/instance.rs @@ -111,7 +111,7 @@ impl Instance { let ctx_ptr = match start_index.local_or_import(&instance.module.info) { LocalOrImport::Local(_) => instance.inner.vmctx, LocalOrImport::Import(imported_func_index) => { - instance.inner.import_backing.vm_functions[imported_func_index].vmctx + instance.inner.import_backing.vm_functions[imported_func_index].vmctx as _ } }; @@ -196,7 +196,7 @@ impl Instance { let ctx = match func_index.local_or_import(&self.module.info) { LocalOrImport::Local(_) => self.inner.vmctx, LocalOrImport::Import(imported_func_index) => { - self.inner.import_backing.vm_functions[imported_func_index].vmctx + self.inner.import_backing.vm_functions[imported_func_index].vmctx as _ } }; @@ -449,7 +449,7 @@ impl InstanceInner { let imported_func = &self.import_backing.vm_functions[imported_func_index]; ( imported_func.func as *const _, - Context::External(imported_func.vmctx), + Context::External(imported_func.vmctx as _), ) } }; @@ -575,7 +575,7 @@ fn call_func_with_index( let ctx_ptr = match func_index.local_or_import(info) { LocalOrImport::Local(_) => local_ctx, LocalOrImport::Import(imported_func_index) => { - import_backing.vm_functions[imported_func_index].vmctx + import_backing.vm_functions[imported_func_index].vmctx as _ } }; diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index 2a38beb1e..8e0819985 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -490,7 +490,7 @@ macro_rules! impl_traits { /// This is required for the llvm backend to be able to unwind through this function. #[cfg_attr(nightly, unwind(allowed))] extern fn wrap<$( $x, )* Rets, Trap, FN>( - vmctx: &mut vm::Ctx $( , $x: <$x as WasmExternType>::Native )* + func_ctx: &mut vm::FuncCtx $( , $x: <$x as WasmExternType>::Native )* ) -> Rets::CStruct where $( $x: WasmExternType, )* @@ -498,6 +498,7 @@ macro_rules! impl_traits { Trap: TrapEarly, FN: Fn(&mut vm::Ctx, $( $x, )*) -> Trap, { + let vmctx = unsafe { &mut *func_ctx.vmctx }; let f: FN = unsafe { mem::transmute_copy(&()) }; let err = match panic::catch_unwind( @@ -548,7 +549,7 @@ macro_rules! impl_traits { /// This is required for the llvm backend to be able to unwind through this function. #[cfg_attr(nightly, unwind(allowed))] extern fn wrap<$( $x, )* Rets, Trap, FN>( - vmctx: &mut vm::Ctx $( , $x: <$x as WasmExternType>::Native )* + func_ctx: &mut vm::FuncCtx $( , $x: <$x as WasmExternType>::Native )* ) -> Rets::CStruct where $( $x: WasmExternType, )* @@ -556,6 +557,7 @@ macro_rules! impl_traits { Trap: TrapEarly, FN: Fn($( $x, )*) -> Trap, { + let vmctx = unsafe { &mut *func_ctx.vmctx }; let f: FN = unsafe { mem::transmute_copy(&()) }; let err = match panic::catch_unwind( diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 2bb734a04..adc33f2c5 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -498,19 +498,30 @@ impl Ctx { } } -enum InnerFunc {} /// Used to provide type safety (ish) for passing around function pointers. -/// The typesystem ensures this cannot be dereferenced since an -/// empty enum cannot actually exist. #[repr(C)] -pub struct Func(InnerFunc); +pub struct Func { + _private: [u8; 0], +} + +#[repr(C)] +pub struct FuncEnv { + _private: [u8; 0], +} + +#[derive(Debug)] +#[repr(C)] +pub struct FuncCtx { + pub vmctx: *mut Ctx, + pub func_env: *mut FuncEnv, +} /// An imported function, which contains the vmctx that owns this function. #[derive(Debug, Clone)] #[repr(C)] pub struct ImportedFunc { pub func: *const Func, - pub vmctx: *mut Ctx, + pub vmctx: *mut FuncCtx, } // manually implemented because ImportedFunc contains raw pointers directly; `Func` is marked Send (But `Ctx` actually isn't! (TODO: review this, shouldn't `Ctx` be Send?))