Update lifting for integers and bools (#4237)
This commit updates lifting for integer types and boolean types to account for WebAssembly/component-model#35 where extra bits are now discarded instead of being validated as all zero.
This commit is contained in:
@@ -712,11 +712,7 @@ macro_rules! integers {
|
|||||||
unsafe impl Lift for $primitive {
|
unsafe impl Lift for $primitive {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lift(_store: &StoreOpaque, _options: &Options, src: &Self::Lower) -> Result<Self> {
|
fn lift(_store: &StoreOpaque, _options: &Options, src: &Self::Lower) -> Result<Self> {
|
||||||
// Perform a lossless cast from our field storage to the
|
Ok(src.$get() as $primitive)
|
||||||
// destination type. Note that `try_from` here is load bearing
|
|
||||||
// which rejects conversions like `500u32` to `u8` because
|
|
||||||
// that's out-of-bounds for `u8`.
|
|
||||||
Ok($primitive::try_from(src.$get())?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -852,8 +848,7 @@ unsafe impl Lift for bool {
|
|||||||
fn lift(_store: &StoreOpaque, _options: &Options, src: &Self::Lower) -> Result<Self> {
|
fn lift(_store: &StoreOpaque, _options: &Options, src: &Self::Lower) -> Result<Self> {
|
||||||
match src.get_i32() {
|
match src.get_i32() {
|
||||||
0 => Ok(false),
|
0 => Ok(false),
|
||||||
1 => Ok(true),
|
_ => Ok(true),
|
||||||
_ => bail!("invalid boolean value"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,8 +856,7 @@ unsafe impl Lift for bool {
|
|||||||
fn load(_mem: &Memory<'_>, bytes: &[u8]) -> Result<Self> {
|
fn load(_mem: &Memory<'_>, bytes: &[u8]) -> Result<Self> {
|
||||||
match bytes[0] {
|
match bytes[0] {
|
||||||
0 => Ok(false),
|
0 => Ok(false),
|
||||||
1 => Ok(true),
|
_ => Ok(true),
|
||||||
_ => bail!("invalid boolean value"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -364,15 +364,12 @@ fn integers() -> Result<()> {
|
|||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
// Returning -1 should fail for u8 and u16, but succeed for all other types.
|
// Returning -1 should reinterpret the bytes as defined by each type.
|
||||||
let err = instance
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), u8, _>(&mut store, "retm1-u8")?
|
.get_typed_func::<(), u8, _>(&mut store, "retm1-u8")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
0xff
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
instance
|
instance
|
||||||
@@ -380,14 +377,11 @@ fn integers() -> Result<()> {
|
|||||||
.call(&mut store, ())?,
|
.call(&mut store, ())?,
|
||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
let err = instance
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), u16, _>(&mut store, "retm1-u16")?
|
.get_typed_func::<(), u16, _>(&mut store, "retm1-u16")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
0xffff
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
instance
|
instance
|
||||||
@@ -420,54 +414,43 @@ fn integers() -> Result<()> {
|
|||||||
-1
|
-1
|
||||||
);
|
);
|
||||||
|
|
||||||
// Returning 100000 should fail for small primitives but succeed for 32-bit.
|
// Returning 100000 should chop off bytes as necessary
|
||||||
let err = instance
|
let ret: u32 = 100000;
|
||||||
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), u8, _>(&mut store, "retbig-u8")?
|
.get_typed_func::<(), u8, _>(&mut store, "retbig-u8")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
ret as u8,
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
let err = instance
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), i8, _>(&mut store, "retbig-s8")?
|
.get_typed_func::<(), i8, _>(&mut store, "retbig-s8")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
ret as i8,
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
let err = instance
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), u16, _>(&mut store, "retbig-u16")?
|
.get_typed_func::<(), u16, _>(&mut store, "retbig-u16")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
ret as u16,
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
let err = instance
|
assert_eq!(
|
||||||
|
instance
|
||||||
.get_typed_func::<(), i16, _>(&mut store, "retbig-s16")?
|
.get_typed_func::<(), i16, _>(&mut store, "retbig-s16")?
|
||||||
.call(&mut store, ())
|
.call(&mut store, ())?,
|
||||||
.unwrap_err();
|
ret as i16,
|
||||||
assert!(
|
|
||||||
err.to_string().contains("out of range integral type"),
|
|
||||||
"{}",
|
|
||||||
err
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
instance
|
instance
|
||||||
.get_typed_func::<(), u32, _>(&mut store, "retbig-u32")?
|
.get_typed_func::<(), u32, _>(&mut store, "retbig-u32")?
|
||||||
.call(&mut store, ())?,
|
.call(&mut store, ())?,
|
||||||
100000
|
ret,
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
instance
|
instance
|
||||||
.get_typed_func::<(), i32, _>(&mut store, "retbig-s32")?
|
.get_typed_func::<(), i32, _>(&mut store, "retbig-s32")?
|
||||||
.call(&mut store, ())?,
|
.call(&mut store, ())?,
|
||||||
100000
|
ret as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -622,8 +605,7 @@ fn bools() -> Result<()> {
|
|||||||
assert_eq!(bool_to_u32.call(&mut store, (true,))?, 1);
|
assert_eq!(bool_to_u32.call(&mut store, (true,))?, 1);
|
||||||
assert_eq!(u32_to_bool.call(&mut store, (0,))?, false);
|
assert_eq!(u32_to_bool.call(&mut store, (0,))?, false);
|
||||||
assert_eq!(u32_to_bool.call(&mut store, (1,))?, true);
|
assert_eq!(u32_to_bool.call(&mut store, (1,))?, true);
|
||||||
let err = u32_to_bool.call(&mut store, (2,)).unwrap_err();
|
assert_eq!(u32_to_bool.call(&mut store, (2,))?, true);
|
||||||
assert!(err.to_string().contains("invalid boolean"), "{}", err);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1305,7 +1287,9 @@ fn char_bool_memory() -> Result<()> {
|
|||||||
let ret = func.call(&mut store, (1, '🍰' as u32))?;
|
let ret = func.call(&mut store, (1, '🍰' as u32))?;
|
||||||
assert_eq!(ret, (true, '🍰'));
|
assert_eq!(ret, (true, '🍰'));
|
||||||
|
|
||||||
assert!(func.call(&mut store, (2, 'a' as u32)).is_err());
|
let ret = func.call(&mut store, (2, 'a' as u32))?;
|
||||||
|
assert_eq!(ret, (true, 'a'));
|
||||||
|
|
||||||
assert!(func.call(&mut store, (0, 0xd800)).is_err());
|
assert!(func.call(&mut store, (0, 0xd800)).is_err());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user