mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
wasm_interp: truncate instructions
This commit is contained in:
parent
6ac46a150f
commit
029f0d00c1
@ -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),
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user