Use transmute instead of casts In RuntimeValue conversion. (#102)
Casts have arithmetic semantics, and under some build configurations Rust will panic when encountering an arithmetic overflow. Use a transmute instead since it's what we mean. The previous code worked, but still I added a test for good measure.
This commit is contained in:
parent
94b797de44
commit
75406dd8ff
|
@ -17,6 +17,19 @@ fn assert_error_properties() {
|
|||
assert_std_err_impl::<Error>();
|
||||
}
|
||||
|
||||
/// Test that converting an u32 (u64) that does not fit in an i32 (i64)
|
||||
/// to a RuntimeValue and back works as expected and the number remains unchanged.
|
||||
#[test]
|
||||
fn unsigned_to_runtime_value() {
|
||||
use super::RuntimeValue;
|
||||
|
||||
let overflow_i32: u32 = ::std::i32::MAX as u32 + 1;
|
||||
assert_eq!(RuntimeValue::from(overflow_i32).try_into::<u32>().unwrap(), overflow_i32);
|
||||
|
||||
let overflow_i64: u64 = ::std::i64::MAX as u64 + 1;
|
||||
assert_eq!(RuntimeValue::from(overflow_i64).try_into::<u64>().unwrap(), overflow_i64);
|
||||
}
|
||||
|
||||
pub fn parse_wat(source: &str) -> Module {
|
||||
let wasm_binary = wabt::wat2wasm(source).expect("Failed to parse wat source");
|
||||
Module::from_buffer(wasm_binary).expect("Failed to load parsed module")
|
||||
|
|
16
src/value.rs
16
src/value.rs
|
@ -1,6 +1,7 @@
|
|||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use nan_preserving_float::{F32, F64};
|
||||
use std::io;
|
||||
use std::mem::transmute;
|
||||
use std::{f32, i32, i64, u32, u64};
|
||||
use TrapKind;
|
||||
|
||||
|
@ -188,13 +189,13 @@ impl From<i64> for RuntimeValue {
|
|||
|
||||
impl From<u32> for RuntimeValue {
|
||||
fn from(val: u32) -> Self {
|
||||
RuntimeValue::I32(val as i32)
|
||||
RuntimeValue::I32(val.transmute_into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for RuntimeValue {
|
||||
fn from(val: u64) -> Self {
|
||||
RuntimeValue::I64(val as i64)
|
||||
RuntimeValue::I64(val.transmute_into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,11 +404,8 @@ macro_rules! impl_transmute_into_as {
|
|||
}
|
||||
|
||||
impl_transmute_into_as!(i8, u8);
|
||||
impl_transmute_into_as!(u8, i8);
|
||||
impl_transmute_into_as!(i32, u32);
|
||||
impl_transmute_into_as!(u32, i32);
|
||||
impl_transmute_into_as!(i64, u64);
|
||||
impl_transmute_into_as!(u64, i64);
|
||||
|
||||
macro_rules! impl_transmute_into_npf {
|
||||
($npf:ident, $float:ident, $signed:ident, $unsigned:ident) => {
|
||||
|
@ -468,6 +466,14 @@ impl TransmuteInto<f64> for i64 {
|
|||
fn transmute_into(self) -> f64 { f64::from_bits(self as u64) }
|
||||
}
|
||||
|
||||
impl TransmuteInto<i32> for u32 {
|
||||
fn transmute_into(self) -> i32 { unsafe { transmute(self) } }
|
||||
}
|
||||
|
||||
impl TransmuteInto<i64> for u64 {
|
||||
fn transmute_into(self) -> i64 { unsafe { transmute(self) } }
|
||||
}
|
||||
|
||||
impl LittleEndianConvert for i8 {
|
||||
fn into_little_endian(self) -> Vec<u8> {
|
||||
vec![self as u8]
|
||||
|
|
Loading…
Reference in New Issue