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,
kind: VMFunctionKind::Dynamic,
vmctx,
function_ptr: 0,
function_ptr: None,
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
where
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 {
env: RefCell::new(env),
@@ -140,6 +140,9 @@ impl Function {
let vmctx = FunctionExtraData {
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 {
store: store.clone(),
@@ -148,8 +151,7 @@ impl Function {
address,
kind: VMFunctionKind::Dynamic,
vmctx,
// TODO:
function_ptr: 0,
function_ptr,
signature: ty.clone(),
},
}
@@ -193,8 +195,9 @@ impl Function {
address,
vmctx,
signature,
// TODO:
function_ptr: 0,
// TODO: figure out what's going on in this function: it takes an `Env`
// param but also marks itself as not having an env
function_ptr: None,
kind: VMFunctionKind::Static,
},
}
@@ -241,8 +244,9 @@ impl Function {
let vmctx = FunctionExtraData {
host_env: Box::into_raw(box_env) as *mut _,
};
let function_ptr = Env::finish as usize;
dbg!(function_ptr);
// 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 as usize);
let signature = function.ty();
Self {

View File

@@ -73,7 +73,7 @@ impl Instance {
pub fn new(module: &Module, resolver: &dyn Resolver) -> Result<Self, InstantiationError> {
let store = module.store();
let (handle, thunks) = module.instantiate(resolver)?;
let handle = module.instantiate(resolver)?;
let exports = module
.exports()
@@ -91,11 +91,10 @@ impl Instance {
exports,
};
for (func, env) in thunks.iter() {
dbg!(func, env);
unsafe {
func(*env, (&instance) as *const _ as *const _);
}
instance
.handle
.initialize_host_envs(&instance as *const _ as *const _);
}
Ok(instance)

View File

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

View File

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

View File

@@ -77,7 +77,8 @@ impl ValFuncRef for Val {
address: item.func_ptr,
signature,
// 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
// are converted to use the trampolines with static signatures).
kind: wasmer_vm::VMFunctionKind::Static,

View File

@@ -86,16 +86,7 @@ pub trait Artifact: Send + Sync + Upcastable {
tunables: &dyn Tunables,
resolver: &dyn Resolver,
host_state: Box<dyn Any>,
) -> Result<
(
InstanceHandle,
Vec<(
fn(*mut std::ffi::c_void, *const std::ffi::c_void),
*mut std::ffi::c_void,
)>,
),
InstantiationError,
> {
) -> Result<InstanceHandle, InstantiationError> {
self.preinstantiate()?;
let module = self.module();
@@ -110,13 +101,17 @@ pub trait Artifact: Send + Sync + Upcastable {
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));
}
for (func_init, func) in imports
.host_function_env_initializers
.values()
.cloned()
.zip(imports.functions.values())
{
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,
self.signatures().clone(),
host_state,
thunks,
)
.map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?;
Ok((handle, thunks))
Ok(handle)
}
/// Finishes the instantiation of a just created `InstanceHandle`.

View File

@@ -125,6 +125,9 @@ pub fn resolve_imports(
_table_styles: &PrimaryMap<TableIndex, TableStyle>,
) -> Result<Imports, LinkError> {
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 memory_imports = PrimaryMap::with_capacity(module.num_imported_memories);
let mut global_imports = PrimaryMap::with_capacity(module.num_imported_globals);
@@ -168,9 +171,9 @@ pub fn resolve_imports(
function_imports.push(VMFunctionImport {
body: address,
extra_data: f.vmctx,
// TODO:
function_ptr: f.function_ptr,
});
host_function_env_initializers.push(f.function_ptr);
}
Export::Table(ref t) => {
table_imports.push(VMTableImport {
@@ -224,6 +227,7 @@ pub fn resolve_imports(
Ok(Imports::new(
function_imports,
host_function_env_initializers,
table_imports,
memory_imports,
global_imports,

View File

@@ -32,7 +32,7 @@ pub struct ExportFunction {
/// Pointer to the containing `VMContext`.
pub vmctx: crate::vmcontext::FunctionExtraData,
/// 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.
pub signature: FunctionType,
/// 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.
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.
pub tables: BoxedSlice<TableIndex, VMTableImport>,
@@ -25,12 +31,17 @@ impl Imports {
/// Construct a new `Imports` instance.
pub fn new(
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>,
memory_imports: PrimaryMap<MemoryIndex, VMMemoryImport>,
global_imports: PrimaryMap<GlobalIndex, VMGlobalImport>,
) -> Self {
Self {
functions: function_imports.into_boxed_slice(),
host_function_env_initializers: host_function_env_initializers.into_boxed_slice(),
tables: table_imports.into_boxed_slice(),
memories: memory_imports.into_boxed_slice(),
globals: global_imports.into_boxed_slice(),
@@ -41,6 +52,7 @@ impl Imports {
pub fn none() -> Self {
Self {
functions: PrimaryMap::new().into_boxed_slice(),
host_function_env_initializers: PrimaryMap::new().into_boxed_slice(),
tables: PrimaryMap::new().into_boxed_slice(),
memories: 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.
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
/// represents a dynamically-sized array that extends beyond the nominal
/// end of the struct (similar to a flexible array member).
@@ -141,6 +152,14 @@ impl Instance {
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.
fn imported_functions_ptr(&self) -> *mut VMFunctionImport {
unsafe { self.vmctx_plus_offset(self.offsets.vmctx_imported_functions_begin()) }
@@ -298,11 +317,12 @@ impl Instance {
crate::vmcontext::FunctionExtraData {
vmctx: self.vmctx_ptr(),
},
0,
None,
)
} else {
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();
ExportFunction {
@@ -815,6 +835,10 @@ impl InstanceHandle {
imports: Imports,
vmshared_signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
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> {
// TODO: investigate `vmctx_tables` and `vmctx_memories`: both of these
// appear to be dropped in this function which may cause memory problems
@@ -859,6 +883,7 @@ impl InstanceHandle {
passive_data,
host_state,
signal_handler: Cell::new(None),
import_initializers,
vmctx: VMContext {},
};
let layout = instance.alloc_layout();
@@ -1076,6 +1101,17 @@ impl InstanceHandle {
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.
///
/// # Safety

View File

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

View File

@@ -109,7 +109,7 @@ impl VMOffsets {
///
/// [`VMFunctionImport`]: crate::vmcontext::VMFunctionImport
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
pub fn memory(&self) -> &Memory {
dbg!("Getting memory", &self.memory);
unsafe { &*self.memory }
}