Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use a union for VMContext for functions #1753

Merged
merged 3 commits into from
Oct 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use std::cmp::max;
use std::fmt;
use wasmer_vm::{
raise_user_trap, resume_panic, wasmer_call_trampoline, Export, ExportFunction,
VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionBody, VMFunctionKind,
VMTrampoline,
VMCallerCheckedAnyfunc, VMDynamicFunctionContext, VMFunctionBody, VMFunctionEnvironment,
VMFunctionKind, VMTrampoline,
};

/// A function defined in the Wasm module
Expand Down Expand Up @@ -85,7 +85,9 @@ impl Function {
// The engine linker will replace the address with one pointing to a
// generated dynamic trampoline.
let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
let vmctx = VMFunctionEnvironment {
host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _,
};

Self {
store: store.clone(),
Expand Down Expand Up @@ -135,7 +137,9 @@ impl Function {
// The engine linker will replace the address with one pointing to a
// generated dynamic trampoline.
let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
let vmctx = VMFunctionEnvironment {
host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _,
};

Self {
store: store.clone(),
Expand Down Expand Up @@ -176,7 +180,9 @@ impl Function {
{
let function = inner::Function::<Args, Rets>::new(func);
let address = function.address() as *const VMFunctionBody;
let vmctx = std::ptr::null_mut() as *mut _ as *mut VMContext;
let vmctx = VMFunctionEnvironment {
host_env: std::ptr::null_mut() as *mut _,
};
let signature = function.ty();

Self {
Expand Down Expand Up @@ -230,7 +236,9 @@ impl Function {
// In the case of Host-defined functions `VMContext` is whatever environment
// the user want to attach to the function.
let box_env = Box::new(env);
let vmctx = Box::into_raw(box_env) as *mut _ as *mut VMContext;
let vmctx = VMFunctionEnvironment {
host_env: Box::into_raw(box_env) as *mut _,
};
let signature = function.ty();

Self {
Expand Down
20 changes: 12 additions & 8 deletions lib/api/src/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{FromToNativeWasmType, Function, FunctionType, RuntimeError, Store, W
use std::panic::{catch_unwind, AssertUnwindSafe};
use wasmer_types::NativeWasmType;
use wasmer_vm::{
ExportFunction, VMContext, VMDynamicFunctionContext, VMFunctionBody, VMFunctionKind,
ExportFunction, VMDynamicFunctionContext, VMFunctionBody, VMFunctionEnvironment, VMFunctionKind,
};

/// A WebAssembly function that can be called natively
Expand All @@ -26,7 +26,7 @@ pub struct NativeFunc<'a, Args = (), Rets = ()> {
definition: FunctionDefinition,
store: Store,
address: *const VMFunctionBody,
vmctx: *mut VMContext,
vmctx: VMFunctionEnvironment,
arg_kind: VMFunctionKind,
// exported: ExportFunction,
_phantom: PhantomData<(&'a (), Args, Rets)>,
Expand All @@ -42,7 +42,7 @@ where
pub(crate) fn new(
store: Store,
address: *const VMFunctionBody,
vmctx: *mut VMContext,
vmctx: VMFunctionEnvironment,
arg_kind: VMFunctionKind,
definition: FunctionDefinition,
) -> Self {
Expand Down Expand Up @@ -165,7 +165,7 @@ macro_rules! impl_native_traits {
match self.arg_kind {
VMFunctionKind::Static => {
let results = catch_unwind(AssertUnwindSafe(|| unsafe {
let f = std::mem::transmute::<_, unsafe extern "C" fn( *mut VMContext, $( $x, )*) -> Rets::CStruct>(self.address);
let f = std::mem::transmute::<_, unsafe extern "C" fn( VMFunctionEnvironment, $( $x, )*) -> Rets::CStruct>(self.address);
// We always pass the vmctx
f( self.vmctx, $( $x, )* )
})).map_err(|e| RuntimeError::new(format!("{:?}", e)))?;
Expand All @@ -175,12 +175,16 @@ macro_rules! impl_native_traits {
let params_list = [ $( $x.to_native().to_value() ),* ];
let results = if !has_env {
type VMContextWithoutEnv = VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>;
let ctx = self.vmctx as *mut VMContextWithoutEnv;
unsafe { (*ctx).ctx.call(&params_list)? }
unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithoutEnv;
(*ctx).ctx.call(&params_list)?
}
} else {
type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>;
let ctx = self.vmctx as *mut VMContextWithEnv;
unsafe { (*ctx).ctx.call(&params_list)? }
unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithEnv;
(*ctx).ctx.call(&params_list)?
}
};
let mut rets_list_array = Rets::empty_array();
let mut_rets = rets_list_array.as_mut() as *mut [i128] as *mut i128;
Expand Down
4 changes: 3 additions & 1 deletion lib/api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ impl ValFuncRef for Val {
Self::ExternRef(ExternRef::Null) => wasmer_vm::VMCallerCheckedAnyfunc {
func_ptr: ptr::null(),
type_index: wasmer_vm::VMSharedSignatureIndex::default(),
vmctx: ptr::null_mut(),
vmctx: wasmer_vm::VMFunctionEnvironment {
host_env: ptr::null_mut(),
},
},
Self::FuncRef(f) => f.checked_anyfunc(),
_ => return Err(RuntimeError::new("val is not funcref")),
Expand Down
8 changes: 4 additions & 4 deletions lib/deprecated/runtime-core/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,14 @@ impl Module {
// Properly drop the empty `vm::Ctx`
// created by the host function.
unsafe {
ptr::drop_in_place::<vm::Ctx>(function.vmctx as _);
ptr::drop_in_place::<vm::Ctx>(function.vmctx.host_env as _);
}

// Update the pointer to `VMContext`,
// which is actually a `vm::Ctx`
// pointer, to fallback on the
// environment hack.
function.vmctx = pre_instance.vmctx_ptr() as _;
function.vmctx.host_env = pre_instance.vmctx_ptr() as _;
}
// `function` is a dynamic host function
// constructed with
Expand Down Expand Up @@ -147,13 +147,13 @@ impl Module {
new::wasmer_vm::VMDynamicFunctionContext<
VMDynamicFunctionWithEnv<DynamicCtx>,
>,
> = unsafe { Box::from_raw(function.vmctx as *mut _) };
> = unsafe { Box::from_raw(function.vmctx.host_env as *mut _) };

// Replace the environment by ours.
vmctx.ctx.env.borrow_mut().vmctx = pre_instance.vmctx();

// … without anyone noticing…
function.vmctx = Box::into_raw(vmctx) as _;
function.vmctx.host_env = Box::into_raw(vmctx) as _;
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/engine/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub fn resolve_imports(
};
function_imports.push(VMFunctionImport {
body: address,
vmctx: f.vmctx,
environment: f.vmctx,
});
}
Export::Table(ref t) => {
Expand Down
4 changes: 2 additions & 2 deletions lib/vm/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use crate::global::Global;
use crate::memory::{Memory, MemoryStyle};
use crate::table::{Table, TableStyle};
use crate::vmcontext::{VMContext, VMFunctionBody, VMFunctionKind, VMTrampoline};
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMFunctionKind, VMTrampoline};
use std::sync::Arc;
use wasmer_types::{FunctionType, MemoryType, TableType};

Expand All @@ -30,7 +30,7 @@ pub struct ExportFunction {
/// The address of the native-code function.
pub address: *const VMFunctionBody,
/// Pointer to the containing `VMContext`.
pub vmctx: *mut VMContext,
pub vmctx: VMFunctionEnvironment,
/// The function type, used for compatibility checking.
pub signature: FunctionType,
/// The function kind (it defines how it's the signature that provided `address` have)
Expand Down
36 changes: 26 additions & 10 deletions lib/vm/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use crate::memory::{Memory, MemoryError};
use crate::table::Table;
use crate::trap::{catch_traps, init_traps, Trap, TrapCode};
use crate::vmcontext::{
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport,
VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMMemoryDefinition, VMMemoryImport,
VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline,
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody,
VMFunctionEnvironment, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport,
VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport,
VMTrampoline,
};
use crate::{ExportFunction, ExportGlobal, ExportMemory, ExportTable};
use crate::{FunctionBodyPtr, ModuleInfo, VMOffsets};
Expand Down Expand Up @@ -296,10 +297,15 @@ impl Instance {
let sig_index = &self.module.functions[*index];
let (address, vmctx) = if let Some(def_index) = self.module.local_func_index(*index)
{
(self.functions[def_index].0 as *const _, self.vmctx_ptr())
(
self.functions[def_index].0 as *const _,
VMFunctionEnvironment {
vmctx: self.vmctx_ptr(),
},
)
} else {
let import = self.imported_function(*index);
(import.body, import.vmctx)
(import.body, import.environment)
};
let call_trampoline = Some(self.function_call_trampolines[*sig_index]);
let signature = self.module.signatures[*sig_index].clone();
Expand Down Expand Up @@ -377,19 +383,24 @@ impl Instance {
.get(local_index)
.expect("function index is out of bounds")
.0;
(body as *const _, self.vmctx_ptr())
(
body as *const _,
VMFunctionEnvironment {
vmctx: self.vmctx_ptr(),
},
)
}
None => {
assert_lt!(start_index.index(), self.module.num_imported_functions);
let import = self.imported_function(start_index);
(import.body, import.vmctx)
(import.body, import.environment)
}
};

// Make the call.
unsafe {
catch_traps(callee_vmctx, || {
mem::transmute::<*const VMFunctionBody, unsafe extern "C" fn(*mut VMContext)>(
mem::transmute::<*const VMFunctionBody, unsafe extern "C" fn(VMFunctionEnvironment)>(
callee_address,
)(callee_vmctx)
})
Expand Down Expand Up @@ -561,10 +572,15 @@ impl Instance {
let type_index = self.signature_id(sig);

let (func_ptr, vmctx) = if let Some(def_index) = self.module.local_func_index(index) {
(self.functions[def_index].0 as *const _, self.vmctx_ptr())
(
self.functions[def_index].0 as *const _,
VMFunctionEnvironment {
vmctx: self.vmctx_ptr(),
},
)
} else {
let import = self.imported_function(index);
(import.body, import.vmctx)
(import.body, import.environment)
};
VMCallerCheckedAnyfunc {
func_ptr,
Expand Down
6 changes: 3 additions & 3 deletions lib/vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ pub use crate::table::{LinearTable, Table, TableStyle};
pub use crate::trap::*;
pub use crate::vmcontext::{
VMBuiltinFunctionIndex, VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext,
VMFunctionBody, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport,
VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport,
VMTrampoline,
VMFunctionBody, VMFunctionEnvironment, VMFunctionImport, VMFunctionKind, VMGlobalDefinition,
VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition,
VMTableImport, VMTrampoline,
};
pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};

Expand Down
16 changes: 8 additions & 8 deletions lib/vm/src/trap/traphandlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use super::trapcode::TrapCode;
use crate::instance::{InstanceHandle, SignalHandler};
use crate::vmcontext::{VMContext, VMFunctionBody, VMTrampoline};
use crate::vmcontext::{VMFunctionBody, VMFunctionEnvironment, VMTrampoline};
use backtrace::Backtrace;
use std::any::Any;
use std::cell::Cell;
Expand Down Expand Up @@ -429,13 +429,13 @@ impl Trap {
/// Wildly unsafe because it calls raw function pointers and reads/writes raw
/// function pointers.
pub unsafe fn wasmer_call_trampoline(
vmctx: *mut VMContext,
vmctx: VMFunctionEnvironment,
trampoline: VMTrampoline,
callee: *const VMFunctionBody,
values_vec: *mut u8,
) -> Result<(), Trap> {
catch_traps(vmctx, || {
mem::transmute::<_, extern "C" fn(*mut VMContext, *const VMFunctionBody, *mut u8)>(
mem::transmute::<_, extern "C" fn(VMFunctionEnvironment, *const VMFunctionBody, *mut u8)>(
trampoline,
)(vmctx, callee, values_vec)
})
Expand All @@ -447,7 +447,7 @@ pub unsafe fn wasmer_call_trampoline(
/// # Safety
///
/// Highly unsafe since `closure` won't have any destructors run.
pub unsafe fn catch_traps<F>(vmctx: *mut VMContext, mut closure: F) -> Result<(), Trap>
pub unsafe fn catch_traps<F>(vmctx: VMFunctionEnvironment, mut closure: F) -> Result<(), Trap>
where
F: FnMut(),
{
Expand Down Expand Up @@ -481,7 +481,7 @@ where
///
/// Check [`catch_traps`].
pub unsafe fn catch_traps_with_result<F, R>(
vmctx: *mut VMContext,
vmctx: VMFunctionEnvironment,
mut closure: F,
) -> Result<R, Trap>
where
Expand All @@ -501,7 +501,7 @@ pub struct CallThreadState {
jmp_buf: Cell<*const u8>,
reset_guard_page: Cell<bool>,
prev: Option<*const CallThreadState>,
vmctx: *mut VMContext,
vmctx: VMFunctionEnvironment,
handling_trap: Cell<bool>,
}

Expand All @@ -518,7 +518,7 @@ enum UnwindReason {
}

impl CallThreadState {
fn new(vmctx: *mut VMContext) -> Self {
fn new(vmctx: VMFunctionEnvironment) -> Self {
Self {
unwind: Cell::new(UnwindReason::None),
vmctx,
Expand Down Expand Up @@ -561,7 +561,7 @@ impl CallThreadState {

fn any_instance(&self, func: impl Fn(&InstanceHandle) -> bool) -> bool {
unsafe {
if func(&InstanceHandle::from_vmctx(self.vmctx)) {
if func(&InstanceHandle::from_vmctx(self.vmctx.vmctx)) {
return true;
}
match self.prev {
Expand Down
Loading