From a70251fe83e44c93d7c1ad4e7a0f4cce03b6fbeb Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 25 Mar 2023 09:37:44 +0100 Subject: [PATCH] classlib: add Integer/Long.compareUnsigned --- .../java/lang/IntegerNativeGenerator.java | 7 +++++++ .../java/lang/LongNativeGenerator.java | 5 +++++ .../org/teavm/classlib/java/lang/TInteger.java | 4 ++++ .../org/teavm/classlib/java/lang/TLong.java | 4 ++++ .../org/teavm/backend/javascript/long.js | 18 ++++++++++++++++++ .../org/teavm/backend/javascript/runtime.js | 5 +++++ 6 files changed, 43 insertions(+) diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/IntegerNativeGenerator.java b/classlib/src/main/java/org/teavm/classlib/java/lang/IntegerNativeGenerator.java index 97c050aaf..d6e99ec79 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/IntegerNativeGenerator.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/IntegerNativeGenerator.java @@ -38,6 +38,13 @@ public class IntegerNativeGenerator implements Injector { context.writeExpr(context.getArgument(1)); context.getWriter().append(")"); break; + case "compareUnsigned": + context.getWriter().append("$rt_ucmp("); + context.writeExpr(context.getArgument(0)); + context.getWriter().append(",").ws(); + context.writeExpr(context.getArgument(1)); + context.getWriter().append(")"); + break; } } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java b/classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java index 3cf532086..5f5b7202c 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/LongNativeGenerator.java @@ -30,6 +30,11 @@ public class LongNativeGenerator implements Generator { .append(context.getParameterName(2)).append(");").softNewLine(); context.useLongLibrary(); break; + case "compareUnsigned": + writer.append("return Long_ucompare(").append(context.getParameterName(1)).append(", ") + .append(context.getParameterName(2)).append(");").softNewLine(); + context.useLongLibrary(); + break; case "divideUnsigned": writer.append("return Long_udiv(").append(context.getParameterName(1)).append(", ") .append(context.getParameterName(2)).append(");").softNewLine(); diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java index 8f781ad3d..e8b7886f6 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TInteger.java @@ -368,4 +368,8 @@ public class TInteger extends TNumber implements TComparable { @InjectedBy(IntegerNativeGenerator.class) @NoSideEffects public static native int remainderUnsigned(int dividend, int divisor); + + @InjectedBy(IntegerNativeGenerator.class) + @NoSideEffects + public static native int compareUnsigned(int a, int b); } diff --git a/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java b/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java index eca1c5c85..200b79ba4 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java +++ b/classlib/src/main/java/org/teavm/classlib/java/lang/TLong.java @@ -359,4 +359,8 @@ public class TLong extends TNumber implements TComparable { @GeneratedBy(LongNativeGenerator.class) @NoSideEffects public static native long remainderUnsigned(long dividend, long divisor); + + @GeneratedBy(LongNativeGenerator.class) + @NoSideEffects + public static native int compareUnsigned(long a, long b); } diff --git a/core/src/main/resources/org/teavm/backend/javascript/long.js b/core/src/main/resources/org/teavm/backend/javascript/long.js index ec0cf7bd2..abc00c957 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/long.js +++ b/core/src/main/resources/org/teavm/backend/javascript/long.js @@ -22,6 +22,7 @@ var Long_ge; var Long_lt; var Long_le; var Long_compare; +var Long_ucompare; var Long_add; var Long_sub; var Long_inc; @@ -185,6 +186,18 @@ if (typeof BigInt !== 'function') { return (a.lo & 1) - (b.lo & 1); } + Long_ucompare = function(a, b) { + var r = $rt_ucmp(a.hi, b.hi); + if (r !== 0) { + return r; + } + r = (a.lo >>> 1) - (b.lo >>> 1); + if (r !== 0) { + return r; + } + return (a.lo & 1) - (b.lo & 1); + } + Long_mul = function(a, b) { var positive = Long_isNegative(a) === Long_isNegative(b); if (Long_isNegative(a)) { @@ -608,6 +621,11 @@ if (typeof BigInt !== 'function') { Long_compare = function(a, b) { return a < b ? -1 : a > b ? 1 : 0; } + Long_ucompare = function(a, b) { + a = BigInt.asUintN(64, a); + b = BigInt.asUintN(64, b); + return a < b ? -1 : a > b ? 1 : 0; + } Long_mul = function(a, b) { return BigInt.asIntN(64, a * b); diff --git a/core/src/main/resources/org/teavm/backend/javascript/runtime.js b/core/src/main/resources/org/teavm/backend/javascript/runtime.js index c29ec4e57..0be7d40f7 100644 --- a/core/src/main/resources/org/teavm/backend/javascript/runtime.js +++ b/core/src/main/resources/org/teavm/backend/javascript/runtime.js @@ -879,6 +879,11 @@ var $rt_udiv = function(a, b) { var $rt_umod = function(a, b) { return ((a >>> 0) % (b >>> 0)) >>> 0; }; +var $rt_ucmp = function(a, b) { + a >>>= 0; + b >>>= 0; + return a < b ? -1 : a > b ? 1 : 0; +}; function $rt_checkBounds(index, array) { if (index < 0 || index >= array.length) { $rt_throwAIOOBE();