зеркало из https://github.com/mozilla/gecko-dev.git
Parser tree nodes of Token.CONVERT type are replaced by Token.TONUMBER and additional optimizer nodes to convert to double or object eliminating the need to distinguish them by Node.TYPE_PROPERTY.
This commit is contained in:
Родитель
8b0aa84272
Коммит
13865e4143
|
@ -768,7 +768,7 @@ public class IRFactory {
|
|||
: Token.SUB,
|
||||
childNode,
|
||||
rhs,
|
||||
ScriptRuntime.NumberClass,
|
||||
true,
|
||||
nodeOp == Token.POST);
|
||||
}
|
||||
|
||||
|
@ -813,18 +813,18 @@ public class IRFactory {
|
|||
public Object createAssignment(int assignOp, Object left, Object right)
|
||||
{
|
||||
return createAssignment(assignOp, (Node) left, (Node) right,
|
||||
null, false);
|
||||
false, false);
|
||||
}
|
||||
|
||||
private Node createAssignment(int assignOp, Node left, Node right,
|
||||
Class convert, boolean postfix)
|
||||
boolean tonumber, boolean postfix)
|
||||
{
|
||||
int nodeType = left.getType();
|
||||
String idString;
|
||||
Node id = null;
|
||||
switch (nodeType) {
|
||||
case Token.NAME:
|
||||
return createSetName(assignOp, left, right, convert, postfix);
|
||||
return createSetName(assignOp, left, right, tonumber, postfix);
|
||||
|
||||
case Token.GETPROP:
|
||||
idString = (String) left.getProp(Node.SPECIAL_PROP_PROP);
|
||||
|
@ -835,7 +835,7 @@ public class IRFactory {
|
|||
if (id == null)
|
||||
id = left.getLastChild();
|
||||
return createSetProp(nodeType, assignOp, left.getFirstChild(),
|
||||
id, right, convert, postfix);
|
||||
id, right, tonumber, postfix);
|
||||
default:
|
||||
// TODO: This should be a ReferenceError--but that's a runtime
|
||||
// exception. Should we compile an exception into the code?
|
||||
|
@ -844,16 +844,12 @@ public class IRFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private Node createConvert(Class toType, Node expr) {
|
||||
if (toType == null)
|
||||
return expr;
|
||||
Node result = new Node(Token.CONVERT, expr);
|
||||
result.putProp(Node.TYPE_PROP, ScriptRuntime.NumberClass);
|
||||
return result;
|
||||
private Node createToNumber(Node expr) {
|
||||
return new Node(Token.TONUMBER, expr);
|
||||
}
|
||||
|
||||
private Node createSetName(int assignOp, Node left, Node right,
|
||||
Class convert, boolean postfix)
|
||||
boolean tonumber, boolean postfix)
|
||||
{
|
||||
if (assignOp == Token.NOP) {
|
||||
left.setType(Token.BINDNAME);
|
||||
|
@ -869,8 +865,8 @@ public class IRFactory {
|
|||
}
|
||||
|
||||
Node opLeft = Node.newString(Token.NAME, s);
|
||||
if (convert != null)
|
||||
opLeft = createConvert(convert, opLeft);
|
||||
if (tonumber)
|
||||
opLeft = createToNumber(opLeft);
|
||||
if (postfix)
|
||||
opLeft = createNewTemp(opLeft);
|
||||
Node op = new Node(assignOp, opLeft, right);
|
||||
|
@ -948,7 +944,7 @@ public class IRFactory {
|
|||
}
|
||||
|
||||
private Node createSetProp(int nodeType, int assignOp, Node obj, Node id,
|
||||
Node expr, Class convert, boolean postfix)
|
||||
Node expr, boolean tonumber, boolean postfix)
|
||||
{
|
||||
int type = nodeType == Token.GETPROP
|
||||
? Token.SETPROP
|
||||
|
@ -993,8 +989,8 @@ public class IRFactory {
|
|||
opLeft = new Node(nodeType, obj, id);
|
||||
}
|
||||
|
||||
if (convert != null)
|
||||
opLeft = createConvert(convert, opLeft);
|
||||
if (tonumber)
|
||||
opLeft = createToNumber(opLeft);
|
||||
if (postfix)
|
||||
opLeft = createNewTemp(opLeft);
|
||||
Node op = new Node(assignOp, opLeft, expr);
|
||||
|
|
|
@ -600,16 +600,10 @@ public class Interpreter
|
|||
itsStackDepth--;
|
||||
break;
|
||||
|
||||
case Token.CONVERT : {
|
||||
case Token.TONUMBER:
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
Object toType = node.getProp(Node.TYPE_PROP);
|
||||
if (toType == ScriptRuntime.NumberClass) {
|
||||
iCodeTop = addToken(Token.POS, iCodeTop);
|
||||
} else {
|
||||
badTree(node);
|
||||
}
|
||||
iCodeTop = addToken(Token.POS, iCodeTop);
|
||||
break;
|
||||
}
|
||||
|
||||
case Token.UNARYOP :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
|
|
|
@ -291,10 +291,9 @@ public class Node implements Cloneable {
|
|||
CASES_PROP = 12,
|
||||
DEFAULT_PROP = 13,
|
||||
CASEARRAY_PROP = 14,
|
||||
TYPE_PROP = 15,
|
||||
SPECIAL_PROP_PROP = 16,
|
||||
LABEL_PROP = 17,
|
||||
FINALLY_PROP = 18,
|
||||
SPECIAL_PROP_PROP = 15,
|
||||
LABEL_PROP = 16,
|
||||
FINALLY_PROP = 17,
|
||||
/*
|
||||
the following properties are defined and manipulated by the
|
||||
optimizer -
|
||||
|
@ -309,13 +308,13 @@ public class Node implements Cloneable {
|
|||
matches.
|
||||
*/
|
||||
|
||||
TARGETBLOCK_PROP = 19,
|
||||
VARIABLE_PROP = 20,
|
||||
LASTUSE_PROP = 21,
|
||||
ISNUMBER_PROP = 22,
|
||||
DIRECTCALL_PROP = 23,
|
||||
TARGETBLOCK_PROP = 18,
|
||||
VARIABLE_PROP = 19,
|
||||
LASTUSE_PROP = 20,
|
||||
ISNUMBER_PROP = 21,
|
||||
DIRECTCALL_PROP = 22,
|
||||
|
||||
SPECIALCALL_PROP = 24;
|
||||
SPECIALCALL_PROP = 23;
|
||||
|
||||
public static final int // this value of the ISNUMBER_PROP specifies
|
||||
BOTH = 0, // which of the children are Number types
|
||||
|
@ -346,7 +345,6 @@ public class Node implements Cloneable {
|
|||
case CASES_PROP: return "cases";
|
||||
case DEFAULT_PROP: return "default";
|
||||
case CASEARRAY_PROP: return "casearray";
|
||||
case TYPE_PROP: return "type";
|
||||
case SPECIAL_PROP_PROP: return "special_prop";
|
||||
case LABEL_PROP: return "label";
|
||||
case FINALLY_PROP: return "finally";
|
||||
|
|
|
@ -215,7 +215,7 @@ public class Token
|
|||
ENUMDONE = 116,
|
||||
EXPRSTMT = 117,
|
||||
PARENT = 118,
|
||||
CONVERT = 119,
|
||||
TONUMBER = 119,
|
||||
JSR = 120,
|
||||
NEWLOCAL = 121,
|
||||
USELOCAL = 122,
|
||||
|
@ -347,7 +347,7 @@ public class Token
|
|||
case ENUMDONE: return "enumdone";
|
||||
case EXPRSTMT: return "exprstmt";
|
||||
case PARENT: return "parent";
|
||||
case CONVERT: return "convert";
|
||||
case TONUMBER: return "tonumber";
|
||||
case JSR: return "jsr";
|
||||
case NEWLOCAL: return "newlocal";
|
||||
case USELOCAL: return "uselocal";
|
||||
|
@ -355,6 +355,6 @@ public class Token
|
|||
}
|
||||
return "<unknown="+token+">";
|
||||
}
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1258,41 +1258,38 @@ public class Codegen extends Interpreter {
|
|||
visitBitOp(node, type, child);
|
||||
break;
|
||||
|
||||
case Token.CONVERT: {
|
||||
Object toType = node.getProp(Node.TYPE_PROP);
|
||||
if (toType == ScriptRuntime.NumberClass) {
|
||||
addByteCode(ByteCode.NEW, "java/lang/Double");
|
||||
addByteCode(ByteCode.DUP);
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("toNumber",
|
||||
"(Ljava/lang/Object;)D");
|
||||
addDoubleConstructor();
|
||||
} else if (toType == ScriptRuntime.DoubleClass) {
|
||||
// cnvt to double (not Double)
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("toNumber",
|
||||
"(Ljava/lang/Object;)D");
|
||||
} else if (toType == ScriptRuntime.ObjectClass) {
|
||||
// convert from double
|
||||
int prop = -1;
|
||||
if (child.getType() == Token.NUMBER) {
|
||||
prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
|
||||
}
|
||||
if (prop != -1) {
|
||||
child.removeProp(Node.ISNUMBER_PROP);
|
||||
generateCodeFromNode(child, node);
|
||||
child.putIntProp(Node.ISNUMBER_PROP, prop);
|
||||
} else {
|
||||
addByteCode(ByteCode.NEW, "java/lang/Double");
|
||||
addByteCode(ByteCode.DUP);
|
||||
generateCodeFromNode(child, node);
|
||||
addDoubleConstructor();
|
||||
}
|
||||
} else {
|
||||
badTree();
|
||||
}
|
||||
case Token.TONUMBER:
|
||||
addByteCode(ByteCode.NEW, "java/lang/Double");
|
||||
addByteCode(ByteCode.DUP);
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
|
||||
addDoubleConstructor();
|
||||
break;
|
||||
|
||||
case Optimizer.TO_DOUBLE:
|
||||
// cnvt to double (not Double)
|
||||
generateCodeFromNode(child, node);
|
||||
addScriptRuntimeInvoke("toNumber", "(Ljava/lang/Object;)D");
|
||||
break;
|
||||
|
||||
case Optimizer.TO_OBJECT: {
|
||||
// convert from double
|
||||
int prop = -1;
|
||||
if (child.getType() == Token.NUMBER) {
|
||||
prop = child.getIntProp(Node.ISNUMBER_PROP, -1);
|
||||
}
|
||||
if (prop != -1) {
|
||||
child.removeProp(Node.ISNUMBER_PROP);
|
||||
generateCodeFromNode(child, node);
|
||||
child.putIntProp(Node.ISNUMBER_PROP, prop);
|
||||
} else {
|
||||
addByteCode(ByteCode.NEW, "java/lang/Double");
|
||||
addByteCode(ByteCode.DUP);
|
||||
generateCodeFromNode(child, node);
|
||||
addDoubleConstructor();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Token.RELOP:
|
||||
// need a result Object
|
||||
|
@ -2784,12 +2781,10 @@ public class Codegen extends Interpreter {
|
|||
|
||||
private Node getConvertToObjectOfNumberNode(Node node)
|
||||
{
|
||||
if (node.getType() == Token.CONVERT) {
|
||||
Object toType = node.getProp(Node.TYPE_PROP);
|
||||
if (toType == ScriptRuntime.ObjectClass) {
|
||||
Node convertChild = node.getFirstChild();
|
||||
if (convertChild.getType() == Token.NUMBER)
|
||||
return convertChild;
|
||||
if (node.getType() == Optimizer.TO_OBJECT) {
|
||||
Node convertChild = node.getFirstChild();
|
||||
if (convertChild.getType() == Token.NUMBER) {
|
||||
return convertChild;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -47,12 +47,16 @@ import java.io.IOException;
|
|||
|
||||
import java.util.Hashtable;
|
||||
|
||||
class Optimizer {
|
||||
class Optimizer
|
||||
{
|
||||
|
||||
static final int NoType = 0;
|
||||
static final int NumberType = 1;
|
||||
static final int AnyType = 3;
|
||||
|
||||
static final int TO_OBJECT = Token.LAST_TOKEN + 1;
|
||||
static final int TO_DOUBLE = Token.LAST_TOKEN + 2;
|
||||
|
||||
// It is assumed that (NumberType | AnyType) == AnyType
|
||||
|
||||
Optimizer(IRFactory irFactory) {
|
||||
|
@ -426,11 +430,7 @@ class Optimizer {
|
|||
if ((theVar != null) && theVar.isNumber()) {
|
||||
if (rType != NumberType) {
|
||||
n.removeChild(rChild);
|
||||
Node newRChild = new Node(Token.CONVERT,
|
||||
rChild);
|
||||
newRChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.DoubleClass);
|
||||
n.addChildToBack(newRChild);
|
||||
n.addChildToBack(new Node(TO_DOUBLE, rChild));
|
||||
}
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
|
||||
markDCPNumberContext(rChild);
|
||||
|
@ -440,10 +440,8 @@ class Optimizer {
|
|||
if (rType == NumberType) {
|
||||
if (!convertParameter(rChild)) {
|
||||
n.removeChild(rChild);
|
||||
Node newRChild = new Node(Token.CONVERT, rChild);
|
||||
newRChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToBack(newRChild);
|
||||
n.addChildToBack(new Node(TO_OBJECT,
|
||||
rChild));
|
||||
}
|
||||
}
|
||||
return NoType;
|
||||
|
@ -463,19 +461,13 @@ class Optimizer {
|
|||
if (lType == NumberType) {
|
||||
if (!convertParameter(lChild)) {
|
||||
n.removeChild(lChild);
|
||||
Node nuChild = new Node(Token.CONVERT, lChild);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToFront(nuChild);
|
||||
n.addChildToFront(new Node(TO_OBJECT, lChild));
|
||||
}
|
||||
}
|
||||
if (rType == NumberType) {
|
||||
if (!convertParameter(rChild)) {
|
||||
n.removeChild(rChild);
|
||||
Node nuChild = new Node(Token.CONVERT, rChild);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToBack(nuChild);
|
||||
n.addChildToBack(new Node(TO_OBJECT, rChild));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -589,10 +581,7 @@ class Optimizer {
|
|||
else {
|
||||
if (!convertParameter(rChild)) {
|
||||
n.removeChild(rChild);
|
||||
Node newRChild = new Node(Token.CONVERT, rChild);
|
||||
newRChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.DoubleClass);
|
||||
n.addChildToBack(newRChild);
|
||||
n.addChildToBack(new Node(TO_DOUBLE, rChild));
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
|
||||
}
|
||||
return NumberType;
|
||||
|
@ -602,10 +591,7 @@ class Optimizer {
|
|||
if (rType == NumberType) {
|
||||
if (!convertParameter(lChild)) {
|
||||
n.removeChild(lChild);
|
||||
Node newLChild = new Node(Token.CONVERT, lChild);
|
||||
newLChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.DoubleClass);
|
||||
n.addChildToFront(newLChild);
|
||||
n.addChildToFront(new Node(TO_DOUBLE, lChild));
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
|
||||
}
|
||||
return NumberType;
|
||||
|
@ -613,17 +599,11 @@ class Optimizer {
|
|||
else {
|
||||
if (!convertParameter(lChild)) {
|
||||
n.removeChild(lChild);
|
||||
Node newLChild = new Node(Token.CONVERT, lChild);
|
||||
newLChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.DoubleClass);
|
||||
n.addChildToFront(newLChild);
|
||||
n.addChildToFront(new Node(TO_DOUBLE, lChild));
|
||||
}
|
||||
if (!convertParameter(rChild)) {
|
||||
n.removeChild(rChild);
|
||||
Node newRChild = new Node(Token.CONVERT, rChild);
|
||||
newRChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.DoubleClass);
|
||||
n.addChildToBack(newRChild);
|
||||
n.addChildToBack(new Node(TO_DOUBLE, rChild));
|
||||
}
|
||||
n.putIntProp(Node.ISNUMBER_PROP, Node.BOTH);
|
||||
return NumberType;
|
||||
|
@ -638,10 +618,7 @@ class Optimizer {
|
|||
if (baseType == NumberType) {// can never happen ???
|
||||
if (!convertParameter(arrayBase)) {
|
||||
n.removeChild(arrayBase);
|
||||
Node nuChild = new Node(Token.CONVERT, arrayBase);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToFront(nuChild);
|
||||
n.addChildToFront(new Node(TO_OBJECT, arrayBase));
|
||||
}
|
||||
}
|
||||
int indexType = rewriteForNumberVariables(arrayIndex);
|
||||
|
@ -656,10 +633,7 @@ class Optimizer {
|
|||
if (rValueType == NumberType) {
|
||||
if (!convertParameter(rValue)) {
|
||||
n.removeChild(rValue);
|
||||
Node nuChild = new Node(Token.CONVERT, rValue);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToBack(nuChild);
|
||||
n.addChildToBack(new Node(TO_OBJECT, rValue));
|
||||
}
|
||||
}
|
||||
return NoType;
|
||||
|
@ -671,10 +645,7 @@ class Optimizer {
|
|||
if (baseType == NumberType) {// can never happen ???
|
||||
if (!convertParameter(arrayBase)) {
|
||||
n.removeChild(arrayBase);
|
||||
Node nuChild = new Node(Token.CONVERT, arrayBase);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
n.addChildToFront(nuChild);
|
||||
n.addChildToFront(new Node(TO_OBJECT, arrayBase));
|
||||
}
|
||||
}
|
||||
int indexType = rewriteForNumberVariables(arrayIndex);
|
||||
|
@ -721,9 +692,7 @@ class Optimizer {
|
|||
if (type == NumberType) {
|
||||
if (!convertParameter(child)) {
|
||||
n.removeChild(child);
|
||||
Node nuChild = new Node(Token.CONVERT, child);
|
||||
nuChild.putProp(Node.TYPE_PROP,
|
||||
ScriptRuntime.ObjectClass);
|
||||
Node nuChild = new Node(TO_OBJECT, child);
|
||||
if (nextChild == null)
|
||||
n.addChildToBack(nuChild);
|
||||
else
|
||||
|
|
Загрузка…
Ссылка в новой задаче