435: Fix f32/f64 conversion, add tests, and rename conversion method r=syrusakbary a=bjfish

Fixes #415

I believe removing this conversion here caused the regression: https://github.com/wasmerio/wasmer/pull/379/files#diff-5e7e23717d05d1d18be5b2e3b75f454dL158

I've added conversion tests and also renamed `NativeWasmType::{to_bits, from_bits}` to `to_binary/from_binary` because it seemed akward to overload the existing `f32::to_bits` method.

Co-authored-by: Brandon Fish <brandon.j.fish@gmail.com>
This commit is contained in:
bors[bot] 2019-05-12 19:29:40 +00:00
commit 8130eb1e14
2 changed files with 73 additions and 18 deletions

View File

@ -247,7 +247,7 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
type CStruct = S1<A>; type CStruct = S1<A>;
type RetArray = [u64; 1]; type RetArray = [u64; 1];
fn from_ret_array(array: Self::RetArray) -> Self { fn from_ret_array(array: Self::RetArray) -> Self {
(WasmExternType::from_native(NativeWasmType::from_bits( (WasmExternType::from_native(NativeWasmType::from_binary(
array[0], array[0],
)),) )),)
} }
@ -274,7 +274,7 @@ impl<A: WasmExternType> WasmTypeList for (A,) {
ctx: *mut Ctx, ctx: *mut Ctx,
) -> Result<Rets, RuntimeError> { ) -> Result<Rets, RuntimeError> {
let (a,) = self; let (a,) = self;
let args = [a.to_native().to_bits()]; let args = [a.to_native().to_binary()];
let mut rets = Rets::empty_ret_array(); let mut rets = Rets::empty_ret_array();
let mut trap = WasmTrapInfo::Unknown; let mut trap = WasmTrapInfo::Unknown;
let mut user_error = None; let mut user_error = None;
@ -322,7 +322,7 @@ macro_rules! impl_traits {
fn from_ret_array(array: Self::RetArray) -> Self { fn from_ret_array(array: Self::RetArray) -> Self {
#[allow(non_snake_case)] #[allow(non_snake_case)]
let [ $( $x ),* ] = array; let [ $( $x ),* ] = array;
( $( WasmExternType::from_native(NativeWasmType::from_bits($x)) ),* ) ( $( WasmExternType::from_native(NativeWasmType::from_binary($x)) ),* )
} }
fn empty_ret_array() -> Self::RetArray { fn empty_ret_array() -> Self::RetArray {
[0; count_idents!( $( $x ),* )] [0; count_idents!( $( $x ),* )]
@ -344,7 +344,7 @@ macro_rules! impl_traits {
unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, RuntimeError> { unsafe fn call<Rets: WasmTypeList>(self, f: NonNull<vm::Func>, wasm: Wasm, ctx: *mut Ctx) -> Result<Rets, RuntimeError> {
#[allow(unused_parens)] #[allow(unused_parens)]
let ( $( $x ),* ) = self; let ( $( $x ),* ) = self;
let args = [ $( $x.to_native().to_bits() ),* ]; let args = [ $( $x.to_native().to_binary()),* ];
let mut rets = Rets::empty_ret_array(); let mut rets = Rets::empty_ret_array();
let mut trap = WasmTrapInfo::Unknown; let mut trap = WasmTrapInfo::Unknown;
let mut user_error = None; let mut user_error = None;

View File

@ -76,44 +76,44 @@ where
Self: Sized, Self: Sized,
{ {
const TYPE: Type; const TYPE: Type;
fn from_bits(bits: u64) -> Self; fn from_binary(bits: u64) -> Self;
fn to_bits(self) -> u64; fn to_binary(self) -> u64;
} }
unsafe impl NativeWasmType for i32 { unsafe impl NativeWasmType for i32 {
const TYPE: Type = Type::I32; const TYPE: Type = Type::I32;
fn from_bits(bits: u64) -> Self { fn from_binary(bits: u64) -> Self {
bits as _ bits as _
} }
fn to_bits(self) -> u64 { fn to_binary(self) -> u64 {
self as _ self as _
} }
} }
unsafe impl NativeWasmType for i64 { unsafe impl NativeWasmType for i64 {
const TYPE: Type = Type::I64; const TYPE: Type = Type::I64;
fn from_bits(bits: u64) -> Self { fn from_binary(bits: u64) -> Self {
bits as _ bits as _
} }
fn to_bits(self) -> u64 { fn to_binary(self) -> u64 {
self as _ self as _
} }
} }
unsafe impl NativeWasmType for f32 { unsafe impl NativeWasmType for f32 {
const TYPE: Type = Type::F32; const TYPE: Type = Type::F32;
fn from_bits(bits: u64) -> Self { fn from_binary(bits: u64) -> Self {
bits as _ f32::from_bits(bits as u32)
} }
fn to_bits(self) -> u64 { fn to_binary(self) -> u64 {
self as _ self.to_bits() as _
} }
} }
unsafe impl NativeWasmType for f64 { unsafe impl NativeWasmType for f64 {
const TYPE: Type = Type::F64; const TYPE: Type = Type::F64;
fn from_bits(bits: u64) -> Self { fn from_binary(bits: u64) -> Self {
bits as _ f64::from_bits(bits)
} }
fn to_bits(self) -> u64 { fn to_binary(self) -> u64 {
self as _ self.to_bits()
} }
} }
@ -516,3 +516,58 @@ where
} }
} }
} }
#[cfg(test)]
mod tests {
use crate::types::NativeWasmType;
use crate::types::WasmExternType;
#[test]
fn test_native_types_round_trip() {
assert_eq!(
42i32,
i32::from_native(i32::from_binary((42i32).to_native().to_binary()))
);
assert_eq!(
-42i32,
i32::from_native(i32::from_binary((-42i32).to_native().to_binary()))
);
use std::i64;
let xi64 = i64::MAX;
assert_eq!(
xi64,
i64::from_native(i64::from_binary((xi64).to_native().to_binary()))
);
let yi64 = i64::MIN;
assert_eq!(
yi64,
i64::from_native(i64::from_binary((yi64).to_native().to_binary()))
);
assert_eq!(
16.5f32,
f32::from_native(f32::from_binary((16.5f32).to_native().to_binary()))
);
assert_eq!(
-16.5f32,
f32::from_native(f32::from_binary((-16.5f32).to_native().to_binary()))
);
use std::f64;
let xf64: f64 = f64::MAX;
assert_eq!(
xf64,
f64::from_native(f64::from_binary((xf64).to_native().to_binary()))
);
let yf64: f64 = f64::MIN;
assert_eq!(
yf64,
f64::from_native(f64::from_binary((yf64).to_native().to_binary()))
);
}
}