diff --git a/crates/cli/tests/run.rs b/crates/cli/tests/run.rs index f56ea9c9aa..cf118e5419 100644 --- a/crates/cli/tests/run.rs +++ b/crates/cli/tests/run.rs @@ -39,8 +39,6 @@ fn test_verbose() { assert!(contains_slice(stdout, b"proc_exit.wat\")::()")); } -/// UTILS - /// gets the path to a wasm binary given it's name fn get_bin_path(name: &str) -> PathBuf { let mut path = PathBuf::new(); diff --git a/crates/wasmi/src/externref.rs b/crates/wasmi/src/externref.rs index 0bd1a80074..a571a8fd2c 100644 --- a/crates/wasmi/src/externref.rs +++ b/crates/wasmi/src/externref.rs @@ -1,12 +1,11 @@ use crate::{ collections::arena::ArenaIndex, core::UntypedVal, - reftype::Transposer, store::Stored, AsContextMut, StoreContext, }; -use core::{any::Any, num::NonZeroU32}; +use core::{any::Any, mem, num::NonZeroU32}; use std::boxed::Box; /// A raw index to a function entity. @@ -117,24 +116,30 @@ fn externref_null_to_zero() { impl From for ExternRef { fn from(untyped: UntypedVal) -> Self { + if u64::from(untyped) == 0 { + return ExternRef::null(); + } // Safety: This operation is safe since there are no invalid // bit patterns for [`ExternRef`] instances. Therefore // this operation cannot produce invalid [`ExternRef`] // instances even though the input [`UntypedVal`] // was modified arbitrarily. - unsafe { >::from(untyped).reftype }.canonicalize() + unsafe { mem::transmute::(untyped.into()) } } } impl From for UntypedVal { fn from(externref: ExternRef) -> Self { - let externref = externref.canonicalize(); + if externref.is_null() { + return UntypedVal::from(0_u64); + } // Safety: This operation is safe since there are no invalid // bit patterns for [`UntypedVal`] instances. Therefore // this operation cannot produce invalid [`UntypedVal`] // instances even if it was possible to arbitrarily modify // the input [`ExternRef`] instance. - Self::from(unsafe { >::new(externref).value }) + let bits = unsafe { mem::transmute::(externref) }; + UntypedVal::from(bits) } } @@ -149,25 +154,6 @@ impl ExternRef { .map(|object| ExternObject::new(ctx, object)) .map(Self::from_object) .unwrap_or_else(Self::null) - .canonicalize() - } - - /// Canonicalize `self` so that all `null` values have the same representation. - /// - /// # Note - /// - /// The underlying issue is that `ExternRef` has many possible values for the - /// `null` value. However, to simplify operating on encoded `ExternRef` instances - /// (encoded as `UntypedValue`) we want it to encode to exactly one `null` - /// value. The most trivial of all possible `null` values is `0_u64`, therefore - /// we canonicalize all `null` values to be represented by `0_u64`. - fn canonicalize(self) -> Self { - if self.is_null() { - // Safety: This is safe since `0u64` can be bit - // interpreted as a valid `ExternRef` value. - return unsafe { >::null().reftype }; - } - self } /// Creates a new [`ExternRef`] to the given [`ExternObject`]. @@ -177,16 +163,16 @@ impl ExternRef { } } - /// Creates a new [`ExternRef`] which is `null`. - pub fn null() -> Self { - Self { inner: None }.canonicalize() - } - /// Returns `true` if [`ExternRef`] is `null`. pub fn is_null(&self) -> bool { self.inner.is_none() } + /// Creates a new [`ExternRef`] which is `null`. + pub fn null() -> Self { + Self { inner: None } + } + /// Returns a shared reference to the underlying data for this [`ExternRef`]. /// /// # Panics diff --git a/crates/wasmi/src/func/funcref.rs b/crates/wasmi/src/func/funcref.rs index 974b31d339..ad861b38b6 100644 --- a/crates/wasmi/src/func/funcref.rs +++ b/crates/wasmi/src/func/funcref.rs @@ -1,5 +1,6 @@ use super::Func; -use crate::{core::UntypedVal, reftype::Transposer}; +use crate::core::UntypedVal; +use core::mem; /// A nullable [`Func`] reference. #[derive(Debug, Default, Copy, Clone)] @@ -35,24 +36,30 @@ fn funcref_null_to_zero() { impl From for FuncRef { fn from(untyped: UntypedVal) -> Self { + if u64::from(untyped) == 0 { + return FuncRef::null(); + } // Safety: This union access is safe since there are no invalid // bit patterns for [`FuncRef`] instances. Therefore // this operation cannot produce invalid [`FuncRef`] // instances even though the input [`UntypedVal`] // was modified arbitrarily. - unsafe { >::from(untyped).reftype }.canonicalize() + unsafe { mem::transmute::(untyped.into()) } } } impl From for UntypedVal { fn from(funcref: FuncRef) -> Self { - let funcref = funcref.canonicalize(); + if funcref.is_null() { + return UntypedVal::from(0_u64); + } // Safety: This operation is safe since there are no invalid // bit patterns for [`UntypedVal`] instances. Therefore // this operation cannot produce invalid [`UntypedVal`] // instances even if it was possible to arbitrarily modify // the input [`FuncRef`] instance. - Self::from(unsafe { >::new(funcref).value }) + let bits = unsafe { mem::transmute::(funcref) }; + UntypedVal::from(bits) } } @@ -62,22 +69,9 @@ impl FuncRef { self.inner.is_none() } - /// Canonicalize `self` so that all `null` values have the same representation. - /// - /// # Note - /// - /// The underlying issue is that `FuncRef` has many possible values for the - /// `null` value. However, to simplify operating on encoded `FuncRef` instances - /// (encoded as `UntypedValue`) we want it to encode to exactly one `null` - /// value. The most trivial of all possible `null` values is `0_u64`, therefore - /// we canonicalize all `null` values to be represented by `0_u64`. - fn canonicalize(self) -> Self { - if self.is_null() { - // Safety: This is safe since `0u64` can be bit - // interpreted as a valid `FuncRef` value. - return unsafe { >::null().reftype }; - } - self + /// Creates a `null` [`FuncRef`]. + pub fn null() -> Self { + Self::new(None) } /// Creates a new [`FuncRef`]. @@ -95,7 +89,6 @@ impl FuncRef { Self { inner: nullable_func.into(), } - .canonicalize() } /// Returns the inner [`Func`] if [`FuncRef`] is not `null`. @@ -104,9 +97,4 @@ impl FuncRef { pub fn func(&self) -> Option<&Func> { self.inner.as_ref() } - - /// Creates a `null` [`FuncRef`]. - pub fn null() -> Self { - Self::new(None).canonicalize() - } } diff --git a/crates/wasmi/src/lib.rs b/crates/wasmi/src/lib.rs index 8cdb1d2044..c627f68f84 100644 --- a/crates/wasmi/src/lib.rs +++ b/crates/wasmi/src/lib.rs @@ -97,7 +97,6 @@ mod limits; mod linker; mod memory; mod module; -mod reftype; mod store; mod table; mod value; diff --git a/crates/wasmi/src/reftype.rs b/crates/wasmi/src/reftype.rs deleted file mode 100644 index 40bb065801..0000000000 --- a/crates/wasmi/src/reftype.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::core::UntypedVal; - -/// Utility type used to convert between `reftype` and [`UntypedVal`]. -/// -/// # Note -/// -/// This is used for conversions of [`FuncRef`] and [`ExternRef`]. -/// -/// [`FuncRef`]: [`crate::FuncRef`] -/// [`ExternRef`]: [`crate::ExternRef`] -pub union Transposer { - /// The `reftype` based representation. - pub reftype: T, - /// The integer based representation to model pointer types. - pub value: u64, -} - -impl Transposer { - /// Creates a `null` [`Transposer`]. - pub fn null() -> Self { - Self { value: 0 } - } -} - -impl Transposer { - /// Creates a new [`Transposer`] from the given `reftype`. - pub fn new(reftype: T) -> Self { - Transposer { reftype } - } -} - -impl From for Transposer { - fn from(untyped: UntypedVal) -> Self { - Transposer { - value: u64::from(untyped), - } - } -}