feat(runtime-core) Introduce vm::FuncCtx.

`vm::FuncCtx` replaces `vm::Ctx` as first argument passed to host
functions (aka imported functions).
This commit is contained in:
Ivan Enderlin 2019-10-31 22:04:00 +01:00
parent 656491a337
commit 177c507a4e
4 changed files with 47 additions and 17 deletions

View File

@ -15,7 +15,7 @@ use crate::{
}, },
vm, vm,
}; };
use std::{fmt::Debug, slice}; use std::{fmt::Debug, ptr, slice};
pub const INTERNALS_SIZE: usize = 256; pub const INTERNALS_SIZE: usize = 256;
@ -384,7 +384,7 @@ impl LocalBacking {
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
let vm::ImportedFunc { func, vmctx } = let vm::ImportedFunc { func, vmctx } =
imports.vm_functions[imported_func_index]; imports.vm_functions[imported_func_index];
(func, vmctx) (func, vmctx as _)
} }
}; };
@ -417,7 +417,7 @@ impl LocalBacking {
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
let vm::ImportedFunc { func, vmctx } = let vm::ImportedFunc { func, vmctx } =
imports.vm_functions[imported_func_index]; 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<vm::FuncCtx> = unsafe { Box::from_raw(imported_func.vmctx) };
imported_func.vmctx = ptr::null_mut();
}
}
}
fn import_functions( fn import_functions(
module: &ModuleInner, module: &ModuleInner,
imports: &ImportObject, imports: &ImportObject,
@ -564,6 +573,7 @@ fn import_functions(
let import = let import =
imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name)); imports.maybe_with_namespace(namespace, |namespace| namespace.get_export(name));
dbg!(vmctx);
match import { match import {
Some(Export::Function { Some(Export::Function {
func, func,
@ -573,9 +583,16 @@ fn import_functions(
if *expected_sig == *signature { if *expected_sig == *signature {
functions.push(vm::ImportedFunc { functions.push(vm::ImportedFunc {
func: func.inner(), func: func.inner(),
vmctx: match ctx { vmctx: {
let _ = match ctx {
Context::External(ctx) => ctx, Context::External(ctx) => ctx,
Context::Internal => vmctx, Context::Internal => vmctx,
};
Box::into_raw(Box::new(vm::FuncCtx {
vmctx,
func_env: ptr::null_mut(),
}))
}, },
}); });
} else { } else {

View File

@ -111,7 +111,7 @@ impl Instance {
let ctx_ptr = match start_index.local_or_import(&instance.module.info) { let ctx_ptr = match start_index.local_or_import(&instance.module.info) {
LocalOrImport::Local(_) => instance.inner.vmctx, LocalOrImport::Local(_) => instance.inner.vmctx,
LocalOrImport::Import(imported_func_index) => { 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) { let ctx = match func_index.local_or_import(&self.module.info) {
LocalOrImport::Local(_) => self.inner.vmctx, LocalOrImport::Local(_) => self.inner.vmctx,
LocalOrImport::Import(imported_func_index) => { 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]; let imported_func = &self.import_backing.vm_functions[imported_func_index];
( (
imported_func.func as *const _, 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) { let ctx_ptr = match func_index.local_or_import(info) {
LocalOrImport::Local(_) => local_ctx, LocalOrImport::Local(_) => local_ctx,
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
import_backing.vm_functions[imported_func_index].vmctx import_backing.vm_functions[imported_func_index].vmctx as _
} }
}; };

View File

@ -490,7 +490,7 @@ macro_rules! impl_traits {
/// This is required for the llvm backend to be able to unwind through this function. /// This is required for the llvm backend to be able to unwind through this function.
#[cfg_attr(nightly, unwind(allowed))] #[cfg_attr(nightly, unwind(allowed))]
extern fn wrap<$( $x, )* Rets, Trap, FN>( 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 ) -> Rets::CStruct
where where
$( $x: WasmExternType, )* $( $x: WasmExternType, )*
@ -498,6 +498,7 @@ macro_rules! impl_traits {
Trap: TrapEarly<Rets>, Trap: TrapEarly<Rets>,
FN: Fn(&mut vm::Ctx, $( $x, )*) -> Trap, FN: Fn(&mut vm::Ctx, $( $x, )*) -> Trap,
{ {
let vmctx = unsafe { &mut *func_ctx.vmctx };
let f: FN = unsafe { mem::transmute_copy(&()) }; let f: FN = unsafe { mem::transmute_copy(&()) };
let err = match panic::catch_unwind( 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. /// This is required for the llvm backend to be able to unwind through this function.
#[cfg_attr(nightly, unwind(allowed))] #[cfg_attr(nightly, unwind(allowed))]
extern fn wrap<$( $x, )* Rets, Trap, FN>( 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 ) -> Rets::CStruct
where where
$( $x: WasmExternType, )* $( $x: WasmExternType, )*
@ -556,6 +557,7 @@ macro_rules! impl_traits {
Trap: TrapEarly<Rets>, Trap: TrapEarly<Rets>,
FN: Fn($( $x, )*) -> Trap, FN: Fn($( $x, )*) -> Trap,
{ {
let vmctx = unsafe { &mut *func_ctx.vmctx };
let f: FN = unsafe { mem::transmute_copy(&()) }; let f: FN = unsafe { mem::transmute_copy(&()) };
let err = match panic::catch_unwind( let err = match panic::catch_unwind(

View File

@ -498,19 +498,30 @@ impl Ctx {
} }
} }
enum InnerFunc {}
/// Used to provide type safety (ish) for passing around function pointers. /// 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)] #[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. /// An imported function, which contains the vmctx that owns this function.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[repr(C)] #[repr(C)]
pub struct ImportedFunc { pub struct ImportedFunc {
pub func: *const Func, 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?)) // 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?))