Skip to content

Commit 8fea281

Browse files
authored
Add reinterpret-like Wasm APIs (#1555)
* add reinterpret-like Wasm APIs * use macro to generate reinterpret functions * move reinterpret funcs definitions up * use new reinterpret API in translator * remove TypedVal::reinterpret as it is no longer needed
1 parent bf8e227 commit 8fea281

4 files changed

Lines changed: 29 additions & 36 deletions

File tree

crates/core/src/typed.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,6 @@ impl TypedVal {
6666
pub fn untyped(&self) -> UntypedVal {
6767
self.value
6868
}
69-
70-
/// Changes the [`ValType`] of `self` to `ty`.
71-
///
72-
/// # Note
73-
///
74-
/// This acts similar to a Wasm reinterpret cast and
75-
/// the underlying `value` bits are unchanged.
76-
pub fn reinterpret(self, ty: ValType) -> Self {
77-
Self { ty, ..self }
78-
}
7969
}
8070

8171
impl<T> From<T> for TypedVal

crates/core/src/wasm.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ impl_untyped_val! {
222222

223223
fn i32_wrap_i64(value: i64) -> i32 = |v| v as i32;
224224
fn i64_extend_i32_s(value: i32) -> i64 = i64::from;
225+
fn i64_extend_i32_u(value: u32) -> u64 = u64::from;
225226
fn f32_demote_f64(value: f64) -> f32 = |v| v as f32;
226227
fn f64_promote_f32(value: f32) -> f64 = f64::from;
227228

@@ -283,6 +284,23 @@ impl_untyped_val! {
283284
fn i64_trunc_sat_f64_u(value: f64) -> u64 = TruncateSaturateInto::truncate_saturate_into;
284285
}
285286

287+
macro_rules! impl_reinterpret_cast {
288+
( $(fn $name:ident($from:ty) -> $to:ty);* $(;)? ) => {
289+
$(
290+
#[doc = concat!("Execute the `", stringify!($name), "` Wasm instruction.")]
291+
pub fn $name(value: $from) -> $to {
292+
<$to>::from_ne_bytes(<$from>::to_ne_bytes(value))
293+
}
294+
)*
295+
};
296+
}
297+
impl_reinterpret_cast! {
298+
fn i32_reinterpret_f32(f32) -> i32;
299+
fn i64_reinterpret_f64(f64) -> i64;
300+
fn f32_reinterpret_i32(i32) -> f32;
301+
fn f64_reinterpret_i64(i64) -> f64;
302+
}
303+
286304
macro_rules! gen_load_extend_fn {
287305
(
288306
$( (fn $load_fn:ident, fn $load_at_fn:ident, $wrapped:ty => $ty:ty); )*

crates/wasmi/src/engine/translator/func/mod.rs

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,25 +1976,11 @@ impl FuncTranslator {
19761976
}
19771977

19781978
/// Translates a Wasm `reinterpret` instruction.
1979-
fn translate_reinterpret(&mut self, ty: ValType) -> Result<(), Error> {
1980-
bail_unreachable!(self);
1981-
if let TypedProvider::Register(_) = self.stack.peek() {
1982-
// Nothing to do.
1983-
//
1984-
// We try to not manipulate the emulation stack if not needed.
1985-
return Ok(());
1986-
}
1987-
// Case: At this point we know that the top-most stack item is a constant value.
1988-
// We pop it, change its type and push it back onto the stack.
1989-
let TypedProvider::Const(value) = self.stack.pop() else {
1990-
panic!("the top-most stack item was asserted to be a constant value but a register was found")
1991-
};
1992-
self.stack.push_const(value.reinterpret(ty));
1993-
Ok(())
1994-
}
1995-
1996-
/// Translates a Wasm `i64.extend_i32_u` instruction.
1997-
fn translate_i64_extend_i32_u(&mut self) -> Result<(), Error> {
1979+
fn translate_reinterpret<T, R>(&mut self, consteval: fn(T) -> R) -> Result<(), Error>
1980+
where
1981+
T: From<TypedVal>,
1982+
R: Into<TypedVal>,
1983+
{
19981984
bail_unreachable!(self);
19991985
if let TypedProvider::Register(_) = self.stack.peek() {
20001986
// Nothing to do.
@@ -2007,8 +1993,7 @@ impl FuncTranslator {
20071993
let TypedProvider::Const(value) = self.stack.pop() else {
20081994
panic!("the top-most stack item was asserted to be a constant value but a register was found")
20091995
};
2010-
debug_assert_eq!(value.ty(), ValType::I32);
2011-
self.stack.push_const(u64::from(u32::from(value)));
1996+
self.stack.push_const(consteval(value.into()));
20121997
Ok(())
20131998
}
20141999

crates/wasmi/src/engine/translator/func/visit.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2844,7 +2844,7 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
28442844
}
28452845

28462846
fn visit_i64_extend_i32_u(&mut self) -> Self::Output {
2847-
self.translate_i64_extend_i32_u()
2847+
self.translate_reinterpret(wasm::i64_extend_i32_u)
28482848
}
28492849

28502850
fn visit_i64_trunc_f32_s(&mut self) -> Self::Output {
@@ -2916,19 +2916,19 @@ impl<'a> VisitOperator<'a> for FuncTranslator {
29162916
}
29172917

29182918
fn visit_i32_reinterpret_f32(&mut self) -> Self::Output {
2919-
self.translate_reinterpret(ValType::I32)
2919+
self.translate_reinterpret(wasm::i32_reinterpret_f32)
29202920
}
29212921

29222922
fn visit_i64_reinterpret_f64(&mut self) -> Self::Output {
2923-
self.translate_reinterpret(ValType::I64)
2923+
self.translate_reinterpret(wasm::i64_reinterpret_f64)
29242924
}
29252925

29262926
fn visit_f32_reinterpret_i32(&mut self) -> Self::Output {
2927-
self.translate_reinterpret(ValType::F32)
2927+
self.translate_reinterpret(wasm::f32_reinterpret_i32)
29282928
}
29292929

29302930
fn visit_f64_reinterpret_i64(&mut self) -> Self::Output {
2931-
self.translate_reinterpret(ValType::F64)
2931+
self.translate_reinterpret(wasm::f64_reinterpret_i64)
29322932
}
29332933

29342934
fn visit_i32_extend8_s(&mut self) -> Self::Output {

0 commit comments

Comments
 (0)