Align order of wasm types/values across Wasmtime (#3292)
Wasmtime has a few representations of `Val` and `ValType` across the internal crates, the `wasmtime` crate, and the C API. These were previously sometimes mentioned in different orders which means that converting between the two took a little extra code than before. This commit is a micro-optimization to align the types across the various places we define these to help reduce the codegen burden when converting between these types. This is not expected to have a major impact on performance, rather it's a small cleanup which should be easy-ish to preserve I've noticed while staring at assembly.
This commit is contained in:
@@ -22,6 +22,8 @@ pub enum Mutability {
|
|||||||
/// A list of all possible value types in WebAssembly.
|
/// A list of all possible value types in WebAssembly.
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||||
pub enum ValType {
|
pub enum ValType {
|
||||||
|
// NB: the ordering here is intended to match the ordering in
|
||||||
|
// `wasmtime_types::WasmType` to help improve codegen when converting.
|
||||||
/// Signed 32 bit integer.
|
/// Signed 32 bit integer.
|
||||||
I32,
|
I32,
|
||||||
/// Signed 64 bit integer.
|
/// Signed 64 bit integer.
|
||||||
@@ -32,10 +34,10 @@ pub enum ValType {
|
|||||||
F64,
|
F64,
|
||||||
/// A 128 bit number.
|
/// A 128 bit number.
|
||||||
V128,
|
V128,
|
||||||
/// A reference to opaque data in the Wasm instance.
|
|
||||||
ExternRef, /* = 128 */
|
|
||||||
/// A reference to a Wasm function.
|
/// A reference to a Wasm function.
|
||||||
FuncRef,
|
FuncRef,
|
||||||
|
/// A reference to opaque data in the Wasm instance.
|
||||||
|
ExternRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ValType {
|
impl fmt::Display for ValType {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ use wasmtime_runtime::{self as runtime, VMExternRef};
|
|||||||
/// produce.
|
/// produce.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Val {
|
pub enum Val {
|
||||||
|
// NB: the ordering here is intended to match the ordering in
|
||||||
|
// `ValType` to improve codegen when learning the type of a value.
|
||||||
/// A 32-bit integer
|
/// A 32-bit integer
|
||||||
I32(i32),
|
I32(i32),
|
||||||
|
|
||||||
@@ -27,12 +29,8 @@ pub enum Val {
|
|||||||
/// `f64::from_bits` to create an `f64` value.
|
/// `f64::from_bits` to create an `f64` value.
|
||||||
F64(u64),
|
F64(u64),
|
||||||
|
|
||||||
/// An `externref` value which can hold opaque data to the Wasm instance
|
/// A 128-bit number
|
||||||
/// itself.
|
V128(u128),
|
||||||
///
|
|
||||||
/// `ExternRef(None)` is the null external reference, created by `ref.null
|
|
||||||
/// extern` in Wasm.
|
|
||||||
ExternRef(Option<ExternRef>),
|
|
||||||
|
|
||||||
/// A first-class reference to a WebAssembly function.
|
/// A first-class reference to a WebAssembly function.
|
||||||
///
|
///
|
||||||
@@ -40,14 +38,19 @@ pub enum Val {
|
|||||||
/// func` in Wasm.
|
/// func` in Wasm.
|
||||||
FuncRef(Option<Func>),
|
FuncRef(Option<Func>),
|
||||||
|
|
||||||
/// A 128-bit number
|
/// An `externref` value which can hold opaque data to the Wasm instance
|
||||||
V128(u128),
|
/// itself.
|
||||||
|
///
|
||||||
|
/// `ExternRef(None)` is the null external reference, created by `ref.null
|
||||||
|
/// extern` in Wasm.
|
||||||
|
ExternRef(Option<ExternRef>),
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! accessors {
|
macro_rules! accessors {
|
||||||
($bind:ident $(($variant:ident($ty:ty) $get:ident $unwrap:ident $cvt:expr))*) => ($(
|
($bind:ident $(($variant:ident($ty:ty) $get:ident $unwrap:ident $cvt:expr))*) => ($(
|
||||||
/// Attempt to access the underlying value of this `Val`, returning
|
/// Attempt to access the underlying value of this `Val`, returning
|
||||||
/// `None` if it is not the correct type.
|
/// `None` if it is not the correct type.
|
||||||
|
#[inline]
|
||||||
pub fn $get(&self) -> Option<$ty> {
|
pub fn $get(&self) -> Option<$ty> {
|
||||||
if let Val::$variant($bind) = self {
|
if let Val::$variant($bind) = self {
|
||||||
Some($cvt)
|
Some($cvt)
|
||||||
@@ -62,6 +65,7 @@ macro_rules! accessors {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `self` is not of the right type.
|
/// Panics if `self` is not of the right type.
|
||||||
|
#[inline]
|
||||||
pub fn $unwrap(&self) -> $ty {
|
pub fn $unwrap(&self) -> $ty {
|
||||||
self.$get().expect(concat!("expected ", stringify!($ty)))
|
self.$get().expect(concat!("expected ", stringify!($ty)))
|
||||||
}
|
}
|
||||||
@@ -70,11 +74,13 @@ macro_rules! accessors {
|
|||||||
|
|
||||||
impl Val {
|
impl Val {
|
||||||
/// Returns a null `externref` value.
|
/// Returns a null `externref` value.
|
||||||
|
#[inline]
|
||||||
pub fn null() -> Val {
|
pub fn null() -> Val {
|
||||||
Val::ExternRef(None)
|
Val::ExternRef(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the corresponding [`ValType`] for this `Val`.
|
/// Returns the corresponding [`ValType`] for this `Val`.
|
||||||
|
#[inline]
|
||||||
pub fn ty(&self) -> ValType {
|
pub fn ty(&self) -> ValType {
|
||||||
match self {
|
match self {
|
||||||
Val::I32(_) => ValType::I32,
|
Val::I32(_) => ValType::I32,
|
||||||
@@ -156,6 +162,7 @@ impl Val {
|
|||||||
/// If this is a null `externref`, then `Some(None)` is returned.
|
/// If this is a null `externref`, then `Some(None)` is returned.
|
||||||
///
|
///
|
||||||
/// If this is a non-null `externref`, then `Some(Some(..))` is returned.
|
/// If this is a non-null `externref`, then `Some(Some(..))` is returned.
|
||||||
|
#[inline]
|
||||||
pub fn externref(&self) -> Option<Option<ExternRef>> {
|
pub fn externref(&self) -> Option<Option<ExternRef>> {
|
||||||
match self {
|
match self {
|
||||||
Val::ExternRef(e) => Some(e.clone()),
|
Val::ExternRef(e) => Some(e.clone()),
|
||||||
@@ -173,6 +180,7 @@ impl Val {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if `self` is not a (nullable) `externref`.
|
/// Panics if `self` is not a (nullable) `externref`.
|
||||||
|
#[inline]
|
||||||
pub fn unwrap_externref(&self) -> Option<ExternRef> {
|
pub fn unwrap_externref(&self) -> Option<ExternRef> {
|
||||||
self.externref().expect("expected externref")
|
self.externref().expect("expected externref")
|
||||||
}
|
}
|
||||||
@@ -204,6 +212,7 @@ impl Val {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque<'_>) -> bool {
|
pub(crate) fn comes_from_same_store(&self, store: &StoreOpaque<'_>) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Val::FuncRef(Some(f)) => f.comes_from_same_store(store),
|
Val::FuncRef(Some(f)) => f.comes_from_same_store(store),
|
||||||
@@ -223,54 +232,63 @@ impl Val {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<i32> for Val {
|
impl From<i32> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: i32) -> Val {
|
fn from(val: i32) -> Val {
|
||||||
Val::I32(val)
|
Val::I32(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i64> for Val {
|
impl From<i64> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: i64) -> Val {
|
fn from(val: i64) -> Val {
|
||||||
Val::I64(val)
|
Val::I64(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f32> for Val {
|
impl From<f32> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: f32) -> Val {
|
fn from(val: f32) -> Val {
|
||||||
Val::F32(val.to_bits())
|
Val::F32(val.to_bits())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<f64> for Val {
|
impl From<f64> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: f64) -> Val {
|
fn from(val: f64) -> Val {
|
||||||
Val::F64(val.to_bits())
|
Val::F64(val.to_bits())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExternRef> for Val {
|
impl From<ExternRef> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: ExternRef) -> Val {
|
fn from(val: ExternRef) -> Val {
|
||||||
Val::ExternRef(Some(val))
|
Val::ExternRef(Some(val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Option<ExternRef>> for Val {
|
impl From<Option<ExternRef>> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: Option<ExternRef>) -> Val {
|
fn from(val: Option<ExternRef>) -> Val {
|
||||||
Val::ExternRef(val)
|
Val::ExternRef(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Option<Func>> for Val {
|
impl From<Option<Func>> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: Option<Func>) -> Val {
|
fn from(val: Option<Func>) -> Val {
|
||||||
Val::FuncRef(val)
|
Val::FuncRef(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Func> for Val {
|
impl From<Func> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: Func) -> Val {
|
fn from(val: Func) -> Val {
|
||||||
Val::FuncRef(Some(val))
|
Val::FuncRef(Some(val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<u128> for Val {
|
impl From<u128> for Val {
|
||||||
|
#[inline]
|
||||||
fn from(val: u128) -> Val {
|
fn from(val: u128) -> Val {
|
||||||
Val::V128(val)
|
Val::V128(val)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user