From 19e12f45e433403c3131edcf1c2e5cd749e80703 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Sun, 16 Feb 2003 20:28:56 +0000 Subject: [PATCH] Remove code duplication when reporting syntax errors in NodeTransformer, ToekStream, IRFactory and Parser and add a method to create FunctionNode to Interpreter/Codegen to remove the need to have OptIRFactory. --- .../src/org/mozilla/javascript/Context.java | 11 +-- .../org/mozilla/javascript/FunctionNode.java | 4 +- .../src/org/mozilla/javascript/IRFactory.java | 44 +++------- .../org/mozilla/javascript/Interpreter.java | 22 +++-- .../mozilla/javascript/NodeTransformer.java | 80 +++++++------------ .../src/org/mozilla/javascript/Parser.java | 76 +++++++++--------- .../mozilla/javascript/optimizer/Block.java | 29 ++++--- .../mozilla/javascript/optimizer/Codegen.java | 38 +++++---- .../javascript/optimizer/FatBlock.java | 6 +- .../javascript/optimizer/OptFunctionNode.java | 5 +- .../javascript/optimizer/OptTransformer.java | 15 ++-- .../javascript/optimizer/Optimizer.java | 7 +- 12 files changed, 158 insertions(+), 179 deletions(-) diff --git a/js/rhino/src/org/mozilla/javascript/Context.java b/js/rhino/src/org/mozilla/javascript/Context.java index de892e0b595c..d417029f4532 100644 --- a/js/rhino/src/org/mozilla/javascript/Context.java +++ b/js/rhino/src/org/mozilla/javascript/Context.java @@ -845,9 +845,10 @@ public class Context { setErrorReporter(new DefaultErrorReporter()); boolean errorseen = false; + Interpreter compiler = new Interpreter(); + IRFactory irf = compiler.createIRFactory(this, ts); + Parser p = createParser(irf); try { - IRFactory irf = new IRFactory(ts, null); - Parser p = createParser(irf); p.parse(ts); } catch (IOException ioe) { errorseen = true; @@ -1999,13 +2000,13 @@ public class Context { Interpreter compiler = createCompiler(); errorCount = 0; - IRFactory irf = compiler.createIRFactory(this, ts, scope); + IRFactory irf = compiler.createIRFactory(this, ts); Parser p = createParser(irf); Node tree = (Node) p.parse(ts); if (tree == null) return null; - tree = compiler.transform(tree, ts, scope); + tree = compiler.transform(this, irf, tree); if (printTrees) { System.out.println(tree.toStringTree()); } @@ -2024,7 +2025,7 @@ public class Context { } Object result = compiler.compile(this, scope, tree, - securityDomain, securityController); + securityController, securityDomain); return errorCount == 0 ? result : null; } diff --git a/js/rhino/src/org/mozilla/javascript/FunctionNode.java b/js/rhino/src/org/mozilla/javascript/FunctionNode.java index 760bc157f9ce..8e99a72bf330 100644 --- a/js/rhino/src/org/mozilla/javascript/FunctionNode.java +++ b/js/rhino/src/org/mozilla/javascript/FunctionNode.java @@ -40,8 +40,8 @@ import java.util.*; public class FunctionNode extends Node { - public FunctionNode(String name, Node statements) { - super(TokenStream.FUNCTION, statements); + public FunctionNode(String name) { + super(TokenStream.FUNCTION); functionName = name; } diff --git a/js/rhino/src/org/mozilla/javascript/IRFactory.java b/js/rhino/src/org/mozilla/javascript/IRFactory.java index 905183b7a30f..00d54d2d40e7 100644 --- a/js/rhino/src/org/mozilla/javascript/IRFactory.java +++ b/js/rhino/src/org/mozilla/javascript/IRFactory.java @@ -44,9 +44,9 @@ package org.mozilla.javascript; */ public class IRFactory { - public IRFactory(TokenStream ts, Scriptable scope) { + public IRFactory(Interpreter compiler, TokenStream ts) { + this.compiler = compiler; this.ts = ts; - this.scope = scope; } /** @@ -72,7 +72,7 @@ public class IRFactory { * Leaf */ public Object createLeaf(int nodeType) { - return new Node(nodeType); + return new Node(nodeType); } public Object createLeaf(int nodeType, int nodeOp) { @@ -202,23 +202,19 @@ public class IRFactory { return new Node(TokenStream.BLOCK, lineno); } - public Object createFunctionNode(String name, Object statements) - { - return new FunctionNode(name, (Node) statements); - } - public Object createFunction(String name, VariableTable vars, Object statements, String sourceName, int baseLineno, - int endLineno, Object source, + int endLineno, String source, int functionType) { if (name == null) { name = ""; } - FunctionNode f = (FunctionNode) createFunctionNode(name, statements); + FunctionNode f = compiler.createFunctionNode(this, name); f.itsVariableTable = vars; f.setFunctionType(functionType); + f.addChildToBack((Node)statements); f.putProp(Node.SOURCENAME_PROP, sourceName); f.putIntProp(Node.BASE_LINENO_PROP, baseLineno); f.putIntProp(Node.END_LINENO_PROP, endLineno); @@ -341,13 +337,13 @@ public class IRFactory { */ Node lastChild = lhsNode.getLastChild(); if (lhsNode.getFirstChild() != lastChild) { - reportError("msg.mult.index"); + ts.reportCurrentLineError("msg.mult.index", null); } lvalue = Node.newString(TokenStream.NAME, lastChild.getString()); break; default: - reportError("msg.bad.for.in.lhs"); + ts.reportCurrentLineError("msg.bad.for.in.lhs", null); return objNode; } @@ -845,7 +841,7 @@ public class IRFactory { default: // TODO: This should be a ReferenceError--but that's a runtime // exception. Should we compile an exception into the code? - reportError("msg.bad.lhs.assign"); + ts.reportCurrentLineError("msg.bad.lhs.assign", null); return left; } } @@ -1014,28 +1010,12 @@ public class IRFactory { return result; } - private void reportError(String msgResource) { + private Interpreter compiler; - if (scope != null) - throw NativeGlobal.constructError( - Context.getContext(), "SyntaxError", - ScriptRuntime.getMessage0(msgResource), - scope, ts.getSourceName(), ts.getLineno(), - ts.getOffset(), ts.getLine()); - else { - String message = Context.getMessage0(msgResource); - Context.reportError(message, ts.getSourceName(), ts.getLineno(), - ts.getLine(), ts.getOffset()); - } - } - - // Only needed to get file/line information. Could create an interface + // Only needed to call reportSyntaxError. Could create an interface // that TokenStream implements if we want to make the connection less // direct. - private TokenStream ts; - - // Only needed to pass to the Erorr exception constructors - private Scriptable scope; + TokenStream ts; private static final int LOOP_DO_WHILE = 0; private static final int LOOP_WHILE = 1; diff --git a/js/rhino/src/org/mozilla/javascript/Interpreter.java b/js/rhino/src/org/mozilla/javascript/Interpreter.java index a31f79ea56b6..0a8654ff784d 100644 --- a/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -60,19 +60,25 @@ public class Interpreter { // Last icode END_ICODE = TokenStream.LAST_TOKEN + 6; - public IRFactory createIRFactory(Context cx, TokenStream ts, - Scriptable scope) + public IRFactory createIRFactory(Context cx, TokenStream ts) { - return new IRFactory(ts, scope); + return new IRFactory(this, ts); } - public Node transform(Node tree, TokenStream ts, Scriptable scope) { - return (new NodeTransformer()).transform(tree, null, ts, scope); + public FunctionNode createFunctionNode(IRFactory irFactory, String name) + { + return new FunctionNode(name); } - public Object compile(Context cx, Scriptable scope, Node tree, - Object securityDomain, - SecurityController securityController) + public Node transform(Context cx, IRFactory irFactory, Node tree) + { + tree = (new NodeTransformer(irFactory)).transform(tree, null); + return tree; + } + + public Object + compile(Context cx, Scriptable scope, Node tree, + SecurityController securityController, Object securityDomain) { version = cx.getLanguageVersion(); itsData = new InterpreterData(securityDomain); diff --git a/js/rhino/src/org/mozilla/javascript/NodeTransformer.java b/js/rhino/src/org/mozilla/javascript/NodeTransformer.java index f448934fba6d..6c2379a452aa 100644 --- a/js/rhino/src/org/mozilla/javascript/NodeTransformer.java +++ b/js/rhino/src/org/mozilla/javascript/NodeTransformer.java @@ -46,35 +46,28 @@ package org.mozilla.javascript; public class NodeTransformer { + public NodeTransformer(IRFactory irFactory) { + this.irFactory = irFactory; + } + /** * Return new instance of this class. So that derived classes * can override methods of the transformer. */ public NodeTransformer newInstance() { - return new NodeTransformer(); + return new NodeTransformer(irFactory); } - public IRFactory createIRFactory(TokenStream ts, Scriptable scope) { - return new IRFactory(ts, scope); - } - - public Node transform(Node tree, Node enclosing, TokenStream ts, - Scriptable scope) + public Node transform(Node tree, Node enclosing) { loops = new ObjArray(); loopEnds = new ObjArray(); inFunction = tree.getType() == TokenStream.FUNCTION; - VariableTable vars; - if (!inFunction) { - vars = (VariableTable)tree.getProp(Node.VARS_PROP); - checkVariables(tree, vars); - } else { - FunctionNode fnNode = (FunctionNode)tree; - vars = fnNode.getVariableTable(); - checkVariables(tree, vars); - fnNode.markVariableTableReady(); + VariableTable vars = getVariableTable(tree); + checkVariables(tree, vars); + if (inFunction) { + ((FunctionNode)tree).markVariableTableReady(); } - irFactory = createIRFactory(ts, scope); // to save against upchecks if no finally blocks are used. boolean hasFinally = false; @@ -112,8 +105,7 @@ public class NodeTransformer { fnNode.setCheckThis(true); } NodeTransformer inner = newInstance(); - fnNode = (FunctionNode) - inner.transform(fnNode, tree, ts, scope); + fnNode = (FunctionNode)inner.transform(fnNode, tree); node.putProp(Node.FUNCTION_PROP, fnNode); ObjArray fns = (ObjArray) tree.getProp(Node.FUNCTION_PROP); if (fns == null) { @@ -136,10 +128,9 @@ public class NodeTransformer { if (n.getType() == TokenStream.LABEL) { String otherId = (String)n.getProp(Node.LABEL_PROP); if (id.equals(otherId)) { - String message = Context.getMessage1( - "msg.dup.label", id); - reportMessage(Context.getContext(), message, node, - tree, true, scope); + Object[] messageArgs = { id }; + reportError("msg.dup.label", messageArgs, + node, tree); break typeswitch; } } @@ -336,25 +327,22 @@ public class NodeTransformer { ? null : (Node) loop.getProp(propType); if (loop == null || target == null) { - String message; + String messageId; + Object[] messageArgs = null; if (!labelled) { // didn't find an appropriate target if (type == TokenStream.CONTINUE) { - message = Context.getMessage - ("msg.continue.outside", null); + messageId = "msg.continue.outside"; } else { - message = Context.getMessage - ("msg.bad.break", null); + messageId = "msg.bad.break"; } } else if (loop != null) { - message = Context.getMessage0("msg.continue.nonloop"); + messageId = "msg.continue.nonloop"; } else { - Object[] errArgs = { id }; - message = Context.getMessage - ("msg.undef.label", errArgs); + messageArgs = new Object[] { id }; + messageId = "msg.undef.label"; } - reportMessage(Context.getContext(), message, node, - tree, true, scope); + reportError(messageId, messageArgs, node, tree); node.setType(TokenStream.NOP); break; } @@ -457,8 +445,7 @@ public class NodeTransformer { Context cx = Context.getCurrentContext(); if ((cx != null && cx.isActivationNeeded(name)) || (name.equals("length") && - Context.getContext().getLanguageVersion() == - Context.VERSION_1_2)) + cx.getLanguageVersion() == Context.VERSION_1_2)) { // Use of "arguments" or "length" in 1.2 requires // an activation object. @@ -657,24 +644,13 @@ public class NodeTransformer { } } - protected void reportMessage(Context cx, String msg, Node stmt, - Node tree, boolean isError, - Scriptable scope) + private void + reportError(String messageId, Object[] messageArgs, Node stmt, Node tree) { int lineno = stmt.getLineno(); - Object prop = tree == null - ? null - : tree.getProp(Node.SOURCENAME_PROP); - if (isError) { - if (scope != null) - throw NativeGlobal.constructError( - cx, "SyntaxError", msg, scope, - (String) prop, lineno, 0, null); - else - cx.reportError(msg, (String) prop, lineno, null, 0); - } - else - cx.reportWarning(msg, (String) prop, lineno, null, 0); + String sourceName = (String)tree.getProp(Node.SOURCENAME_PROP); + irFactory.ts.reportSyntaxError(true, messageId, messageArgs, + sourceName, lineno, null, 0); } protected ObjArray loops; diff --git a/js/rhino/src/org/mozilla/javascript/Parser.java b/js/rhino/src/org/mozilla/javascript/Parser.java index 0efc1478e40d..24f6c6e77cf9 100644 --- a/js/rhino/src/org/mozilla/javascript/Parser.java +++ b/js/rhino/src/org/mozilla/javascript/Parser.java @@ -65,7 +65,7 @@ class Parser { } private void mustMatchToken(TokenStream ts, int toMatch, String messageId) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; if ((tt = ts.getToken()) != toMatch) { @@ -75,17 +75,14 @@ class Parser { } private void reportError(TokenStream ts, String messageId) - throws JavaScriptException + throws ParserException { this.ok = false; - ts.reportSyntaxError(messageId, null); + ts.reportCurrentLineError(messageId, null); - /* Throw an exception to unwind the recursive descent parse. - * We use JavaScriptException here even though it is really - * a different use of the exception than it is usually used - * for. - */ - throw new JavaScriptException(messageId); + // Throw a ParserException exception to unwind the recursive descent + // parse. + throw new ParserException(); } /* @@ -129,7 +126,7 @@ class Parser { if (tt == ts.FUNCTION) { try { n = function(ts, FunctionNode.FUNCTION_STATEMENT); - } catch (JavaScriptException e) { + } catch (ParserException e) { this.ok = false; break; } @@ -179,7 +176,7 @@ class Parser { } nf.addChildToBack(pn, n); } - } catch (JavaScriptException e) { + } catch (ParserException e) { this.ok = false; } finally { // also in finally block: @@ -192,7 +189,7 @@ class Parser { } private Object function(TokenStream ts, int functionType) - throws IOException, JavaScriptException + throws IOException, ParserException { int baseLineno = ts.getLineno(); // line number where source starts @@ -266,7 +263,7 @@ class Parser { String s = ts.getString(); if (new_vars.hasVariable(s)) { Object[] msgArgs = { s }; - ts.reportSyntaxWarning("msg.dup.parms", msgArgs); + ts.reportCurrentLineWarning("msg.dup.parms", msgArgs); } new_vars.addParameter(s); sourceAddString(ts.NAME, s); @@ -345,7 +342,7 @@ class Parser { } private Object condition(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn; mustMatchToken(ts, ts.LP, "msg.no.paren.cond"); @@ -360,7 +357,7 @@ class Parser { } private void checkWellTerminated(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt = ts.peekTokenSameLine(); switch (tt) { @@ -385,7 +382,7 @@ class Parser { } private void checkWellTerminatedFunction(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { if (languageVersion < Context.VERSION_1_2) { // See comments in checkWellTerminated @@ -396,7 +393,7 @@ class Parser { // match a NAME; return null if no match. private String matchLabel(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int lineno = ts.getLineno(); @@ -419,7 +416,7 @@ class Parser { { try { return statementHelper(ts); - } catch (JavaScriptException e) { + } catch (ParserException e) { // skip to end of statement int lineno = ts.getLineno(); int t; @@ -437,7 +434,7 @@ class Parser { */ private Object statementHelper(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = null; @@ -868,7 +865,7 @@ class Parser { } private Object variables(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = nf.createVariables(ts.getLineno()); boolean first = true; @@ -909,7 +906,7 @@ class Parser { } private Object expr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = assignExpr(ts, inForInit); while (ts.matchToken(ts.COMMA)) { @@ -920,7 +917,7 @@ class Parser { } private Object assignExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = condExpr(ts, inForInit); @@ -936,7 +933,7 @@ class Parser { } private Object condExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object ifTrue; Object ifFalse; @@ -956,7 +953,7 @@ class Parser { } private Object orExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = andExpr(ts, inForInit); if (ts.matchToken(ts.OR)) { @@ -968,7 +965,7 @@ class Parser { } private Object andExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = bitOrExpr(ts, inForInit); if (ts.matchToken(ts.AND)) { @@ -980,7 +977,7 @@ class Parser { } private Object bitOrExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = bitXorExpr(ts, inForInit); while (ts.matchToken(ts.BITOR)) { @@ -991,7 +988,7 @@ class Parser { } private Object bitXorExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = bitAndExpr(ts, inForInit); while (ts.matchToken(ts.BITXOR)) { @@ -1002,7 +999,7 @@ class Parser { } private Object bitAndExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = eqExpr(ts, inForInit); while (ts.matchToken(ts.BITAND)) { @@ -1013,7 +1010,7 @@ class Parser { } private Object eqExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = relExpr(ts, inForInit); while (ts.matchToken(ts.EQOP)) { @@ -1026,7 +1023,7 @@ class Parser { } private Object relExpr(TokenStream ts, boolean inForInit) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = shiftExpr(ts); while (ts.matchToken(ts.RELOP)) { @@ -1043,7 +1040,7 @@ class Parser { } private Object shiftExpr(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { Object pn = addExpr(ts); while (ts.matchToken(ts.SHOP)) { @@ -1055,7 +1052,7 @@ class Parser { } private Object addExpr(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; Object pn = mulExpr(ts); @@ -1071,7 +1068,7 @@ class Parser { } private Object mulExpr(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; @@ -1090,7 +1087,7 @@ class Parser { } private Object unaryExpr(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; @@ -1153,7 +1150,7 @@ class Parser { } private Object argumentList(TokenStream ts, Object listNode) - throws IOException, JavaScriptException + throws IOException, ParserException { boolean matched; ts.flags |= ts.TSF_REGEXP; @@ -1175,7 +1172,7 @@ class Parser { } private Object memberExpr(TokenStream ts, boolean allowCallSyntax) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; @@ -1222,7 +1219,7 @@ class Parser { private Object memberExprTail(TokenStream ts, boolean allowCallSyntax, Object pn) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; while ((tt = ts.getToken()) > ts.EOF) { @@ -1261,7 +1258,7 @@ class Parser { } private Object primaryExpr(TokenStream ts) - throws IOException, JavaScriptException + throws IOException, ParserException { int tt; @@ -2298,3 +2295,6 @@ class Parser { } +// Exception to unwind +class ParserException extends Exception { } + diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Block.java b/js/rhino/src/org/mozilla/javascript/optimizer/Block.java index 63d4ddeb0f50..8ded49282d1f 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Block.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Block.java @@ -46,8 +46,10 @@ import java.io.StringWriter; public class Block { - public Block(int startNodeIndex, int endNodeIndex, Node[] statementNodes) + public Block(IRFactory irFactory, int startNodeIndex, int endNodeIndex, + Node[] statementNodes) { + itsIRFactory = irFactory; itsStartNodeIndex = startNodeIndex; itsEndNodeIndex = endNodeIndex; itsStatementNodes = statementNodes; @@ -61,7 +63,8 @@ public class Block { public Block[] getPredecessorList() { return itsPredecessors; } public Block[] getSuccessorList() { return itsSuccessors; } - public static Block[] buildBlocks(Node[] statementNodes) + public static Block[] + buildBlocks(IRFactory irFactory, Node[] statementNodes) { // a mapping from each target node to the block it begins Hashtable theTargetBlocks = new Hashtable(); @@ -75,8 +78,9 @@ public class Block { case TokenStream.TARGET : { if (i != beginNodeIndex) { - FatBlock fb = new FatBlock(beginNodeIndex, - i - 1, statementNodes); + FatBlock fb = new FatBlock(irFactory, + beginNodeIndex, i - 1, + statementNodes); if (statementNodes[beginNodeIndex].getType() == TokenStream.TARGET) theTargetBlocks.put(statementNodes[beginNodeIndex], fb); @@ -90,8 +94,9 @@ public class Block { case TokenStream.IFEQ : case TokenStream.GOTO : { - FatBlock fb = new FatBlock(beginNodeIndex, - i, statementNodes); + FatBlock fb = new FatBlock(irFactory, + beginNodeIndex, i, + statementNodes); if (statementNodes[beginNodeIndex].getType() == TokenStream.TARGET) theTargetBlocks.put(statementNodes[beginNodeIndex], fb); @@ -104,9 +109,10 @@ public class Block { } if ((beginNodeIndex != statementNodes.length)) { - FatBlock fb = new FatBlock(beginNodeIndex, - statementNodes.length - 1, - statementNodes); + FatBlock fb = new FatBlock(irFactory, + beginNodeIndex, + statementNodes.length - 1, + statementNodes); if (statementNodes[beginNodeIndex].getType() == TokenStream.TARGET) theTargetBlocks.put(statementNodes[beginNodeIndex], fb); theBlocks.add(fb); @@ -607,11 +613,8 @@ public class Block { } } - private IRFactory itsIRFactory; - Hashtable localCSE(Hashtable theCSETable, OptFunctionNode theFunction) { - itsIRFactory = new IRFactory(null, null); if (theCSETable == null) theCSETable = new Hashtable(5); for (int i = itsStartNodeIndex; i <= itsEndNodeIndex; i++) { Node n = itsStatementNodes[i]; @@ -666,6 +669,8 @@ public class Block { public void setSuccessorList(Block[] b) { itsSuccessors = b; } public void setPredecessorList(Block[] b) { itsPredecessors = b; } + private IRFactory itsIRFactory; + // all the Blocks that come immediately after this private Block[] itsSuccessors; // all the Blocks that come immediately before this diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java index 924455ed04d7..390de927bae1 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Codegen.java @@ -53,38 +53,46 @@ import java.lang.reflect.Constructor; public class Codegen extends Interpreter { - public Codegen() { - } + public Codegen() { } - private Codegen(Codegen parent) { + private Codegen(Codegen parent) + { this.nameHelper = parent.nameHelper; this.classNames = parent.classNames; } - public IRFactory createIRFactory(Context cx, TokenStream ts, - Scriptable scope) + public IRFactory createIRFactory(Context cx, TokenStream ts) { if (nameHelper == null) { nameHelper = (OptClassNameHelper)ClassNameHelper.get(cx); classNames = new ObjToIntMap(); } - return new OptIRFactory(ts, scope, this); + return new IRFactory(this, ts); } - public Node transform(Node tree, TokenStream ts, Scriptable scope) { - OptTransformer opt = new OptTransformer(new Hashtable(11)); - return opt.transform(tree, null, ts, scope); + public FunctionNode createFunctionNode(IRFactory irFactory, String name) + { + String className = getScriptClassName(name, false); + return new OptFunctionNode(name, className); } - public Object compile(Context cx, Scriptable scope, Node tree, - Object securityDomain, - SecurityController securityController) + public Node transform(Context cx, IRFactory irFactory, Node tree) + { + int optimizationLevel = cx.getOptimizationLevel(); + OptTransformer opt = new OptTransformer(irFactory, new Hashtable(11)); + tree = opt.transform(tree, null); + if (optimizationLevel > 0) { + (new Optimizer(irFactory)).optimize(tree, optimizationLevel); + } + return tree; + } + + public Object + compile(Context cx, Scriptable scope, Node tree, + SecurityController securityController, Object securityDomain) { ObjArray classFiles = new ObjArray(); ObjArray names = new ObjArray(); - if (cx.getOptimizationLevel() > 0) { - (new Optimizer()).optimize(tree, cx.getOptimizationLevel()); - } generateCode(tree, names, classFiles); String generatedName = name; diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/FatBlock.java b/js/rhino/src/org/mozilla/javascript/optimizer/FatBlock.java index fb1173b25321..574e808e1fe9 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/FatBlock.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/FatBlock.java @@ -40,9 +40,11 @@ import org.mozilla.javascript.*; public class FatBlock { - public FatBlock(int startNodeIndex, int endNodeIndex, Node[] statementNodes) + public FatBlock(IRFactory irFactory, int startNodeIndex, int endNodeIndex, + Node[] statementNodes) { - itsShadowOfFormerSelf = new Block(startNodeIndex, endNodeIndex, statementNodes); + itsShadowOfFormerSelf = new Block(irFactory, startNodeIndex, + endNodeIndex, statementNodes); } public Node getEndNode() diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java b/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java index 494111bfa001..c043220361fc 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/OptFunctionNode.java @@ -41,9 +41,8 @@ import java.util.*; class OptFunctionNode extends FunctionNode { - OptFunctionNode(String name, Node statements, String className) - { - super(name, statements); + OptFunctionNode(String name, String className) { + super(name); itsClassName = className; } diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/OptTransformer.java b/js/rhino/src/org/mozilla/javascript/optimizer/OptTransformer.java index b245e243b4d3..9df9cd9623e7 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/OptTransformer.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/OptTransformer.java @@ -49,27 +49,24 @@ import java.util.Hashtable; class OptTransformer extends NodeTransformer { private Hashtable theFnClassNameList; - OptTransformer(Hashtable theFnClassNameList) { + OptTransformer(IRFactory irFactory, Hashtable theFnClassNameList) { + super(irFactory); this.theFnClassNameList = theFnClassNameList; } public NodeTransformer newInstance() { - return new OptTransformer((Hashtable) theFnClassNameList.clone()); + Hashtable listCopy = (Hashtable) theFnClassNameList.clone(); + return new OptTransformer(irFactory, listCopy); } - public IRFactory createIRFactory(TokenStream ts, Scriptable scope) { - return new IRFactory(ts, scope); - } - - public Node transform(Node tree, Node enclosing, TokenStream ts, - Scriptable scope) { + public Node transform(Node tree, Node enclosing) { // Collect all of the contained functions into a hashtable // so that the call optimizer can access the class name & parameter // count for any call it encounters collectContainedFunctions(tree.getFirstChild()); - return super.transform(tree, enclosing, ts, scope); + return super.transform(tree, enclosing); } private int detectDirectCall(Node node, Node tree) diff --git a/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java b/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java index bcee06da199c..c3aac64e9716 100644 --- a/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java +++ b/js/rhino/src/org/mozilla/javascript/optimizer/Optimizer.java @@ -49,6 +49,10 @@ import java.util.Hashtable; class Optimizer { + Optimizer(IRFactory irFactory) { + this.irFactory = irFactory; + } + void optimize(Node tree, int optLevel) { itsOptLevel = optLevel; @@ -74,7 +78,7 @@ class Optimizer { inDirectCallFunction = theFunction.isTargetOfDirectCall(); Node[] theStatementNodes = buildStatementList(theFunction); - Block[] theBlocks = Block.buildBlocks(theStatementNodes); + Block[] theBlocks = Block.buildBlocks(irFactory, theStatementNodes); PrintWriter pw = null; try { if (DEBUG_OPTIMIZER) { @@ -1040,6 +1044,7 @@ class Optimizer { private static final int ALWAYS_TRUE_BOOLEAN = 1; private static final int ALWAYS_FALSE_BOOLEAN = -1; + private IRFactory irFactory; private int itsOptLevel; private boolean inDirectCallFunction; private boolean parameterUsedInNumberContext;