Add hacked together vertical slice of host env updating idea

This commit is contained in:
Mark McCaskey
2020-10-19 17:19:46 -07:00
parent a1ccfe228d
commit 3c7dfe29f3
18 changed files with 222 additions and 68 deletions

View File

@@ -11,8 +11,8 @@ use std::cmp::max;
use std::fmt; use std::fmt;
use wasmer_vm::{ use wasmer_vm::{
raise_user_trap, resume_panic, wasmer_call_trampoline, Export, ExportFunction, raise_user_trap, resume_panic, wasmer_call_trampoline, Export, ExportFunction,
VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionBody, VMFunctionKind, FunctionExtraData, VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, VMFunctionBody,
VMTrampoline, VMFunctionKind, VMTrampoline,
}; };
/// A function defined in the Wasm module /// A function defined in the Wasm module
@@ -85,7 +85,9 @@ impl Function {
// The engine linker will replace the address with one pointing to a // The engine linker will replace the address with one pointing to a
// generated dynamic trampoline. // generated dynamic trampoline.
let address = std::ptr::null() as *const VMFunctionBody; let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext; let vmctx = FunctionExtraData {
host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _,
};
Self { Self {
store: store.clone(), store: store.clone(),
@@ -94,6 +96,7 @@ impl Function {
address, address,
kind: VMFunctionKind::Dynamic, kind: VMFunctionKind::Dynamic,
vmctx, vmctx,
function_ptr: 0,
signature: ty.clone(), signature: ty.clone(),
}, },
} }
@@ -134,7 +137,9 @@ impl Function {
// The engine linker will replace the address with one pointing to a // The engine linker will replace the address with one pointing to a
// generated dynamic trampoline. // generated dynamic trampoline.
let address = std::ptr::null() as *const VMFunctionBody; let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext; let vmctx = FunctionExtraData {
host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _,
};
Self { Self {
store: store.clone(), store: store.clone(),
@@ -143,6 +148,8 @@ impl Function {
address, address,
kind: VMFunctionKind::Dynamic, kind: VMFunctionKind::Dynamic,
vmctx, vmctx,
// TODO:
function_ptr: 0,
signature: ty.clone(), signature: ty.clone(),
}, },
} }
@@ -174,7 +181,9 @@ impl Function {
{ {
let function = inner::Function::<Args, Rets>::new(func); let function = inner::Function::<Args, Rets>::new(func);
let address = function.address() as *const VMFunctionBody; let address = function.address() as *const VMFunctionBody;
let vmctx = std::ptr::null_mut() as *mut _ as *mut VMContext; let vmctx = FunctionExtraData {
host_env: std::ptr::null_mut() as *mut _,
};
let signature = function.ty(); let signature = function.ty();
Self { Self {
@@ -184,6 +193,8 @@ impl Function {
address, address,
vmctx, vmctx,
signature, signature,
// TODO:
function_ptr: 0,
kind: VMFunctionKind::Static, kind: VMFunctionKind::Static,
}, },
} }
@@ -216,7 +227,7 @@ impl Function {
F: HostFunction<Args, Rets, WithEnv, Env>, F: HostFunction<Args, Rets, WithEnv, Env>,
Args: WasmTypeList, Args: WasmTypeList,
Rets: WasmTypeList, Rets: WasmTypeList,
Env: Sized + 'static, Env: Sized + crate::WasmerPostInstantiate + 'static,
{ {
let function = inner::Function::<Args, Rets>::new(func); let function = inner::Function::<Args, Rets>::new(func);
let address = function.address(); let address = function.address();
@@ -227,7 +238,11 @@ impl Function {
// In the case of Host-defined functions `VMContext` is whatever environment // In the case of Host-defined functions `VMContext` is whatever environment
// the user want to attach to the function. // the user want to attach to the function.
let box_env = Box::new(env); let box_env = Box::new(env);
let vmctx = Box::into_raw(box_env) as *mut _ as *mut VMContext; let vmctx = FunctionExtraData {
host_env: Box::into_raw(box_env) as *mut _,
};
let function_ptr = Env::finish as usize;
dbg!(function_ptr);
let signature = function.ty(); let signature = function.ty();
Self { Self {
@@ -237,6 +252,7 @@ impl Function {
address, address,
kind: VMFunctionKind::Static, kind: VMFunctionKind::Static,
vmctx, vmctx,
function_ptr,
signature, signature,
}, },
} }

View File

@@ -73,7 +73,7 @@ impl Instance {
pub fn new(module: &Module, resolver: &dyn Resolver) -> Result<Self, InstantiationError> { pub fn new(module: &Module, resolver: &dyn Resolver) -> Result<Self, InstantiationError> {
let store = module.store(); let store = module.store();
let handle = module.instantiate(resolver)?; let (handle, thunks) = module.instantiate(resolver)?;
let exports = module let exports = module
.exports() .exports()
@@ -85,11 +85,20 @@ impl Instance {
}) })
.collect::<Exports>(); .collect::<Exports>();
Ok(Self { let instance = Self {
handle, handle,
module: module.clone(), module: module.clone(),
exports, exports,
}) };
for (func, env) in thunks.iter() {
dbg!(func, env);
unsafe {
func(*env, (&instance) as *const _ as *const _);
}
}
Ok(instance)
} }
/// Gets the [`Module`] associated with this instance. /// Gets the [`Module`] associated with this instance.

View File

@@ -118,3 +118,17 @@ pub use wasmer_engine_native::{Native, NativeArtifact, NativeEngine};
/// Version number of this crate. /// Version number of this crate.
pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub const VERSION: &str = env!("CARGO_PKG_VERSION");
// --------------------------------------------------------------
// TODO: put this in a proper location, just prototyping for now:
// TODO: rename everything, all names are throw-away names
/// Prototype trait for finishing envs.
pub trait WasmerPostInstantiate {
/// The function that Wasmer will call on your type to let it finish
/// instantiating.
fn finish(&mut self, instance: &Instance);
/// Frees memory written to `self` so it can be dropped without any memory leaks.
fn free(&mut self);
}

View File

@@ -261,9 +261,18 @@ impl Module {
pub(crate) fn instantiate( pub(crate) fn instantiate(
&self, &self,
resolver: &dyn Resolver, resolver: &dyn Resolver,
) -> Result<InstanceHandle, InstantiationError> { ) -> Result<
(
InstanceHandle,
Vec<(
fn(*mut std::ffi::c_void, *const std::ffi::c_void),
*mut std::ffi::c_void,
)>,
),
InstantiationError,
> {
unsafe { unsafe {
let instance_handle = let (instance_handle, thunks) =
self.artifact self.artifact
.instantiate(self.store.tunables(), resolver, Box::new(()))?; .instantiate(self.store.tunables(), resolver, Box::new(()))?;
@@ -274,7 +283,7 @@ impl Module {
// instance tables. // instance tables.
self.artifact.finish_instantiation(&instance_handle)?; self.artifact.finish_instantiation(&instance_handle)?;
Ok(instance_handle) Ok((instance_handle, thunks))
} }
} }

View File

@@ -17,7 +17,8 @@ use crate::{FromToNativeWasmType, Function, FunctionType, RuntimeError, Store, W
use std::panic::{catch_unwind, AssertUnwindSafe}; use std::panic::{catch_unwind, AssertUnwindSafe};
use wasmer_types::NativeWasmType; use wasmer_types::NativeWasmType;
use wasmer_vm::{ use wasmer_vm::{
ExportFunction, VMContext, VMDynamicFunctionContext, VMFunctionBody, VMFunctionKind, ExportFunction, FunctionExtraData, VMContext, VMDynamicFunctionContext, VMFunctionBody,
VMFunctionKind,
}; };
/// A WebAssembly function that can be called natively /// A WebAssembly function that can be called natively
@@ -26,7 +27,7 @@ pub struct NativeFunc<'a, Args = (), Rets = ()> {
definition: FunctionDefinition, definition: FunctionDefinition,
store: Store, store: Store,
address: *const VMFunctionBody, address: *const VMFunctionBody,
vmctx: *mut VMContext, vmctx: FunctionExtraData,
arg_kind: VMFunctionKind, arg_kind: VMFunctionKind,
// exported: ExportFunction, // exported: ExportFunction,
_phantom: PhantomData<(&'a (), Args, Rets)>, _phantom: PhantomData<(&'a (), Args, Rets)>,
@@ -42,7 +43,7 @@ where
pub(crate) fn new( pub(crate) fn new(
store: Store, store: Store,
address: *const VMFunctionBody, address: *const VMFunctionBody,
vmctx: *mut VMContext, vmctx: FunctionExtraData,
arg_kind: VMFunctionKind, arg_kind: VMFunctionKind,
definition: FunctionDefinition, definition: FunctionDefinition,
) -> Self { ) -> Self {
@@ -68,6 +69,8 @@ where
address: other.address, address: other.address,
vmctx: other.vmctx, vmctx: other.vmctx,
signature, signature,
// TODO:
function_ptr: 0,
kind: other.arg_kind, kind: other.arg_kind,
} }
} }
@@ -87,6 +90,8 @@ where
address: other.address, address: other.address,
vmctx: other.vmctx, vmctx: other.vmctx,
signature, signature,
// TODO:
function_ptr: 0,
kind: other.arg_kind, kind: other.arg_kind,
}, },
} }
@@ -163,7 +168,7 @@ macro_rules! impl_native_traits {
match self.arg_kind { match self.arg_kind {
VMFunctionKind::Static => { VMFunctionKind::Static => {
let results = catch_unwind(AssertUnwindSafe(|| unsafe { 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( FunctionExtraData, $( $x, )*) -> Rets::CStruct>(self.address);
// We always pass the vmctx // We always pass the vmctx
f( self.vmctx, $( $x, )* ) f( self.vmctx, $( $x, )* )
})).map_err(|e| RuntimeError::new(format!("{:?}", e)))?; })).map_err(|e| RuntimeError::new(format!("{:?}", e)))?;
@@ -173,12 +178,16 @@ macro_rules! impl_native_traits {
let params_list = [ $( $x.to_native().to_value() ),* ]; let params_list = [ $( $x.to_native().to_value() ),* ];
let results = if !has_env { let results = if !has_env {
type VMContextWithoutEnv = VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>; type VMContextWithoutEnv = VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>;
let ctx = self.vmctx as *mut VMContextWithoutEnv; unsafe {
unsafe { (*ctx).ctx.call(&params_list)? } let ctx = self.vmctx.host_env as *mut VMContextWithoutEnv;
(*ctx).ctx.call(&params_list)?
}
} else { } else {
type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>; type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>;
let ctx = self.vmctx as *mut VMContextWithEnv; unsafe {
unsafe { (*ctx).ctx.call(&params_list)? } 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_list_array = Rets::empty_array();
let mut_rets = rets_list_array.as_mut() as *mut [i128] as *mut i128; let mut_rets = rets_list_array.as_mut() as *mut [i128] as *mut i128;

View File

@@ -56,7 +56,9 @@ impl ValFuncRef for Val {
Self::ExternRef(ExternRef::Null) => wasmer_vm::VMCallerCheckedAnyfunc { Self::ExternRef(ExternRef::Null) => wasmer_vm::VMCallerCheckedAnyfunc {
func_ptr: ptr::null(), func_ptr: ptr::null(),
type_index: wasmer_vm::VMSharedSignatureIndex::default(), type_index: wasmer_vm::VMSharedSignatureIndex::default(),
vmctx: ptr::null_mut(), vmctx: wasmer_vm::FunctionExtraData {
host_env: ptr::null_mut(),
},
}, },
Self::FuncRef(f) => f.checked_anyfunc(), Self::FuncRef(f) => f.checked_anyfunc(),
_ => return Err(RuntimeError::new("val is not funcref")), _ => return Err(RuntimeError::new("val is not funcref")),
@@ -74,6 +76,8 @@ impl ValFuncRef for Val {
let export = wasmer_vm::ExportFunction { let export = wasmer_vm::ExportFunction {
address: item.func_ptr, address: item.func_ptr,
signature, signature,
// TODO:
function_ptr: 0,
// All functions in tables are already Static (as dynamic functions // All functions in tables are already Static (as dynamic functions
// are converted to use the trampolines with static signatures). // are converted to use the trampolines with static signatures).
kind: wasmer_vm::VMFunctionKind::Static, kind: wasmer_vm::VMFunctionKind::Static,

View File

@@ -58,7 +58,7 @@ default = [
"object-file", "object-file",
"cache", "cache",
"wasi", "wasi",
"emscripten", # "emscripten",
] ]
engine = [] engine = []
jit = [ jit = [

View File

@@ -58,7 +58,7 @@ impl Wasi {
let import_object = wasi_env.import_object(&module)?; let import_object = wasi_env.import_object(&module)?;
let instance = Instance::new(&module, &import_object)?; let instance = Instance::new(&module, &import_object)?;
wasi_env.set_memory(instance.exports.get_memory("memory")?.clone()); //wasi_env.set_memory(instance.exports.get_memory("memory")?.clone());
let start = instance.exports.get_function("_start")?; let start = instance.exports.get_function("_start")?;
let result = start.call(&[]); let result = start.call(&[]);

View File

@@ -86,7 +86,16 @@ pub trait Artifact: Send + Sync + Upcastable {
tunables: &dyn Tunables, tunables: &dyn Tunables,
resolver: &dyn Resolver, resolver: &dyn Resolver,
host_state: Box<dyn Any>, host_state: Box<dyn Any>,
) -> Result<InstanceHandle, InstantiationError> { ) -> Result<
(
InstanceHandle,
Vec<(
fn(*mut std::ffi::c_void, *const std::ffi::c_void),
*mut std::ffi::c_void,
)>,
),
InstantiationError,
> {
self.preinstantiate()?; self.preinstantiate()?;
let module = self.module(); let module = self.module();
@@ -98,6 +107,19 @@ pub trait Artifact: Send + Sync + Upcastable {
self.table_styles(), self.table_styles(),
) )
.map_err(InstantiationError::Link)?; .map_err(InstantiationError::Link)?;
let mut thunks = vec![];
// ------------
for func in imports.functions.values() {
unsafe {
let finish: fn(*mut std::ffi::c_void, instance: *const std::ffi::c_void) =
std::mem::transmute(func.function_ptr);
dbg!(func.extra_data.host_env);
thunks.push((finish, func.extra_data.host_env));
}
}
// ------------
let finished_memories = tunables let finished_memories = tunables
.create_memories(&module, self.memory_styles()) .create_memories(&module, self.memory_styles())
.map_err(InstantiationError::Link)? .map_err(InstantiationError::Link)?
@@ -113,7 +135,7 @@ pub trait Artifact: Send + Sync + Upcastable {
self.register_frame_info(); self.register_frame_info();
InstanceHandle::new( let handle = InstanceHandle::new(
module, module,
self.finished_functions().clone(), self.finished_functions().clone(),
finished_memories, finished_memories,
@@ -123,7 +145,8 @@ pub trait Artifact: Send + Sync + Upcastable {
self.signatures().clone(), self.signatures().clone(),
host_state, host_state,
) )
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap))) .map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?;
Ok((handle, thunks))
} }
/// Finishes the instantiation of a just created `InstanceHandle`. /// Finishes the instantiation of a just created `InstanceHandle`.

View File

@@ -167,7 +167,9 @@ pub fn resolve_imports(
}; };
function_imports.push(VMFunctionImport { function_imports.push(VMFunctionImport {
body: address, body: address,
vmctx: f.vmctx, extra_data: f.vmctx,
// TODO:
function_ptr: f.function_ptr,
}); });
} }
Export::Table(ref t) => { Export::Table(ref t) => {

View File

@@ -30,7 +30,9 @@ pub struct ExportFunction {
/// The address of the native-code function. /// The address of the native-code function.
pub address: *const VMFunctionBody, pub address: *const VMFunctionBody,
/// Pointer to the containing `VMContext`. /// Pointer to the containing `VMContext`.
pub vmctx: *mut VMContext, pub vmctx: crate::vmcontext::FunctionExtraData,
/// temp code to set vmctx for host functions
pub function_ptr: usize,
/// The function type, used for compatibility checking. /// The function type, used for compatibility checking.
pub signature: FunctionType, pub signature: FunctionType,
/// The function kind (it defines how it's the signature that provided `address` have) /// The function kind (it defines how it's the signature that provided `address` have)

View File

@@ -291,13 +291,19 @@ impl Instance {
match export { match export {
ExportIndex::Function(index) => { ExportIndex::Function(index) => {
let sig_index = &self.module.functions[*index]; let sig_index = &self.module.functions[*index];
let (address, vmctx) = if let Some(def_index) = self.module.local_func_index(*index) let (address, vmctx, function_ptr) =
{ if let Some(def_index) = self.module.local_func_index(*index) {
(self.functions[def_index].0 as *const _, self.vmctx_ptr()) (
} else { self.functions[def_index].0 as *const _,
let import = self.imported_function(*index); crate::vmcontext::FunctionExtraData {
(import.body, import.vmctx) vmctx: self.vmctx_ptr(),
}; },
0,
)
} else {
let import = self.imported_function(*index);
(import.body, import.extra_data, import.function_ptr)
};
let signature = self.module.signatures[*sig_index].clone(); let signature = self.module.signatures[*sig_index].clone();
ExportFunction { ExportFunction {
address, address,
@@ -308,6 +314,7 @@ impl Instance {
kind: VMFunctionKind::Static, kind: VMFunctionKind::Static,
signature, signature,
vmctx, vmctx,
function_ptr,
} }
.into() .into()
} }
@@ -365,28 +372,34 @@ impl Instance {
None => return Ok(()), None => return Ok(()),
}; };
let (callee_address, callee_vmctx) = match self.module.local_func_index(start_index) { let (callee_address, callee_extra_data) = match self.module.local_func_index(start_index) {
Some(local_index) => { Some(local_index) => {
let body = self let body = self
.functions .functions
.get(local_index) .get(local_index)
.expect("function index is out of bounds") .expect("function index is out of bounds")
.0; .0;
(body as *const _, self.vmctx_ptr()) (
body as *const _,
crate::FunctionExtraData {
vmctx: self.vmctx_ptr(),
},
)
} }
None => { None => {
assert_lt!(start_index.index(), self.module.num_imported_functions); assert_lt!(start_index.index(), self.module.num_imported_functions);
let import = self.imported_function(start_index); let import = self.imported_function(start_index);
(import.body, import.vmctx) (import.body, import.extra_data)
} }
}; };
// Make the call. // Make the call.
unsafe { unsafe {
catch_traps(callee_vmctx, || { catch_traps(callee_extra_data, || {
mem::transmute::<*const VMFunctionBody, unsafe extern "C" fn(*mut VMContext)>( mem::transmute::<
callee_address, *const VMFunctionBody,
)(callee_vmctx) unsafe extern "C" fn(crate::FunctionExtraData),
>(callee_address)(callee_extra_data)
}) })
} }
} }
@@ -556,10 +569,15 @@ impl Instance {
let type_index = self.signature_id(sig); let type_index = self.signature_id(sig);
let (func_ptr, vmctx) = if let Some(def_index) = self.module.local_func_index(index) { 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 _,
crate::FunctionExtraData {
vmctx: self.vmctx_ptr(),
},
)
} else { } else {
let import = self.imported_function(index); let import = self.imported_function(index);
(import.body, import.vmctx) (import.body, import.extra_data)
}; };
VMCallerCheckedAnyfunc { VMCallerCheckedAnyfunc {
func_ptr, func_ptr,

View File

@@ -48,10 +48,10 @@ pub use crate::sig_registry::SignatureRegistry;
pub use crate::table::{LinearTable, Table, TableStyle}; pub use crate::table::{LinearTable, Table, TableStyle};
pub use crate::trap::*; pub use crate::trap::*;
pub use crate::vmcontext::{ pub use crate::vmcontext::{
VMBuiltinFunctionIndex, VMCallerCheckedAnyfunc, VMContext, VMDynamicFunctionContext, FunctionExtraData, VMBuiltinFunctionIndex, VMCallerCheckedAnyfunc, VMContext,
VMFunctionBody, VMFunctionImport, VMFunctionKind, VMGlobalDefinition, VMGlobalImport, VMDynamicFunctionContext, VMFunctionBody, VMFunctionImport, VMFunctionKind, VMGlobalDefinition,
VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex, VMTableDefinition,
VMTrampoline, VMTableImport, VMTrampoline,
}; };
pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets}; pub use crate::vmoffsets::{TargetSharedSignatureIndex, VMOffsets};

View File

@@ -429,13 +429,13 @@ impl Trap {
/// Wildly unsafe because it calls raw function pointers and reads/writes raw /// Wildly unsafe because it calls raw function pointers and reads/writes raw
/// function pointers. /// function pointers.
pub unsafe fn wasmer_call_trampoline( pub unsafe fn wasmer_call_trampoline(
vmctx: *mut VMContext, vmctx: crate::FunctionExtraData,
trampoline: VMTrampoline, trampoline: VMTrampoline,
callee: *const VMFunctionBody, callee: *const VMFunctionBody,
values_vec: *mut u8, values_vec: *mut u8,
) -> Result<(), Trap> { ) -> Result<(), Trap> {
catch_traps(vmctx, || { catch_traps(vmctx, || {
mem::transmute::<_, extern "C" fn(*mut VMContext, *const VMFunctionBody, *mut u8)>( mem::transmute::<_, extern "C" fn(crate::FunctionExtraData, *const VMFunctionBody, *mut u8)>(
trampoline, trampoline,
)(vmctx, callee, values_vec) )(vmctx, callee, values_vec)
}) })
@@ -447,7 +447,7 @@ pub unsafe fn wasmer_call_trampoline(
/// # Safety /// # Safety
/// ///
/// Highly unsafe since `closure` won't have any destructors run. /// 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: crate::FunctionExtraData, mut closure: F) -> Result<(), Trap>
where where
F: FnMut(), F: FnMut(),
{ {
@@ -481,7 +481,7 @@ where
/// ///
/// Check [`catch_traps`]. /// Check [`catch_traps`].
pub unsafe fn catch_traps_with_result<F, R>( pub unsafe fn catch_traps_with_result<F, R>(
vmctx: *mut VMContext, vmctx: crate::FunctionExtraData,
mut closure: F, mut closure: F,
) -> Result<R, Trap> ) -> Result<R, Trap>
where where
@@ -501,7 +501,7 @@ pub struct CallThreadState {
jmp_buf: Cell<*const u8>, jmp_buf: Cell<*const u8>,
reset_guard_page: Cell<bool>, reset_guard_page: Cell<bool>,
prev: Option<*const CallThreadState>, prev: Option<*const CallThreadState>,
vmctx: *mut VMContext, vmctx: crate::FunctionExtraData,
handling_trap: Cell<bool>, handling_trap: Cell<bool>,
} }
@@ -518,7 +518,7 @@ enum UnwindReason {
} }
impl CallThreadState { impl CallThreadState {
fn new(vmctx: *mut VMContext) -> Self { fn new(vmctx: crate::FunctionExtraData) -> Self {
Self { Self {
unwind: Cell::new(UnwindReason::None), unwind: Cell::new(UnwindReason::None),
vmctx, vmctx,
@@ -561,7 +561,7 @@ impl CallThreadState {
fn any_instance(&self, func: impl Fn(&InstanceHandle) -> bool) -> bool { fn any_instance(&self, func: impl Fn(&InstanceHandle) -> bool) -> bool {
unsafe { unsafe {
if func(&InstanceHandle::from_vmctx(self.vmctx)) { if func(&InstanceHandle::from_vmctx(self.vmctx.vmctx)) {
return true; return true;
} }
match self.prev { match self.prev {

View File

@@ -15,6 +15,29 @@ use std::ptr::{self, NonNull};
use std::sync::Arc; use std::sync::Arc;
use std::u32; use std::u32;
/// We stop lying about what this daat is
/// TODO:
#[derive(Copy, Clone)]
pub union FunctionExtraData {
/// Wasm function, it has a real VMContext:
pub vmctx: *mut VMContext,
/// Host functions can have custom environments
pub host_env: *mut std::ffi::c_void,
}
impl std::fmt::Debug for FunctionExtraData {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "FunctionExtarData union")
}
}
impl std::cmp::PartialEq for FunctionExtraData {
fn eq(&self, rhs: &Self) -> bool {
// TODO
false
}
}
/// An imported function. /// An imported function.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
#[repr(C)] #[repr(C)]
@@ -22,8 +45,12 @@ pub struct VMFunctionImport {
/// A pointer to the imported function body. /// A pointer to the imported function body.
pub body: *const VMFunctionBody, pub body: *const VMFunctionBody,
/// A pointer to the `VMContext` that owns the function. /// A pointer to the `VMContext` that owns the function or host data.
pub vmctx: *mut VMContext, pub extra_data: FunctionExtraData,
/// temporary hack
/// Only used by host env
pub function_ptr: usize,
} }
#[cfg(test)] #[cfg(test)]
@@ -46,7 +73,7 @@ mod test_vmfunction_import {
usize::from(offsets.vmfunction_import_body()) usize::from(offsets.vmfunction_import_body())
); );
assert_eq!( assert_eq!(
offset_of!(VMFunctionImport, vmctx), offset_of!(VMFunctionImport, extra_data),
usize::from(offsets.vmfunction_import_vmctx()) usize::from(offsets.vmfunction_import_vmctx())
); );
} }
@@ -729,7 +756,7 @@ pub struct VMCallerCheckedAnyfunc {
/// Function signature id. /// Function signature id.
pub type_index: VMSharedSignatureIndex, pub type_index: VMSharedSignatureIndex,
/// Function `VMContext`. /// Function `VMContext`.
pub vmctx: *mut VMContext, pub vmctx: FunctionExtraData,
// If more elements are added here, remember to add offset_of tests below! // If more elements are added here, remember to add offset_of tests below!
} }
@@ -768,7 +795,9 @@ impl Default for VMCallerCheckedAnyfunc {
Self { Self {
func_ptr: ptr::null_mut(), func_ptr: ptr::null_mut(),
type_index: Default::default(), type_index: Default::default(),
vmctx: ptr::null_mut(), vmctx: FunctionExtraData {
vmctx: ptr::null_mut(),
},
} }
} }
} }

View File

@@ -109,7 +109,7 @@ impl VMOffsets {
/// ///
/// [`VMFunctionImport`]: crate::vmcontext::VMFunctionImport /// [`VMFunctionImport`]: crate::vmcontext::VMFunctionImport
pub fn size_of_vmfunction_import(&self) -> u8 { pub fn size_of_vmfunction_import(&self) -> u8 {
2 * self.pointer_size 3 * self.pointer_size
} }
} }

View File

@@ -51,7 +51,25 @@ pub enum WasiError {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct WasiEnv { pub struct WasiEnv {
state: Arc<Mutex<WasiState>>, state: Arc<Mutex<WasiState>>,
memory: Arc<WasiMemory>, memory: *mut Memory,
}
impl wasmer::WasmerPostInstantiate for WasiEnv {
fn finish(&mut self, instance: &wasmer::Instance) {
dbg!("in Wasi::Finish");
let memory = instance.exports.get_memory("memory").unwrap();
unsafe {
let heap_ptr = Box::into_raw(Box::new(memory.clone()));
self.memory = heap_ptr;
}
}
fn free(&mut self) {
unsafe {
Box::from_raw(self.memory);
self.memory = std::ptr::null_mut();
}
}
} }
/// Wrapper type around `Memory` used to delay initialization of the memory. /// Wrapper type around `Memory` used to delay initialization of the memory.
@@ -140,7 +158,7 @@ impl WasiEnv {
pub fn new(state: WasiState) -> Self { pub fn new(state: WasiState) -> Self {
Self { Self {
state: Arc::new(Mutex::new(state)), state: Arc::new(Mutex::new(state)),
memory: Arc::new(WasiMemory::new()), memory: std::ptr::null_mut(),
} }
} }
@@ -154,9 +172,9 @@ impl WasiEnv {
} }
/// Set the memory /// Set the memory
pub fn set_memory(&mut self, memory: Memory) -> bool { /*pub fn set_memory(&mut self, memory: Memory) -> bool {
self.memory.set_memory(memory) self.memory.set_memory(memory)
} }*/
/// Get the WASI state /// Get the WASI state
pub fn state(&self) -> MutexGuard<WasiState> { pub fn state(&self) -> MutexGuard<WasiState> {
@@ -170,7 +188,8 @@ impl WasiEnv {
/// Get a reference to the memory /// Get a reference to the memory
pub fn memory(&self) -> &Memory { pub fn memory(&self) -> &Memory {
self.memory.get_memory().expect("The expected Memory is not attached to the `WasiEnv`. Did you forgot to call wasi_env.set_memory(...)?") dbg!("Getting memory", &self.memory);
unsafe { &*self.memory }
} }
pub(crate) fn get_memory_and_wasi_state( pub(crate) fn get_memory_and_wasi_state(

View File

@@ -84,7 +84,7 @@ impl<'a> WasiTest<'a> {
let imports = self.get_imports(store, &module, env.clone())?; let imports = self.get_imports(store, &module, env.clone())?;
let instance = Instance::new(&module, &imports)?; let instance = Instance::new(&module, &imports)?;
let memory: &Memory = instance.exports.get("memory")?; let memory: &Memory = instance.exports.get("memory")?;
env.set_memory(memory.clone()); //env.set_memory(memory.clone());
let start = instance.exports.get_function("_start")?; let start = instance.exports.get_function("_start")?;
// TODO: handle errors here when the error fix gets shipped // TODO: handle errors here when the error fix gets shipped