fix(runtime-core) Introduce Context::ExternalWithEnv.

Host functions use `Context::External` with a `*mut vm::FuncCtx`
pointer, casted to `*mut vm::Ctx`. It creates a conflict with exports
that also use `Context::External`.

This patch introduces `Context::ExternalWithEnv` to create a specific
path in the code for an external context with `*mut vm::FuncEnv`.

This patch fixes all the `linking.wast` tests in the spectests.
This commit is contained in:
Ivan Enderlin
2019-11-07 14:32:19 +01:00
parent dfaad35f8d
commit 2e05104d45
4 changed files with 18 additions and 16 deletions

View File

@ -591,16 +591,21 @@ fn import_functions(
// ^^^^^^^^ `vm::FuncCtx` is purposely leaked. // ^^^^^^^^ `vm::FuncCtx` is purposely leaked.
// It is dropped by the specific `Drop` // It is dropped by the specific `Drop`
// implementation of `ImportBacking`. // implementation of `ImportBacking`.
vmctx: NonNull::new(vmctx).expect("`vmctx` must not be null."), vmctx: NonNull::new(match ctx {
func_env: match ctx { Context::External(vmctx) => vmctx,
Context::External(ctx) => { Context::ExternalWithEnv(vmctx_, _) => {
NonNull::new(ctx).map(NonNull::cast) if vmctx_.is_null() {
// ^^^^^^^^^^^^^ vmctx
// `*mut vm::FuncEnv` was casted to } else {
// `*mut vm::Ctx` to fit in vmctx_
// `Context::External`. Cast it back.
} }
Context::Internal => None, }
_ => vmctx,
})
.expect("`vmctx` must not be null."),
func_env: match ctx {
Context::ExternalWithEnv(_, func_env) => Some(func_env),
_ => None,
}, },
}))) })))
.unwrap(), .unwrap(),

View File

@ -3,11 +3,12 @@ use crate::{
module::ModuleInner, table::Table, types::FuncSig, vm, module::ModuleInner, table::Table, types::FuncSig, vm,
}; };
use indexmap::map::Iter as IndexMapIter; use indexmap::map::Iter as IndexMapIter;
use std::sync::Arc; 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>),
Internal, Internal,
} }

View File

@ -413,6 +413,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,
}, },
signature, signature,
} }
@ -463,7 +464,6 @@ impl InstanceInner {
}; };
let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]); let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]);
// let signature = &module.info.signatures[sig_index];
(unsafe { FuncPointer::new(func_ptr) }, ctx, signature) (unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
} }

View File

@ -724,11 +724,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::External(func_env.cast().as_ptr()), Some(func_env) => Context::ExternalWithEnv(self.vmctx, func_env),
// ^^^^^^
// `Context::External` expects a `vm::Ctx`.
// Casting to `vm::FuncCtx` happens in the
// `backing` module.
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()));