feat(runtime-core) Ability for an export function to get a func env.

This commit is contained in:
Ivan Enderlin
2019-11-07 20:44:17 +01:00
parent 2e05104d45
commit ba87af5b1a
4 changed files with 28 additions and 19 deletions

View File

@ -600,11 +600,11 @@ fn import_functions(
vmctx_ vmctx_
} }
} }
_ => vmctx, Context::Internal => vmctx,
}) })
.expect("`vmctx` must not be null."), .expect("`vmctx` must not be null."),
func_env: match ctx { func_env: match ctx {
Context::ExternalWithEnv(_, func_env) => Some(func_env), Context::ExternalWithEnv(_, func_env) => func_env,
_ => None, _ => None,
}, },
}))) })))

View File

@ -8,7 +8,7 @@ use std::{ptr::NonNull, sync::Arc};
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum Context { pub enum Context {
External(*mut vm::Ctx), External(*mut vm::Ctx),
ExternalWithEnv(*mut vm::Ctx, NonNull<vm::FuncEnv>), ExternalWithEnv(*mut vm::Ctx, Option<NonNull<vm::FuncEnv>>),
Internal, Internal,
} }

View File

@ -133,7 +133,7 @@ impl Instance {
.expect("wasm trampoline"); .expect("wasm trampoline");
let start_func: Func<(), (), Wasm> = let start_func: Func<(), (), Wasm> =
unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, ctx_ptr) }; unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, None, ctx_ptr) };
start_func.call()?; start_func.call()?;
} }
@ -214,20 +214,26 @@ impl Instance {
.get_trampoline(&self.module.info, sig_index) .get_trampoline(&self.module.info, sig_index)
.unwrap(); .unwrap();
let func_ptr = match func_index.local_or_import(&self.module.info) { let (func_ptr, func_env) = match func_index.local_or_import(&self.module.info) {
LocalOrImport::Local(local_func_index) => self LocalOrImport::Local(local_func_index) => (
.module self.module
.runnable_module .runnable_module
.get_func(&self.module.info, local_func_index) .get_func(&self.module.info, local_func_index)
.unwrap(), .unwrap(),
LocalOrImport::Import(import_func_index) => NonNull::new( None,
self.inner.import_backing.vm_functions[import_func_index].func as *mut _, ),
) LocalOrImport::Import(import_func_index) => {
.unwrap(), let imported_func = &self.inner.import_backing.vm_functions[import_func_index];
(
NonNull::new(imported_func.func as *mut _).unwrap(),
unsafe { imported_func.func_ctx.as_ref() }.func_env,
)
}
}; };
let typed_func: Func<Args, Rets, Wasm> = let typed_func: Func<Args, Rets, Wasm> =
unsafe { Func::from_raw_parts(func_wasm_inner, func_ptr, ctx) }; unsafe { Func::from_raw_parts(func_wasm_inner, func_ptr, func_env, ctx) };
Ok(typed_func) Ok(typed_func)
} else { } else {
@ -413,7 +419,7 @@ impl InstanceInner {
ctx: match ctx { ctx: match ctx {
Context::Internal => Context::External(self.vmctx), Context::Internal => Context::External(self.vmctx),
ctx @ Context::External(_) => ctx, ctx @ Context::External(_) => ctx,
func_ctx @ Context::ExternalWithEnv(_, _) => func_ctx, ctx @ Context::ExternalWithEnv(_, _) => ctx,
}, },
signature, signature,
} }
@ -456,9 +462,11 @@ impl InstanceInner {
), ),
LocalOrImport::Import(imported_func_index) => { LocalOrImport::Import(imported_func_index) => {
let imported_func = &self.import_backing.vm_functions[imported_func_index]; let imported_func = &self.import_backing.vm_functions[imported_func_index];
let func_ctx = unsafe { imported_func.func_ctx.as_ref() };
( (
imported_func.func as *const _, imported_func.func as *const _,
Context::External(unsafe { imported_func.func_ctx.as_ref() }.vmctx.as_ptr()), Context::ExternalWithEnv(func_ctx.vmctx.as_ptr(), func_ctx.func_env),
) )
} }
}; };

View File

@ -227,12 +227,13 @@ where
pub(crate) unsafe fn from_raw_parts( pub(crate) unsafe fn from_raw_parts(
inner: Wasm, inner: Wasm,
func: NonNull<vm::Func>, func: NonNull<vm::Func>,
func_env: Option<NonNull<vm::FuncEnv>>,
vmctx: *mut vm::Ctx, vmctx: *mut vm::Ctx,
) -> Func<'a, Args, Rets, Wasm> { ) -> Func<'a, Args, Rets, Wasm> {
Func { Func {
inner, inner,
func, func,
func_env: None, func_env,
vmctx, vmctx,
_phantom: PhantomData, _phantom: PhantomData,
} }
@ -724,7 +725,7 @@ where
fn to_export(&self) -> Export { fn to_export(&self) -> Export {
let func = unsafe { FuncPointer::new(self.func.as_ptr()) }; let func = unsafe { FuncPointer::new(self.func.as_ptr()) };
let ctx = match self.func_env { let ctx = match self.func_env {
Some(func_env) => Context::ExternalWithEnv(self.vmctx, func_env), func_env @ Some(_) => Context::ExternalWithEnv(self.vmctx, func_env),
None => Context::Internal, None => Context::Internal,
}; };
let signature = Arc::new(FuncSig::new(Args::types(), Rets::types())); let signature = Arc::new(FuncSig::new(Args::types(), Rets::types()));