mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
JS: improve performance float<->int reinterpretation conversion, improve performance of Double.equals.
This commit is contained in:
parent
658ef711ab
commit
cd9db17d73
|
@ -23,6 +23,14 @@ import org.teavm.model.MethodReference;
|
|||
public class DoubleGenerator implements Injector {
|
||||
@Override
|
||||
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
||||
if (methodRef.getName().equals("doubleEqualsJs")) {
|
||||
context.getWriter().appendFunction("$rt_equalDoubles").append("(");
|
||||
context.writeExpr(context.getArgument(0));
|
||||
context.getWriter().append(',').ws();
|
||||
context.writeExpr(context.getArgument(1));
|
||||
context.getWriter().append(')');
|
||||
return;
|
||||
}
|
||||
context.getWriter().append("$rt_").append(methodRef.getName()).append("(");
|
||||
context.writeExpr(context.getArgument(0));
|
||||
context.getWriter().append(")");
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.classlib.PlatformDetector;
|
||||
import org.teavm.classlib.impl.text.DoubleSynthesizer;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.interop.NoSideEffects;
|
||||
|
@ -201,7 +202,18 @@ public class TDouble extends TNumber implements TComparable<TDouble> {
|
|||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
return other instanceof TDouble && doubleToLongBits(((TDouble) other).value) == doubleToLongBits(value);
|
||||
return other instanceof TDouble && equals(value, ((TDouble) other).value);
|
||||
}
|
||||
|
||||
private static boolean equals(double a, double b) {
|
||||
return PlatformDetector.isJavaScript() ? doubleEqualsJs(a, b) : equalsWithBits(a, b);
|
||||
}
|
||||
|
||||
@InjectedBy(DoubleGenerator.class)
|
||||
private static native boolean doubleEqualsJs(double a, double b);
|
||||
|
||||
private static boolean equalsWithBits(double a, double b) {
|
||||
return a != a ? b != b : doubleToRawLongBits(a) == doubleToRawLongBits(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -85,7 +85,11 @@ public class TFloat extends TNumber implements TComparable<TFloat> {
|
|||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
return other instanceof TFloat && floatToIntBits(((TFloat) other).value) == floatToIntBits(value);
|
||||
return other instanceof TFloat && equals(value, ((TFloat) other).value);
|
||||
}
|
||||
|
||||
private static boolean equals(float a, float b) {
|
||||
return a != a ? b != b : floatToRawIntBits(a) == floatToRawIntBits(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -656,7 +656,11 @@ function $rt_eraseClinit(target) {
|
|||
return target.$clinit = function() {};
|
||||
}
|
||||
|
||||
var $rt_numberConversionView = new DataView(new ArrayBuffer(8));
|
||||
var $rt_numberConversionBuffer = new ArrayBuffer(16);
|
||||
var $rt_numberConversionView = new DataView($rt_numberConversionBuffer);
|
||||
var $rt_numberConversionFloatArray = new Float32Array($rt_numberConversionBuffer);
|
||||
var $rt_numberConversionDoubleArray = new Float64Array($rt_numberConversionBuffer);
|
||||
var $rt_numberConversionIntArray = new Int32Array($rt_numberConversionBuffer);
|
||||
|
||||
var $rt_doubleToRawLongBits;
|
||||
var $rt_longBitsToDouble;
|
||||
|
@ -670,31 +674,47 @@ if (typeof BigInt !== 'function') {
|
|||
$rt_numberConversionView.setInt32(4, n.hi, true);
|
||||
return $rt_numberConversionView.getFloat64(0, true);
|
||||
}
|
||||
} else {
|
||||
} else if (typeof BigInt64Array !== 'function') {
|
||||
$rt_doubleToRawLongBits = function(n) {
|
||||
$rt_numberConversionView.setFloat64(0, n, true);
|
||||
// For compatibility with Safari
|
||||
var lo = $rt_numberConversionView.getInt32(0, true);
|
||||
var hi = $rt_numberConversionView.getInt32(4, true);
|
||||
return BigInt.asIntN(64, BigInt.asUintN(32, BigInt(lo)) | (BigInt(hi) << BigInt(32)));
|
||||
}
|
||||
$rt_longBitsToDouble = function(n) {
|
||||
// For compatibility with Safari
|
||||
var hi = Number(BigInt.asIntN(32, n >> BigInt(32)));
|
||||
var lo = Number(BigInt.asIntN(32, n & BigInt(0xFFFFFFFF)));
|
||||
$rt_numberConversionView.setInt32(0, lo, true);
|
||||
$rt_numberConversionView.setInt32(4, hi, true);
|
||||
return $rt_numberConversionView.getFloat64(0, true);
|
||||
$rt_numberConversionView.setFloat64(0, n, true);
|
||||
var lo = $rt_numberConversionView.getInt32(0, true);
|
||||
var hi = $rt_numberConversionView.getInt32(4, true);
|
||||
return BigInt.asIntN(64, BigInt.asUintN(32, BigInt(lo)) | (BigInt(hi) << BigInt(32)));
|
||||
}
|
||||
} else {
|
||||
var $rt_numberConversionLongArray = new BigInt64Array($rt_numberConversionBuffer);
|
||||
$rt_doubleToRawLongBits = function(n) {
|
||||
$rt_numberConversionDoubleArray[0] = n;
|
||||
return $rt_numberConversionLongArray[0];
|
||||
}
|
||||
$rt_longBitsToDouble = function(n) {
|
||||
$rt_numberConversionLongArray[0] = n;
|
||||
return $rt_numberConversionDoubleArray[0];
|
||||
}
|
||||
}
|
||||
|
||||
function $rt_floatToRawIntBits(n) {
|
||||
$rt_numberConversionView.setFloat32(0, n);
|
||||
return $rt_numberConversionView.getInt32(0);
|
||||
$rt_numberConversionFloatArray[0] = n;
|
||||
return $rt_numberConversionIntArray[0];
|
||||
}
|
||||
function $rt_intBitsToFloat(n) {
|
||||
$rt_numberConversionView.setInt32(0, n);
|
||||
return $rt_numberConversionView.getFloat32(0);
|
||||
$rt_numberConversionIntArray[0] = n;
|
||||
return $rt_numberConversionFloatArray[0];
|
||||
}
|
||||
function $rt_equalDoubles(a, b) {
|
||||
if (a !== a) {
|
||||
return b !== b;
|
||||
}
|
||||
$rt_numberConversionDoubleArray[0] = a;
|
||||
$rt_numberConversionDoubleArray[1] = b;
|
||||
return $rt_numberConversionIntArray[0] === $rt_numberConversionIntArray[2]
|
||||
&& $rt_numberConversionIntArray[1] === $rt_numberConversionIntArray[3];
|
||||
}
|
||||
|
||||
var JavaError;
|
||||
|
|
Loading…
Reference in New Issue
Block a user