Store line number and operation type as int field instead of wrapping them into Integer; use Node subclass for nodes with string data; add few explicit checks about node structure assumptions.
git-svn-id: svn://10.0.0.236/trunk@128822 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
f13c73a6c4
commit
cf6e89d89b
@ -38,7 +38,7 @@ package org.mozilla.javascript;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class FunctionNode extends Node {
|
||||
public class FunctionNode extends Node.StringNode {
|
||||
|
||||
public FunctionNode(String name, Node left, Node right) {
|
||||
super(TokenStream.FUNCTION, left, right, name);
|
||||
@ -46,7 +46,7 @@ public class FunctionNode extends Node {
|
||||
}
|
||||
|
||||
public String getFunctionName() {
|
||||
return getString();
|
||||
return str;
|
||||
}
|
||||
|
||||
public VariableTable getVariableTable() {
|
||||
|
||||
@ -55,7 +55,7 @@ public class IRFactory {
|
||||
public Object createScript(Object body, String sourceName,
|
||||
int baseLineno, int endLineno, Object source)
|
||||
{
|
||||
Node result = new Node(TokenStream.SCRIPT, sourceName);
|
||||
Node result = Node.newString(TokenStream.SCRIPT, sourceName);
|
||||
Node children = ((Node) body).getFirstChild();
|
||||
if (children != null)
|
||||
result.addChildrenToBack(children);
|
||||
@ -74,10 +74,6 @@ public class IRFactory {
|
||||
return new Node(nodeType);
|
||||
}
|
||||
|
||||
public Object createLeaf(int nodeType, String id) {
|
||||
return new Node(nodeType, id);
|
||||
}
|
||||
|
||||
public Object createLeaf(int nodeType, int nodeOp) {
|
||||
return new Node(nodeType, nodeOp);
|
||||
}
|
||||
@ -107,14 +103,14 @@ public class IRFactory {
|
||||
* Name
|
||||
*/
|
||||
public Object createName(String name) {
|
||||
return new Node(TokenStream.NAME, name);
|
||||
return Node.newString(TokenStream.NAME, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* String (for literals)
|
||||
*/
|
||||
public Object createString(String string) {
|
||||
return new Node(TokenStream.STRING, string);
|
||||
return Node.newString(string);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,12 +131,11 @@ public class IRFactory {
|
||||
public Object createCatch(String varName, Object catchCond, Object stmts,
|
||||
int lineno)
|
||||
{
|
||||
if (catchCond == null)
|
||||
if (catchCond == null) {
|
||||
catchCond = new Node(TokenStream.PRIMARY, TokenStream.TRUE);
|
||||
Node result = new Node(TokenStream.CATCH, (Node)createName(varName),
|
||||
(Node)catchCond, (Node)stmts);
|
||||
result.setDatum(new Integer(lineno));
|
||||
return result;
|
||||
}
|
||||
return new Node(TokenStream.CATCH, (Node)createName(varName),
|
||||
(Node)catchCond, (Node)stmts, lineno);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +159,7 @@ public class IRFactory {
|
||||
*/
|
||||
public Object createLabel(String label, int lineno) {
|
||||
Node result = new Node(TokenStream.LABEL, lineno);
|
||||
Node name = new Node(TokenStream.NAME, label);
|
||||
Node name = Node.newString(TokenStream.NAME, label);
|
||||
result.addChildToBack(name);
|
||||
return result;
|
||||
}
|
||||
@ -177,7 +172,7 @@ public class IRFactory {
|
||||
if (label == null) {
|
||||
return result;
|
||||
} else {
|
||||
Node name = new Node(TokenStream.NAME, label);
|
||||
Node name = Node.newString(TokenStream.NAME, label);
|
||||
result.addChildToBack(name);
|
||||
return result;
|
||||
}
|
||||
@ -191,7 +186,7 @@ public class IRFactory {
|
||||
if (label == null) {
|
||||
return result;
|
||||
} else {
|
||||
Node name = new Node(TokenStream.NAME, label);
|
||||
Node name = Node.newString(TokenStream.NAME, label);
|
||||
result.addChildToBack(name);
|
||||
return result;
|
||||
}
|
||||
@ -228,7 +223,7 @@ public class IRFactory {
|
||||
f.putIntProp(Node.END_LINENO_PROP, endLineno);
|
||||
if (source != null)
|
||||
f.putProp(Node.SOURCE_PROP, source);
|
||||
Node result = new Node(TokenStream.FUNCTION, name);
|
||||
Node result = Node.newString(TokenStream.FUNCTION, name);
|
||||
result.putProp(Node.FUNCTION_PROP, f);
|
||||
return result;
|
||||
}
|
||||
@ -340,7 +335,7 @@ public class IRFactory {
|
||||
if (lhsNode.getFirstChild() != lastChild) {
|
||||
reportError("msg.mult.index");
|
||||
}
|
||||
lvalue = new Node(TokenStream.NAME, lastChild.getString());
|
||||
lvalue = Node.newString(TokenStream.NAME, lastChild.getString());
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -483,7 +478,7 @@ public class IRFactory {
|
||||
Node cb = catchNodes.getFirstChild();
|
||||
while (cb != null) {
|
||||
Node catchStmt = new Node(TokenStream.BLOCK);
|
||||
int catchLineNo = cb.getInt();
|
||||
int catchLineNo = cb.getLineno();
|
||||
|
||||
Node name = cb.getFirstChild();
|
||||
Node cond = name.getNextSibling();
|
||||
@ -494,7 +489,7 @@ public class IRFactory {
|
||||
|
||||
Node newScope = createNewLocal(new Node(TokenStream.NEWSCOPE));
|
||||
Node initScope = new Node(TokenStream.SETPROP, newScope,
|
||||
new Node(TokenStream.STRING,
|
||||
Node.newString(
|
||||
name.getString()),
|
||||
createUseLocal(exn));
|
||||
catchStmt.addChildToBack(new Node(TokenStream.POP, initScope));
|
||||
@ -578,7 +573,7 @@ public class IRFactory {
|
||||
Node array;
|
||||
Node result;
|
||||
array = result = new Node(TokenStream.NEW,
|
||||
new Node(TokenStream.NAME, "Array"));
|
||||
Node.newString(TokenStream.NAME, "Array"));
|
||||
Node temp = createNewTemp(result);
|
||||
result = temp;
|
||||
|
||||
@ -590,7 +585,7 @@ public class IRFactory {
|
||||
elem = cursor;
|
||||
cursor = cursor.getNextSibling();
|
||||
if (elem.getType() == TokenStream.PRIMARY &&
|
||||
elem.getInt() == TokenStream.UNDEFINED)
|
||||
elem.getOperation() == TokenStream.UNDEFINED)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
@ -618,11 +613,11 @@ public class IRFactory {
|
||||
* never set anything at all. */
|
||||
if (elem != null &&
|
||||
elem.getType() == TokenStream.PRIMARY &&
|
||||
elem.getInt() == TokenStream.UNDEFINED)
|
||||
elem.getOperation() == TokenStream.UNDEFINED)
|
||||
{
|
||||
Node setlength = new Node(TokenStream.SETPROP,
|
||||
createUseTemp(temp),
|
||||
new Node(TokenStream.STRING,
|
||||
Node.newString(
|
||||
"length"),
|
||||
Node.newNumber(i));
|
||||
result = new Node(TokenStream.COMMA, result, setlength);
|
||||
@ -640,7 +635,7 @@ public class IRFactory {
|
||||
* stages don't need to know about object literals.
|
||||
*/
|
||||
public Object createObjectLiteral(Object obj) {
|
||||
Node result = new Node(TokenStream.NEW, new Node(TokenStream.NAME,
|
||||
Node result = new Node(TokenStream.NEW, Node.newString(TokenStream.NAME,
|
||||
"Object"));
|
||||
Node temp = createNewTemp(result);
|
||||
result = temp;
|
||||
@ -666,10 +661,10 @@ public class IRFactory {
|
||||
public Object createRegExp(String string, String flags) {
|
||||
return flags.length() == 0
|
||||
? new Node(TokenStream.REGEXP,
|
||||
new Node(TokenStream.STRING, string))
|
||||
Node.newString(string))
|
||||
: new Node(TokenStream.REGEXP,
|
||||
new Node(TokenStream.STRING, string),
|
||||
new Node(TokenStream.STRING, flags));
|
||||
Node.newString(string),
|
||||
Node.newString(flags));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -816,8 +811,7 @@ public class IRFactory {
|
||||
return createAssignment(nodeOp, (Node) left, (Node) right,
|
||||
null, false);
|
||||
}
|
||||
return new Node(nodeType, (Node) left, (Node) right,
|
||||
new Integer(nodeOp));
|
||||
return new Node(nodeType, (Node) left, (Node) right, nodeOp);
|
||||
}
|
||||
|
||||
public Object createAssignment(int nodeOp, Node left, Node right,
|
||||
@ -833,7 +827,7 @@ public class IRFactory {
|
||||
case TokenStream.GETPROP:
|
||||
idString = (String) left.getProp(Node.SPECIAL_PROP_PROP);
|
||||
if (idString != null)
|
||||
id = new Node(TokenStream.STRING, idString);
|
||||
id = Node.newString(idString);
|
||||
/* fall through */
|
||||
case TokenStream.GETELEM:
|
||||
if (id == null)
|
||||
@ -872,14 +866,14 @@ public class IRFactory {
|
||||
return result;
|
||||
}
|
||||
|
||||
Node opLeft = new Node(TokenStream.NAME, s);
|
||||
Node opLeft = Node.newString(TokenStream.NAME, s);
|
||||
if (convert != null)
|
||||
opLeft = createConvert(convert, opLeft);
|
||||
if (postfix)
|
||||
opLeft = createNewTemp(opLeft);
|
||||
Node op = new Node(nodeOp, opLeft, right);
|
||||
|
||||
Node lvalueLeft = new Node(TokenStream.BINDNAME, s);
|
||||
Node lvalueLeft = Node.newString(TokenStream.BINDNAME, s);
|
||||
Node result = new Node(TokenStream.SETNAME, lvalueLeft, op);
|
||||
if (postfix) {
|
||||
result = new Node(TokenStream.COMMA, result,
|
||||
@ -958,12 +952,9 @@ public class IRFactory {
|
||||
? TokenStream.SETPROP
|
||||
: TokenStream.SETELEM;
|
||||
|
||||
Object datum = id.getDatum();
|
||||
if (type == TokenStream.SETPROP && datum != null &&
|
||||
datum instanceof String)
|
||||
{
|
||||
String s = (String) datum;
|
||||
if (s.equals("__proto__") || s.equals("__parent__")) {
|
||||
if (type == TokenStream.SETPROP) {
|
||||
String s = id.getString();
|
||||
if (s != null && s.equals("__proto__") || s.equals("__parent__")) {
|
||||
Node result = new Node(type, obj, expr);
|
||||
result.putProp(Node.SPECIAL_PROP_PROP, s);
|
||||
return result;
|
||||
|
||||
@ -249,10 +249,7 @@ public class Interpreter {
|
||||
}
|
||||
|
||||
private int updateLineNumber(Node node, int iCodeTop) {
|
||||
Object datum = node.getDatum();
|
||||
if (datum == null || !(datum instanceof Number))
|
||||
return iCodeTop;
|
||||
int lineno = ((Number) datum).intValue();
|
||||
int lineno = node.getLineno();
|
||||
if (lineno != itsLineNumber && lineno >= 0) {
|
||||
itsLineNumber = lineno;
|
||||
iCodeTop = addByte(LINE_ICODE, iCodeTop);
|
||||
@ -391,7 +388,7 @@ public class Interpreter {
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
child = child.getNextSibling();
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
if (version == Context.VERSION_1_2) {
|
||||
if (op == TokenStream.EQ)
|
||||
op = TokenStream.SHEQ;
|
||||
@ -602,7 +599,7 @@ public class Interpreter {
|
||||
|
||||
case TokenStream.UNARYOP :
|
||||
iCodeTop = generateICode(child, iCodeTop);
|
||||
switch (node.getInt()) {
|
||||
switch (node.getOperation()) {
|
||||
case TokenStream.VOID :
|
||||
iCodeTop = addByte(TokenStream.POP, iCodeTop);
|
||||
iCodeTop = addByte(TokenStream.UNDEFINED, iCodeTop);
|
||||
@ -982,7 +979,7 @@ public class Interpreter {
|
||||
break;
|
||||
|
||||
case TokenStream.PRIMARY:
|
||||
iCodeTop = addByte(node.getInt(), iCodeTop);
|
||||
iCodeTop = addByte(node.getOperation(), iCodeTop);
|
||||
itsStackDepth++;
|
||||
if (itsStackDepth > itsData.itsMaxStack)
|
||||
itsData.itsMaxStack = itsStackDepth;
|
||||
|
||||
@ -56,6 +56,21 @@ public class Node implements Cloneable {
|
||||
double number;
|
||||
}
|
||||
|
||||
static class StringNode extends Node {
|
||||
|
||||
StringNode(int type, String str) {
|
||||
super(type);
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
StringNode(int nodeType, Node left, Node right, String str) {
|
||||
super(nodeType, left, right);
|
||||
this.str = str;
|
||||
}
|
||||
|
||||
String str;
|
||||
}
|
||||
|
||||
public Node(int nodeType) {
|
||||
type = nodeType;
|
||||
}
|
||||
@ -85,33 +100,36 @@ public class Node implements Cloneable {
|
||||
|
||||
public Node(int nodeType, int value) {
|
||||
type = nodeType;
|
||||
this.datum = new Integer(value);
|
||||
}
|
||||
|
||||
public Node(int nodeType, String str) {
|
||||
type = nodeType;
|
||||
this.datum = str;
|
||||
intDatum = value;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node child, int value) {
|
||||
this(nodeType, child);
|
||||
this.datum = new Integer(value);
|
||||
intDatum = value;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node child, Object datum) {
|
||||
this(nodeType, child);
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node left, Node right, Object datum) {
|
||||
public Node(int nodeType, Node left, Node right, int value) {
|
||||
this(nodeType, left, right);
|
||||
this.datum = datum;
|
||||
intDatum = value;
|
||||
}
|
||||
|
||||
public Node(int nodeType, Node left, Node mid, Node right, int value) {
|
||||
this(nodeType, left, mid, right);
|
||||
intDatum = value;
|
||||
}
|
||||
|
||||
public static Node newNumber(double number) {
|
||||
return new NumberNode(number);
|
||||
}
|
||||
|
||||
public static Node newString(String str) {
|
||||
return new StringNode(TokenStream.STRING, str);
|
||||
}
|
||||
|
||||
public static Node newString(int type, String str) {
|
||||
return new StringNode(type, str);
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
@ -396,20 +414,27 @@ public class Node implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
public Object getDatum() {
|
||||
return datum;
|
||||
public int getOperation() {
|
||||
switch (type) {
|
||||
case TokenStream.EQOP:
|
||||
case TokenStream.RELOP:
|
||||
case TokenStream.UNARYOP:
|
||||
case TokenStream.PRIMARY:
|
||||
return intDatum;
|
||||
}
|
||||
Context.codeBug();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setDatum(Object datum) {
|
||||
this.datum = datum;
|
||||
}
|
||||
|
||||
public Number getNumber() {
|
||||
return (Number)datum;
|
||||
}
|
||||
|
||||
public int getInt() {
|
||||
return ((Number) datum).intValue();
|
||||
public int getLineno() {
|
||||
switch (type) {
|
||||
case TokenStream.EQOP:
|
||||
case TokenStream.RELOP:
|
||||
case TokenStream.UNARYOP:
|
||||
case TokenStream.PRIMARY:
|
||||
Context.codeBug();
|
||||
}
|
||||
return intDatum;
|
||||
}
|
||||
|
||||
/** Can only be called when <tt>getType() == TokenStream.NUMBER</tt> */
|
||||
@ -417,8 +442,9 @@ public class Node implements Cloneable {
|
||||
return ((NumberNode)this).number;
|
||||
}
|
||||
|
||||
/** Can only be called when <tt>this instanceof StringNode</tt> */
|
||||
public String getString() {
|
||||
return (String) datum;
|
||||
return ((StringNode)this).str;
|
||||
}
|
||||
|
||||
public Node cloneNode() {
|
||||
@ -438,16 +464,30 @@ public class Node implements Cloneable {
|
||||
public String toString() {
|
||||
if (Context.printTrees) {
|
||||
StringBuffer sb = new StringBuffer(TokenStream.tokenToName(type));
|
||||
if (type == TokenStream.TARGET) {
|
||||
sb.append(' ');
|
||||
sb.append(hashCode());
|
||||
} else if (type == TokenStream.NUMBER) {
|
||||
sb.append(' ');
|
||||
sb.append(getDouble());
|
||||
if (this instanceof StringNode) {
|
||||
sb.append(' ');
|
||||
sb.append(getString());
|
||||
|
||||
} else {
|
||||
switch (type) {
|
||||
case TokenStream.TARGET:
|
||||
sb.append(' ');
|
||||
sb.append(hashCode());
|
||||
break;
|
||||
case TokenStream.NUMBER:
|
||||
sb.append(' ');
|
||||
sb.append(getDouble());
|
||||
break;
|
||||
case TokenStream.FUNCTION:
|
||||
FunctionNode fn = (FunctionNode)this;
|
||||
sb.append(' ');
|
||||
sb.append(fn.getFunctionName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (datum != null) {
|
||||
if (intDatum != -1) {
|
||||
sb.append(' ');
|
||||
sb.append(datum.toString());
|
||||
sb.append(intDatum);
|
||||
}
|
||||
if (props == null)
|
||||
return sb.toString();
|
||||
@ -523,7 +563,7 @@ public class Node implements Cloneable {
|
||||
protected Node next; // next sibling
|
||||
protected Node first; // first element of a linked list of children
|
||||
protected Node last; // last element of a linked list of children
|
||||
private Object datum; // encapsulated data; depends on type
|
||||
private int intDatum = -1; // encapsulated int data; depends on type
|
||||
private UintMap props;
|
||||
}
|
||||
|
||||
|
||||
@ -416,7 +416,7 @@ public class NodeTransformer {
|
||||
Node asn = (Node) irFactory.createAssignment(
|
||||
TokenStream.NOP, n, init, null,
|
||||
false);
|
||||
Node pop = new Node(TokenStream.POP, asn, node.getDatum());
|
||||
Node pop = new Node(TokenStream.POP, asn, node.getLineno());
|
||||
result.addChildToBack(pop);
|
||||
}
|
||||
iterator.replaceCurrent(result);
|
||||
@ -525,24 +525,26 @@ public class NodeTransformer {
|
||||
vars.addLocal(name, createVariableObject(name, false));
|
||||
}
|
||||
}
|
||||
String name = tree.getString();
|
||||
if (inFunction && ((FunctionNode) tree).getFunctionType() ==
|
||||
FunctionNode.FUNCTION_EXPRESSION &&
|
||||
name != null && name.length() > 0 && vars.hasVariable(name))
|
||||
{
|
||||
// A function expression needs to have its name as a variable
|
||||
// (if it isn't already allocated as a variable). See
|
||||
// ECMA Ch. 13. We add code to the beginning of the function
|
||||
// to initialize a local variable of the function's name
|
||||
// to the function value.
|
||||
vars.addLocal(name, createVariableObject(name, false));
|
||||
Node block = tree.getLastChild();
|
||||
Node setFn = new Node(TokenStream.POP,
|
||||
new Node(TokenStream.SETVAR,
|
||||
new Node(TokenStream.STRING, name),
|
||||
new Node(TokenStream.PRIMARY,
|
||||
TokenStream.THISFN)));
|
||||
block.addChildrenToFront(setFn);
|
||||
if (inFunction) {
|
||||
FunctionNode fn = (FunctionNode)tree;
|
||||
String name = fn.getFunctionName();
|
||||
if (fn.getFunctionType() == FunctionNode.FUNCTION_EXPRESSION
|
||||
&& name != null && name.length() > 0 && vars.hasVariable(name))
|
||||
{
|
||||
// A function expression needs to have its name as a variable
|
||||
// (if it isn't already allocated as a variable). See
|
||||
// ECMA Ch. 13. We add code to the beginning of the function
|
||||
// to initialize a local variable of the function's name
|
||||
// to the function value.
|
||||
vars.addLocal(name, createVariableObject(name, false));
|
||||
Node block = tree.getLastChild();
|
||||
Node setFn = new Node(TokenStream.POP,
|
||||
new Node(TokenStream.SETVAR,
|
||||
Node.newString(name),
|
||||
new Node(TokenStream.PRIMARY,
|
||||
TokenStream.THISFN)));
|
||||
block.addChildrenToFront(setFn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,10 +704,7 @@ public class NodeTransformer {
|
||||
Node tree, boolean isError,
|
||||
Scriptable scope)
|
||||
{
|
||||
Object obj = stmt.getDatum();
|
||||
int lineno = 0;
|
||||
if (obj != null && obj instanceof Integer)
|
||||
lineno = ((Integer) obj).intValue();
|
||||
int lineno = stmt.getLineno();
|
||||
Object prop = tree == null
|
||||
? null
|
||||
: tree.getProp(Node.SOURCENAME_PROP);
|
||||
|
||||
@ -538,9 +538,12 @@ public class Block {
|
||||
break;
|
||||
case TokenStream.GETPROP : {
|
||||
Node baseChild = n.getFirstChild();
|
||||
if (baseChild != null) localCSE(n, baseChild, theCSETable, theFunction);
|
||||
if ((baseChild.getType() == TokenStream.PRIMARY)
|
||||
&& (baseChild.getInt() == TokenStream.THIS)) {
|
||||
if (baseChild != null) {
|
||||
localCSE(n, baseChild, theCSETable, theFunction);
|
||||
}
|
||||
if (baseChild.getType() == TokenStream.PRIMARY
|
||||
&& baseChild.getOperation() == TokenStream.THIS)
|
||||
{
|
||||
Node nameChild = baseChild.getNextSibling();
|
||||
if (nameChild.getType() == TokenStream.STRING) {
|
||||
String theName = nameChild.getString();
|
||||
|
||||
@ -721,14 +721,9 @@ public class Codegen extends Interpreter {
|
||||
else {
|
||||
int interLabel = acquireLabel();
|
||||
if (type == TokenStream.AND) {
|
||||
generateCodeFromNode(child, node, interLabel, falseLabel);
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
generateCodeFromNode(child, node, interLabel,
|
||||
falseLabel);
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
addByteCode(ByteCode.IFNE, interLabel);
|
||||
@ -737,13 +732,7 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
else {
|
||||
generateCodeFromNode(child, node, trueLabel, interLabel);
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
addByteCode(ByteCode.IFNE, trueLabel);
|
||||
@ -753,13 +742,7 @@ public class Codegen extends Interpreter {
|
||||
markLabel(interLabel);
|
||||
child = child.getNextSibling();
|
||||
generateCodeFromNode(child, node, trueLabel, falseLabel);
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
addByteCode(ByteCode.IFNE, trueLabel);
|
||||
@ -1308,7 +1291,7 @@ public class Codegen extends Interpreter {
|
||||
addByteCode(ByteCode.DUP); // make another reference to the array
|
||||
push(i); // to set up for aastore at end of loop
|
||||
|
||||
Node def = (Node) fns.get(i);
|
||||
FunctionNode def = (FunctionNode) fns.get(i);
|
||||
Codegen codegen = new Codegen();
|
||||
String fnClassName = codegen.generateCode(def, namesVector,
|
||||
classFilesVector,
|
||||
@ -1335,7 +1318,7 @@ public class Codegen extends Interpreter {
|
||||
aload(variableObjectLocal);
|
||||
}
|
||||
// load 'fnName'
|
||||
String str = def.getString();
|
||||
String str = def.getFunctionName();
|
||||
if (str != null) {
|
||||
push(str);
|
||||
} else {
|
||||
@ -1660,13 +1643,7 @@ public class Codegen extends Interpreter {
|
||||
generateCodeFromNode(child, node, targetLabel, fallThruLabel);
|
||||
else
|
||||
generateCodeFromNode(child, node, fallThruLabel, targetLabel);
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
if (type == TokenStream.IFEQ)
|
||||
@ -2119,10 +2096,7 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
|
||||
private void visitStatement(Node node) {
|
||||
Object datum = node.getDatum();
|
||||
if (datum == null || !(datum instanceof Number))
|
||||
return;
|
||||
itsLineNumber = ((Number) datum).shortValue();
|
||||
itsLineNumber = node.getLineno();
|
||||
if (itsLineNumber == -1)
|
||||
return;
|
||||
classFile.addLineNumberEntry((short)itsLineNumber);
|
||||
@ -2364,19 +2338,13 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
|
||||
private void visitUnary(Node node, Node child, int trueGOTO, int falseGOTO) {
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
switch (op) {
|
||||
case TokenStream.NOT:
|
||||
{
|
||||
if (trueGOTO != -1) {
|
||||
generateCodeFromNode(child, node, falseGOTO, trueGOTO);
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
addByteCode(ByteCode.IFNE, falseGOTO);
|
||||
@ -2389,13 +2357,7 @@ public class Codegen extends Interpreter {
|
||||
int beyond = acquireLabel();
|
||||
generateCodeFromNode(child, node, trueTarget, falseTarget);
|
||||
|
||||
if (((child.getType() == TokenStream.UNARYOP) && (child.getInt() == TokenStream.NOT))
|
||||
|| (child.getType() == TokenStream.AND)
|
||||
|| (child.getType() == TokenStream.OR)
|
||||
|| (child.getType() == TokenStream.RELOP)
|
||||
|| (child.getType() == TokenStream.EQOP)) {
|
||||
}
|
||||
else {
|
||||
if (!childIsBoolean(child)) {
|
||||
addScriptRuntimeInvoke("toBoolean",
|
||||
"(Ljava/lang/Object;)", "Z");
|
||||
addByteCode(ByteCode.IFEQ, falseTarget);
|
||||
@ -2454,6 +2416,19 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean childIsBoolean(Node child) {
|
||||
switch (child.getType()) {
|
||||
case TokenStream.UNARYOP:
|
||||
return child.getOperation() == TokenStream.NOT;
|
||||
case TokenStream.AND:
|
||||
case TokenStream.OR:
|
||||
case TokenStream.RELOP:
|
||||
case TokenStream.EQOP:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void visitTypeof(Node node, Node child) {
|
||||
if (node.getType() == TokenStream.UNARYOP) {
|
||||
generateCodeFromNode(child, node, -1, -1);
|
||||
@ -2678,7 +2653,7 @@ public class Codegen extends Interpreter {
|
||||
private void visitGOTOingRelOp(Node node, Node child, Node parent,
|
||||
int trueGOTO, int falseGOTO)
|
||||
{
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
|
||||
if (childNumberFlag == Node.BOTH) {
|
||||
generateCodeFromNode(child, node, -1, -1);
|
||||
@ -2818,7 +2793,7 @@ public class Codegen extends Interpreter {
|
||||
/*
|
||||
this is the version that returns an Object result
|
||||
*/
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
int childNumberFlag = node.getIntProp(Node.ISNUMBER_PROP, -1);
|
||||
if (childNumberFlag == Node.BOTH
|
||||
|| op == TokenStream.INSTANCEOF
|
||||
@ -2911,13 +2886,13 @@ public class Codegen extends Interpreter {
|
||||
private void visitEqOp(Node node, Node child, Node parent, int trueGOTO,
|
||||
int falseGOTO)
|
||||
{
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
Node rightChild = child.getNextSibling();
|
||||
boolean isStrict = op == TokenStream.SHEQ ||
|
||||
op == TokenStream.SHNE;
|
||||
if (trueGOTO == -1) {
|
||||
if (rightChild.getType() == TokenStream.PRIMARY &&
|
||||
rightChild.getInt() == TokenStream.NULL)
|
||||
rightChild.getOperation() == TokenStream.NULL)
|
||||
{
|
||||
generateCodeFromNode(child, node, -1, -1);
|
||||
if (isStrict) {
|
||||
@ -2981,7 +2956,7 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
else {
|
||||
if (rightChild.getType() == TokenStream.PRIMARY &&
|
||||
rightChild.getInt() == TokenStream.NULL)
|
||||
rightChild.getOperation() == TokenStream.NULL)
|
||||
{
|
||||
if (op != TokenStream.EQ && op != TokenStream.SHEQ) {
|
||||
// invert true and false.
|
||||
@ -3186,7 +3161,7 @@ public class Codegen extends Interpreter {
|
||||
}
|
||||
|
||||
private void visitPrimary(Node node) {
|
||||
int op = node.getInt();
|
||||
int op = node.getOperation();
|
||||
switch (op) {
|
||||
|
||||
case TokenStream.THIS:
|
||||
@ -3418,10 +3393,10 @@ public class Codegen extends Interpreter {
|
||||
generateCodeFromNode(nameChild, node, -1, -1); // the name
|
||||
if (nameChild.getType() == TokenStream.STRING) {
|
||||
if ((child.getType() == TokenStream.PRIMARY &&
|
||||
child.getInt() == TokenStream.THIS)
|
||||
child.getOperation() == TokenStream.THIS)
|
||||
|| ((child.getType() == TokenStream.NEWTEMP)
|
||||
&& (child.getFirstChild().getType() == TokenStream.PRIMARY)
|
||||
&& (child.getFirstChild().getInt() == TokenStream.THIS))
|
||||
&& (child.getFirstChild().getOperation() == TokenStream.THIS))
|
||||
) {
|
||||
aload(variableObjectLocal);
|
||||
addOptRuntimeInvoke("thisGet",
|
||||
|
||||
@ -464,8 +464,8 @@ public class Optimizer {
|
||||
markDCPNumberContext(lChild);
|
||||
markDCPNumberContext(rChild);
|
||||
|
||||
if ((n.getInt() == TokenStream.INSTANCEOF)
|
||||
|| (n.getInt() == TokenStream.IN)) {
|
||||
int op = n.getOperation();
|
||||
if (op == TokenStream.INSTANCEOF || op == TokenStream.IN) {
|
||||
if (lType == TypeEvent.NumberType) {
|
||||
if (!convertParameter(lChild)) {
|
||||
n.removeChild(lChild);
|
||||
@ -792,18 +792,18 @@ public class Optimizer {
|
||||
}
|
||||
else if (lt == TokenStream.STRING && rt == TokenStream.STRING) {
|
||||
// string + string
|
||||
replace = new Node(TokenStream.STRING,
|
||||
replace = Node.newString(
|
||||
lChild.getString() + rChild.getString());
|
||||
}
|
||||
else if (lt == TokenStream.STRING && rt == TokenStream.NUMBER) {
|
||||
// string + num
|
||||
replace = new Node(TokenStream.STRING,
|
||||
replace = Node.newString(
|
||||
lChild.getString() +
|
||||
ScriptRuntime.numberToString(rChild.getDouble(), 10));
|
||||
}
|
||||
else if (lt == TokenStream.NUMBER && rt == TokenStream.STRING) {
|
||||
// num + string
|
||||
replace = new Node(TokenStream.STRING,
|
||||
replace = Node.newString(
|
||||
ScriptRuntime.numberToString(lChild.getDouble(), 10) +
|
||||
rChild.getString());
|
||||
}
|
||||
@ -974,7 +974,7 @@ public class Optimizer {
|
||||
int result = 0;
|
||||
int type = node.getType();
|
||||
if (type == TokenStream.PRIMARY) {
|
||||
int id = node.getInt();
|
||||
int id = node.getOperation();
|
||||
if (id == TokenStream.FALSE || id == TokenStream.NULL
|
||||
|| id == TokenStream.UNDEFINED)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user