Address feedback

This commit is contained in:
Mark McCaskey
2020-12-08 11:02:26 -08:00
parent 476e8d1cd6
commit 6e95c50dc2
5 changed files with 40 additions and 39 deletions

View File

@@ -105,7 +105,6 @@ impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicU32 {}
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI64 {} impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicI64 {}
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicUsize {} impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicUsize {}
impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicIsize {} impl<'a> WasmerEnv for &'a ::std::sync::atomic::AtomicIsize {}
//impl WasmerEnv for dyn ::std::any::Any + Clone {}
impl<T: WasmerEnv> WasmerEnv for Box<T> { impl<T: WasmerEnv> WasmerEnv for Box<T> {
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> { fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
(&mut **self).init_with_instance(instance) (&mut **self).init_with_instance(instance)
@@ -119,13 +118,6 @@ impl<T: WasmerEnv> WasmerEnv for ::std::sync::Arc<::std::sync::Mutex<T>> {
} }
} }
/*impl<T: WasmerEnv> WasmerEnv for &'static T {
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
T::init_with_instance()
(*self).init_with_instance(instance)
}
}*/
/// Lazily init an item /// Lazily init an item
pub struct LazyInit<T: Sized> { pub struct LazyInit<T: Sized> {
/// The data to be initialized /// The data to be initialized

View File

@@ -88,8 +88,8 @@ impl Function {
where where
F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static, F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
{ {
let dynamic_ctx: VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv> = let dynamic_ctx: VMDynamicFunctionContext<DynamicFunctionWithoutEnv> =
VMDynamicFunctionContext::from_context(VMDynamicFunctionWithoutEnv { VMDynamicFunctionContext::from_context(DynamicFunctionWithoutEnv {
func: Arc::new(func), func: Arc::new(func),
function_type: ty.clone(), function_type: ty.clone(),
}); });
@@ -100,16 +100,16 @@ impl Function {
let host_env = Box::into_raw(Box::new(dynamic_ctx)) as *mut _; let host_env = Box::into_raw(Box::new(dynamic_ctx)) as *mut _;
let vmctx = VMFunctionEnvironment { host_env }; let vmctx = VMFunctionEnvironment { host_env };
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| { let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let duped_env: VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv> = unsafe { let duped_env: VMDynamicFunctionContext<DynamicFunctionWithoutEnv> = unsafe {
let ptr: *mut VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv> = ptr as _; let ptr: *mut VMDynamicFunctionContext<DynamicFunctionWithoutEnv> = ptr as _;
let item: &VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv> = &*ptr; let item: &VMDynamicFunctionContext<DynamicFunctionWithoutEnv> = &*ptr;
item.clone() item.clone()
}; };
Box::into_raw(Box::new(duped_env)) as _ Box::into_raw(Box::new(duped_env)) as _
}; };
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| { let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| {
unsafe { unsafe {
Box::from_raw(ptr as *mut VMDynamicFunctionContext<VMDynamicFunctionWithoutEnv>) Box::from_raw(ptr as *mut VMDynamicFunctionContext<DynamicFunctionWithoutEnv>)
}; };
}; };
@@ -162,8 +162,8 @@ impl Function {
F: Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static, F: Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
Env: Sized + WasmerEnv + 'static, Env: Sized + WasmerEnv + 'static,
{ {
let dynamic_ctx: VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>> = let dynamic_ctx: VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> =
VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv { VMDynamicFunctionContext::from_context(DynamicFunctionWithEnv {
env: { env: {
let e = Box::new(env); let e = Box::new(env);
e e
@@ -179,7 +179,7 @@ impl Function {
let vmctx = VMFunctionEnvironment { host_env }; let vmctx = VMFunctionEnvironment { host_env };
let import_init_function_ptr: fn(_, _) -> Result<(), _> = let import_init_function_ptr: fn(_, _) -> Result<(), _> =
|ptr: *mut std::ffi::c_void, instance: *const std::ffi::c_void| { |ptr: *mut std::ffi::c_void, instance: *const std::ffi::c_void| {
let ptr = ptr as *mut VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>>; let ptr = ptr as *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>;
unsafe { unsafe {
let env = &mut *ptr; let env = &mut *ptr;
let env: &mut Env = &mut *env.ctx.env; let env: &mut Env = &mut *env.ctx.env;
@@ -193,16 +193,16 @@ impl Function {
) )
}); });
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| { let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let duped_env: VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>> = unsafe { let duped_env: VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = unsafe {
let ptr: *mut VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>> = ptr as _; let ptr: *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = ptr as _;
let item: &VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>> = &*ptr; let item: &VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = &*ptr;
item.clone() item.clone()
}; };
Box::into_raw(Box::new(duped_env)) as _ Box::into_raw(Box::new(duped_env)) as _
}; };
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| { let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| {
unsafe { unsafe {
Box::from_raw(ptr as *mut VMDynamicFunctionContext<VMDynamicFunctionWithEnv<Env>>) Box::from_raw(ptr as *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>)
}; };
}; };
@@ -795,13 +795,13 @@ pub(crate) trait VMDynamicFunction {
} }
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct VMDynamicFunctionWithoutEnv { pub(crate) struct DynamicFunctionWithoutEnv {
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
func: Arc<dyn Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>, func: Arc<dyn Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>,
function_type: FunctionType, function_type: FunctionType,
} }
impl VMDynamicFunction for VMDynamicFunctionWithoutEnv { impl VMDynamicFunction for DynamicFunctionWithoutEnv {
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError> { fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
(*self.func)(&args) (*self.func)(&args)
} }
@@ -810,19 +810,17 @@ impl VMDynamicFunction for VMDynamicFunctionWithoutEnv {
} }
} }
#[repr(C)] pub(crate) struct DynamicFunctionWithEnv<Env>
pub(crate) struct VMDynamicFunctionWithEnv<Env>
where where
Env: Sized + 'static, Env: Sized + 'static,
{ {
// This field _must_ come first in this struct.
env: Box<Env>,
function_type: FunctionType, function_type: FunctionType,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
func: Arc<dyn Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>, func: Arc<dyn Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>,
env: Box<Env>,
} }
impl<Env: Sized + Clone + 'static> Clone for VMDynamicFunctionWithEnv<Env> { impl<Env: Sized + Clone + 'static> Clone for DynamicFunctionWithEnv<Env> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
env: self.env.clone(), env: self.env.clone(),
@@ -832,7 +830,7 @@ impl<Env: Sized + Clone + 'static> Clone for VMDynamicFunctionWithEnv<Env> {
} }
} }
impl<Env> VMDynamicFunction for VMDynamicFunctionWithEnv<Env> impl<Env> VMDynamicFunction for DynamicFunctionWithEnv<Env>
where where
Env: Sized + 'static, Env: Sized + 'static,
{ {

View File

@@ -10,8 +10,8 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::externals::function::{ use crate::externals::function::{
FunctionDefinition, HostFunctionDefinition, VMDynamicFunction, VMDynamicFunctionWithEnv, DynamicFunctionWithEnv, DynamicFunctionWithoutEnv, FunctionDefinition, HostFunctionDefinition,
VMDynamicFunctionWithoutEnv, WasmFunctionDefinition, VMDynamicFunction, WasmFunctionDefinition,
}; };
use crate::{FromToNativeWasmType, Function, FunctionType, RuntimeError, Store, WasmTypeList}; use crate::{FromToNativeWasmType, Function, FunctionType, RuntimeError, Store, WasmTypeList};
use std::panic::{catch_unwind, AssertUnwindSafe}; use std::panic::{catch_unwind, AssertUnwindSafe};
@@ -205,13 +205,13 @@ macro_rules! impl_native_traits {
VMFunctionKind::Dynamic => { VMFunctionKind::Dynamic => {
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<DynamicFunctionWithoutEnv>;
unsafe { unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithoutEnv; let ctx = self.vmctx.host_env as *mut VMContextWithoutEnv;
(*ctx).ctx.call(&params_list)? (*ctx).ctx.call(&params_list)?
} }
} else { } else {
type VMContextWithEnv = VMDynamicFunctionContext<VMDynamicFunctionWithEnv<std::ffi::c_void>>; type VMContextWithEnv = VMDynamicFunctionContext<DynamicFunctionWithEnv<std::ffi::c_void>>;
unsafe { unsafe {
let ctx = self.vmctx.host_env as *mut VMContextWithEnv; let ctx = self.vmctx.host_env as *mut VMContextWithEnv;
(*ctx).ctx.call(&params_list)? (*ctx).ctx.call(&params_list)?

View File

@@ -46,11 +46,25 @@ impl From<VMExport> for Export {
} }
} }
/// TODO: rename, etc. /// Extra metadata about `ExportFunction`s.
///
/// The metadata acts as a kind of manual virtual dispatch. We store the
/// user-supplied `WasmerEnv` as a void pointer and have methods on it
/// that have been adapted to accept a void pointer.
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct ExportFunctionMetadata { pub struct ExportFunctionMetadata {
/// duplicated here so we can free it.... /// This field is stored here to be accessible by `Drop`.
/// TODO: refactor all this stuff so it's less of a nightmare. ///
/// At the time it was added, it's not accessed anywhere outside of
/// the `Drop` implementation. This field is the "master copy" of the env,
/// that is, the original env passed in by the user. Every time we create
/// an `Instance` we clone this with the `host_env_clone_fn` field.
///
/// Thus, we only bother to store the master copy at all here so that
/// we can free it.
///
/// See `wasmer_vm::export::VMExportFunction::vmctx` for the version of
/// this pointer that is used by the VM when creating an `Instance`.
pub host_env: *mut std::ffi::c_void, pub host_env: *mut std::ffi::c_void,
/// Function pointer to `WasmerEnv::init_with_instance(&mut self, instance: &Instance)`. /// Function pointer to `WasmerEnv::init_with_instance(&mut self, instance: &Instance)`.
/// ///
@@ -69,7 +83,6 @@ pub struct ExportFunctionMetadata {
// so all the `host_env`s freed at the `Instance` level won't touch the original. // so all the `host_env`s freed at the `Instance` level won't touch the original.
impl Drop for ExportFunctionMetadata { impl Drop for ExportFunctionMetadata {
fn drop(&mut self) { fn drop(&mut self) {
dbg!("DROPPING ORIGINAL HOST ENV!");
if !self.host_env.is_null() { if !self.host_env.is_null() {
(self.host_env_drop_fn)(self.host_env); (self.host_env_drop_fn)(self.host_env);
} }

View File

@@ -357,7 +357,6 @@ fn multi_use_host_fn_manages_memory_correctly() -> Result<()> {
impl WasmerEnv for Env { impl WasmerEnv for Env {
fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> { fn init_with_instance(&mut self, instance: &Instance) -> Result<(), HostEnvInitError> {
dbg!("Initing the env!");
let memory = instance.exports.get_memory("memory")?.clone(); let memory = instance.exports.get_memory("memory")?.clone();
self.memory.initialize(memory); self.memory.initialize(memory);
Ok(()) Ok(())
@@ -368,7 +367,6 @@ fn multi_use_host_fn_manages_memory_correctly() -> Result<()> {
memory: LazyInit::default(), memory: LazyInit::default(),
}; };
fn host_fn(env: &Env) { fn host_fn(env: &Env) {
dbg!(env as *const _);
assert!(env.memory.get_ref().is_some()); assert!(env.memory.get_ref().is_some());
println!("Hello, world!"); println!("Hello, world!");
} }