mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-21 01:00:54 +08:00
classlib: implement Integer.compareUnsigned in Wasm and C
This commit is contained in:
parent
a3f0ec52d4
commit
a7f115a541
@ -27,6 +27,7 @@ public class IntegerIntrinsic implements Intrinsic {
|
||||
switch (method.getName()) {
|
||||
case "divideUnsigned":
|
||||
case "remainderUnsigned":
|
||||
case "compareUnsigned":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -42,6 +43,13 @@ public class IntegerIntrinsic implements Intrinsic {
|
||||
case "remainderUnsigned":
|
||||
writeBinary(context, invocation, "%");
|
||||
break;
|
||||
case "compareUnsigned":
|
||||
context.writer().print("teavm_compare_u32(");
|
||||
context.emit(invocation.getArguments().get(0));
|
||||
context.writer().print(", ");
|
||||
context.emit(invocation.getArguments().get(1));
|
||||
context.writer().print(")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,10 @@ public final class WasmRuntime {
|
||||
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
||||
}
|
||||
|
||||
public static int compareUnsigned(int a, int b) {
|
||||
return gtu(a, b) ? 1 : ltu(a, b) ? -1 : 0;
|
||||
}
|
||||
|
||||
public static int compare(long a, long b) {
|
||||
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
|
||||
}
|
||||
@ -55,6 +59,10 @@ public final class WasmRuntime {
|
||||
|
||||
private static native boolean gt(int a, int b);
|
||||
|
||||
private static native boolean ltu(int a, int b);
|
||||
|
||||
private static native boolean gtu(int a, int b);
|
||||
|
||||
private static native boolean lt(long a, long b);
|
||||
|
||||
private static native boolean gt(long a, long b);
|
||||
|
@ -16,6 +16,8 @@
|
||||
package org.teavm.backend.wasm.intrinsics;
|
||||
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.wasm.WasmRuntime;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmIntBinary;
|
||||
import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation;
|
||||
@ -23,6 +25,9 @@ import org.teavm.backend.wasm.model.expression.WasmIntType;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
public class IntegerIntrinsic implements WasmIntrinsic {
|
||||
private static final MethodReference COMPARE_UNSIGNED = new MethodReference(WasmRuntime.class,
|
||||
"compareUnsigned", int.class, int.class, int.class);
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(MethodReference methodReference) {
|
||||
if (!methodReference.getClassName().equals(Integer.class.getName())) {
|
||||
@ -32,6 +37,7 @@ public class IntegerIntrinsic implements WasmIntrinsic {
|
||||
switch (methodReference.getName()) {
|
||||
case "divideUnsigned":
|
||||
case "remainderUnsigned":
|
||||
case "compareUnsigned":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -49,6 +55,10 @@ public class IntegerIntrinsic implements WasmIntrinsic {
|
||||
return new WasmIntBinary(WasmIntType.INT32, WasmIntBinaryOperation.REM_UNSIGNED,
|
||||
manager.generate(invocation.getArguments().get(0)),
|
||||
manager.generate(invocation.getArguments().get(1)));
|
||||
case "compareUnsigned":
|
||||
return new WasmCall(manager.getNames().forMethod(COMPARE_UNSIGNED),
|
||||
manager.generate(invocation.getArguments().get(0)),
|
||||
manager.generate(invocation.getArguments().get(1)));
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
|
||||
switch (methodReference.getName()) {
|
||||
case "gt":
|
||||
case "lt":
|
||||
case "gtu":
|
||||
case "ltu":
|
||||
case "initStack":
|
||||
return true;
|
||||
default:
|
||||
@ -53,6 +55,12 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
|
||||
case "gt":
|
||||
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.GT,
|
||||
invocation, manager);
|
||||
case "ltu":
|
||||
return comparison(WasmIntBinaryOperation.LT_UNSIGNED, WasmFloatBinaryOperation.LT,
|
||||
invocation, manager);
|
||||
case "gtu":
|
||||
return comparison(WasmIntBinaryOperation.GT_UNSIGNED, WasmFloatBinaryOperation.GT,
|
||||
invocation, manager);
|
||||
default:
|
||||
throw new IllegalArgumentException(invocation.getMethod().getName());
|
||||
}
|
||||
|
@ -129,6 +129,9 @@ extern void teavm_throwArrayIndexOutOfBoundsException();
|
||||
static inline int32_t teavm_compare_i32(int32_t a, int32_t b) {
|
||||
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
||||
}
|
||||
static inline int32_t teavm_compare_u32(int32_t a, int32_t b) {
|
||||
return (uint32_t) a > (uint32_t) b ? INT32_C(1) : (uint32_t) a < (uint32_t) b ? INT32_C(-1) : INT32_C(0);
|
||||
}
|
||||
static inline int32_t teavm_compare_i64(int64_t a, int64_t b) {
|
||||
return a > b ? INT32_C(1) : a < b ? INT32_C(-1) : INT32_C(0);
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ TeaVM.wasm = function() {
|
||||
let length = instance.exports.teavm_arrayLength(arrayPtr);
|
||||
let arrayData = new DataView(memory, instance.exports.teavm_charArrayData(arrayPtr), length * 2);
|
||||
for (let i = 0; i < length; ++i) {
|
||||
putwchar(arrayData.memory.getUint16(i * 2, true));
|
||||
putwchar(arrayData.getUint16(i * 2, true));
|
||||
}
|
||||
}
|
||||
function logInt(i) {
|
||||
|
Loading…
Reference in New Issue
Block a user