@@ -8,39 +8,42 @@ use tinywasm_types::{ValType, WasmValue};
88/// See [`WasmValue`] for the public representation.
99#[ derive( Clone , Copy , Default , PartialEq , Eq ) ]
1010#[ repr( transparent) ]
11- pub struct RawWasmValue ( u64 ) ;
11+ pub struct RawWasmValue ( [ u8 ; 16 ] ) ;
1212
1313impl Debug for RawWasmValue {
1414 fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
15- write ! ( f, "RawWasmValue({})" , self . 0 as i64 ) // cast to i64 so at least negative numbers for i32 and i64 are printed correctly
15+ write ! ( f, "RawWasmValue({})" , 0 )
1616 }
1717}
1818
1919impl RawWasmValue {
2020 #[ inline( always) ]
21- pub fn raw_value ( & self ) -> u64 {
21+ pub fn raw_value ( & self ) -> [ u8 ; 16 ] {
2222 self . 0
2323 }
2424
2525 #[ inline]
2626 pub fn attach_type ( self , ty : ValType ) -> WasmValue {
2727 match ty {
28- ValType :: I32 => WasmValue :: I32 ( self . 0 as i32 ) ,
29- ValType :: I64 => WasmValue :: I64 ( self . 0 as i64 ) ,
30- ValType :: F32 => WasmValue :: F32 ( f32:: from_bits ( self . 0 as u32 ) ) ,
31- ValType :: F64 => WasmValue :: F64 ( f64:: from_bits ( self . 0 ) ) ,
28+ ValType :: I32 => WasmValue :: I32 ( self . into ( ) ) ,
29+ ValType :: I64 => WasmValue :: I64 ( self . into ( ) ) ,
30+ ValType :: F32 => WasmValue :: F32 ( f32:: from_bits ( self . into ( ) ) ) ,
31+ ValType :: F64 => WasmValue :: F64 ( f64:: from_bits ( self . into ( ) ) ) ,
32+ ValType :: V128 => WasmValue :: V128 ( self . into ( ) ) ,
3233 ValType :: RefExtern => {
33- if self . 0 == -1i64 as u64 {
34+ let val: i64 = self . into ( ) ;
35+ if val < 0 {
3436 WasmValue :: RefNull ( ValType :: RefExtern )
3537 } else {
36- WasmValue :: RefExtern ( self . 0 as u32 )
38+ WasmValue :: RefExtern ( val as u32 )
3739 }
3840 }
3941 ValType :: RefFunc => {
40- if self . 0 == -1i64 as u64 {
42+ let val: i64 = self . into ( ) ;
43+ if val < 0 {
4144 WasmValue :: RefNull ( ValType :: RefFunc )
4245 } else {
43- WasmValue :: RefFunc ( self . 0 as u32 )
46+ WasmValue :: RefFunc ( val as u32 )
4447 }
4548 }
4649 }
@@ -51,13 +54,14 @@ impl From<WasmValue> for RawWasmValue {
5154 #[ inline]
5255 fn from ( v : WasmValue ) -> Self {
5356 match v {
54- WasmValue :: I32 ( i) => Self ( i as u64 ) ,
55- WasmValue :: I64 ( i) => Self ( i as u64 ) ,
56- WasmValue :: F32 ( i) => Self ( i. to_bits ( ) as u64 ) ,
57- WasmValue :: F64 ( i) => Self ( i. to_bits ( ) ) ,
58- WasmValue :: RefExtern ( v) => Self ( v as i64 as u64 ) ,
59- WasmValue :: RefFunc ( v) => Self ( v as i64 as u64 ) ,
60- WasmValue :: RefNull ( _) => Self ( -1i64 as u64 ) ,
57+ WasmValue :: I32 ( i) => Self :: from ( i) ,
58+ WasmValue :: I64 ( i) => Self :: from ( i) ,
59+ WasmValue :: F32 ( i) => Self :: from ( i) ,
60+ WasmValue :: F64 ( i) => Self :: from ( i) ,
61+ WasmValue :: V128 ( i) => Self :: from ( i) ,
62+ WasmValue :: RefExtern ( v) => Self :: from ( v as i64 ) ,
63+ WasmValue :: RefFunc ( v) => Self :: from ( v as i64 ) ,
64+ WasmValue :: RefNull ( _) => Self :: from ( -1i64 ) ,
6165 }
6266 }
6367}
@@ -69,7 +73,7 @@ macro_rules! impl_from_raw_wasm_value {
6973 #[ inline]
7074 fn from( value: $type) -> Self {
7175 #[ allow( clippy:: redundant_closure_call) ] // the comiler will figure it out :)
72- Self ( $to_raw( value) )
76+ Self ( u128 :: to_ne_bytes ( $to_raw( value) ) )
7377 }
7478 }
7579
@@ -84,13 +88,22 @@ macro_rules! impl_from_raw_wasm_value {
8488 } ;
8589}
8690
87- impl_from_raw_wasm_value ! ( i32 , |x| x as u64 , |x| x as i32 ) ;
88- impl_from_raw_wasm_value ! ( i64 , |x| x as u64 , |x| x as i64 ) ;
89- impl_from_raw_wasm_value ! ( f32 , |x| f32 :: to_bits( x) as u64 , |x| f32 :: from_bits( x as u32 ) ) ;
90- impl_from_raw_wasm_value ! ( f64 , f64 :: to_bits, f64 :: from_bits) ;
91+ // This all looks like a lot of extra steps, but the compiler will optimize it all away.
92+ // The u128 just makes it a bit easier to write.
93+ impl_from_raw_wasm_value ! ( i32 , |x| x as u128 , |x: [ u8 ; 16 ] | i32 :: from_ne_bytes( x[ 0 ..4 ] . try_into( ) . unwrap( ) ) ) ;
94+ impl_from_raw_wasm_value ! ( i64 , |x| x as u128 , |x: [ u8 ; 16 ] | i64 :: from_ne_bytes( x[ 0 ..8 ] . try_into( ) . unwrap( ) ) ) ;
95+ impl_from_raw_wasm_value ! ( f32 , |x| f32 :: to_bits( x) as u128 , |x: [ u8 ; 16 ] | f32 :: from_bits( u32 :: from_ne_bytes(
96+ x[ 0 ..4 ] . try_into( ) . unwrap( )
97+ ) ) ) ;
98+ impl_from_raw_wasm_value ! ( f64 , |x| f64 :: to_bits( x) as u128 , |x: [ u8 ; 16 ] | f64 :: from_bits( u64 :: from_ne_bytes(
99+ x[ 0 ..8 ] . try_into( ) . unwrap( )
100+ ) ) ) ;
91101
92- // used for memory load/store
93- impl_from_raw_wasm_value ! ( i8 , |x| x as u64 , |x| x as i8 ) ;
94- impl_from_raw_wasm_value ! ( i16 , |x| x as u64 , |x| x as i16 ) ;
95- impl_from_raw_wasm_value ! ( u32 , |x| x as u64 , |x| x as u32 ) ;
96- impl_from_raw_wasm_value ! ( u64 , |x| x, |x| x) ;
102+ impl_from_raw_wasm_value ! ( u8 , |x| x as u128 , |x: [ u8 ; 16 ] | u8 :: from_ne_bytes( x[ 0 ..1 ] . try_into( ) . unwrap( ) ) ) ;
103+ impl_from_raw_wasm_value ! ( u16 , |x| x as u128 , |x: [ u8 ; 16 ] | u16 :: from_ne_bytes( x[ 0 ..2 ] . try_into( ) . unwrap( ) ) ) ;
104+ impl_from_raw_wasm_value ! ( u32 , |x| x as u128 , |x: [ u8 ; 16 ] | u32 :: from_ne_bytes( x[ 0 ..4 ] . try_into( ) . unwrap( ) ) ) ;
105+ impl_from_raw_wasm_value ! ( u64 , |x| x as u128 , |x: [ u8 ; 16 ] | u64 :: from_ne_bytes( x[ 0 ..8 ] . try_into( ) . unwrap( ) ) ) ;
106+ impl_from_raw_wasm_value ! ( u128 , |x| x, |x: [ u8 ; 16 ] | u128 :: from_ne_bytes( x. try_into( ) . unwrap( ) ) ) ;
107+
108+ impl_from_raw_wasm_value ! ( i8 , |x| x as u128 , |x: [ u8 ; 16 ] | i8 :: from_ne_bytes( x[ 0 ..1 ] . try_into( ) . unwrap( ) ) ) ;
109+ impl_from_raw_wasm_value ! ( i16 , |x| x as u128 , |x: [ u8 ; 16 ] | i16 :: from_ne_bytes( x[ 0 ..2 ] . try_into( ) . unwrap( ) ) ) ;
0 commit comments