From cf6e89d89b26fb0d670b34490e9e79af30a61eea Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Wed, 4 Sep 2002 09:28:58 +0000 Subject: [PATCH] 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 --- .../org/mozilla/javascript/FunctionNode.java | 4 +- .../src/org/mozilla/javascript/IRFactory.java | 67 +++++------ .../org/mozilla/javascript/Interpreter.java | 11 +- .../src/org/mozilla/javascript/Node.java | 112 ++++++++++++------ .../mozilla/javascript/NodeTransformer.java | 45 ++++--- .../mozilla/javascript/optimizer/Block.java | 9 +- .../mozilla/javascript/optimizer/Codegen.java | 91 ++++++-------- .../javascript/optimizer/Optimizer.java | 12 +- 8 files changed, 178 insertions(+), 173 deletions(-) diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java b/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java index 00fc570831f..3fe5213c4bf 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/FunctionNode.java @@ -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() { diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java index 319cd16737c..f5932e88798 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/IRFactory.java @@ -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; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java index 69b8c0c3376..1920e569a9e 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -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; diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/Node.java b/mozilla/js/rhino/src/org/mozilla/javascript/Node.java index 77958caa72f..ce42e649d4c 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/Node.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/Node.java @@ -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 getType() == TokenStream.NUMBER */ @@ -417,8 +442,9 @@ public class Node implements Cloneable { return ((NumberNode)this).number; } + /** Can only be called when this instanceof StringNode */ 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; } diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java b/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java index 0cf4e6423b5..d450a1a7ddf 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/NodeTransformer.java @@ -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); diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Block.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Block.java index 6bfc5909c33..910671f5c82 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Block.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Block.java @@ -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(); diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index 8b1c2bc9aab..d2fab2dfa6b 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -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", diff --git a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java index f9dac563c85..11233487704 100644 --- a/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java +++ b/mozilla/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java @@ -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) {