Clean up code a bit

This commit is contained in:
Mark McCaskey
2020-10-20 12:21:16 -07:00
parent 3c7dfe29f3
commit ed1202181e
13 changed files with 96 additions and 58 deletions

View File

@@ -96,7 +96,7 @@ impl Function {
address, address,
kind: VMFunctionKind::Dynamic, kind: VMFunctionKind::Dynamic,
vmctx, vmctx,
function_ptr: 0, function_ptr: None,
signature: ty.clone(), signature: ty.clone(),
}, },
} }
@@ -126,7 +126,7 @@ impl Function {
pub fn new_with_env<F, Env>(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self pub fn new_with_env<F, Env>(store: &Store, ty: &FunctionType, env: Env, func: F) -> Self
where where
F: Fn(&mut Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static, F: Fn(&mut Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
Env: Sized + 'static, Env: Sized + crate::WasmerPostInstantiate + 'static,
{ {
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv { let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv {
env: RefCell::new(env), env: RefCell::new(env),
@@ -140,6 +140,9 @@ impl Function {
let vmctx = FunctionExtraData { let vmctx = FunctionExtraData {
host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _, host_env: Box::into_raw(Box::new(dynamic_ctx)) as *mut _,
}; };
// TODO: look into removing transmute by changing API type signatures
let function_ptr = Some(unsafe { std::mem::transmute::<fn(_, _), fn(_, _)>(Env::finish) });
//dbg!(function_ptr);
Self { Self {
store: store.clone(), store: store.clone(),
@@ -148,8 +151,7 @@ impl Function {
address, address,
kind: VMFunctionKind::Dynamic, kind: VMFunctionKind::Dynamic,
vmctx, vmctx,
// TODO: function_ptr,
function_ptr: 0,
signature: ty.clone(), signature: ty.clone(),
}, },
} }
@@ -193,8 +195,9 @@ impl Function {
address, address,
vmctx, vmctx,
signature, signature,
// TODO: // TODO: figure out what's going on in this function: it takes an `Env`
function_ptr: 0, // param but also marks itself as not having an env
function_ptr: None,
kind: VMFunctionKind::Static, kind: VMFunctionKind::Static,
}, },
} }
@@ -241,8 +244,9 @@ impl Function {
let vmctx = FunctionExtraData { let vmctx = FunctionExtraData {
host_env: Box::into_raw(box_env) as *mut _, host_env: Box::into_raw(box_env) as *mut _,
}; };
let function_ptr = Env::finish as usize; // TODO: look into removing transmute by changing API type signatures
dbg!(function_ptr); let function_ptr = Some(unsafe { std::mem::transmute::<fn(_, _), fn(_, _)>(Env::finish) });
//dbg!(function_ptr as usize);
let signature = function.ty(); let signature = function.ty();
Self { Self {

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, thunks) = module.instantiate(resolver)?; let handle = module.instantiate(resolver)?;
let exports = module let exports = module
.exports() .exports()
@@ -91,11 +91,10 @@ impl Instance {
exports, exports,
}; };
for (func, env) in thunks.iter() { unsafe {
dbg!(func, env); instance
unsafe { .handle
func(*env, (&instance) as *const _ as *const _); .initialize_host_envs(&instance as *const _ as *const _);
}
} }
Ok(instance) Ok(instance)

View File

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

View File

@@ -70,7 +70,7 @@ where
vmctx: other.vmctx, vmctx: other.vmctx,
signature, signature,
// TODO: // TODO:
function_ptr: 0, function_ptr: None,
kind: other.arg_kind, kind: other.arg_kind,
} }
} }
@@ -91,7 +91,7 @@ where
vmctx: other.vmctx, vmctx: other.vmctx,
signature, signature,
// TODO: // TODO:
function_ptr: 0, function_ptr: None,
kind: other.arg_kind, kind: other.arg_kind,
}, },
} }

View File

@@ -77,7 +77,8 @@ impl ValFuncRef for Val {
address: item.func_ptr, address: item.func_ptr,
signature, signature,
// TODO: // TODO:
function_ptr: 0, // figure out if we ever need a value here: need testing with complicated import patterns
function_ptr: None,
// 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

@@ -86,16 +86,7 @@ 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< ) -> Result<InstanceHandle, InstantiationError> {
(
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();
@@ -110,13 +101,17 @@ pub trait Artifact: Send + Sync + Upcastable {
let mut thunks = vec![]; let mut thunks = vec![];
// ------------ // ------------
for func in imports.functions.values() { for (func_init, func) in imports
unsafe { .host_function_env_initializers
let finish: fn(*mut std::ffi::c_void, instance: *const std::ffi::c_void) = .values()
std::mem::transmute(func.function_ptr); .cloned()
dbg!(func.extra_data.host_env); .zip(imports.functions.values())
thunks.push((finish, func.extra_data.host_env)); {
} let host_env = unsafe {
//dbg!(func.extra_data.host_env);
func.extra_data.host_env
};
thunks.push((func_init, host_env));
} }
// ------------ // ------------
@@ -144,9 +139,10 @@ pub trait Artifact: Send + Sync + Upcastable {
imports, imports,
self.signatures().clone(), self.signatures().clone(),
host_state, host_state,
thunks,
) )
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?; .map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?;
Ok((handle, thunks)) Ok(handle)
} }
/// Finishes the instantiation of a just created `InstanceHandle`. /// Finishes the instantiation of a just created `InstanceHandle`.

View File

@@ -125,6 +125,9 @@ pub fn resolve_imports(
_table_styles: &PrimaryMap<TableIndex, TableStyle>, _table_styles: &PrimaryMap<TableIndex, TableStyle>,
) -> Result<Imports, LinkError> { ) -> Result<Imports, LinkError> {
let mut function_imports = PrimaryMap::with_capacity(module.num_imported_functions); let mut function_imports = PrimaryMap::with_capacity(module.num_imported_functions);
// TODO: account for imported functions without env / from other Wasm instances
let mut host_function_env_initializers =
PrimaryMap::with_capacity(module.num_imported_functions);
let mut table_imports = PrimaryMap::with_capacity(module.num_imported_tables); let mut table_imports = PrimaryMap::with_capacity(module.num_imported_tables);
let mut memory_imports = PrimaryMap::with_capacity(module.num_imported_memories); let mut memory_imports = PrimaryMap::with_capacity(module.num_imported_memories);
let mut global_imports = PrimaryMap::with_capacity(module.num_imported_globals); let mut global_imports = PrimaryMap::with_capacity(module.num_imported_globals);
@@ -168,9 +171,9 @@ pub fn resolve_imports(
function_imports.push(VMFunctionImport { function_imports.push(VMFunctionImport {
body: address, body: address,
extra_data: f.vmctx, extra_data: f.vmctx,
// TODO:
function_ptr: f.function_ptr,
}); });
host_function_env_initializers.push(f.function_ptr);
} }
Export::Table(ref t) => { Export::Table(ref t) => {
table_imports.push(VMTableImport { table_imports.push(VMTableImport {
@@ -224,6 +227,7 @@ pub fn resolve_imports(
Ok(Imports::new( Ok(Imports::new(
function_imports, function_imports,
host_function_env_initializers,
table_imports, table_imports,
memory_imports, memory_imports,
global_imports, global_imports,

View File

@@ -32,7 +32,7 @@ pub struct ExportFunction {
/// Pointer to the containing `VMContext`. /// Pointer to the containing `VMContext`.
pub vmctx: crate::vmcontext::FunctionExtraData, pub vmctx: crate::vmcontext::FunctionExtraData,
/// temp code to set vmctx for host functions /// temp code to set vmctx for host functions
pub function_ptr: usize, pub function_ptr: Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)>,
/// 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

@@ -11,6 +11,12 @@ pub struct Imports {
/// Resolved addresses for imported functions. /// Resolved addresses for imported functions.
pub functions: BoxedSlice<FunctionIndex, VMFunctionImport>, pub functions: BoxedSlice<FunctionIndex, VMFunctionImport>,
/// Initializers for host function environments. This is split out from `functions`
/// because the generated code never needs to touch this and the extra wasted
/// space may affect Wasm runtime performance due to increased cache pressure.
pub host_function_env_initializers:
BoxedSlice<FunctionIndex, Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)>>,
/// Resolved addresses for imported tables. /// Resolved addresses for imported tables.
pub tables: BoxedSlice<TableIndex, VMTableImport>, pub tables: BoxedSlice<TableIndex, VMTableImport>,
@@ -25,12 +31,17 @@ impl Imports {
/// Construct a new `Imports` instance. /// Construct a new `Imports` instance.
pub fn new( pub fn new(
function_imports: PrimaryMap<FunctionIndex, VMFunctionImport>, function_imports: PrimaryMap<FunctionIndex, VMFunctionImport>,
host_function_env_initializers: PrimaryMap<
FunctionIndex,
Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)>,
>,
table_imports: PrimaryMap<TableIndex, VMTableImport>, table_imports: PrimaryMap<TableIndex, VMTableImport>,
memory_imports: PrimaryMap<MemoryIndex, VMMemoryImport>, memory_imports: PrimaryMap<MemoryIndex, VMMemoryImport>,
global_imports: PrimaryMap<GlobalIndex, VMGlobalImport>, global_imports: PrimaryMap<GlobalIndex, VMGlobalImport>,
) -> Self { ) -> Self {
Self { Self {
functions: function_imports.into_boxed_slice(), functions: function_imports.into_boxed_slice(),
host_function_env_initializers: host_function_env_initializers.into_boxed_slice(),
tables: table_imports.into_boxed_slice(), tables: table_imports.into_boxed_slice(),
memories: memory_imports.into_boxed_slice(), memories: memory_imports.into_boxed_slice(),
globals: global_imports.into_boxed_slice(), globals: global_imports.into_boxed_slice(),
@@ -41,6 +52,7 @@ impl Imports {
pub fn none() -> Self { pub fn none() -> Self {
Self { Self {
functions: PrimaryMap::new().into_boxed_slice(), functions: PrimaryMap::new().into_boxed_slice(),
host_function_env_initializers: PrimaryMap::new().into_boxed_slice(),
tables: PrimaryMap::new().into_boxed_slice(), tables: PrimaryMap::new().into_boxed_slice(),
memories: PrimaryMap::new().into_boxed_slice(), memories: PrimaryMap::new().into_boxed_slice(),
globals: PrimaryMap::new().into_boxed_slice(), globals: PrimaryMap::new().into_boxed_slice(),

View File

@@ -100,6 +100,17 @@ pub(crate) struct Instance {
/// Handler run when `SIGBUS`, `SIGFPE`, `SIGILL`, or `SIGSEGV` are caught by the instance thread. /// Handler run when `SIGBUS`, `SIGFPE`, `SIGILL`, or `SIGSEGV` are caught by the instance thread.
pub(crate) signal_handler: Cell<Option<Box<SignalHandler>>>, pub(crate) signal_handler: Cell<Option<Box<SignalHandler>>>,
/// TODO: document this
/// Functions to initialize the host environments in the imports.
/// Do we want to drain this? There's probably no reason to keep this memory
/// around once we've used it.
///
/// Be sure to test with serialize/deserialize and imported functions from other Wasm modules.
import_initializers: Vec<(
Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)>,
*mut std::ffi::c_void,
)>,
/// Additional context used by compiled wasm code. This field is last, and /// Additional context used by compiled wasm code. This field is last, and
/// represents a dynamically-sized array that extends beyond the nominal /// represents a dynamically-sized array that extends beyond the nominal
/// end of the struct (similar to a flexible array member). /// end of the struct (similar to a flexible array member).
@@ -141,6 +152,14 @@ impl Instance {
unsafe { &*self.imported_functions_ptr().add(index) } unsafe { &*self.imported_functions_ptr().add(index) }
} }
/// TODO: document this
fn imported_function_env_initializer(
&self,
index: FunctionIndex,
) -> Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)> {
self.import_initializers[index.as_u32() as usize].0
}
/// Return a pointer to the `VMFunctionImport`s. /// Return a pointer to the `VMFunctionImport`s.
fn imported_functions_ptr(&self) -> *mut VMFunctionImport { fn imported_functions_ptr(&self) -> *mut VMFunctionImport {
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_imported_functions_begin()) } unsafe { self.vmctx_plus_offset(self.offsets.vmctx_imported_functions_begin()) }
@@ -298,11 +317,12 @@ impl Instance {
crate::vmcontext::FunctionExtraData { crate::vmcontext::FunctionExtraData {
vmctx: self.vmctx_ptr(), vmctx: self.vmctx_ptr(),
}, },
0, None,
) )
} else { } else {
let import = self.imported_function(*index); let import = self.imported_function(*index);
(import.body, import.extra_data, import.function_ptr) let initializer = self.imported_function_env_initializer(*index);
(import.body, import.extra_data, initializer)
}; };
let signature = self.module.signatures[*sig_index].clone(); let signature = self.module.signatures[*sig_index].clone();
ExportFunction { ExportFunction {
@@ -815,6 +835,10 @@ impl InstanceHandle {
imports: Imports, imports: Imports,
vmshared_signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>, vmshared_signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
host_state: Box<dyn Any>, host_state: Box<dyn Any>,
import_initializers: Vec<(
Option<fn(*mut std::ffi::c_void, *const std::ffi::c_void)>,
*mut std::ffi::c_void,
)>,
) -> Result<Self, Trap> { ) -> Result<Self, Trap> {
// TODO: investigate `vmctx_tables` and `vmctx_memories`: both of these // TODO: investigate `vmctx_tables` and `vmctx_memories`: both of these
// appear to be dropped in this function which may cause memory problems // appear to be dropped in this function which may cause memory problems
@@ -859,6 +883,7 @@ impl InstanceHandle {
passive_data, passive_data,
host_state, host_state,
signal_handler: Cell::new(None), signal_handler: Cell::new(None),
import_initializers,
vmctx: VMContext {}, vmctx: VMContext {},
}; };
let layout = instance.alloc_layout(); let layout = instance.alloc_layout();
@@ -1076,6 +1101,17 @@ impl InstanceHandle {
unsafe { &*(self.instance as *const Instance) } unsafe { &*(self.instance as *const Instance) }
} }
/// TODO: document this
/// Initializes the host environments.
pub unsafe fn initialize_host_envs(&self, instance_ptr: *const std::ffi::c_void) {
for (func, env) in self.instance().import_initializers.iter() {
if let Some(f) = func {
dbg!(f, env);
f(*env, instance_ptr);
}
}
}
/// Deallocates memory associated with this instance. /// Deallocates memory associated with this instance.
/// ///
/// # Safety /// # Safety

View File

@@ -47,10 +47,6 @@ pub struct VMFunctionImport {
/// A pointer to the `VMContext` that owns the function or host data. /// A pointer to the `VMContext` that owns the function or host data.
pub extra_data: FunctionExtraData, pub extra_data: FunctionExtraData,
/// temporary hack
/// Only used by host env
pub function_ptr: usize,
} }
#[cfg(test)] #[cfg(test)]

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 {
3 * self.pointer_size 2 * self.pointer_size
} }
} }

View File

@@ -188,7 +188,6 @@ impl WasiEnv {
/// Get a reference to the memory /// Get a reference to the memory
pub fn memory(&self) -> &Memory { pub fn memory(&self) -> &Memory {
dbg!("Getting memory", &self.memory);
unsafe { &*self.memory } unsafe { &*self.memory }
} }