diff --git a/Cargo.toml b/Cargo.toml index f355cb2..e36d9ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ byteorder = "1.0" memory_units = "0.3.0" [dev-dependencies] -wabt = "0.2.0" +wabt = "~0.2.2" [features] # 32-bit platforms are not supported and not tested. Use this flag if you really want to use diff --git a/src/value.rs b/src/value.rs index 3cd6915..e5b8760 100644 --- a/src/value.rs +++ b/src/value.rs @@ -134,12 +134,12 @@ impl RuntimeValue { /// Creates new value by interpreting passed u32 as f32. pub fn decode_f32(val: u32) -> Self { - RuntimeValue::F32(f32_from_bits(val)) + RuntimeValue::F32(f32::from_bits(val)) } /// Creates new value by interpreting passed u64 as f64. pub fn decode_f64(val: u64) -> Self { - RuntimeValue::F64(f64_from_bits(val)) + RuntimeValue::F64(f64::from_bits(val)) } /// Get variable type for this value. @@ -367,21 +367,20 @@ impl_transmute_into_as!(u32, i32); impl_transmute_into_as!(i64, u64); impl_transmute_into_as!(u64, i64); -// TODO: rewrite these safely when `f32/f32::to_bits/from_bits` stabilized. impl TransmuteInto for f32 { - fn transmute_into(self) -> i32 { unsafe { ::std::mem::transmute(self) } } + fn transmute_into(self) -> i32 { self.to_bits() as i32 } } impl TransmuteInto for f64 { - fn transmute_into(self) -> i64 { unsafe { ::std::mem::transmute(self) } } + fn transmute_into(self) -> i64 { self.to_bits() as i64 } } impl TransmuteInto for i32 { - fn transmute_into(self) -> f32 { f32_from_bits(self as _) } + fn transmute_into(self) -> f32 { f32::from_bits(self as u32) } } impl TransmuteInto for i64 { - fn transmute_into(self) -> f64 { f64_from_bits(self as _) } + fn transmute_into(self) -> f64 { f64::from_bits(self as u64) } } impl LittleEndianConvert for i8 { @@ -488,7 +487,7 @@ impl LittleEndianConvert for f32 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u32::() - .map(f32_from_bits) + .map(f32::from_bits) .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -503,47 +502,11 @@ impl LittleEndianConvert for f64 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u64::() - .map(f64_from_bits) + .map(f64::from_bits) .map_err(|_| Error::InvalidLittleEndianBuffer) } } -// Convert u32 to f32 safely, masking out sNAN -fn f32_from_bits(mut v: u32) -> f32 { - const EXP_MASK: u32 = 0x7F800000; - const QNAN_MASK: u32 = 0x00400000; - const FRACT_MASK: u32 = 0x007FFFFF; - - if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 { - // If we have a NaN value, we - // convert signaling NaN values to quiet NaN - // by setting the the highest bit of the fraction - // TODO: remove when https://github.com/BurntSushi/byteorder/issues/71 closed. - // or `f32::from_bits` stabilized. - v |= QNAN_MASK; - } - - unsafe { ::std::mem::transmute(v) } -} - -// Convert u64 to f64 safely, masking out sNAN -fn f64_from_bits(mut v: u64) -> f64 { - const EXP_MASK: u64 = 0x7FF0000000000000; - const QNAN_MASK: u64 = 0x0001000000000000; - const FRACT_MASK: u64 = 0x000FFFFFFFFFFFFF; - - if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 { - // If we have a NaN value, we - // convert signaling NaN values to quiet NaN - // by setting the the highest bit of the fraction - // TODO: remove when https://github.com/BurntSushi/byteorder/issues/71 closed. - // or `f64::from_bits` stabilized. - v |= QNAN_MASK; - } - - unsafe { ::std::mem::transmute(v) } -} - macro_rules! impl_integer_arithmetic_ops { ($type: ident) => { impl ArithmeticOps<$type> for $type { diff --git a/tests/spec/mod.rs b/tests/spec/mod.rs index 388fd30..33c68b5 100644 --- a/tests/spec/mod.rs +++ b/tests/spec/mod.rs @@ -21,9 +21,7 @@ run_test!("call", wasm_call); run_test!("call_indirect", wasm_call_indirect); run_test!("comments", wasm_comments); run_test!("const", wasm_const); -// TODO: commented out until sNaN issue is resolved: -// https://github.com/NikVolf/parity-wasm/blob/b5aaf103cf28f1e36df832f4883f55043e67894b/src/interpreter/value.rs#L510 -// run_test!("conversions", wasm_conversions); +run_test!("conversions", wasm_conversions); run_test!("custom_section", wasm_custom_section); run_test!("elem", wasm_elem); run_test!("endianness", wasm_endianness); @@ -35,11 +33,9 @@ run_test!("f64", wasm_f64); run_test!("f64_bitwise", wasm_f64_bitwise); run_test!("f64_cmp", wasm_f64_cmp); run_test!("fac", wasm_fac); -// TODO: commented out until sNaN issue is resolved: -// https://github.com/NikVolf/parity-wasm/blob/b5aaf103cf28f1e36df832f4883f55043e67894b/src/interpreter/value.rs#L510 -// run_test!("float_exprs", wasm_float_exprs); -// run_test!("float_literals", wasm_float_literals); -// run_test!("float_memory", wasm_float_memory); +run_test!("float_exprs", wasm_float_exprs); +run_test!("float_literals", wasm_float_literals); +run_test!("float_memory", wasm_float_memory); run_test!("float_misc", wasm_float_misc); run_test!("forward", wasm_forward); run_test!("func", wasm_func);