Skip to content

Commit

Permalink
fix: Implement i64 ops and specs
Browse files Browse the repository at this point in the history
  • Loading branch information
bhelx committed Sep 25, 2023
1 parent 75c3960 commit dae9a0a
Show file tree
Hide file tree
Showing 5 changed files with 688 additions and 79 deletions.
7 changes: 6 additions & 1 deletion runtime/scripts/generate-java.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def java_header(class_name)
public class #{class_name} {
public static long longVal(String v) {
return new BigInteger(v).longValue();
}
HEADER
end

Expand All @@ -36,7 +40,7 @@ def val_to_java_value(val)
when 'i32'
"(int)(#{val['value']}L & 0xFFFFFFFFL)"
when 'i64'
"new BigInteger(\"#{val['value']}\").longValue()"
"longVal(\"#{val['value']}\")"
end
end

Expand Down Expand Up @@ -123,4 +127,5 @@ def generate_test(inputs)
# generate_test(inputs)
generate_test([
'src/test/resources/wasm/specv1/i32.json',
'src/test/resources/wasm/specv1/i64.json',
])
132 changes: 108 additions & 24 deletions runtime/src/main/java/com/dylibso/chicory/runtime/Machine.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,16 @@ void eval(List<Instruction> code) throws ChicoryException {
var a = this.stack.pop().asUInt();
this.stack.push(a < b ? Value.TRUE : Value.FALSE);
}
// TODO split
case I64_LT_S, I64_LT_U -> {
case I64_LT_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(a < b ? Value.TRUE : Value.FALSE);
}
case I64_LT_U -> {
var b = this.stack.pop().asULong();
var a = this.stack.pop().asULong();
this.stack.push(a.compareTo(b) < 0 ? Value.TRUE : Value.FALSE);
}
case I32_GT_S -> {
var b = this.stack.pop().asInt();
var a = this.stack.pop().asInt();
Expand All @@ -254,12 +258,16 @@ void eval(List<Instruction> code) throws ChicoryException {
var a = this.stack.pop().asUInt();
this.stack.push(a > b ? Value.TRUE : Value.FALSE);
}
// TODO split
case I64_GT_S, I64_GT_U -> {
case I64_GT_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(a > b ? Value.TRUE : Value.FALSE);
}
case I64_GT_U -> {
var b = this.stack.pop().asULong();
var a = this.stack.pop().asULong();
this.stack.push(a.compareTo(b) > 0 ? Value.TRUE : Value.FALSE);
}
case I32_GE_S -> {
var b = this.stack.pop().asInt();
var a = this.stack.pop().asInt();
Expand All @@ -270,8 +278,12 @@ void eval(List<Instruction> code) throws ChicoryException {
var a = this.stack.pop().asUInt();
this.stack.push(a >= b ? Value.TRUE : Value.FALSE);
}
// TODO split
case I64_GE_U, I64_GE_S -> {
case I64_GE_U -> {
var b = this.stack.pop().asULong();
var a = this.stack.pop().asULong();
this.stack.push(a.compareTo(b) >= 0 ? Value.TRUE : Value.FALSE);
}
case I64_GE_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(a >= b ? Value.TRUE : Value.FALSE);
Expand All @@ -286,21 +298,29 @@ void eval(List<Instruction> code) throws ChicoryException {
var a = this.stack.pop().asUInt();
this.stack.push(a <= b ? Value.TRUE : Value.FALSE);
}
case I64_LE_U, I64_LE_S -> {
case I64_LE_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(a <= b ? Value.TRUE : Value.FALSE);
}
case I64_LE_U -> {
var b = this.stack.pop().asULong();
var a = this.stack.pop().asULong();
this.stack.push(a.compareTo(b) <= 0 ? Value.TRUE : Value.FALSE);
}
case I32_CLZ -> {
var count = this.stack.pop().i32CLZ();
var tos = this.stack.pop().asInt();
var count = Integer.numberOfLeadingZeros(tos);
this.stack.push(Value.i32(count));
}
case I32_CTZ -> {
var count = this.stack.pop().i32CTZ();
var tos = this.stack.pop().asInt();
var count = Integer.numberOfTrailingZeros(tos);
this.stack.push(Value.i32(count));
}
case I32_POPCNT -> {
var count = this.stack.pop().popCount();
var tos = this.stack.pop().asInt();
var count = Integer.bitCount(tos);
this.stack.push(Value.i32(count));
}
case I32_ADD -> {
Expand Down Expand Up @@ -343,12 +363,16 @@ void eval(List<Instruction> code) throws ChicoryException {
var a = this.stack.pop().asUInt();
this.stack.push(Value.i32(a / b));
}
// TODO split up
case I64_DIV_S, I64_DIV_U -> {
case I64_DIV_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(Value.i64(a / b));
}
case I64_DIV_U -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(Value.i64(Long.divideUnsigned(a, b)));
}
case I32_REM_S -> {
var b = this.stack.pop().asInt();
var a = this.stack.pop().asInt();
Expand All @@ -360,26 +384,72 @@ void eval(List<Instruction> code) throws ChicoryException {
this.stack.push(Value.i32(a % b));
}
case I64_AND -> {
var a = this.stack.pop().asInt();
var b = this.stack.pop().asInt();
var a = this.stack.pop().asLong();
var b = this.stack.pop().asLong();
this.stack.push(Value.i64(a & b));
}
case I64_OR -> {
var a = this.stack.pop().asInt();
var b = this.stack.pop().asInt();
var a = this.stack.pop().asLong();
var b = this.stack.pop().asLong();
this.stack.push(Value.i64(a | b));
}
case I64_XOR -> {
var a = this.stack.pop().asInt();
var b = this.stack.pop().asInt();
var a = this.stack.pop().asLong();
var b = this.stack.pop().asLong();
this.stack.push(Value.i64(a ^ b));
}
// TODO split up
case I64_REM_S, I64_REM_U -> {
case I64_SHL -> {
var c = this.stack.pop().asLong();
var v = this.stack.pop().asLong();
this.stack.push(Value.i64(v << c));
}
case I64_SHR_S -> {
var c = this.stack.pop().asLong();
var v = this.stack.pop().asLong();
this.stack.push(Value.i64(v >> c));
}
case I64_SHR_U -> {
var c = this.stack.pop().asLong();
var v = this.stack.pop().asLong();
this.stack.push(Value.i64(v >>> c));
}
case I64_REM_S -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(Value.i64(a % b));
}
case I64_REM_U -> {
var b = this.stack.pop().asLong();
var a = this.stack.pop().asLong();
this.stack.push(Value.i64(Long.remainderUnsigned(a, b)));
}
case I64_ROTL -> {
var c = this.stack.pop().asLong();
var v = this.stack.pop().asLong();
var z = (v << c) | (v >>> (64 - c));
this.stack.push(Value.i64(z));
}
case I64_ROTR -> {
var c = this.stack.pop().asLong();
var v = this.stack.pop().asLong();
var z = (v >>> c) | (v << (64 - c));
this.stack.push(Value.i64(z));
}
case I64_CLZ -> {
var tos = this.stack.pop();
var count = Long.numberOfLeadingZeros(tos.asLong());
this.stack.push(Value.i64(count));
}
case I64_CTZ -> {
var tos = this.stack.pop();
var count = Long.numberOfTrailingZeros(tos.asLong());
this.stack.push(Value.i64(count));
}
case I64_POPCNT -> {
var tos = this.stack.pop().asLong();
var count = Long.bitCount(tos);
this.stack.push(Value.i64(count));
}
case CALL -> {
var funcId = (int) operands[0];
var typeId = instance.getFunctionTypes()[funcId];
Expand Down Expand Up @@ -431,16 +501,30 @@ void eval(List<Instruction> code) throws ChicoryException {
var z = (v >>> c) | (v << (32 - c));
this.stack.push(Value.i32(z));
}
// For the extend_* operations, note that java
// automatically does this when casting from
// smaller to larger primitives
case I32_EXTEND_8_S -> {
int tos = this.stack.pop().asInt();
int result = tos << 24 >> 24;
this.stack.push(Value.i32(result));
var tos = this.stack.pop().asByte();
this.stack.push(Value.i32(tos));
}
case I32_EXTEND_16_S -> {
int original = this.stack.pop().asInt() & 0xFFFF;
var original = this.stack.pop().asInt() & 0xFFFF;
if ((original & 0x8000) != 0) original |= 0xFFFF0000;
this.stack.push(Value.i32(original & 0xFFFFFFFFL));
}
case I64_EXTEND_8_S -> {
var tos = this.stack.pop().asByte();
this.stack.push(Value.i64(tos));
}
case I64_EXTEND_16_S -> {
var tos = this.stack.pop().asShort();
this.stack.push(Value.i64(tos));
}
case I64_EXTEND_32_S -> {
var tos = this.stack.pop().asInt();
this.stack.push(Value.i64(tos));
}
default -> throw new RuntimeException("Machine doesn't recognize Instruction " + instruction);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

public class SpecV1I32Test {

public static long longVal(String v) {
return new BigInteger(v).longValue();
}

@Test
public void testI320Wasm() {
var instance = Module.build("src/test/resources/wasm/specv1/i32.0.wasm").instantiate();
Expand Down
Loading

0 comments on commit dae9a0a

Please sign in to comment.