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:
igor%mir2.org 2004-04-18 14:53:34 +00:00
Родитель 719bb92768
Коммит 09018e0533
2 изменённых файлов: 24 добавлений и 77 удалений

Просмотреть файл

@ -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