From 78aa7d3a9001b5d61f9c68a78d2c7cb5f79420a8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 May 2022 12:37:13 -0700 Subject: [PATCH] Make `ValRaw` fields private Force accessing to go through constructors and accessors to localize the knowledge about little-endian-ness. This is spawned since I made a mistake in #4039 about endianness. --- crates/runtime/src/vmcontext.rs | 126 ++++++++++++++++++++++++++++-- crates/wasmtime/src/func.rs | 2 +- crates/wasmtime/src/func/typed.rs | 32 ++++---- crates/wasmtime/src/values.rs | 34 ++++---- 4 files changed, 150 insertions(+), 44 deletions(-) diff --git a/crates/runtime/src/vmcontext.rs b/crates/runtime/src/vmcontext.rs index c670e3d9972d..22a148a2b081 100644 --- a/crates/runtime/src/vmcontext.rs +++ b/crates/runtime/src/vmcontext.rs @@ -794,7 +794,7 @@ pub union ValRaw { /// or unsigned. The Rust type `i32` is simply chosen for convenience. /// /// This value is always stored in a little-endian format. - pub i32: i32, + i32: i32, /// A WebAssembly `i64` value. /// @@ -803,7 +803,7 @@ pub union ValRaw { /// or unsigned. The Rust type `i64` is simply chosen for convenience. /// /// This value is always stored in a little-endian format. - pub i64: i64, + i64: i64, /// A WebAssembly `f32` value. /// @@ -813,7 +813,7 @@ pub union ValRaw { /// `u32` value is the return value of `f32::to_bits` in Rust. /// /// This value is always stored in a little-endian format. - pub f32: u32, + f32: u32, /// A WebAssembly `f64` value. /// @@ -823,7 +823,7 @@ pub union ValRaw { /// `u64` value is the return value of `f64::to_bits` in Rust. /// /// This value is always stored in a little-endian format. - pub f64: u64, + f64: u64, /// A WebAssembly `v128` value. /// @@ -833,7 +833,7 @@ pub union ValRaw { /// underlying bits is left up to the instructions which consume this value. /// /// This value is always stored in a little-endian format. - pub v128: u128, + v128: u128, /// A WebAssembly `funcref` value. /// @@ -843,7 +843,7 @@ pub union ValRaw { /// carefully calling the correct functions throughout the runtime. /// /// This value is always stored in a little-endian format. - pub funcref: usize, + funcref: usize, /// A WebAssembly `externref` value. /// @@ -853,7 +853,119 @@ pub union ValRaw { /// carefully calling the correct functions throughout the runtime. /// /// This value is always stored in a little-endian format. - pub externref: usize, + externref: usize, +} + +impl ValRaw { + /// Creates a WebAssembly `i32` value + #[inline] + pub fn i32(i: i32) -> ValRaw { + ValRaw { i32: i.to_le() } + } + + /// Creates a WebAssembly `i64` value + #[inline] + pub fn i64(i: i64) -> ValRaw { + ValRaw { i64: i.to_le() } + } + + /// Creates a WebAssembly `i32` value + #[inline] + pub fn u32(i: u32) -> ValRaw { + ValRaw::i32(i as i32) + } + + /// Creates a WebAssembly `i64` value + #[inline] + pub fn u64(i: u64) -> ValRaw { + ValRaw::i64(i as i64) + } + + /// Creates a WebAssembly `f32` value + #[inline] + pub fn f32(i: u32) -> ValRaw { + ValRaw { f32: i.to_le() } + } + + /// Creates a WebAssembly `f64` value + #[inline] + pub fn f64(i: u64) -> ValRaw { + ValRaw { f64: i.to_le() } + } + + /// Creates a WebAssembly `v128` value + #[inline] + pub fn v128(i: u128) -> ValRaw { + ValRaw { v128: i.to_le() } + } + + /// Creates a WebAssembly `funcref` value + #[inline] + pub fn funcref(i: usize) -> ValRaw { + ValRaw { funcref: i.to_le() } + } + + /// Creates a WebAssembly `externref` value + #[inline] + pub fn externref(i: usize) -> ValRaw { + ValRaw { + externref: i.to_le(), + } + } + + /// Gets the WebAssembly `i32` value + #[inline] + pub fn get_i32(&self) -> i32 { + unsafe { i32::from_le(self.i32) } + } + + /// Gets the WebAssembly `i64` value + #[inline] + pub fn get_i64(&self) -> i64 { + unsafe { i64::from_le(self.i64) } + } + + /// Gets the WebAssembly `i32` value + #[inline] + pub fn get_u32(&self) -> u32 { + self.get_i32() as u32 + } + + /// Gets the WebAssembly `i64` value + #[inline] + pub fn get_u64(&self) -> u64 { + self.get_i64() as u64 + } + + /// Gets the WebAssembly `f32` value + #[inline] + pub fn get_f32(&self) -> u32 { + unsafe { u32::from_le(self.f32) } + } + + /// Gets the WebAssembly `f64` value + #[inline] + pub fn get_f64(&self) -> u64 { + unsafe { u64::from_le(self.f64) } + } + + /// Gets the WebAssembly `v128` value + #[inline] + pub fn get_v128(&self) -> u128 { + unsafe { u128::from_le(self.v128) } + } + + /// Gets the WebAssembly `funcref` value + #[inline] + pub fn get_funcref(&self) -> usize { + unsafe { usize::from_le(self.funcref) } + } + + /// Gets the WebAssembly `externref` value + #[inline] + pub fn get_externref(&self) -> usize { + unsafe { usize::from_le(self.externref) } + } } /// Trampoline function pointer type. diff --git a/crates/wasmtime/src/func.rs b/crates/wasmtime/src/func.rs index 3c8463f6a7c1..1b019c2310fd 100644 --- a/crates/wasmtime/src/func.rs +++ b/crates/wasmtime/src/func.rs @@ -966,7 +966,7 @@ impl Func { // Store the argument values into `values_vec`. let mut values_vec = store.0.take_wasm_val_raw_storage(); debug_assert!(values_vec.is_empty()); - values_vec.resize_with(values_vec_size, || ValRaw { i32: 0 }); + values_vec.resize_with(values_vec_size, || ValRaw::i32(0)); for (arg, slot) in params.iter().cloned().zip(&mut values_vec) { unsafe { *slot = arg.to_raw(&mut *store); diff --git a/crates/wasmtime/src/func/typed.rs b/crates/wasmtime/src/func/typed.rs index 9cdd3309b2cc..d16d3e1a4290 100644 --- a/crates/wasmtime/src/func/typed.rs +++ b/crates/wasmtime/src/func/typed.rs @@ -231,7 +231,7 @@ pub unsafe trait WasmTy: Send { } macro_rules! integers { - ($($primitive:ident => $ty:ident in $raw:ident)*) => ($( + ($($primitive:ident/$get_primitive:ident => $ty:ident in $raw:ident)*) => ($( unsafe impl WasmTy for $primitive { type Abi = $primitive; #[inline] @@ -248,11 +248,11 @@ macro_rules! integers { } #[inline] unsafe fn abi_from_raw(raw: *mut ValRaw) -> $primitive { - $primitive::from_le((*raw).$raw as $primitive) + (*raw).$get_primitive() } #[inline] unsafe fn abi_into_raw(abi: $primitive, raw: *mut ValRaw) { - (*raw).$raw = abi.to_le() as $raw; + *raw = ValRaw::$primitive(abi); } #[inline] fn into_abi(self, _store: &mut StoreOpaque) -> Self::Abi { @@ -267,14 +267,14 @@ macro_rules! integers { } integers! { - i32 => I32 in i32 - i64 => I64 in i64 - u32 => I32 in i32 - u64 => I64 in i64 + i32/get_i32 => I32 in i32 + i64/get_i64 => I64 in i64 + u32/get_u32 => I32 in i32 + u64/get_u64 => I64 in i64 } macro_rules! floats { - ($($float:ident/$int:ident => $ty:ident)*) => ($( + ($($float:ident/$int:ident/$get_float:ident => $ty:ident)*) => ($( unsafe impl WasmTy for $float { type Abi = $float; #[inline] @@ -291,11 +291,11 @@ macro_rules! floats { } #[inline] unsafe fn abi_from_raw(raw: *mut ValRaw) -> $float { - $float::from_bits($int::from_le((*raw).$float)) + $float::from_bits((*raw).$get_float()) } #[inline] unsafe fn abi_into_raw(abi: $float, raw: *mut ValRaw) { - (*raw).$float = abi.to_bits().to_le(); + *raw = ValRaw::$float(abi.to_bits()); } #[inline] fn into_abi(self, _store: &mut StoreOpaque) -> Self::Abi { @@ -310,8 +310,8 @@ macro_rules! floats { } floats! { - f32/u32 => F32 - f64/u64 => F64 + f32/u32/get_f32 => F32 + f64/u64/get_f64 => F64 } unsafe impl WasmTy for Option { @@ -334,12 +334,12 @@ unsafe impl WasmTy for Option { #[inline] unsafe fn abi_from_raw(raw: *mut ValRaw) -> *mut u8 { - usize::from_le((*raw).externref) as *mut u8 + (*raw).get_externref() as *mut u8 } #[inline] unsafe fn abi_into_raw(abi: *mut u8, raw: *mut ValRaw) { - (*raw).externref = (abi as usize).to_le(); + *raw = ValRaw::externref(abi as usize); } #[inline] @@ -420,12 +420,12 @@ unsafe impl WasmTy for Option { #[inline] unsafe fn abi_from_raw(raw: *mut ValRaw) -> Self::Abi { - usize::from_le((*raw).funcref) as Self::Abi + (*raw).get_funcref() as Self::Abi } #[inline] unsafe fn abi_into_raw(abi: Self::Abi, raw: *mut ValRaw) { - (*raw).funcref = (abi as usize).to_le(); + *raw = ValRaw::funcref(abi as usize); } #[inline] diff --git a/crates/wasmtime/src/values.rs b/crates/wasmtime/src/values.rs index 45d1b10bc12e..377c309249a2 100644 --- a/crates/wasmtime/src/values.rs +++ b/crates/wasmtime/src/values.rs @@ -103,28 +103,24 @@ impl Val { /// [`Func::to_raw`] are unsafe. pub unsafe fn to_raw(&self, store: impl AsContextMut) -> ValRaw { match self { - Val::I32(i) => ValRaw { i32: i.to_le() }, - Val::I64(i) => ValRaw { i64: i.to_le() }, - Val::F32(u) => ValRaw { f32: u.to_le() }, - Val::F64(u) => ValRaw { f64: u.to_le() }, - Val::V128(b) => ValRaw { v128: b.to_le() }, + Val::I32(i) => ValRaw::i32(*i), + Val::I64(i) => ValRaw::i64(*i), + Val::F32(u) => ValRaw::f32(*u), + Val::F64(u) => ValRaw::f64(*u), + Val::V128(b) => ValRaw::v128(*b), Val::ExternRef(e) => { let externref = match e { Some(e) => e.to_raw(store), None => 0, }; - ValRaw { - externref: externref.to_le(), - } + ValRaw::externref(externref) } Val::FuncRef(f) => { let funcref = match f { Some(f) => f.to_raw(store), None => 0, }; - ValRaw { - funcref: funcref.to_le(), - } + ValRaw::funcref(funcref) } } } @@ -138,15 +134,13 @@ impl Val { /// otherwise that `raw` should have the type `ty` specified. pub unsafe fn from_raw(store: impl AsContextMut, raw: ValRaw, ty: ValType) -> Val { match ty { - ValType::I32 => Val::I32(i32::from_le(raw.i32)), - ValType::I64 => Val::I64(i64::from_le(raw.i64)), - ValType::F32 => Val::F32(u32::from_le(raw.f32)), - ValType::F64 => Val::F64(u64::from_le(raw.f64)), - ValType::V128 => Val::V128(u128::from_le(raw.v128)), - ValType::ExternRef => { - Val::ExternRef(ExternRef::from_raw(usize::from_le(raw.externref))) - } - ValType::FuncRef => Val::FuncRef(Func::from_raw(store, usize::from_le(raw.funcref))), + ValType::I32 => Val::I32(raw.get_i32()), + ValType::I64 => Val::I64(raw.get_i64()), + ValType::F32 => Val::F32(raw.get_f32()), + ValType::F64 => Val::F64(raw.get_f64()), + ValType::V128 => Val::V128(raw.get_v128()), + ValType::ExternRef => Val::ExternRef(ExternRef::from_raw(raw.get_externref())), + ValType::FuncRef => Val::FuncRef(Func::from_raw(store, raw.get_funcref())), } }