зеркало из https://github.com/mozilla/pjs.git
Trust JVM to implement "<=" and "<" according to JVM specs and replace code like
d1 == d1 && d2 == d2 && d1 < d2 with simple d1 < d2 That in turn allows to simplify code generation and remove OptRuntime.cmp_ functions.
This commit is contained in:
Родитель
719bb92768
Коммит
09018e0533
|
@ -3037,7 +3037,13 @@ class BodyCodegen
|
|||
}
|
||||
}
|
||||
generateCodeFromNode(child, node);
|
||||
if (childNumberFlag == Node.RIGHT) {
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
|
||||
}
|
||||
generateCodeFromNode(rChild, node);
|
||||
if (childNumberFlag == Node.LEFT) {
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
|
||||
}
|
||||
if (childNumberFlag == -1) {
|
||||
if (type == Token.GE || type == Token.GT) {
|
||||
cfw.add(ByteCode.SWAP);
|
||||
|
@ -3048,28 +3054,11 @@ class BodyCodegen
|
|||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+")Z");
|
||||
cfw.add(ByteCode.IFNE, trueGOTO);
|
||||
cfw.add(ByteCode.GOTO, falseGOTO);
|
||||
} else {
|
||||
boolean doubleThenObject = (childNumberFlag == Node.LEFT);
|
||||
if (type == Token.GE || type == Token.GT) {
|
||||
if (doubleThenObject) {
|
||||
cfw.add(ByteCode.DUP_X2);
|
||||
cfw.add(ByteCode.POP);
|
||||
doubleThenObject = false;
|
||||
} else {
|
||||
cfw.add(ByteCode.DUP2_X1);
|
||||
cfw.add(ByteCode.POP2);
|
||||
doubleThenObject = true;
|
||||
}
|
||||
}
|
||||
String routine = ((type == Token.LT)
|
||||
|| (type == Token.GT)) ? "cmp_LT" : "cmp_LE";
|
||||
if (doubleThenObject)
|
||||
addOptRuntimeInvoke(routine, "(DLjava/lang/Object;)Z");
|
||||
else
|
||||
addOptRuntimeInvoke(routine, "(Ljava/lang/Object;D)Z");
|
||||
genSimpleCompare(type, trueGOTO, falseGOTO);
|
||||
}
|
||||
cfw.add(ByteCode.IFNE, trueGOTO);
|
||||
cfw.add(ByteCode.GOTO, falseGOTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3094,9 +3083,14 @@ class BodyCodegen
|
|||
}
|
||||
|
||||
int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
|
||||
if (childNumberFlag == Node.BOTH) {
|
||||
generateCodeFromNode(child, node);
|
||||
generateCodeFromNode(child.getNext(), node);
|
||||
|
||||
generateCodeFromNode(child, node);
|
||||
if (childNumberFlag == Node.RIGHT) {
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D"); }
|
||||
generateCodeFromNode(child.getNext(), node);
|
||||
if (childNumberFlag == Node.LEFT) {
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D"); }
|
||||
if (childNumberFlag != -1) {
|
||||
int trueGOTO = cfw.acquireLabel();
|
||||
int skip = cfw.acquireLabel();
|
||||
genSimpleCompare(type, trueGOTO, -1);
|
||||
|
@ -3110,38 +3104,15 @@ class BodyCodegen
|
|||
cfw.adjustStackTop(-1); // only have 1 of true/false
|
||||
}
|
||||
else {
|
||||
if (type == Token.GE || type == Token.GT) {
|
||||
cfw.add(ByteCode.SWAP);
|
||||
}
|
||||
String routine = (type == Token.LT || type == Token.GT)
|
||||
? "cmp_LT" : "cmp_LE";
|
||||
generateCodeFromNode(child, node);
|
||||
generateCodeFromNode(child.getNext(), node);
|
||||
if (childNumberFlag == -1) {
|
||||
if (type == Token.GE || type == Token.GT) {
|
||||
cfw.add(ByteCode.SWAP);
|
||||
}
|
||||
addScriptRuntimeInvoke(routine,
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+")Z");
|
||||
}
|
||||
else {
|
||||
boolean doubleThenObject = (childNumberFlag == Node.LEFT);
|
||||
if (type == Token.GE || type == Token.GT) {
|
||||
if (doubleThenObject) {
|
||||
cfw.add(ByteCode.DUP_X2);
|
||||
cfw.add(ByteCode.POP);
|
||||
doubleThenObject = false;
|
||||
}
|
||||
else {
|
||||
cfw.add(ByteCode.DUP2_X1);
|
||||
cfw.add(ByteCode.POP2);
|
||||
doubleThenObject = true;
|
||||
}
|
||||
}
|
||||
if (doubleThenObject)
|
||||
addOptRuntimeInvoke(routine, "(DLjava/lang/Object;)Z");
|
||||
else
|
||||
addOptRuntimeInvoke(routine, "(Ljava/lang/Object;D)Z");
|
||||
}
|
||||
addScriptRuntimeInvoke(routine,
|
||||
"(Ljava/lang/Object;"
|
||||
+"Ljava/lang/Object;"
|
||||
+")Z");
|
||||
addBooleanWrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,30 +121,6 @@ public final class OptRuntime extends ScriptRuntime
|
|||
return toString(val1).concat((String)val2);
|
||||
}
|
||||
|
||||
public static boolean cmp_LT(double d1, Object val2)
|
||||
{
|
||||
double d2 = toNumber(val2);
|
||||
return d1 == d1 && d2 == d2 && d1 < d2;
|
||||
}
|
||||
|
||||
public static boolean cmp_LT(Object val1, double d2)
|
||||
{
|
||||
double d1 = toNumber(val1);
|
||||
return d1 == d1 && d2 == d2 && d1 < d2;
|
||||
}
|
||||
|
||||
public static boolean cmp_LE(double d1, Object val2)
|
||||
{
|
||||
double d2 = toNumber(val2);
|
||||
return d1 == d1 && d2 == d2 && d1 <= d2;
|
||||
}
|
||||
|
||||
public static boolean cmp_LE(Object val1, double d2)
|
||||
{
|
||||
double d1 = toNumber(val1);
|
||||
return d1 == d1 && d2 == d2 && d1 <= d2;
|
||||
}
|
||||
|
||||
public static Object callSimple(Context cx, String id, Scriptable scope,
|
||||
Object[] args)
|
||||
throws JavaScriptException
|
||||
|
|
Загрузка…
Ссылка в новой задаче