wasm_interp: truncate instructions

This commit is contained in:
Brian Carroll 2022-11-29 07:52:17 +00:00
parent 6ac46a150f
commit 029f0d00c1
No known key found for this signature in database
GPG Key ID: 5C7B2EC4101703C0
2 changed files with 184 additions and 24 deletions

View File

@ -1122,10 +1122,34 @@ impl<'a> Instance<'a> {
let wrapped: u32 = (arg & 0xffff_ffff) as u32;
self.value_stack.push(Value::from(wrapped));
}
I32TRUNCSF32 => todo!("{:?} @ {:#x}", op_code, file_offset),
I32TRUNCUF32 => todo!("{:?} @ {:#x}", op_code, file_offset),
I32TRUNCSF64 => todo!("{:?} @ {:#x}", op_code, file_offset),
I32TRUNCUF64 => todo!("{:?} @ {:#x}", op_code, file_offset),
I32TRUNCSF32 => {
let arg = self.value_stack.pop_f32();
if arg < i32::MIN as f32 || arg > i32::MAX as f32 {
panic!("Cannot truncate {} from F32 to I32", arg);
}
self.value_stack.push(Value::I32(arg as i32));
}
I32TRUNCUF32 => {
let arg = self.value_stack.pop_f32();
if arg < u32::MIN as f32 || arg > u32::MAX as f32 {
panic!("Cannot truncate {} from F32 to unsigned I32", arg);
}
self.value_stack.push(Value::from(arg as u32));
}
I32TRUNCSF64 => {
let arg = self.value_stack.pop_f64();
if arg < i32::MIN as f64 || arg > i32::MAX as f64 {
panic!("Cannot truncate {} from F64 to I32", arg);
}
self.value_stack.push(Value::I32(arg as i32));
}
I32TRUNCUF64 => {
let arg = self.value_stack.pop_f64();
if arg < u32::MIN as f64 || arg > u32::MAX as f64 {
panic!("Cannot truncate {} from F64 to unsigned I32", arg);
}
self.value_stack.push(Value::from(arg as u32));
}
I64EXTENDSI32 => {
let arg = self.value_stack.pop_i32();
self.value_stack.push(Value::I64(arg as i64));
@ -1134,10 +1158,34 @@ impl<'a> Instance<'a> {
let arg = self.value_stack.pop_u32();
self.value_stack.push(Value::from(arg as u64));
}
I64TRUNCSF32 => todo!("{:?} @ {:#x}", op_code, file_offset),
I64TRUNCUF32 => todo!("{:?} @ {:#x}", op_code, file_offset),
I64TRUNCSF64 => todo!("{:?} @ {:#x}", op_code, file_offset),
I64TRUNCUF64 => todo!("{:?} @ {:#x}", op_code, file_offset),
I64TRUNCSF32 => {
let arg = self.value_stack.pop_f32();
if arg < i64::MIN as f32 || arg > i64::MAX as f32 {
panic!("Cannot truncate {} from F32 to I64", arg);
}
self.value_stack.push(Value::I64(arg as i64));
}
I64TRUNCUF32 => {
let arg = self.value_stack.pop_f32();
if arg < u64::MIN as f32 || arg > u64::MAX as f32 {
panic!("Cannot truncate {} from F32 to unsigned I64", arg);
}
self.value_stack.push(Value::from(arg as u64));
}
I64TRUNCSF64 => {
let arg = self.value_stack.pop_f64();
if arg < i64::MIN as f64 || arg > i64::MAX as f64 {
panic!("Cannot truncate {} from F64 to I64", arg);
}
self.value_stack.push(Value::I64(arg as i64));
}
I64TRUNCUF64 => {
let arg = self.value_stack.pop_f64();
if arg < u64::MIN as f64 || arg > u64::MAX as f64 {
panic!("Cannot truncate {} from F64 to unsigned I64", arg);
}
self.value_stack.push(Value::from(arg as u64));
}
F32CONVERTSI32 => todo!("{:?} @ {:#x}", op_code, file_offset),
F32CONVERTUI32 => todo!("{:?} @ {:#x}", op_code, file_offset),
F32CONVERTSI64 => todo!("{:?} @ {:#x}", op_code, file_offset),

View File

@ -12,17 +12,73 @@ fn test_i32wrapi64() {
);
}
// #[test]
// fn test_i32truncsf32() {}
#[test]
fn test_i32truncsf32() {
test_op_example(I32TRUNCSF32, [Value::F32(2.9)], Value::I32(2));
}
// #[test]
// fn test_i32truncuf32() {}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i32truncsf32_oob() {
test_op_example(
I32TRUNCSF32,
[Value::F32(i32::MAX as f32 * 2.0)],
Value::I32(i32::MIN),
);
}
// #[test]
// fn test_i32truncsf64() {}
#[test]
fn test_i32truncuf32() {
test_op_example(
I32TRUNCUF32,
[Value::F32(i32::MAX as f32 + 1.0)],
Value::I32(i32::MIN),
);
}
// #[test]
// fn test_i32truncuf64() {}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i32truncuf32_oob() {
test_op_example(
I32TRUNCUF32,
[Value::F32(u32::MAX as f32 * 2.0)],
Value::I32(0),
);
}
#[test]
fn test_i32truncsf64() {
test_op_example(I32TRUNCSF64, [Value::F64(2.9)], Value::I32(2));
}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i32truncsf64_oob() {
test_op_example(
I32TRUNCSF64,
[Value::F64(i32::MAX as f64 * 2.0)],
Value::I32(i32::MIN),
);
}
#[test]
fn test_i32truncuf64() {
test_op_example(
I32TRUNCUF64,
[Value::F64(i32::MAX as f64 + 1.0)],
Value::I32(i32::MIN),
);
}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i32truncuf64_oob() {
test_op_example(
I32TRUNCUF64,
[Value::F64(u32::MAX as f64 * 2.0)],
Value::I32(0),
);
}
#[test]
fn test_i64extendsi32() {
@ -34,17 +90,73 @@ fn test_i64extendui32() {
test_op_example(I64EXTENDUI32, [Value::I32(-1)], Value::I64(0xffff_ffff));
}
// #[test]
// fn test_i64truncsf32() {}
#[test]
fn test_i64truncsf32() {
test_op_example(I64TRUNCSF32, [Value::F32(2.9)], Value::I64(2));
}
// #[test]
// fn test_i64truncuf32() {}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i64truncsf32_oob() {
test_op_example(
I64TRUNCSF32,
[Value::F32(i64::MAX as f32 * 2.0)],
Value::I64(i64::MIN),
);
}
// #[test]
// fn test_i64truncsf64() {}
#[test]
fn test_i64truncuf32() {
test_op_example(
I64TRUNCUF32,
[Value::F32(i64::MAX as f32 + 1.0)],
Value::I64(i64::MIN),
);
}
// #[test]
// fn test_i64truncuf64() {}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i64truncuf32_oob() {
test_op_example(
I64TRUNCUF32,
[Value::F32(u64::MAX as f32 * 2.0)],
Value::I64(0),
);
}
#[test]
fn test_i64truncsf64() {
test_op_example(I64TRUNCSF64, [Value::F64(2.9)], Value::I64(2));
}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i64truncsf64_oob() {
test_op_example(
I64TRUNCSF64,
[Value::F64(i64::MAX as f64 * 2.0)],
Value::I64(i64::MIN),
);
}
#[test]
fn test_i64truncuf64() {
test_op_example(
I64TRUNCUF64,
[Value::F64(i64::MAX as f64 + 1.0)],
Value::I64(i64::MIN),
);
}
#[test]
#[should_panic(expected = "Cannot truncate")]
fn test_i64truncuf64_oob() {
test_op_example(
I32TRUNCUF64,
[Value::F64(u64::MAX as f64 * 2.0)],
Value::I32(0),
);
}
#[test]
fn test_f32demotef64() {