From 309d1b671624b916ed4dde8762bbdf02515c68f3 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 10 Sep 2020 12:23:51 +0200 Subject: [PATCH 1/3] Add i32/i64 converters from unsigned ints --- lib/wasmer-types/src/values.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/wasmer-types/src/values.rs b/lib/wasmer-types/src/values.rs index 98389d3c106..3e774bb5d60 100644 --- a/lib/wasmer-types/src/values.rs +++ b/lib/wasmer-types/src/values.rs @@ -8,10 +8,14 @@ use crate::types::Type; /// produce. #[derive(Clone, PartialEq)] pub enum Value { - /// A 32-bit integer + /// A 32-bit integer. + /// + /// In Wasm integers are sign-agnostic, i.e. this can either be signed or unsigned. I32(i32), - /// A 64-bit integer + /// A 64-bit integer. + /// + /// In Wasm integers are sign-agnostic, i.e. this can either be signed or unsigned. I64(i64), /// A 32-bit float. @@ -175,12 +179,26 @@ impl From for Value { } } +impl From for Value { + fn from(val: u32) -> Self { + // In Wasm integers are sign-agnostic, so i32 is basically a 4 byte storage we can use for signed or unsigned 32-bit integers. + Self::I32(val as i32) + } +} + impl From for Value { fn from(val: i64) -> Self { Self::I64(val) } } +impl From for Value { + fn from(val: u64) -> Self { + // In Wasm integers are sign-agnostic, so i64 is basically an 8 byte storage we can use for signed or unsigned 64-bit integers. + Self::I64(val as i64) + } +} + impl From for Value { fn from(val: f32) -> Self { Self::F32(val) From 209dbedf66a1577174f957d4099a044dfea5625e Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 16 Sep 2020 08:23:18 +0200 Subject: [PATCH 2/3] Add unit tests for Value from u32/u64 --- lib/wasmer-types/src/values.rs | 75 ++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/lib/wasmer-types/src/values.rs b/lib/wasmer-types/src/values.rs index 3e774bb5d60..4f37a71288b 100644 --- a/lib/wasmer-types/src/values.rs +++ b/lib/wasmer-types/src/values.rs @@ -222,3 +222,78 @@ impl From for Value { // Self::FuncRef(val) // } // } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_value_i32_from_u32() { + let input: u32 = 0x00000000; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0x00000000); + + let input: u32 = 0x00000001; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0x00000001); + + let input: u32 = 0xaabbccdd; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0xaabbccdd); + + let input: u32 = 0xffffffff; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0xffffffff); + } + + #[test] + fn test_value_i64_from_u64() { + let input: u64 = 0x0000000000000000; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0x0000000000000000); + + let input: u64 = 0x0000000000000001; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0x0000000000000001); + + let input: u64 = 0xaabbccddeeff0011; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0xaabbccddeeff0011); + + let input: u64 = 0xffffffffffffffff; + let value = Value::<()>::from(input); + let mut out: i128 = 0; + unsafe { + value.write_value_to(&mut out as *mut i128); + } + assert_eq!(out, 0xffffffffffffffff); + } +} From 5cc8439487a8d5bd62542db890fbdc1f668b8464 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Sat, 10 Oct 2020 08:36:30 +0200 Subject: [PATCH 3/3] Use from_be_bytes for tests --- lib/wasmer-types/src/values.rs | 80 ++++++++++------------------------ 1 file changed, 24 insertions(+), 56 deletions(-) diff --git a/lib/wasmer-types/src/values.rs b/lib/wasmer-types/src/values.rs index 4f37a71288b..bf497701b1a 100644 --- a/lib/wasmer-types/src/values.rs +++ b/lib/wasmer-types/src/values.rs @@ -229,71 +229,39 @@ mod tests { #[test] fn test_value_i32_from_u32() { - let input: u32 = 0x00000000; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0x00000000); + let bytes = [0x00, 0x00, 0x00, 0x00]; + let v = Value::<()>::from(u32::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I32(i32::from_be_bytes(bytes.clone()))); - let input: u32 = 0x00000001; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0x00000001); + let bytes = [0x00, 0x00, 0x00, 0x01]; + let v = Value::<()>::from(u32::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I32(i32::from_be_bytes(bytes.clone()))); - let input: u32 = 0xaabbccdd; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0xaabbccdd); + let bytes = [0xAA, 0xBB, 0xCC, 0xDD]; + let v = Value::<()>::from(u32::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I32(i32::from_be_bytes(bytes.clone()))); - let input: u32 = 0xffffffff; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0xffffffff); + let bytes = [0xFF, 0xFF, 0xFF, 0xFF]; + let v = Value::<()>::from(u32::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I32(i32::from_be_bytes(bytes.clone()))); } #[test] fn test_value_i64_from_u64() { - let input: u64 = 0x0000000000000000; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0x0000000000000000); + let bytes = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; + let v = Value::<()>::from(u64::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I64(i64::from_be_bytes(bytes.clone()))); - let input: u64 = 0x0000000000000001; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0x0000000000000001); + let bytes = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]; + let v = Value::<()>::from(u64::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I64(i64::from_be_bytes(bytes.clone()))); - let input: u64 = 0xaabbccddeeff0011; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0xaabbccddeeff0011); + let bytes = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11]; + let v = Value::<()>::from(u64::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I64(i64::from_be_bytes(bytes.clone()))); - let input: u64 = 0xffffffffffffffff; - let value = Value::<()>::from(input); - let mut out: i128 = 0; - unsafe { - value.write_value_to(&mut out as *mut i128); - } - assert_eq!(out, 0xffffffffffffffff); + let bytes = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; + let v = Value::<()>::from(u64::from_be_bytes(bytes.clone())); + assert_eq!(v, Value::I64(i64::from_be_bytes(bytes.clone()))); } }