mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
wasm_interp: fix return type for i64 comparison ops
This commit is contained in:
parent
c2bf7d68fc
commit
fc10c520b1
2 changed files with 80 additions and 64 deletions
|
@ -716,67 +716,67 @@ impl<'a> Instance<'a> {
|
||||||
I64EQZ => {
|
I64EQZ => {
|
||||||
let arg = self.value_stack.pop_i64();
|
let arg = self.value_stack.pop_i64();
|
||||||
let result: bool = arg == 0;
|
let result: bool = arg == 0;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64EQ => {
|
I64EQ => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 == arg2;
|
let result: bool = arg1 == arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64NE => {
|
I64NE => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 != arg2;
|
let result: bool = arg1 != arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64LTS => {
|
I64LTS => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 < arg2;
|
let result: bool = arg1 < arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64LTU => {
|
I64LTU => {
|
||||||
let arg2 = self.value_stack.pop_u64();
|
let arg2 = self.value_stack.pop_u64();
|
||||||
let arg1 = self.value_stack.pop_u64();
|
let arg1 = self.value_stack.pop_u64();
|
||||||
let result: bool = arg1 < arg2;
|
let result: bool = arg1 < arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64GTS => {
|
I64GTS => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 > arg2;
|
let result: bool = arg1 > arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64GTU => {
|
I64GTU => {
|
||||||
let arg2 = self.value_stack.pop_u64();
|
let arg2 = self.value_stack.pop_u64();
|
||||||
let arg1 = self.value_stack.pop_u64();
|
let arg1 = self.value_stack.pop_u64();
|
||||||
let result: bool = arg1 > arg2;
|
let result: bool = arg1 > arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64LES => {
|
I64LES => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 <= arg2;
|
let result: bool = arg1 <= arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64LEU => {
|
I64LEU => {
|
||||||
let arg2 = self.value_stack.pop_u64();
|
let arg2 = self.value_stack.pop_u64();
|
||||||
let arg1 = self.value_stack.pop_u64();
|
let arg1 = self.value_stack.pop_u64();
|
||||||
let result: bool = arg1 <= arg2;
|
let result: bool = arg1 <= arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64GES => {
|
I64GES => {
|
||||||
let arg2 = self.value_stack.pop_i64();
|
let arg2 = self.value_stack.pop_i64();
|
||||||
let arg1 = self.value_stack.pop_i64();
|
let arg1 = self.value_stack.pop_i64();
|
||||||
let result: bool = arg1 >= arg2;
|
let result: bool = arg1 >= arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
I64GEU => {
|
I64GEU => {
|
||||||
let arg2 = self.value_stack.pop_u64();
|
let arg2 = self.value_stack.pop_u64();
|
||||||
let arg1 = self.value_stack.pop_u64();
|
let arg1 = self.value_stack.pop_u64();
|
||||||
let result: bool = arg1 >= arg2;
|
let result: bool = arg1 >= arg2;
|
||||||
self.value_stack.push(Value::I64(result as i64));
|
self.value_stack.push(Value::I32(result as i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
F32EQ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
F32EQ => todo!("{:?} @ {:#x}", op_code, file_offset),
|
||||||
|
|
|
@ -3,6 +3,22 @@
|
||||||
use roc_wasm_interp::test_utils::test_op_example;
|
use roc_wasm_interp::test_utils::test_op_example;
|
||||||
use roc_wasm_module::{opcodes::OpCode, opcodes::OpCode::*, Value};
|
use roc_wasm_module::{opcodes::OpCode, opcodes::OpCode::*, Value};
|
||||||
|
|
||||||
|
fn test_i64_comparison(op: OpCode, arg1: i64, arg2: i64, expected: bool) {
|
||||||
|
test_op_example(
|
||||||
|
op,
|
||||||
|
[Value::from(arg1), Value::from(arg2)],
|
||||||
|
Value::I32(expected as i32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_u64_comparison(op: OpCode, arg1: u64, arg2: u64, expected: bool) {
|
||||||
|
test_op_example(
|
||||||
|
op,
|
||||||
|
[Value::from(arg1), Value::from(arg2)],
|
||||||
|
Value::I32(expected as i32),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn test_i64_binop(op: OpCode, arg1: i64, arg2: i64, expected: i64) {
|
fn test_i64_binop(op: OpCode, arg1: i64, arg2: i64, expected: i64) {
|
||||||
test_op_example(
|
test_op_example(
|
||||||
op,
|
op,
|
||||||
|
@ -26,109 +42,109 @@ fn test_i64_unop(op: OpCode, arg: i64, expected: i64) {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64eqz() {
|
fn test_i64eqz() {
|
||||||
let op = I64EQZ;
|
let op = I64EQZ;
|
||||||
test_i64_unop(op, 0, 1);
|
test_op_example(op, [Value::I64(0)], Value::I32(true as i32));
|
||||||
test_i64_unop(op, i64::MIN, 0);
|
test_op_example(op, [Value::I64(i64::MIN)], Value::I32(false as i32));
|
||||||
test_i64_unop(op, i64::MAX, 0);
|
test_op_example(op, [Value::I64(i64::MAX)], Value::I32(false as i32));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64eq() {
|
fn test_i64eq() {
|
||||||
let op = I64EQ;
|
let op = I64EQ;
|
||||||
test_i64_binop(op, 0, 0, 1);
|
test_i64_comparison(op, 0, 0, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 1);
|
test_i64_comparison(op, i64::MIN, i64::MIN, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 1);
|
test_i64_comparison(op, i64::MAX, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 0);
|
test_i64_comparison(op, i64::MIN, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 0);
|
test_i64_comparison(op, i64::MAX, i64::MIN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64ne() {
|
fn test_i64ne() {
|
||||||
let op = I64NE;
|
let op = I64NE;
|
||||||
test_i64_binop(op, 0, 0, 0);
|
test_i64_comparison(op, 0, 0, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 0);
|
test_i64_comparison(op, i64::MIN, i64::MIN, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 0);
|
test_i64_comparison(op, i64::MAX, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 1);
|
test_i64_comparison(op, i64::MIN, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 1);
|
test_i64_comparison(op, i64::MAX, i64::MIN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64lts() {
|
fn test_i64lts() {
|
||||||
let op = I64LTS;
|
let op = I64LTS;
|
||||||
test_i64_binop(op, 0, 0, 0);
|
test_i64_comparison(op, 0, 0, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 0);
|
test_i64_comparison(op, i64::MIN, i64::MIN, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 0);
|
test_i64_comparison(op, i64::MAX, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 1);
|
test_i64_comparison(op, i64::MIN, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 0);
|
test_i64_comparison(op, i64::MAX, i64::MIN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64ltu() {
|
fn test_i64ltu() {
|
||||||
let op = I64LTU;
|
let op = I64LTU;
|
||||||
test_u64_binop(op, 0, 0, 0);
|
test_u64_comparison(op, 0, 0, false);
|
||||||
test_u64_binop(op, u64::MIN, u64::MIN, 0);
|
test_u64_comparison(op, u64::MIN, u64::MIN, false);
|
||||||
test_u64_binop(op, u64::MAX, u64::MAX, 0);
|
test_u64_comparison(op, u64::MAX, u64::MAX, false);
|
||||||
test_u64_binop(op, u64::MIN, u64::MAX, 1);
|
test_u64_comparison(op, u64::MIN, u64::MAX, true);
|
||||||
test_u64_binop(op, u64::MAX, u64::MIN, 0);
|
test_u64_comparison(op, u64::MAX, u64::MIN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64gts() {
|
fn test_i64gts() {
|
||||||
let op = I64GTS;
|
let op = I64GTS;
|
||||||
test_i64_binop(op, 0, 0, 0);
|
test_i64_comparison(op, 0, 0, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 0);
|
test_i64_comparison(op, i64::MIN, i64::MIN, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 0);
|
test_i64_comparison(op, i64::MAX, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 0);
|
test_i64_comparison(op, i64::MIN, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 1);
|
test_i64_comparison(op, i64::MAX, i64::MIN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64gtu() {
|
fn test_i64gtu() {
|
||||||
let op = I64GTU;
|
let op = I64GTU;
|
||||||
test_u64_binop(op, 0, 0, 0);
|
test_u64_comparison(op, 0, 0, false);
|
||||||
test_u64_binop(op, u64::MIN, u64::MIN, 0);
|
test_u64_comparison(op, u64::MIN, u64::MIN, false);
|
||||||
test_u64_binop(op, u64::MAX, u64::MAX, 0);
|
test_u64_comparison(op, u64::MAX, u64::MAX, false);
|
||||||
test_u64_binop(op, u64::MIN, u64::MAX, 0);
|
test_u64_comparison(op, u64::MIN, u64::MAX, false);
|
||||||
test_u64_binop(op, u64::MAX, u64::MIN, 1);
|
test_u64_comparison(op, u64::MAX, u64::MIN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64les() {
|
fn test_i64les() {
|
||||||
let op = I64LES;
|
let op = I64LES;
|
||||||
test_i64_binop(op, 0, 0, 1);
|
test_i64_comparison(op, 0, 0, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 1);
|
test_i64_comparison(op, i64::MIN, i64::MIN, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 1);
|
test_i64_comparison(op, i64::MAX, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 1);
|
test_i64_comparison(op, i64::MIN, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 0);
|
test_i64_comparison(op, i64::MAX, i64::MIN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64leu() {
|
fn test_i64leu() {
|
||||||
let op = I64LEU;
|
let op = I64LEU;
|
||||||
test_u64_binop(op, 0, 0, 1);
|
test_u64_comparison(op, 0, 0, true);
|
||||||
test_u64_binop(op, u64::MIN, u64::MIN, 1);
|
test_u64_comparison(op, u64::MIN, u64::MIN, true);
|
||||||
test_u64_binop(op, u64::MAX, u64::MAX, 1);
|
test_u64_comparison(op, u64::MAX, u64::MAX, true);
|
||||||
test_u64_binop(op, u64::MIN, u64::MAX, 1);
|
test_u64_comparison(op, u64::MIN, u64::MAX, true);
|
||||||
test_u64_binop(op, u64::MAX, u64::MIN, 0);
|
test_u64_comparison(op, u64::MAX, u64::MIN, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64ges() {
|
fn test_i64ges() {
|
||||||
let op = I64GES;
|
let op = I64GES;
|
||||||
test_i64_binop(op, 0, 0, 1);
|
test_i64_comparison(op, 0, 0, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MIN, 1);
|
test_i64_comparison(op, i64::MIN, i64::MIN, true);
|
||||||
test_i64_binop(op, i64::MAX, i64::MAX, 1);
|
test_i64_comparison(op, i64::MAX, i64::MAX, true);
|
||||||
test_i64_binop(op, i64::MIN, i64::MAX, 0);
|
test_i64_comparison(op, i64::MIN, i64::MAX, false);
|
||||||
test_i64_binop(op, i64::MAX, i64::MIN, 1);
|
test_i64_comparison(op, i64::MAX, i64::MIN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_i64geu() {
|
fn test_i64geu() {
|
||||||
let op = I64GEU;
|
let op = I64GEU;
|
||||||
test_u64_binop(op, 0, 0, 1);
|
test_u64_comparison(op, 0, 0, true);
|
||||||
test_u64_binop(op, u64::MIN, u64::MIN, 1);
|
test_u64_comparison(op, u64::MIN, u64::MIN, true);
|
||||||
test_u64_binop(op, u64::MAX, u64::MAX, 1);
|
test_u64_comparison(op, u64::MAX, u64::MAX, true);
|
||||||
test_u64_binop(op, u64::MIN, u64::MAX, 0);
|
test_u64_comparison(op, u64::MIN, u64::MAX, false);
|
||||||
test_u64_binop(op, u64::MAX, u64::MIN, 1);
|
test_u64_comparison(op, u64::MAX, u64::MIN, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue