classlib: improve Math min/max implementations in C and Wasm

Follow-up to ihromant's "fix Math min/max functions in JS"
This commit is contained in:
Alexey Andreev 2023-09-28 17:00:51 +02:00
parent 56ff3fbdd8
commit d4113a6744
3 changed files with 33 additions and 0 deletions

View File

@ -16,6 +16,7 @@
package org.teavm.classlib.java.lang; package org.teavm.classlib.java.lang;
import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.backend.wasm.WasmRuntime;
import org.teavm.backend.wasm.runtime.WasmSupport; import org.teavm.backend.wasm.runtime.WasmSupport;
import org.teavm.classlib.PlatformDetector; import org.teavm.classlib.PlatformDetector;
import org.teavm.interop.Import; import org.teavm.interop.Import;
@ -197,11 +198,15 @@ public final class TMath extends TObject {
@GeneratedBy(MathNativeGenerator.class) @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
@Unmanaged
private static native float minImpl(double a, double b); private static native float minImpl(double a, double b);
@Unmanaged
public static double min(double a, double b) { public static double min(double a, double b) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return minImpl(a, b); return minImpl(a, b);
} else if (PlatformDetector.isWebAssembly()) {
return WasmRuntime.min(a, b);
} }
if (a != a) { if (a != a) {
return a; return a;
@ -214,11 +219,15 @@ public final class TMath extends TObject {
@GeneratedBy(MathNativeGenerator.class) @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
@Unmanaged
private static native float maxImpl(double a, double b); private static native float maxImpl(double a, double b);
@Unmanaged
public static double max(double a, double b) { public static double max(double a, double b) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return maxImpl(a, b); return maxImpl(a, b);
} else if (PlatformDetector.isWebAssembly()) {
return WasmRuntime.max(a, b);
} }
if (a != a) { if (a != a) {
return a; return a;
@ -231,11 +240,15 @@ public final class TMath extends TObject {
@GeneratedBy(MathNativeGenerator.class) @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
@Unmanaged
private static native float minImpl(float a, float b); private static native float minImpl(float a, float b);
@Unmanaged
public static float min(float a, float b) { public static float min(float a, float b) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return minImpl(a, b); return minImpl(a, b);
} else if (PlatformDetector.isWebAssembly()) {
return WasmRuntime.min(a, b);
} }
if (a != a) { if (a != a) {
return a; return a;
@ -248,11 +261,15 @@ public final class TMath extends TObject {
@GeneratedBy(MathNativeGenerator.class) @GeneratedBy(MathNativeGenerator.class)
@NoSideEffects @NoSideEffects
@Unmanaged
private static native float maxImpl(float a, float b); private static native float maxImpl(float a, float b);
@Unmanaged
public static float max(float a, float b) { public static float max(float a, float b) {
if (PlatformDetector.isJavaScript()) { if (PlatformDetector.isJavaScript()) {
return maxImpl(a, b); return maxImpl(a, b);
} else if (PlatformDetector.isWebAssembly()) {
return WasmRuntime.max(a, b);
} }
if (a != a) { if (a != a) {
return a; return a;

View File

@ -51,6 +51,14 @@ public final class WasmRuntime {
return gt(a, b) ? 1 : lt(a, b) ? -1 : 0; return gt(a, b) ? 1 : lt(a, b) ? -1 : 0;
} }
public static native float min(float a, float b);
public static native double min(double a, double b);
public static native float max(float a, float b);
public static native double max(double a, double b);
public static float remainder(float a, float b) { public static float remainder(float a, float b) {
return a - (float) (int) (a / b) * b; return a - (float) (int) (a / b) * b;
} }

View File

@ -40,6 +40,8 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
case "lt": case "lt":
case "gtu": case "gtu":
case "ltu": case "ltu":
case "min":
case "max":
case "initStack": case "initStack":
case "callFunctionFromTable": case "callFunctionFromTable":
return true; return true;
@ -63,6 +65,12 @@ public class WasmRuntimeIntrinsic implements WasmIntrinsic {
case "gtu": case "gtu":
return comparison(WasmIntBinaryOperation.GT_UNSIGNED, WasmFloatBinaryOperation.GT, return comparison(WasmIntBinaryOperation.GT_UNSIGNED, WasmFloatBinaryOperation.GT,
invocation, manager); invocation, manager);
case "min":
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.MIN,
invocation, manager);
case "max":
return comparison(WasmIntBinaryOperation.GT_SIGNED, WasmFloatBinaryOperation.MAX,
invocation, manager);
case "callFunctionFromTable": { case "callFunctionFromTable": {
var call = new WasmIndirectCall(manager.generate(invocation.getArguments().get(0))); var call = new WasmIndirectCall(manager.generate(invocation.getArguments().get(0)));
call.getArguments().add(manager.generate(invocation.getArguments().get(1))); call.getArguments().add(manager.generate(invocation.getArguments().get(1)));