зеркало из https://github.com/mozilla/pjs.git
Removal of Token.PRIMARY: it was used in parser to group primary tokens such as false, true, null, this but since the semantic of them is very different it is simpler to create parse tree nodes directly from tokens and check only for node type, not for type and operation.
This commit is contained in:
Родитель
460a747fb7
Коммит
5447c67824
|
@ -129,8 +129,7 @@ public class FunctionNode extends ScriptOrFnNode {
|
|||
addVar(name);
|
||||
Node setFn = new Node(Token.POP,
|
||||
new Node(Token.SETVAR, Node.newString(name),
|
||||
new Node(Token.PRIMARY,
|
||||
Token.THISFN)));
|
||||
new Node(Token.THISFN)));
|
||||
stmts.addChildrenToFront(setFn);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class IRFactory {
|
|||
int lineno)
|
||||
{
|
||||
if (catchCond == null) {
|
||||
catchCond = new Node(Token.PRIMARY, Token.TRUE);
|
||||
catchCond = new Node(Token.TRUE);
|
||||
}
|
||||
return new Node(Token.CATCH, (Node)createName(varName),
|
||||
(Node)catchCond, (Node)stmts, lineno);
|
||||
|
@ -259,7 +259,7 @@ public class IRFactory {
|
|||
Node bodyTarget = new Node(Token.TARGET);
|
||||
Node condTarget = new Node(Token.TARGET);
|
||||
if (loopType == LOOP_FOR && cond.getType() == Token.VOID) {
|
||||
cond = new Node(Token.PRIMARY, Token.TRUE);
|
||||
cond = new Node(Token.TRUE);
|
||||
}
|
||||
Node IFEQ = new Node(Token.IFEQ, (Node)cond);
|
||||
IFEQ.putProp(Node.TARGET_PROP, bodyTarget);
|
||||
|
@ -346,7 +346,7 @@ public class IRFactory {
|
|||
Node temp = createNewTemp(next);
|
||||
Node cond = new Node(Token.EQOP, Token.NE);
|
||||
cond.addChildToBack(temp);
|
||||
cond.addChildToBack(new Node(Token.PRIMARY, Token.NULL));
|
||||
cond.addChildToBack(new Node(Token.NULL));
|
||||
Node newBody = new Node(Token.BLOCK);
|
||||
Node assign = (Node) createAssignment(Token.NOP, lvalue,
|
||||
createUseTemp(temp));
|
||||
|
@ -586,9 +586,7 @@ public class IRFactory {
|
|||
// altered in new Node constructor
|
||||
elem = cursor;
|
||||
cursor = cursor.getNext();
|
||||
if (elem.getType() == Token.PRIMARY &&
|
||||
elem.getOperation() == Token.UNDEFINED)
|
||||
{
|
||||
if (elem.getType() == Token.UNDEFINED) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
@ -613,10 +611,7 @@ public class IRFactory {
|
|||
* length explicitly, because we can't depend on SETELEM
|
||||
* to do it for us - because empty [,,] array elements
|
||||
* never set anything at all. */
|
||||
if (elem != null &&
|
||||
elem.getType() == Token.PRIMARY &&
|
||||
elem.getOperation() == Token.UNDEFINED)
|
||||
{
|
||||
if (elem != null && elem.getType() == Token.UNDEFINED) {
|
||||
Node setlength = new Node(Token.SETPROP,
|
||||
createUseTemp(temp),
|
||||
Node.newString("length"),
|
||||
|
@ -724,7 +719,7 @@ public class IRFactory {
|
|||
childNode.removeChild(left);
|
||||
childNode.removeChild(right);
|
||||
} else {
|
||||
return new Node(Token.PRIMARY, Token.TRUE);
|
||||
return new Node(Token.TRUE);
|
||||
}
|
||||
return new Node(nodeType, left, right);
|
||||
}
|
||||
|
|
|
@ -961,8 +961,13 @@ public class Interpreter
|
|||
break;
|
||||
}
|
||||
|
||||
case Token.PRIMARY:
|
||||
iCodeTop = addToken(node.getOperation(), iCodeTop);
|
||||
case Token.NULL:
|
||||
case Token.THIS:
|
||||
case Token.THISFN:
|
||||
case Token.FALSE:
|
||||
case Token.TRUE:
|
||||
case Token.UNDEFINED:
|
||||
iCodeTop = addToken(type, iCodeTop);
|
||||
itsStackDepth++;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
|
|
|
@ -444,7 +444,6 @@ public class Node implements Cloneable {
|
|||
case Token.EQOP:
|
||||
case Token.RELOP:
|
||||
case Token.UNARYOP:
|
||||
case Token.PRIMARY:
|
||||
return intDatum;
|
||||
}
|
||||
Context.codeBug();
|
||||
|
@ -456,7 +455,6 @@ public class Node implements Cloneable {
|
|||
case Token.EQOP:
|
||||
case Token.RELOP:
|
||||
case Token.UNARYOP:
|
||||
case Token.PRIMARY:
|
||||
Context.codeBug();
|
||||
}
|
||||
return intDatum;
|
||||
|
|
|
@ -386,8 +386,7 @@ public class NodeTransformer {
|
|||
bind.setType(Token.STRING);
|
||||
} else {
|
||||
// Local variables are by definition permanent
|
||||
Node n = new Node(Token.PRIMARY,
|
||||
Token.FALSE);
|
||||
Node n = new Node(Token.FALSE);
|
||||
iter.replaceCurrent(n);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1316,8 +1316,8 @@ class Parser {
|
|||
}
|
||||
|
||||
if (tt == Token.COMMA) {
|
||||
nf.addChildToBack(pn, nf.createLeaf(Token.PRIMARY,
|
||||
Token.UNDEFINED));
|
||||
nf.addChildToBack(pn,
|
||||
nf.createLeaf(Token.UNDEFINED));
|
||||
} else {
|
||||
nf.addChildToBack(pn, assignExpr(ts, false));
|
||||
}
|
||||
|
@ -1426,7 +1426,7 @@ class Parser {
|
|||
case Token.FALSE:
|
||||
case Token.TRUE:
|
||||
decompiler.addToken(tt);
|
||||
return nf.createLeaf(Token.PRIMARY, tt);
|
||||
return nf.createLeaf(tt);
|
||||
|
||||
case Token.RESERVED:
|
||||
reportError(ts, "msg.reserved.id");
|
||||
|
|
|
@ -204,24 +204,23 @@ public class Token
|
|||
EQOP = 106, // equality ops (== !=)
|
||||
RELOP = 107, // relational ops (< <= > >= in instanceof)
|
||||
UNARYOP = 108, // unary prefix operator
|
||||
PRIMARY = 109, // true, false, null, this
|
||||
|
||||
BLOCK = 110, // statement block
|
||||
ARRAYLIT = 111, // array literal
|
||||
OBJLIT = 112, // object literal
|
||||
LABEL = 113, // label
|
||||
TARGET = 114,
|
||||
LOOP = 115,
|
||||
ENUMDONE = 116,
|
||||
EXPRSTMT = 117,
|
||||
PARENT = 118,
|
||||
TONUMBER = 119,
|
||||
JSR = 120,
|
||||
NEWLOCAL = 121,
|
||||
USELOCAL = 122,
|
||||
SCRIPT = 123, // top-level node for entire script
|
||||
BLOCK = 109, // statement block
|
||||
ARRAYLIT = 110, // array literal
|
||||
OBJLIT = 111, // object literal
|
||||
LABEL = 112, // label
|
||||
TARGET = 113,
|
||||
LOOP = 114,
|
||||
ENUMDONE = 115,
|
||||
EXPRSTMT = 116,
|
||||
PARENT = 117,
|
||||
TONUMBER = 118,
|
||||
JSR = 119,
|
||||
NEWLOCAL = 120,
|
||||
USELOCAL = 121,
|
||||
SCRIPT = 122, // top-level node for entire script
|
||||
|
||||
LAST_TOKEN = 123;
|
||||
LAST_TOKEN = 122;
|
||||
|
||||
public static String name(int token)
|
||||
{
|
||||
|
@ -315,7 +314,6 @@ public class Token
|
|||
case INC: return "inc";
|
||||
case DEC: return "dec";
|
||||
case DOT: return "dot";
|
||||
case PRIMARY: return "primary";
|
||||
case FUNCTION: return "function";
|
||||
case EXPORT: return "export";
|
||||
case IMPORT: return "import";
|
||||
|
|
|
@ -547,9 +547,7 @@ public class Block {
|
|||
if (baseChild != null) {
|
||||
localCSE(n, baseChild, theCSETable, theFunction);
|
||||
}
|
||||
if (baseChild.getType() == Token.PRIMARY
|
||||
&& baseChild.getOperation() == Token.THIS)
|
||||
{
|
||||
if (baseChild.getType() == Token.THIS) {
|
||||
Node nameChild = baseChild.getNext();
|
||||
if (nameChild.getType() == Token.STRING) {
|
||||
String theName = nameChild.getString();
|
||||
|
|
|
@ -1077,8 +1077,30 @@ public class Codegen extends Interpreter {
|
|||
visitLiteral(node);
|
||||
break;
|
||||
|
||||
case Token.PRIMARY:
|
||||
visitPrimary(node);
|
||||
case Token.THIS:
|
||||
aload(thisObjLocal);
|
||||
break;
|
||||
|
||||
case Token.THISFN:
|
||||
classFile.add(ByteCode.ALOAD_0);
|
||||
break;
|
||||
|
||||
case Token.NULL:
|
||||
addByteCode(ByteCode.ACONST_NULL);
|
||||
break;
|
||||
|
||||
case Token.TRUE:
|
||||
classFile.add(ByteCode.GETSTATIC, "java/lang/Boolean",
|
||||
"TRUE", "Ljava/lang/Boolean;");
|
||||
break;
|
||||
|
||||
case Token.FALSE:
|
||||
classFile.add(ByteCode.GETSTATIC, "java/lang/Boolean",
|
||||
"FALSE", "Ljava/lang/Boolean;");
|
||||
break;
|
||||
|
||||
case Token.UNDEFINED:
|
||||
pushUndefined();
|
||||
break;
|
||||
|
||||
case Token.REGEXP:
|
||||
|
@ -2796,9 +2818,7 @@ public class Codegen extends Interpreter {
|
|||
Node rightChild = child.getNext();
|
||||
boolean isStrict = op == Token.SHEQ ||
|
||||
op == Token.SHNE;
|
||||
if (rightChild.getType() == Token.PRIMARY &&
|
||||
rightChild.getOperation() == Token.NULL)
|
||||
{
|
||||
if (rightChild.getType() == Token.NULL) {
|
||||
generateCodeFromNode(child, node);
|
||||
if (isStrict) {
|
||||
addByteCode(ByteCode.IFNULL, 9);
|
||||
|
@ -2869,9 +2889,7 @@ public class Codegen extends Interpreter {
|
|||
boolean isStrict = op == Token.SHEQ ||
|
||||
op == Token.SHNE;
|
||||
|
||||
if (rightChild.getType() == Token.PRIMARY &&
|
||||
rightChild.getOperation() == Token.NULL)
|
||||
{
|
||||
if (rightChild.getType() == Token.NULL) {
|
||||
if (op != Token.EQ && op != Token.SHEQ) {
|
||||
// invert true and false.
|
||||
int temp = trueGOTO;
|
||||
|
@ -3266,12 +3284,9 @@ public class Codegen extends Interpreter {
|
|||
generateCodeFromNode(child, node); // the object
|
||||
generateCodeFromNode(nameChild, node); // the name
|
||||
if (nameChild.getType() == Token.STRING) {
|
||||
if ((child.getType() == Token.PRIMARY
|
||||
&& child.getOperation() == Token.THIS)
|
||||
if ((child.getType() == Token.THIS)
|
||||
|| (child.getType() == Token.NEWTEMP
|
||||
&& child.getFirstChild().getType() == Token.PRIMARY
|
||||
&& child.getFirstChild().getOperation()
|
||||
== Token.THIS))
|
||||
&& child.getFirstChild().getType() == Token.THIS))
|
||||
{
|
||||
aload(variableObjectLocal);
|
||||
addOptRuntimeInvoke(
|
||||
|
|
|
@ -843,8 +843,7 @@ class Optimizer
|
|||
if (isLDefined == ALWAYS_FALSE_BOOLEAN) {
|
||||
// if the first one is false, replace with FALSE
|
||||
if (!IRFactory.hasSideEffects(rChild)) {
|
||||
replace = new Node(Token.PRIMARY,
|
||||
Token.FALSE);
|
||||
replace = new Node(Token.FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -852,8 +851,7 @@ class Optimizer
|
|||
if (isRDefined == ALWAYS_FALSE_BOOLEAN) {
|
||||
// if the second one is false, replace with FALSE
|
||||
if (!IRFactory.hasSideEffects(lChild)) {
|
||||
replace = new Node(Token.PRIMARY,
|
||||
Token.FALSE);
|
||||
replace = new Node(Token.FALSE);
|
||||
}
|
||||
}
|
||||
else if (isRDefined == ALWAYS_TRUE_BOOLEAN) {
|
||||
|
@ -873,8 +871,7 @@ class Optimizer
|
|||
if (isLDefined == ALWAYS_TRUE_BOOLEAN) {
|
||||
// if the first one is true, replace with TRUE
|
||||
if (!IRFactory.hasSideEffects(rChild)) {
|
||||
replace = new Node(Token.PRIMARY,
|
||||
Token.TRUE);
|
||||
replace = new Node(Token.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,8 +879,7 @@ class Optimizer
|
|||
if (isRDefined == ALWAYS_TRUE_BOOLEAN) {
|
||||
// if the second one is true, replace with TRUE
|
||||
if (!IRFactory.hasSideEffects(lChild)) {
|
||||
replace = new Node(Token.PRIMARY,
|
||||
Token.TRUE);
|
||||
replace = new Node(Token.TRUE);
|
||||
}
|
||||
}
|
||||
else if (isRDefined == ALWAYS_FALSE_BOOLEAN) {
|
||||
|
@ -935,37 +931,31 @@ class Optimizer
|
|||
}
|
||||
|
||||
// Check if Node always mean true or false in boolean context
|
||||
private static int isAlwaysDefinedBoolean(Node node) {
|
||||
int result = 0;
|
||||
int type = node.getType();
|
||||
if (type == Token.PRIMARY) {
|
||||
int id = node.getOperation();
|
||||
if (id == Token.FALSE || id == Token.NULL
|
||||
|| id == Token.UNDEFINED)
|
||||
private static int isAlwaysDefinedBoolean(Node node)
|
||||
{
|
||||
result = ALWAYS_FALSE_BOOLEAN;
|
||||
}
|
||||
else if (id == Token.TRUE) {
|
||||
result = ALWAYS_TRUE_BOOLEAN;
|
||||
}
|
||||
}
|
||||
else if (type == Token.NUMBER) {
|
||||
switch (node.getType()) {
|
||||
case Token.FALSE:
|
||||
case Token.NULL:
|
||||
case Token.UNDEFINED:
|
||||
return ALWAYS_FALSE_BOOLEAN;
|
||||
case Token.TRUE:
|
||||
return ALWAYS_TRUE_BOOLEAN;
|
||||
case Token.NUMBER:
|
||||
double num = node.getDouble();
|
||||
if (num == 0) {
|
||||
// Is it neccessary to check for -0.0 here?
|
||||
if (1 / num > 0) {
|
||||
result = ALWAYS_FALSE_BOOLEAN;
|
||||
return ALWAYS_FALSE_BOOLEAN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = ALWAYS_TRUE_BOOLEAN;
|
||||
return ALWAYS_TRUE_BOOLEAN;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void
|
||||
replaceVariableAccess(Node n, OptFunctionNode fn)
|
||||
private static void replaceVariableAccess(Node n, OptFunctionNode fn)
|
||||
{
|
||||
Node child = n.getFirstChild();
|
||||
while (child != null) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче