Tue, 07 May 2013 14:43:17 +0200
8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
Reviewed-by: jlaskey, attila
1.1 --- a/make/project.properties Tue May 07 14:36:57 2013 +0200 1.2 +++ b/make/project.properties Tue May 07 14:43:17 2013 +0200 1.3 @@ -214,7 +214,7 @@ 1.4 1.5 # -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods 1.6 # add '-Dtest.js.outofprocess' to run each test in a new sub-process 1.7 -run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:-TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8 1.8 +run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8 1.9 #-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M 1.10 run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main} 1.11
2.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java Tue May 07 14:36:57 2013 +0200 2.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Tue May 07 14:43:17 2013 +0200 2.3 @@ -78,6 +78,7 @@ 2.4 import jdk.nashorn.internal.ir.ReturnNode; 2.5 import jdk.nashorn.internal.ir.RuntimeNode; 2.6 import jdk.nashorn.internal.ir.RuntimeNode.Request; 2.7 +import jdk.nashorn.internal.ir.Statement; 2.8 import jdk.nashorn.internal.ir.SwitchNode; 2.9 import jdk.nashorn.internal.ir.Symbol; 2.10 import jdk.nashorn.internal.ir.TernaryNode; 2.11 @@ -154,7 +155,9 @@ 2.12 2.13 @Override 2.14 public Node leaveAccessNode(final AccessNode accessNode) { 2.15 - //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this 2.16 + //While Object type is assigned here, Access Specialization in FinalizeTypes may narrow this, that 2.17 + //is why we can't set the access node base to be an object here, that will ruin access specialization 2.18 + //for example for a.x | 17. 2.19 return end(ensureSymbol(Type.OBJECT, accessNode)); 2.20 } 2.21 2.22 @@ -435,6 +438,7 @@ 2.23 final IdentNode callee = compilerConstant(CALLEE); 2.24 VarNode selfInit = 2.25 new VarNode( 2.26 + newFunctionNode.getLineNumber(), 2.27 newFunctionNode.getToken(), 2.28 newFunctionNode.getFinish(), 2.29 newFunctionNode.getIdent(), 2.30 @@ -442,7 +446,7 @@ 2.31 2.32 LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName()); 2.33 2.34 - final List<Node> newStatements = new ArrayList<>(); 2.35 + final List<Statement> newStatements = new ArrayList<>(); 2.36 assert callee.getSymbol() != null && callee.getSymbol().hasSlot(); 2.37 2.38 final IdentNode name = selfInit.getName(); 2.39 @@ -492,7 +496,7 @@ 2.40 final Symbol pseudoSymbol = pseudoSymbol(name); 2.41 LOG.info("IdentNode is property name -> assigning pseudo symbol ", pseudoSymbol); 2.42 LOG.unindent(); 2.43 - return identNode.setSymbol(lc, pseudoSymbol); 2.44 + return end(identNode.setSymbol(lc, pseudoSymbol)); 2.45 } 2.46 2.47 final Block block = lc.getCurrentBlock(); 2.48 @@ -658,7 +662,7 @@ 2.49 if (literalNode instanceof ArrayLiteralNode) { 2.50 ((ArrayLiteralNode)literalNode).analyze(); 2.51 } 2.52 - return literalNode.setSymbol(getLexicalContext(), symbol); 2.53 + return end(literalNode.setSymbol(getLexicalContext(), symbol)); 2.54 } 2.55 2.56 @Override 2.57 @@ -779,17 +783,18 @@ 2.58 final IdentNode ident = newVarNode.getName(); 2.59 final String name = ident.getName(); 2.60 2.61 + final LexicalContext lc = getLexicalContext(); 2.62 + final Symbol symbol = findSymbol(lc.getCurrentBlock(), ident.getName()); 2.63 + 2.64 if (init == null) { 2.65 // var x; with no init will be treated like a use of x by 2.66 // leaveIdentNode unless we remove the name from the localdef list. 2.67 removeLocalDef(name); 2.68 - return newVarNode; 2.69 + return newVarNode.setSymbol(lc, symbol); 2.70 } 2.71 2.72 addLocalDef(name); 2.73 2.74 - final LexicalContext lc = getLexicalContext(); 2.75 - final Symbol symbol = findSymbol(lc.getCurrentBlock(), ident.getName()); 2.76 assert symbol != null; 2.77 2.78 final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol); 2.79 @@ -1398,7 +1403,9 @@ 2.80 private FunctionNode finalizeParameters(final FunctionNode functionNode) { 2.81 final List<IdentNode> newParams = new ArrayList<>(); 2.82 final boolean isVarArg = functionNode.isVarArg(); 2.83 + final int nparams = functionNode.getParameters().size(); 2.84 2.85 + int specialize = 0; 2.86 int pos = 0; 2.87 for (final IdentNode param : functionNode.getParameters()) { 2.88 final Symbol paramSymbol = functionNode.getBody().getExistingSymbol(param.getName()); 2.89 @@ -1414,9 +1421,13 @@ 2.90 2.91 // if we know that a parameter is only used as a certain type throughout 2.92 // this function, we can tell the runtime system that no matter what the 2.93 - // call site is, use this information. TODO 2.94 - if (!paramSymbol.getSymbolType().isObject()) { 2.95 + // call site is, use this information: 2.96 + // we also need more than half of the parameters to be specializable 2.97 + // for the heuristic to be worth it, and we need more than one use of 2.98 + // the parameter to consider it, i.e. function(x) { call(x); } doens't count 2.99 + if (paramSymbol.getUseCount() > 1 && !paramSymbol.getSymbolType().isObject()) { 2.100 LOG.finest("Parameter ", param, " could profit from specialization to ", paramSymbol.getSymbolType()); 2.101 + specialize++; 2.102 } 2.103 2.104 newType(paramSymbol, Type.widest(type, paramSymbol.getSymbolType())); 2.105 @@ -1429,7 +1440,13 @@ 2.106 pos++; 2.107 } 2.108 2.109 - return functionNode.setParameters(getLexicalContext(), newParams); 2.110 + FunctionNode newFunctionNode = functionNode; 2.111 + 2.112 + if (nparams == 0 || (specialize * 2) < nparams) { 2.113 + newFunctionNode = newFunctionNode.clearSnapshot(getLexicalContext()); 2.114 + } 2.115 + 2.116 + return newFunctionNode.setParameters(getLexicalContext(), newParams); 2.117 } 2.118 2.119 /**
3.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue May 07 14:36:57 2013 +0200 3.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue May 07 14:43:17 2013 +0200 3.3 @@ -63,6 +63,7 @@ 3.4 import java.util.List; 3.5 import java.util.Map; 3.6 import java.util.TreeMap; 3.7 + 3.8 import jdk.nashorn.internal.codegen.ClassEmitter.Flag; 3.9 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 3.10 import jdk.nashorn.internal.codegen.RuntimeCallSite.SpecializedRuntimeNode; 3.11 @@ -88,7 +89,6 @@ 3.12 import jdk.nashorn.internal.ir.IndexNode; 3.13 import jdk.nashorn.internal.ir.LexicalContext; 3.14 import jdk.nashorn.internal.ir.LexicalContextNode; 3.15 -import jdk.nashorn.internal.ir.LineNumberNode; 3.16 import jdk.nashorn.internal.ir.LiteralNode; 3.17 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; 3.18 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; 3.19 @@ -100,6 +100,7 @@ 3.20 import jdk.nashorn.internal.ir.RuntimeNode; 3.21 import jdk.nashorn.internal.ir.RuntimeNode.Request; 3.22 import jdk.nashorn.internal.ir.SplitNode; 3.23 +import jdk.nashorn.internal.ir.Statement; 3.24 import jdk.nashorn.internal.ir.SwitchNode; 3.25 import jdk.nashorn.internal.ir.Symbol; 3.26 import jdk.nashorn.internal.ir.TernaryNode; 3.27 @@ -191,6 +192,8 @@ 3.28 /** Current compile unit */ 3.29 private CompileUnit unit; 3.30 3.31 + private int lastLineNumber = -1; 3.32 + 3.33 /** When should we stop caching regexp expressions in fields to limit bytecode size? */ 3.34 private static final int MAX_REGEX_FIELDS = 2 * 1024; 3.35 3.36 @@ -619,6 +622,8 @@ 3.37 3.38 @Override 3.39 public boolean enterBreakNode(final BreakNode breakNode) { 3.40 + lineNumber(breakNode); 3.41 + 3.42 final BreakableNode breakFrom = getLexicalContext().getBreakable(breakNode.getLabel()); 3.43 for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(breakFrom); i++) { 3.44 closeWith(); 3.45 @@ -663,6 +668,8 @@ 3.46 3.47 @Override 3.48 public boolean enterCallNode(final CallNode callNode) { 3.49 + lineNumber(callNode); 3.50 + 3.51 final List<Node> args = callNode.getArgs(); 3.52 final Node function = callNode.getFunction(); 3.53 final Block currentBlock = getLexicalContext().getCurrentBlock(); 3.54 @@ -836,6 +843,8 @@ 3.55 3.56 @Override 3.57 public boolean enterContinueNode(final ContinueNode continueNode) { 3.58 + lineNumber(continueNode); 3.59 + 3.60 final LoopNode continueTo = getLexicalContext().getContinueTo(continueNode.getLabel()); 3.61 for (int i = 0; i < getLexicalContext().getScopeNestingLevelTo(continueTo); i++) { 3.62 closeWith(); 3.63 @@ -847,11 +856,15 @@ 3.64 3.65 @Override 3.66 public boolean enterEmptyNode(final EmptyNode emptyNode) { 3.67 + lineNumber(emptyNode); 3.68 + 3.69 return false; 3.70 } 3.71 3.72 @Override 3.73 public boolean enterExecuteNode(final ExecuteNode executeNode) { 3.74 + lineNumber(executeNode); 3.75 + 3.76 final Node expression = executeNode.getExpression(); 3.77 expression.accept(this); 3.78 3.79 @@ -860,6 +873,8 @@ 3.80 3.81 @Override 3.82 public boolean enterForNode(final ForNode forNode) { 3.83 + lineNumber(forNode); 3.84 + 3.85 final Node test = forNode.getTest(); 3.86 final Block body = forNode.getBody(); 3.87 final Node modify = forNode.getModify(); 3.88 @@ -1148,6 +1163,8 @@ 3.89 3.90 @Override 3.91 public boolean enterIfNode(final IfNode ifNode) { 3.92 + lineNumber(ifNode); 3.93 + 3.94 final Node test = ifNode.getTest(); 3.95 final Block pass = ifNode.getPass(); 3.96 final Block fail = ifNode.getFail(); 3.97 @@ -1187,12 +1204,12 @@ 3.98 return false; 3.99 } 3.100 3.101 - @Override 3.102 - public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) { 3.103 - final Label label = new Label((String)null); 3.104 - method.label(label); 3.105 - method.lineNumber(lineNumberNode.getLineNumber(), label); 3.106 - return false; 3.107 + private void lineNumber(final Statement statement) { 3.108 + final int lineNumber = statement.getLineNumber(); 3.109 + if (lineNumber != lastLineNumber) { 3.110 + method.lineNumber(statement.getLineNumber()); 3.111 + } 3.112 + lastLineNumber = lineNumber; 3.113 } 3.114 3.115 /** 3.116 @@ -1524,6 +1541,8 @@ 3.117 3.118 @Override 3.119 public boolean enterReturnNode(final ReturnNode returnNode) { 3.120 + lineNumber(returnNode); 3.121 + 3.122 method.registerReturn(); 3.123 3.124 final Type returnType = getLexicalContext().getCurrentFunction().getReturnType(); 3.125 @@ -1733,6 +1752,8 @@ 3.126 3.127 @Override 3.128 public boolean enterSplitNode(final SplitNode splitNode) { 3.129 + lineNumber(splitNode); 3.130 + 3.131 final CompileUnit splitCompileUnit = splitNode.getCompileUnit(); 3.132 3.133 final FunctionNode fn = getLexicalContext().getCurrentFunction(); 3.134 @@ -1876,6 +1897,8 @@ 3.135 3.136 @Override 3.137 public boolean enterSwitchNode(final SwitchNode switchNode) { 3.138 + lineNumber(switchNode); 3.139 + 3.140 final Node expression = switchNode.getExpression(); 3.141 final Symbol tag = switchNode.getTag(); 3.142 final boolean allInteger = tag.getSymbolType().isInteger(); 3.143 @@ -1958,7 +1981,6 @@ 3.144 method.tableswitch(lo, hi, defaultLabel, table); 3.145 } else { 3.146 final int[] ints = new int[size]; 3.147 - 3.148 for (int i = 0; i < size; i++) { 3.149 ints[i] = values[i]; 3.150 } 3.151 @@ -2004,6 +2026,8 @@ 3.152 3.153 @Override 3.154 public boolean enterThrowNode(final ThrowNode throwNode) { 3.155 + lineNumber(throwNode); 3.156 + 3.157 method._new(ECMAException.class).dup(); 3.158 3.159 final Source source = getLexicalContext().getCurrentFunction().getSource(); 3.160 @@ -2028,6 +2052,8 @@ 3.161 3.162 @Override 3.163 public boolean enterTryNode(final TryNode tryNode) { 3.164 + lineNumber(tryNode); 3.165 + 3.166 final Block body = tryNode.getBody(); 3.167 final List<Block> catchBlocks = tryNode.getCatchBlocks(); 3.168 final Symbol symbol = tryNode.getException(); 3.169 @@ -2124,12 +2150,15 @@ 3.170 3.171 @Override 3.172 public boolean enterVarNode(final VarNode varNode) { 3.173 + 3.174 final Node init = varNode.getInit(); 3.175 3.176 if (init == null) { 3.177 return false; 3.178 } 3.179 3.180 + lineNumber(varNode); 3.181 + 3.182 final Symbol varSymbol = varNode.getSymbol(); 3.183 assert varSymbol != null : "variable node " + varNode + " requires a symbol"; 3.184 3.185 @@ -2162,6 +2191,8 @@ 3.186 3.187 @Override 3.188 public boolean enterWhileNode(final WhileNode whileNode) { 3.189 + lineNumber(whileNode); 3.190 + 3.191 final Node test = whileNode.getTest(); 3.192 final Block body = whileNode.getBody(); 3.193 final Label breakLabel = whileNode.getBreakLabel(); 3.194 @@ -2184,7 +2215,7 @@ 3.195 } 3.196 3.197 private void closeWith() { 3.198 - if(method.hasScope()) { 3.199 + if (method.hasScope()) { 3.200 method.loadCompilerConstant(SCOPE); 3.201 method.invoke(ScriptRuntime.CLOSE_WITH); 3.202 method.storeCompilerConstant(SCOPE); 3.203 @@ -2227,7 +2258,7 @@ 3.204 // Always process body 3.205 body.accept(this); 3.206 3.207 - if(hasScope) { 3.208 + if (hasScope) { 3.209 // Ensure we always close the WithObject 3.210 final Label endLabel = new Label("with_end"); 3.211 final Label catchLabel = new Label("with_catch"); 3.212 @@ -3010,6 +3041,7 @@ 3.213 * @param block the block we are in 3.214 * @param ident identifier for block or function where applicable 3.215 */ 3.216 + @SuppressWarnings("resource") 3.217 private void printSymbols(final Block block, final String ident) { 3.218 if (!compiler.getEnv()._print_symbols) { 3.219 return; 3.220 @@ -3190,9 +3222,6 @@ 3.221 return; 3.222 } 3.223 3.224 - //System.err.println("Store with out discard that shouldn't just return " + assignNode); 3.225 - //new Throwable().printStackTrace(); 3.226 - 3.227 final Symbol symbol = assignNode.getSymbol(); 3.228 if (symbol.hasSlot()) { 3.229 method.dup().store(symbol); 3.230 @@ -3288,7 +3317,7 @@ 3.231 // Such immediately-called functions are invoked using INVOKESTATIC (see enterFunctionNode() of the embedded 3.232 // visitor of enterCallNode() for details), and if they don't need a callee, they don't have it on their 3.233 // static method's parameter list. 3.234 - if(lc.getOutermostFunction() == functionNode || 3.235 + if (lc.getOutermostFunction() == functionNode || 3.236 (!functionNode.needsCallee()) && lc.isFunctionDefinedInCurrentCall(originalFunctionNode)) { 3.237 return; 3.238 }
4.1 --- a/src/jdk/nashorn/internal/codegen/FinalizeTypes.java Tue May 07 14:36:57 2013 +0200 4.2 +++ b/src/jdk/nashorn/internal/codegen/FinalizeTypes.java Tue May 07 14:43:17 2013 +0200 4.3 @@ -228,19 +228,19 @@ 4.4 } 4.5 4.6 @Override 4.7 - public Node leaveBIT_AND(BinaryNode binaryNode) { 4.8 + public Node leaveBIT_AND(final BinaryNode binaryNode) { 4.9 assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); 4.10 return leaveBinary(binaryNode, Type.INT, Type.INT); 4.11 } 4.12 4.13 @Override 4.14 - public Node leaveBIT_OR(BinaryNode binaryNode) { 4.15 + public Node leaveBIT_OR(final BinaryNode binaryNode) { 4.16 assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); 4.17 return leaveBinary(binaryNode, Type.INT, Type.INT); 4.18 } 4.19 4.20 @Override 4.21 - public Node leaveBIT_XOR(BinaryNode binaryNode) { 4.22 + public Node leaveBIT_XOR(final BinaryNode binaryNode) { 4.23 assert binaryNode.getSymbol() != null && binaryNode.getSymbol().getSymbolType().isInteger() : "int coercion expected: " + binaryNode.getSymbol(); 4.24 return leaveBinary(binaryNode, Type.INT, Type.INT); 4.25 }
5.1 --- a/src/jdk/nashorn/internal/codegen/FoldConstants.java Tue May 07 14:36:57 2013 +0200 5.2 +++ b/src/jdk/nashorn/internal/codegen/FoldConstants.java Tue May 07 14:43:17 2013 +0200 5.3 @@ -88,7 +88,7 @@ 5.4 if (test instanceof LiteralNode) { 5.5 final Block shortCut = ((LiteralNode<?>)test).isTrue() ? ifNode.getPass() : ifNode.getFail(); 5.6 if (shortCut != null) { 5.7 - return new ExecuteNode(shortCut); 5.8 + return new ExecuteNode(shortCut.getLineNumber(), shortCut.getToken(), shortCut.getFinish(), shortCut); 5.9 } 5.10 return new EmptyNode(ifNode); 5.11 }
6.1 --- a/src/jdk/nashorn/internal/codegen/Label.java Tue May 07 14:36:57 2013 +0200 6.2 +++ b/src/jdk/nashorn/internal/codegen/Label.java Tue May 07 14:43:17 2013 +0200 6.3 @@ -27,6 +27,7 @@ 6.4 import java.util.ArrayDeque; 6.5 6.6 import jdk.nashorn.internal.codegen.types.Type; 6.7 +import jdk.nashorn.internal.runtime.Debug; 6.8 6.9 /** 6.10 * Abstraction for labels, separating a label from the underlying 6.11 @@ -35,13 +36,16 @@ 6.12 * 6.13 * see -Dnashorn.codegen.debug, --log=codegen 6.14 */ 6.15 -public class Label extends jdk.internal.org.objectweb.asm.Label { 6.16 +public final class Label { 6.17 /** Name of this label */ 6.18 private final String name; 6.19 6.20 /** Type stack at this label */ 6.21 private ArrayDeque<Type> stack; 6.22 6.23 + /** ASM representation of this label */ 6.24 + private jdk.internal.org.objectweb.asm.Label label; 6.25 + 6.26 /** 6.27 * Constructor 6.28 * 6.29 @@ -62,6 +66,14 @@ 6.30 this.name = label.name; 6.31 } 6.32 6.33 + 6.34 + jdk.internal.org.objectweb.asm.Label getLabel() { 6.35 + if (this.label == null) { 6.36 + this.label = new jdk.internal.org.objectweb.asm.Label(); 6.37 + } 6.38 + return label; 6.39 + } 6.40 + 6.41 ArrayDeque<Type> getStack() { 6.42 return stack; 6.43 } 6.44 @@ -72,12 +84,7 @@ 6.45 6.46 @Override 6.47 public String toString() { 6.48 - final StringBuilder sb = new StringBuilder(); 6.49 - String s = super.toString(); 6.50 - s = s.substring(1, s.length()); 6.51 - sb.append(name).append('_').append(Long.toHexString(Long.parseLong(s))); 6.52 - 6.53 - return sb.toString(); 6.54 + return name + '_' + Debug.id(this); 6.55 } 6.56 } 6.57
7.1 --- a/src/jdk/nashorn/internal/codegen/Lower.java Tue May 07 14:36:57 2013 +0200 7.2 +++ b/src/jdk/nashorn/internal/codegen/Lower.java Tue May 07 14:43:17 2013 +0200 7.3 @@ -32,6 +32,7 @@ 7.4 import java.util.ArrayList; 7.5 import java.util.Arrays; 7.6 import java.util.List; 7.7 + 7.8 import jdk.nashorn.internal.ir.BaseNode; 7.9 import jdk.nashorn.internal.ir.BinaryNode; 7.10 import jdk.nashorn.internal.ir.Block; 7.11 @@ -49,16 +50,15 @@ 7.12 import jdk.nashorn.internal.ir.IfNode; 7.13 import jdk.nashorn.internal.ir.LabelNode; 7.14 import jdk.nashorn.internal.ir.LexicalContext; 7.15 -import jdk.nashorn.internal.ir.LineNumberNode; 7.16 import jdk.nashorn.internal.ir.LiteralNode; 7.17 import jdk.nashorn.internal.ir.LoopNode; 7.18 import jdk.nashorn.internal.ir.Node; 7.19 import jdk.nashorn.internal.ir.ReturnNode; 7.20 +import jdk.nashorn.internal.ir.Statement; 7.21 import jdk.nashorn.internal.ir.SwitchNode; 7.22 import jdk.nashorn.internal.ir.Symbol; 7.23 import jdk.nashorn.internal.ir.ThrowNode; 7.24 import jdk.nashorn.internal.ir.TryNode; 7.25 -import jdk.nashorn.internal.ir.UnaryNode; 7.26 import jdk.nashorn.internal.ir.VarNode; 7.27 import jdk.nashorn.internal.ir.WhileNode; 7.28 import jdk.nashorn.internal.ir.WithNode; 7.29 @@ -93,21 +93,25 @@ 7.30 super(new BlockLexicalContext() { 7.31 7.32 @Override 7.33 - public List<Node> popStatements() { 7.34 - List<Node> newStatements = new ArrayList<>(); 7.35 + public List<Statement> popStatements() { 7.36 + final List<Statement> newStatements = new ArrayList<>(); 7.37 boolean terminated = false; 7.38 7.39 - final List<Node> statements = super.popStatements(); 7.40 - for (final Node statement : statements) { 7.41 + final List<Statement> statements = super.popStatements(); 7.42 + for (final Statement statement : statements) { 7.43 if (!terminated) { 7.44 newStatements.add(statement); 7.45 - if (statement.isTerminal()) { 7.46 + if (statement.isTerminal() || statement instanceof BreakNode || statement instanceof ContinueNode) { //TODO hasGoto? But some Loops are hasGoto too - why? 7.47 terminated = true; 7.48 } 7.49 } else { 7.50 - if (statement instanceof VarNode) { 7.51 - newStatements.add(((VarNode)statement).setInit(null)); 7.52 - } 7.53 + statement.accept(new NodeVisitor() { 7.54 + @Override 7.55 + public boolean enterVarNode(final VarNode varNode) { 7.56 + newStatements.add(varNode.setInit(null)); 7.57 + return false; 7.58 + } 7.59 + }); 7.60 } 7.61 } 7.62 return newStatements; 7.63 @@ -120,7 +124,7 @@ 7.64 final LexicalContext lc = getLexicalContext(); 7.65 final FunctionNode function = lc.getCurrentFunction(); 7.66 if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) { 7.67 - new ExecuteNode(block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this); 7.68 + new ExecuteNode(block.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this); 7.69 } 7.70 return true; 7.71 } 7.72 @@ -132,19 +136,20 @@ 7.73 7.74 final BlockLexicalContext lc = (BlockLexicalContext)getLexicalContext(); 7.75 7.76 - Node last = lc.getLastStatement(); 7.77 + Statement last = lc.getLastStatement(); 7.78 7.79 if (lc.isFunctionBody()) { 7.80 final FunctionNode currentFunction = getLexicalContext().getCurrentFunction(); 7.81 final boolean isProgram = currentFunction.isProgram(); 7.82 final ReturnNode returnNode = new ReturnNode( 7.83 + last == null ? block.getLineNumber() : last.getLineNumber(), //TODO? 7.84 currentFunction.getToken(), 7.85 currentFunction.getFinish(), 7.86 isProgram ? 7.87 compilerConstant(RETURN) : 7.88 LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)); 7.89 7.90 - last = returnNode.accept(this); 7.91 + last = (Statement)returnNode.accept(this); 7.92 } 7.93 7.94 if (last != null && last.isTerminal()) { 7.95 @@ -239,12 +244,6 @@ 7.96 } 7.97 7.98 @Override 7.99 - public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) { 7.100 - addStatement(lineNumberNode); // don't put it in lastStatement cache 7.101 - return false; 7.102 - } 7.103 - 7.104 - @Override 7.105 public Node leaveReturnNode(final ReturnNode returnNode) { 7.106 addStatement(returnNode); //ReturnNodes are always terminal, marked as such in constructor 7.107 return returnNode; 7.108 @@ -271,10 +270,10 @@ 7.109 }); 7.110 } 7.111 7.112 - private static List<Node> copyFinally(final Block finallyBody) { 7.113 - final List<Node> newStatements = new ArrayList<>(); 7.114 - for (final Node statement : finallyBody.getStatements()) { 7.115 - newStatements.add(ensureUniqueLabelsIn(statement)); 7.116 + private static List<Statement> copyFinally(final Block finallyBody) { 7.117 + final List<Statement> newStatements = new ArrayList<>(); 7.118 + for (final Statement statement : finallyBody.getStatements()) { 7.119 + newStatements.add((Statement)ensureUniqueLabelsIn(statement)); 7.120 if (statement.hasTerminalFlags()) { 7.121 return newStatements; 7.122 } 7.123 @@ -283,16 +282,17 @@ 7.124 } 7.125 7.126 private Block catchAllBlock(final TryNode tryNode) { 7.127 - final long token = tryNode.getToken(); 7.128 - final int finish = tryNode.getFinish(); 7.129 + final int lineNumber = tryNode.getLineNumber(); 7.130 + final long token = tryNode.getToken(); 7.131 + final int finish = tryNode.getFinish(); 7.132 7.133 final IdentNode exception = new IdentNode(token, finish, getLexicalContext().getCurrentFunction().uniqueName("catch_all")); 7.134 7.135 - final Block catchBody = new Block(token, finish, new ThrowNode(token, finish, new IdentNode(exception))). 7.136 + final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception))). 7.137 setIsTerminal(getLexicalContext(), true); //ends with throw, so terminal 7.138 7.139 - final CatchNode catchAllNode = new CatchNode(token, finish, new IdentNode(exception), null, catchBody); 7.140 - final Block catchAllBlock = new Block(token, finish, catchAllNode); 7.141 + final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody); 7.142 + final Block catchAllBlock = new Block(lineNumber, token, finish, catchAllNode); 7.143 7.144 //catchallblock -> catchallnode (catchnode) -> exception -> throw 7.145 7.146 @@ -304,7 +304,7 @@ 7.147 return new IdentNode(functionNode.getToken(), functionNode.getFinish(), cc.symbolName()); 7.148 } 7.149 7.150 - private static boolean isTerminal(final List<Node> statements) { 7.151 + private static boolean isTerminal(final List<Statement> statements) { 7.152 return !statements.isEmpty() && statements.get(statements.size() - 1).hasTerminalFlags(); 7.153 } 7.154 7.155 @@ -316,7 +316,7 @@ 7.156 * @return new try node after splicing finally code (same if nop) 7.157 */ 7.158 private Node spliceFinally(final TryNode tryNode, final List<ThrowNode> rethrows, final Block finallyBody) { 7.159 - final int finish = tryNode.getFinish(); 7.160 + final int finish = tryNode.getFinish(); 7.161 7.162 assert tryNode.getFinallyBody() == null; 7.163 7.164 @@ -338,11 +338,11 @@ 7.165 @Override 7.166 public Node leaveThrowNode(final ThrowNode throwNode) { 7.167 if (rethrows.contains(throwNode)) { 7.168 - final List<Node> newStatements = copyFinally(finallyBody); 7.169 + final List<Statement> newStatements = copyFinally(finallyBody); 7.170 if (!isTerminal(newStatements)) { 7.171 newStatements.add(throwNode); 7.172 } 7.173 - return new Block(throwNode.getToken(), throwNode.getFinish(), newStatements); 7.174 + return new Block(throwNode.getLineNumber(), throwNode.getToken(), throwNode.getFinish(), newStatements); 7.175 } 7.176 return throwNode; 7.177 } 7.178 @@ -360,14 +360,14 @@ 7.179 @Override 7.180 public Node leaveReturnNode(final ReturnNode returnNode) { 7.181 final Node expr = returnNode.getExpression(); 7.182 - final List<Node> newStatements = new ArrayList<>(); 7.183 + final List<Statement> newStatements = new ArrayList<>(); 7.184 7.185 final Node resultNode; 7.186 if (expr != null) { 7.187 //we need to evaluate the result of the return in case it is complex while 7.188 //still in the try block, store it in a result value and return it afterwards 7.189 resultNode = new IdentNode(Lower.this.compilerConstant(RETURN)); 7.190 - newStatements.add(new ExecuteNode(new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr))); 7.191 + newStatements.add(new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr))); 7.192 } else { 7.193 resultNode = null; 7.194 } 7.195 @@ -377,16 +377,16 @@ 7.196 newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode)); 7.197 } 7.198 7.199 - return new ExecuteNode(new Block(returnNode.getToken(), getLexicalContext().getCurrentBlock().getFinish(), newStatements)); 7.200 + return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), getLexicalContext().getCurrentBlock().getFinish(), newStatements)); 7.201 } 7.202 7.203 - private Node copy(final Node endpoint, final Node targetNode) { 7.204 + private Node copy(final Statement endpoint, final Node targetNode) { 7.205 if (!insideTry.contains(targetNode)) { 7.206 - final List<Node> newStatements = copyFinally(finallyBody); 7.207 + final List<Statement> newStatements = copyFinally(finallyBody); 7.208 if (!isTerminal(newStatements)) { 7.209 newStatements.add(endpoint); 7.210 } 7.211 - return new ExecuteNode(new Block(endpoint.getToken(), finish, newStatements)); 7.212 + return new ExecuteNode(endpoint.getLineNumber(), endpoint.getToken(), endpoint.getFinish(), new Block(endpoint.getLineNumber(), endpoint.getToken(), finish, newStatements)); 7.213 } 7.214 return endpoint; 7.215 } 7.216 @@ -394,7 +394,7 @@ 7.217 7.218 addStatement(newTryNode); 7.219 for (final Node statement : finallyBody.getStatements()) { 7.220 - addStatement(statement); 7.221 + addStatement((Statement)statement); 7.222 } 7.223 7.224 return newTryNode; 7.225 @@ -448,7 +448,7 @@ 7.226 if (tryNode.getCatchBlocks().isEmpty()) { 7.227 newTryNode = tryNode.setFinallyBody(null); 7.228 } else { 7.229 - Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), new ArrayList<Node>(Arrays.asList(tryNode.setFinallyBody(null)))); 7.230 + Block outerBody = new Block(tryNode.getLineNumber(), tryNode.getToken(), tryNode.getFinish(), new ArrayList<Statement>(Arrays.asList(tryNode.setFinallyBody(null)))); 7.231 newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null); 7.232 } 7.233 7.234 @@ -465,7 +465,7 @@ 7.235 public Node leaveVarNode(final VarNode varNode) { 7.236 addStatement(varNode); 7.237 if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && getLexicalContext().getCurrentFunction().isProgram()) { 7.238 - new ExecuteNode(varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this); 7.239 + new ExecuteNode(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this); 7.240 } 7.241 return varNode; 7.242 } 7.243 @@ -477,7 +477,7 @@ 7.244 7.245 if (conservativeAlwaysTrue(test)) { 7.246 //turn it into a for node without a test. 7.247 - final ForNode forNode = (ForNode)new ForNode(whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this); 7.248 + final ForNode forNode = (ForNode)new ForNode(whileNode.getLineNumber(), whileNode.getToken(), whileNode.getFinish(), null, null, body, null, ForNode.IS_FOR).accept(this); 7.249 getLexicalContext().replace(whileNode, forNode); 7.250 return forNode; 7.251 } 7.252 @@ -490,16 +490,6 @@ 7.253 return addStatement(withNode); 7.254 } 7.255 7.256 - @Override 7.257 - public Node leaveDELETE(final UnaryNode unaryNode) { 7.258 - final Node rhs = unaryNode.rhs(); 7.259 - if (rhs instanceof IdentNode || rhs instanceof BaseNode) { 7.260 - return unaryNode; 7.261 - } 7.262 - addStatement(new ExecuteNode(rhs)); 7.263 - return LiteralNode.newInstance(unaryNode, true); 7.264 - } 7.265 - 7.266 /** 7.267 * Given a function node that is a callee in a CallNode, replace it with 7.268 * the appropriate marker function. This is used by {@link CodeGenerator} 7.269 @@ -616,7 +606,7 @@ 7.270 } 7.271 7.272 7.273 - private Node addStatement(final Node statement) { 7.274 + private Node addStatement(final Statement statement) { 7.275 ((BlockLexicalContext)getLexicalContext()).appendStatement(statement); 7.276 return statement; 7.277 }
8.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java Tue May 07 14:36:57 2013 +0200 8.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java Tue May 07 14:43:17 2013 +0200 8.3 @@ -71,6 +71,7 @@ 8.4 import java.util.EnumSet; 8.5 import java.util.Iterator; 8.6 import java.util.List; 8.7 + 8.8 import jdk.internal.dynalink.support.NameCodec; 8.9 import jdk.internal.org.objectweb.asm.Handle; 8.10 import jdk.internal.org.objectweb.asm.MethodVisitor; 8.11 @@ -189,7 +190,7 @@ 8.12 @Override 8.13 public void begin() { 8.14 classEmitter.beginMethod(this); 8.15 - stack = new ArrayDeque<>(); 8.16 + newStack(); 8.17 method.visitCode(); 8.18 } 8.19 8.20 @@ -205,6 +206,10 @@ 8.21 classEmitter.endMethod(this); 8.22 } 8.23 8.24 + private void newStack() { 8.25 + stack = new ArrayDeque<>(); 8.26 + } 8.27 + 8.28 @Override 8.29 public String toString() { 8.30 return "methodEmitter: " + (functionNode == null ? method : functionNode.getName()).toString() + ' ' + Debug.id(this); 8.31 @@ -484,7 +489,7 @@ 8.32 name = THIS_DEBUGGER.symbolName(); 8.33 } 8.34 8.35 - method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start, end, symbol.getSlot()); 8.36 + method.visitLocalVariable(name, symbol.getSymbolType().getDescriptor(), null, start.getLabel(), end.getLabel(), symbol.getSlot()); 8.37 } 8.38 8.39 /** 8.40 @@ -509,17 +514,6 @@ 8.41 } 8.42 8.43 /** 8.44 - * Associate a variable with a given range 8.45 - * 8.46 - * @param name name of the variable 8.47 - * @param start start 8.48 - * @param end end 8.49 - */ 8.50 - void markerVariable(final String name, final Label start, final Label end) { 8.51 - method.visitLocalVariable(name, Type.OBJECT.getDescriptor(), null, start, end, 0); 8.52 - } 8.53 - 8.54 - /** 8.55 * Pops two integer types from the stack, performs a bitwise and and pushes 8.56 * the result 8.57 * 8.58 @@ -626,7 +620,7 @@ 8.59 * @param typeDescriptor type descriptor for exception 8.60 */ 8.61 void _try(final Label entry, final Label exit, final Label recovery, final String typeDescriptor) { 8.62 - method.visitTryCatchBlock(entry, exit, recovery, typeDescriptor); 8.63 + method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), typeDescriptor); 8.64 } 8.65 8.66 /** 8.67 @@ -638,7 +632,7 @@ 8.68 * @param clazz exception class 8.69 */ 8.70 void _try(final Label entry, final Label exit, final Label recovery, final Class<?> clazz) { 8.71 - method.visitTryCatchBlock(entry, exit, recovery, CompilerConstants.className(clazz)); 8.72 + method.visitTryCatchBlock(entry.getLabel(), exit.getLabel(), recovery.getLabel(), CompilerConstants.className(clazz)); 8.73 } 8.74 8.75 /** 8.76 @@ -1228,6 +1222,14 @@ 8.77 return invoke(INVOKEINTERFACE, className, methodName, methodDescriptor, true); 8.78 } 8.79 8.80 + static jdk.internal.org.objectweb.asm.Label[] getLabels(final Label... table) { 8.81 + final jdk.internal.org.objectweb.asm.Label[] internalLabels = new jdk.internal.org.objectweb.asm.Label[table.length]; 8.82 + for (int i = 0; i < table.length; i++) { 8.83 + internalLabels[i] = table[i].getLabel(); 8.84 + } 8.85 + return internalLabels; 8.86 + } 8.87 + 8.88 /** 8.89 * Generate a lookup switch, popping the switch value from the stack 8.90 * 8.91 @@ -1235,10 +1237,10 @@ 8.92 * @param values case values for the table 8.93 * @param table default label 8.94 */ 8.95 - void lookupswitch(final Label defaultLabel, final int[] values, final Label[] table) { 8.96 + void lookupswitch(final Label defaultLabel, final int[] values, final Label... table) {//Collection<Label> table) { 8.97 debug("lookupswitch", peekType()); 8.98 popType(Type.INT); 8.99 - method.visitLookupSwitchInsn(defaultLabel, values, table); 8.100 + method.visitLookupSwitchInsn(defaultLabel.getLabel(), values, getLabels(table)); 8.101 } 8.102 8.103 /** 8.104 @@ -1248,10 +1250,10 @@ 8.105 * @param defaultLabel default label 8.106 * @param table label table 8.107 */ 8.108 - void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label[] table) { 8.109 + void tableswitch(final int lo, final int hi, final Label defaultLabel, final Label... table) { 8.110 debug("tableswitch", peekType()); 8.111 popType(Type.INT); 8.112 - method.visitTableSwitchInsn(lo, hi, defaultLabel, table); 8.113 + method.visitTableSwitchInsn(lo, hi, defaultLabel.getLabel(), getLabels(table)); 8.114 } 8.115 8.116 /** 8.117 @@ -1358,7 +1360,7 @@ 8.118 popType(); 8.119 } 8.120 mergeStackTo(label); 8.121 - method.visitJumpInsn(opcode, label); 8.122 + method.visitJumpInsn(opcode, label.getLabel()); 8.123 } 8.124 8.125 /** 8.126 @@ -1487,9 +1489,9 @@ 8.127 * @param label destination label 8.128 */ 8.129 void _goto(final Label label) { 8.130 - debug("goto", label); 8.131 + //debug("goto", label); 8.132 jump(GOTO, label, 0); 8.133 - stack = null; 8.134 + stack = null; //whoever reaches the point after us provides the stack, because we don't 8.135 } 8.136 8.137 /** 8.138 @@ -1521,13 +1523,24 @@ 8.139 /** 8.140 * A join in control flow - helper function that makes sure all entry stacks 8.141 * discovered for the join point so far are equivalent 8.142 - * @param label 8.143 + * 8.144 + * MergeStack: we are about to enter a label. If its stack, label.getStack() is null 8.145 + * we have never been here before. Then we are expected to carry a stack with us. 8.146 + * 8.147 + * @param label label 8.148 */ 8.149 private void mergeStackTo(final Label label) { 8.150 + //sometimes we can do a merge stack without having a stack - i.e. when jumping ahead to dead code 8.151 + //see NASHORN-73. So far we had been saved by the line number nodes. This should have been fixed 8.152 + //by Lower removing everything after an unconditionally executed terminating statement OR a break 8.153 + //or continue in a block. Previously code left over after breaks and continues was still there 8.154 + //and caused bytecode to be generated - which crashed on stack not being there, as the merge 8.155 + //was not in fact preceeded by a visit. Furthermore, this led to ASM putting out its NOP NOP NOP 8.156 + //ATHROW sequences instead of no code being generated at all. This should now be fixed. 8.157 + assert stack != null : label + " entered with no stack. deadcode that remains?"; 8.158 + 8.159 final ArrayDeque<Type> labelStack = label.getStack(); 8.160 - //debug(labelStack == null ? " >> Control flow - first visit ", label : " >> Control flow - JOIN with ", labelStack, " at ", label); 8.161 if (labelStack == null) { 8.162 - assert stack != null; 8.163 label.setStack(stack.clone()); 8.164 return; 8.165 } 8.166 @@ -1548,14 +1561,14 @@ 8.167 if (stack == null) { 8.168 stack = label.getStack(); 8.169 if (stack == null) { 8.170 - stack = new ArrayDeque<>(); //we don't have a stack at this point. 8.171 + newStack(); 8.172 } 8.173 } 8.174 debug_label(label); 8.175 8.176 mergeStackTo(label); //we have to merge our stack to whatever is in the label 8.177 8.178 - method.visitLabel(label); 8.179 + method.visitLabel(label.getLabel()); 8.180 } 8.181 8.182 /** 8.183 @@ -2018,8 +2031,13 @@ 8.184 * @param line line number 8.185 * @param label label 8.186 */ 8.187 - void lineNumber(final int line, final Label label) { 8.188 - method.visitLineNumber(line, label); 8.189 + void lineNumber(final int line) { 8.190 + if (env._debug_lines) { 8.191 + debug_label("[LINE]", line); 8.192 + final jdk.internal.org.objectweb.asm.Label l = new jdk.internal.org.objectweb.asm.Label(); 8.193 + method.visitLabel(l); 8.194 + method.visitLineNumber(line, l); 8.195 + } 8.196 } 8.197 8.198 /* 8.199 @@ -2116,7 +2134,7 @@ 8.200 pad--; 8.201 } 8.202 8.203 - if (!stack.isEmpty()) { 8.204 + if (stack != null && !stack.isEmpty()) { 8.205 sb.append("{"); 8.206 sb.append(stack.size()); 8.207 sb.append(":");
9.1 --- a/src/jdk/nashorn/internal/codegen/Splitter.java Tue May 07 14:36:57 2013 +0200 9.2 +++ b/src/jdk/nashorn/internal/codegen/Splitter.java Tue May 07 14:43:17 2013 +0200 9.3 @@ -31,6 +31,7 @@ 9.4 import java.util.HashMap; 9.5 import java.util.List; 9.6 import java.util.Map; 9.7 + 9.8 import jdk.nashorn.internal.ir.Block; 9.9 import jdk.nashorn.internal.ir.FunctionNode; 9.10 import jdk.nashorn.internal.ir.FunctionNode.CompilationState; 9.11 @@ -40,6 +41,7 @@ 9.12 import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode.ArrayUnit; 9.13 import jdk.nashorn.internal.ir.Node; 9.14 import jdk.nashorn.internal.ir.SplitNode; 9.15 +import jdk.nashorn.internal.ir.Statement; 9.16 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 9.17 import jdk.nashorn.internal.runtime.DebugLogger; 9.18 import jdk.nashorn.internal.runtime.options.Options; 9.19 @@ -126,18 +128,18 @@ 9.20 final List<FunctionNode> dc = directChildren(functionNode); 9.21 9.22 final Block newBody = (Block)body.accept(new NodeVisitor() { 9.23 - @Override 9.24 - public boolean enterFunctionNode(final FunctionNode nestedFunction) { 9.25 - return dc.contains(nestedFunction); 9.26 - } 9.27 + @Override 9.28 + public boolean enterFunctionNode(final FunctionNode nestedFunction) { 9.29 + return dc.contains(nestedFunction); 9.30 + } 9.31 9.32 - @Override 9.33 - public Node leaveFunctionNode(final FunctionNode nestedFunction) { 9.34 - FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction); 9.35 - getLexicalContext().replace(nestedFunction, split); 9.36 - return split; 9.37 - } 9.38 - }); 9.39 + @Override 9.40 + public Node leaveFunctionNode(final FunctionNode nestedFunction) { 9.41 + FunctionNode split = new Splitter(compiler, nestedFunction, outermostCompileUnit).split(nestedFunction); 9.42 + getLexicalContext().replace(nestedFunction, split); 9.43 + return split; 9.44 + } 9.45 + }); 9.46 functionNode = functionNode.setBody(lc, newBody); 9.47 9.48 assert functionNode.getCompileUnit() != null; 9.49 @@ -181,11 +183,11 @@ 9.50 private Block splitBlock(final Block block, final FunctionNode function) { 9.51 getLexicalContext().setFlag(getLexicalContext().getCurrentFunction(), FunctionNode.IS_SPLIT); 9.52 9.53 - final List<Node> splits = new ArrayList<>(); 9.54 - List<Node> statements = new ArrayList<>(); 9.55 + final List<Statement> splits = new ArrayList<>(); 9.56 + List<Statement> statements = new ArrayList<>(); 9.57 long statementsWeight = 0; 9.58 9.59 - for (final Node statement : block.getStatements()) { 9.60 + for (final Statement statement : block.getStatements()) { 9.61 final long weight = WeighNodes.weigh(statement, weightCache); 9.62 9.63 if (statementsWeight + weight >= SPLIT_THRESHOLD || statement.isTerminal()) { 9.64 @@ -219,14 +221,15 @@ 9.65 * 9.66 * @return New split node. 9.67 */ 9.68 - private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Node> statements, final long weight) { 9.69 - final long token = parent.getToken(); 9.70 - final int finish = parent.getFinish(); 9.71 - final String name = function.uniqueName(SPLIT_PREFIX.symbolName()); 9.72 + private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List<Statement> statements, final long weight) { 9.73 + final int lineNumber = parent.getLineNumber(); 9.74 + final long token = parent.getToken(); 9.75 + final int finish = parent.getFinish(); 9.76 + final String name = function.uniqueName(SPLIT_PREFIX.symbolName()); 9.77 9.78 - final Block newBlock = new Block(token, finish, statements); 9.79 + final Block newBlock = new Block(lineNumber, token, finish, statements); 9.80 9.81 - return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT)); 9.82 + return new SplitNode(lineNumber, name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT)); 9.83 } 9.84 9.85 @Override
10.1 --- a/src/jdk/nashorn/internal/ir/Block.java Tue May 07 14:36:57 2013 +0200 10.2 +++ b/src/jdk/nashorn/internal/ir/Block.java Tue May 07 14:43:17 2013 +0200 10.3 @@ -44,7 +44,7 @@ 10.4 @Immutable 10.5 public class Block extends BreakableNode implements Flags<Block> { 10.6 /** List of statements */ 10.7 - protected final List<Node> statements; 10.8 + protected final List<Statement> statements; 10.9 10.10 /** Symbol table - keys must be returned in the order they were put in. */ 10.11 protected final Map<String, Symbol> symbols; 10.12 @@ -76,12 +76,13 @@ 10.13 /** 10.14 * Constructor 10.15 * 10.16 + * @param lineNumber line number 10.17 * @param token token 10.18 * @param finish finish 10.19 * @param statements statements 10.20 */ 10.21 - public Block(final long token, final int finish, final Node... statements) { 10.22 - super(token, finish, new Label("block_break")); 10.23 + public Block(final int lineNumber, final long token, final int finish, final Statement... statements) { 10.24 + super(lineNumber, token, finish, new Label("block_break")); 10.25 10.26 this.statements = Arrays.asList(statements); 10.27 this.symbols = new LinkedHashMap<>(); 10.28 @@ -92,15 +93,16 @@ 10.29 /** 10.30 * Constructor 10.31 * 10.32 + * @param lineNumber line number 10.33 * @param token token 10.34 * @param finish finish 10.35 * @param statements statements 10.36 */ 10.37 - public Block(final long token, final int finish, final List<Node> statements) { 10.38 - this(token, finish, statements.toArray(new Node[statements.size()])); 10.39 + public Block(final int lineNumber, final long token, final int finish, final List<Statement> statements) { 10.40 + this(lineNumber, token, finish, statements.toArray(new Statement[statements.size()])); 10.41 } 10.42 10.43 - private Block(final Block block, final int finish, final List<Node> statements, final int flags, final Map<String, Symbol> symbols) { 10.44 + private Block(final Block block, final int finish, final List<Statement> statements, final int flags, final Map<String, Symbol> symbols) { 10.45 super(block); 10.46 this.statements = statements; 10.47 this.flags = flags; 10.48 @@ -131,7 +133,7 @@ 10.49 @Override 10.50 public Node accept(final LexicalContext lc, final NodeVisitor visitor) { 10.51 if (visitor.enterBlock(this)) { 10.52 - return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Node.class, statements))); 10.53 + return visitor.leaveBlock(setStatements(lc, Node.accept(visitor, Statement.class, statements))); 10.54 } 10.55 10.56 return this; 10.57 @@ -226,7 +228,7 @@ 10.58 * 10.59 * @return a list of statements 10.60 */ 10.61 - public List<Node> getStatements() { 10.62 + public List<Statement> getStatements() { 10.63 return Collections.unmodifiableList(statements); 10.64 } 10.65 10.66 @@ -237,7 +239,7 @@ 10.67 * @param statements new statement list 10.68 * @return new block if statements changed, identity of statements == block.statements 10.69 */ 10.70 - public Block setStatements(final LexicalContext lc, final List<Node> statements) { 10.71 + public Block setStatements(final LexicalContext lc, final List<Statement> statements) { 10.72 if (this.statements == statements) { 10.73 return this; 10.74 }
11.1 --- a/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Tue May 07 14:36:57 2013 +0200 11.2 +++ b/src/jdk/nashorn/internal/ir/BlockLexicalContext.java Tue May 07 14:43:17 2013 +0200 11.3 @@ -41,16 +41,16 @@ 11.4 public class BlockLexicalContext extends LexicalContext { 11.5 /** statement stack, each block on the lexical context maintains one of these, which is 11.6 * committed to the block on pop */ 11.7 - private Deque<List<Node>> sstack = new ArrayDeque<>(); 11.8 + private Deque<List<Statement>> sstack = new ArrayDeque<>(); 11.9 11.10 /** Last non debug statement emitted in this context */ 11.11 - protected Node lastStatement; 11.12 + protected Statement lastStatement; 11.13 11.14 @Override 11.15 public <T extends LexicalContextNode> T push(final T node) { 11.16 T pushed = super.push(node); 11.17 if (node instanceof Block) { 11.18 - sstack.push(new ArrayList<Node>()); 11.19 + sstack.push(new ArrayList<Statement>()); 11.20 } 11.21 return pushed; 11.22 } 11.23 @@ -59,7 +59,7 @@ 11.24 * Get the statement list from the stack, possibly filtered 11.25 * @return statement list 11.26 */ 11.27 - protected List<Node> popStatements() { 11.28 + protected List<Statement> popStatements() { 11.29 return sstack.pop(); 11.30 } 11.31 11.32 @@ -68,7 +68,7 @@ 11.33 public <T extends LexicalContextNode> T pop(final T node) { 11.34 T expected = node; 11.35 if (node instanceof Block) { 11.36 - final List<Node> newStatements = popStatements(); 11.37 + final List<Statement> newStatements = popStatements(); 11.38 expected = (T)((Block)node).setStatements(this, newStatements); 11.39 if (!sstack.isEmpty()) { 11.40 lastStatement = lastStatement(sstack.peek()); 11.41 @@ -81,12 +81,10 @@ 11.42 * Append a statement to the block being generated 11.43 * @param statement statement to add 11.44 */ 11.45 - public void appendStatement(final Node statement) { 11.46 + public void appendStatement(final Statement statement) { 11.47 assert statement != null; 11.48 sstack.peek().add(statement); 11.49 - if (!statement.isDebug()) { 11.50 - lastStatement = statement; 11.51 - } 11.52 + lastStatement = statement; 11.53 } 11.54 11.55 /** 11.56 @@ -94,26 +92,24 @@ 11.57 * @param statement statement to prepend 11.58 * @return the prepended statement 11.59 */ 11.60 - public Node prependStatement(final Node statement) { 11.61 + public Node prependStatement(final Statement statement) { 11.62 assert statement != null; 11.63 sstack.peek().add(0, statement); 11.64 return statement; 11.65 } 11.66 11.67 /** 11.68 - * Get the last (non debug) statement that was emitted into a block 11.69 + * Get the last statement that was emitted into a block 11.70 * @return the last statement emitted 11.71 */ 11.72 - public Node getLastStatement() { 11.73 + public Statement getLastStatement() { 11.74 return lastStatement; 11.75 } 11.76 11.77 - private static Node lastStatement(final List<Node> statements) { 11.78 - for (final ListIterator<Node> iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) { 11.79 - final Node node = iter.previous(); 11.80 - if (!node.isDebug()) { 11.81 - return node; 11.82 - } 11.83 + private static Statement lastStatement(final List<Statement> statements) { 11.84 + for (final ListIterator<Statement> iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) { 11.85 + final Statement node = iter.previous(); 11.86 + return node; 11.87 } 11.88 return null; 11.89 }
12.1 --- a/src/jdk/nashorn/internal/ir/BreakNode.java Tue May 07 14:36:57 2013 +0200 12.2 +++ b/src/jdk/nashorn/internal/ir/BreakNode.java Tue May 07 14:43:17 2013 +0200 12.3 @@ -32,19 +32,20 @@ 12.4 * IR representation for {@code break} statements. 12.5 */ 12.6 @Immutable 12.7 -public final class BreakNode extends Node { 12.8 +public final class BreakNode extends Statement { 12.9 12.10 private final IdentNode label; 12.11 12.12 /** 12.13 * Constructor 12.14 * 12.15 - * @param token token 12.16 - * @param finish finish 12.17 - * @param label label for break or null if none 12.18 + * @param lineNumber line number 12.19 + * @param token token 12.20 + * @param finish finish 12.21 + * @param label label for break or null if none 12.22 */ 12.23 - public BreakNode(final long token, final int finish, final IdentNode label) { 12.24 - super(token, finish); 12.25 + public BreakNode(final int lineNumber, final long token, final int finish, final IdentNode label) { 12.26 + super(lineNumber, token, finish); 12.27 this.label = label; 12.28 } 12.29
13.1 --- a/src/jdk/nashorn/internal/ir/BreakableNode.java Tue May 07 14:36:57 2013 +0200 13.2 +++ b/src/jdk/nashorn/internal/ir/BreakableNode.java Tue May 07 14:43:17 2013 +0200 13.3 @@ -44,12 +44,13 @@ 13.4 /** 13.5 * Constructor 13.6 * 13.7 + * @param lineNumber line number 13.8 * @param token token 13.9 * @param finish finish 13.10 * @param breakLabel break label 13.11 */ 13.12 - protected BreakableNode(final long token, final int finish, final Label breakLabel) { 13.13 - super(token, finish); 13.14 + protected BreakableNode(final int lineNumber, final long token, final int finish, final Label breakLabel) { 13.15 + super(lineNumber, token, finish); 13.16 this.breakLabel = breakLabel; 13.17 } 13.18
14.1 --- a/src/jdk/nashorn/internal/ir/CallNode.java Tue May 07 14:36:57 2013 +0200 14.2 +++ b/src/jdk/nashorn/internal/ir/CallNode.java Tue May 07 14:43:17 2013 +0200 14.3 @@ -136,13 +136,14 @@ 14.4 /** 14.5 * Constructors 14.6 * 14.7 - * @param token token 14.8 - * @param finish finish 14.9 - * @param function the function to call 14.10 - * @param args args to the call 14.11 + * @param lineNumber line number 14.12 + * @param token token 14.13 + * @param finish finish 14.14 + * @param function the function to call 14.15 + * @param args args to the call 14.16 */ 14.17 - public CallNode(final long token, final int finish, final Node function, final List<Node> args) { 14.18 - super(token, finish); 14.19 + public CallNode(final int lineNumber, final long token, final int finish, final Node function, final List<Node> args) { 14.20 + super(lineNumber, token, finish); 14.21 14.22 this.function = function; 14.23 this.args = args;
15.1 --- a/src/jdk/nashorn/internal/ir/CatchNode.java Tue May 07 14:36:57 2013 +0200 15.2 +++ b/src/jdk/nashorn/internal/ir/CatchNode.java Tue May 07 14:43:17 2013 +0200 15.3 @@ -32,7 +32,7 @@ 15.4 * IR representation of a catch clause. 15.5 */ 15.6 @Immutable 15.7 -public final class CatchNode extends Node { 15.8 +public final class CatchNode extends Statement { 15.9 /** Exception identifier. */ 15.10 private final IdentNode exception; 15.11 15.12 @@ -45,14 +45,15 @@ 15.13 /** 15.14 * Constructors 15.15 * 15.16 + * @param lineNumber lineNumber 15.17 * @param token token 15.18 * @param finish finish 15.19 * @param exception variable name of exception 15.20 * @param exceptionCondition exception condition 15.21 * @param body catch body 15.22 */ 15.23 - public CatchNode(final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) { 15.24 - super(token, finish); 15.25 + public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) { 15.26 + super(lineNumber, token, finish); 15.27 this.exception = exception; 15.28 this.exceptionCondition = exceptionCondition; 15.29 this.body = body;
16.1 --- a/src/jdk/nashorn/internal/ir/ContinueNode.java Tue May 07 14:36:57 2013 +0200 16.2 +++ b/src/jdk/nashorn/internal/ir/ContinueNode.java Tue May 07 14:43:17 2013 +0200 16.3 @@ -32,19 +32,20 @@ 16.4 * IR representation for CONTINUE statements. 16.5 */ 16.6 @Immutable 16.7 -public class ContinueNode extends Node { 16.8 +public class ContinueNode extends Statement { 16.9 16.10 private IdentNode label; 16.11 16.12 /** 16.13 * Constructor 16.14 * 16.15 - * @param token token 16.16 - * @param finish finish 16.17 - * @param label label for break or null if none 16.18 + * @param lineNumber line number 16.19 + * @param token token 16.20 + * @param finish finish 16.21 + * @param label label for break or null if none 16.22 */ 16.23 - public ContinueNode(final long token, final int finish, final IdentNode label) { 16.24 - super(token, finish); 16.25 + public ContinueNode(final int lineNumber, final long token, final int finish, final IdentNode label) { 16.26 + super(lineNumber, token, finish); 16.27 this.label = label; 16.28 } 16.29
17.1 --- a/src/jdk/nashorn/internal/ir/EmptyNode.java Tue May 07 14:36:57 2013 +0200 17.2 +++ b/src/jdk/nashorn/internal/ir/EmptyNode.java Tue May 07 14:43:17 2013 +0200 17.3 @@ -32,25 +32,26 @@ 17.4 * IR representation for an empty statement. 17.5 */ 17.6 @Immutable 17.7 -public final class EmptyNode extends Node { 17.8 +public final class EmptyNode extends Statement { 17.9 17.10 /** 17.11 * Constructor 17.12 * 17.13 * @param node node to wrap 17.14 */ 17.15 - public EmptyNode(final Node node) { 17.16 + public EmptyNode(final Statement node) { 17.17 super(node); 17.18 } 17.19 17.20 /** 17.21 * Constructor 17.22 * 17.23 + * @param lineNumber line number 17.24 * @param token token 17.25 * @param finish finish 17.26 */ 17.27 - public EmptyNode(final long token, final int finish) { 17.28 - super(token, finish); 17.29 + public EmptyNode(final int lineNumber, final long token, final int finish) { 17.30 + super(lineNumber, token, finish); 17.31 } 17.32 17.33
18.1 --- a/src/jdk/nashorn/internal/ir/ExecuteNode.java Tue May 07 14:36:57 2013 +0200 18.2 +++ b/src/jdk/nashorn/internal/ir/ExecuteNode.java Tue May 07 14:43:17 2013 +0200 18.3 @@ -34,19 +34,20 @@ 18.4 * statements being added to the IR 18.5 */ 18.6 @Immutable 18.7 -public final class ExecuteNode extends Node { 18.8 +public final class ExecuteNode extends Statement { 18.9 /** Expression to execute. */ 18.10 private final Node expression; 18.11 18.12 /** 18.13 * Constructor 18.14 * 18.15 + * @param lineNumber line number 18.16 * @param token token 18.17 * @param finish finish 18.18 * @param expression the expression to execute 18.19 */ 18.20 - public ExecuteNode(final long token, final int finish, final Node expression) { 18.21 - super(token, finish); 18.22 + public ExecuteNode(final int lineNumber, final long token, final int finish, final Node expression) { 18.23 + super(lineNumber, token, finish); 18.24 this.expression = expression; 18.25 } 18.26 18.27 @@ -55,16 +56,6 @@ 18.28 this.expression = expression; 18.29 } 18.30 18.31 - /** 18.32 - * Constructor 18.33 - * 18.34 - * @param expression an expression to wrap, from which source, tokens and finish are also inherited 18.35 - */ 18.36 - public ExecuteNode(final Node expression) { 18.37 - super(expression.getToken(), expression.getFinish()); 18.38 - this.expression = expression; 18.39 - } 18.40 - 18.41 @Override 18.42 public boolean isTerminal() { 18.43 return expression.isTerminal();
19.1 --- a/src/jdk/nashorn/internal/ir/ForNode.java Tue May 07 14:36:57 2013 +0200 19.2 +++ b/src/jdk/nashorn/internal/ir/ForNode.java Tue May 07 14:43:17 2013 +0200 19.3 @@ -56,16 +56,17 @@ 19.4 /** 19.5 * Constructor 19.6 * 19.7 - * @param token token 19.8 - * @param finish finish 19.9 - * @param init init 19.10 - * @param test test 19.11 - * @param body body 19.12 - * @param modify modify 19.13 - * @param flags flags 19.14 + * @param lineNumber line number 19.15 + * @param token token 19.16 + * @param finish finish 19.17 + * @param init initialization expression 19.18 + * @param test test 19.19 + * @param body body 19.20 + * @param modify modify 19.21 + * @param flags flags 19.22 */ 19.23 - public ForNode(final long token, final int finish, final Node init, final Node test, final Block body, final Node modify, final int flags) { 19.24 - super(token, finish, test, body, false); 19.25 + public ForNode(final int lineNumber, final long token, final int finish, final Node init, final Node test, final Block body, final Node modify, final int flags) { 19.26 + super(lineNumber, token, finish, test, body, false); 19.27 this.init = init; 19.28 this.modify = modify; 19.29 this.flags = flags;
20.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java Tue May 07 14:36:57 2013 +0200 20.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java Tue May 07 14:43:17 2013 +0200 20.3 @@ -204,6 +204,7 @@ 20.4 * Constructor 20.5 * 20.6 * @param source the source 20.7 + * @param lineNumber line number 20.8 * @param token token 20.9 * @param finish finish 20.10 * @param firstToken first token of the funtion node (including the function declaration) 20.11 @@ -216,6 +217,7 @@ 20.12 */ 20.13 public FunctionNode( 20.14 final Source source, 20.15 + final int lineNumber, 20.16 final long token, 20.17 final int finish, 20.18 final long firstToken, 20.19 @@ -225,7 +227,7 @@ 20.20 final List<IdentNode> parameters, 20.21 final FunctionNode.Kind kind, 20.22 final int flags) { 20.23 - super(token, finish); 20.24 + super(lineNumber, token, finish); 20.25 20.26 this.source = source; 20.27 this.ident = ident; 20.28 @@ -303,6 +305,20 @@ 20.29 } 20.30 20.31 /** 20.32 + * Throw away the snapshot, if any, to save memory. Used when heuristic 20.33 + * determines that a method is not worth specializing 20.34 + * 20.35 + * @param lc lexical context 20.36 + * @return new function node if a snapshot was present, now with snapsnot null 20.37 + */ 20.38 + public FunctionNode clearSnapshot(final LexicalContext lc) { 20.39 + if (this.snapshot == null) { 20.40 + return this; 20.41 + } 20.42 + return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, compilationState, body, parameters, null, hints)); 20.43 + } 20.44 + 20.45 + /** 20.46 * Take a snapshot of this function node at a given point in time 20.47 * and store it in the function node 20.48 * @param lc lexical context 20.49 @@ -806,5 +822,4 @@ 20.50 public Symbol compilerConstant(final CompilerConstants cc) { 20.51 return body.getExistingSymbol(cc.symbolName()); 20.52 } 20.53 - 20.54 }
21.1 --- a/src/jdk/nashorn/internal/ir/IfNode.java Tue May 07 14:36:57 2013 +0200 21.2 +++ b/src/jdk/nashorn/internal/ir/IfNode.java Tue May 07 14:43:17 2013 +0200 21.3 @@ -32,7 +32,7 @@ 21.4 * IR representation for an IF statement. 21.5 */ 21.6 @Immutable 21.7 -public final class IfNode extends Node { 21.8 +public final class IfNode extends Statement { 21.9 /** Test expression. */ 21.10 private final Node test; 21.11 21.12 @@ -45,14 +45,15 @@ 21.13 /** 21.14 * Constructor 21.15 * 21.16 - * @param token token 21.17 - * @param finish finish 21.18 - * @param test test 21.19 - * @param pass block to execute when test passes 21.20 - * @param fail block to execute when test fails or null 21.21 + * @param lineNumber line number 21.22 + * @param token token 21.23 + * @param finish finish 21.24 + * @param test test 21.25 + * @param pass block to execute when test passes 21.26 + * @param fail block to execute when test fails or null 21.27 */ 21.28 - public IfNode(final long token, final int finish, final Node test, final Block pass, final Block fail) { 21.29 - super(token, finish); 21.30 + public IfNode(final int lineNumber, final long token, final int finish, final Node test, final Block pass, final Block fail) { 21.31 + super(lineNumber, token, finish); 21.32 this.test = test; 21.33 this.pass = pass; 21.34 this.fail = fail;
22.1 --- a/src/jdk/nashorn/internal/ir/LabelNode.java Tue May 07 14:36:57 2013 +0200 22.2 +++ b/src/jdk/nashorn/internal/ir/LabelNode.java Tue May 07 14:43:17 2013 +0200 22.3 @@ -42,13 +42,14 @@ 22.4 /** 22.5 * Constructor 22.6 * 22.7 - * @param token token 22.8 - * @param finish finish 22.9 - * @param label label identifier 22.10 - * @param body body of label node 22.11 + * @param lineNumber line number 22.12 + * @param token token 22.13 + * @param finish finish 22.14 + * @param label label identifier 22.15 + * @param body body of label node 22.16 */ 22.17 - public LabelNode(final long token, final int finish, final IdentNode label, final Block body) { 22.18 - super(token, finish); 22.19 + public LabelNode(final int lineNumber, final long token, final int finish, final IdentNode label, final Block body) { 22.20 + super(lineNumber, token, finish); 22.21 22.22 this.label = label; 22.23 this.body = body;
23.1 --- a/src/jdk/nashorn/internal/ir/LexicalContextNode.java Tue May 07 14:36:57 2013 +0200 23.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContextNode.java Tue May 07 14:43:17 2013 +0200 23.3 @@ -30,15 +30,16 @@ 23.4 * Superclass for nodes that can be part of the lexical context 23.5 * @see LexicalContext 23.6 */ 23.7 -public abstract class LexicalContextNode extends Node { 23.8 +public abstract class LexicalContextNode extends Statement { 23.9 /** 23.10 * Constructor 23.11 * 23.12 - * @param token token 23.13 - * @param finish finish 23.14 + * @param lineNumber line number 23.15 + * @param token token 23.16 + * @param finish finish 23.17 */ 23.18 - protected LexicalContextNode(final long token, final int finish) { 23.19 - super(token, finish); 23.20 + protected LexicalContextNode(final int lineNumber, final long token, final int finish) { 23.21 + super(lineNumber, token, finish); 23.22 } 23.23 23.24 /**
24.1 --- a/src/jdk/nashorn/internal/ir/LineNumberNode.java Tue May 07 14:36:57 2013 +0200 24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 24.3 @@ -1,89 +0,0 @@ 24.4 -/* 24.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 24.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 24.7 - * 24.8 - * This code is free software; you can redistribute it and/or modify it 24.9 - * under the terms of the GNU General Public License version 2 only, as 24.10 - * published by the Free Software Foundation. Oracle designates this 24.11 - * particular file as subject to the "Classpath" exception as provided 24.12 - * by Oracle in the LICENSE file that accompanied this code. 24.13 - * 24.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 24.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 24.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24.17 - * version 2 for more details (a copy is included in the LICENSE file that 24.18 - * accompanied this code). 24.19 - * 24.20 - * You should have received a copy of the GNU General Public License version 24.21 - * 2 along with this work; if not, write to the Free Software Foundation, 24.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 24.23 - * 24.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 24.25 - * or visit www.oracle.com if you need additional information or have any 24.26 - * questions. 24.27 - */ 24.28 - 24.29 -package jdk.nashorn.internal.ir; 24.30 - 24.31 -import jdk.nashorn.internal.ir.annotations.Immutable; 24.32 -import jdk.nashorn.internal.ir.visitor.NodeVisitor; 24.33 -import jdk.nashorn.internal.parser.Token; 24.34 - 24.35 -/** 24.36 - * IR Node representing a line number 24.37 - */ 24.38 -@Immutable 24.39 -public final class LineNumberNode extends Node { 24.40 - /** Line number */ 24.41 - private final int lineNumber; 24.42 - 24.43 - /** 24.44 - * Constructor 24.45 - * 24.46 - * @param token token 24.47 - * @param lineNumber the line number 24.48 - */ 24.49 - public LineNumberNode(final long token, final int lineNumber) { 24.50 - super(token, Token.descPosition(token)); 24.51 - this.lineNumber = lineNumber; 24.52 - } 24.53 - 24.54 - private LineNumberNode(final LineNumberNode lineNumberNode) { 24.55 - super(lineNumberNode); 24.56 - this.lineNumber = lineNumberNode.getLineNumber(); 24.57 - } 24.58 - 24.59 - @Override 24.60 - public Node accept(final NodeVisitor visitor) { 24.61 - if (visitor.enterLineNumberNode(this)) { 24.62 - return visitor.leaveLineNumberNode(this); 24.63 - } 24.64 - 24.65 - return this; 24.66 - } 24.67 - 24.68 - @Override 24.69 - public void toString(final StringBuilder sb) { 24.70 - sb.append("[|"); 24.71 - sb.append(lineNumber); 24.72 - sb.append("|]"); 24.73 - } 24.74 - 24.75 - @Override 24.76 - public boolean isAtom() { 24.77 - return true; 24.78 - } 24.79 - 24.80 - /** 24.81 - * Get the line number 24.82 - * @return line number 24.83 - */ 24.84 - public int getLineNumber() { 24.85 - return lineNumber; 24.86 - } 24.87 - 24.88 - @Override 24.89 - public boolean isDebug() { 24.90 - return true; 24.91 - } 24.92 -}
25.1 --- a/src/jdk/nashorn/internal/ir/LoopNode.java Tue May 07 14:36:57 2013 +0200 25.2 +++ b/src/jdk/nashorn/internal/ir/LoopNode.java Tue May 07 14:43:17 2013 +0200 25.3 @@ -49,14 +49,15 @@ 25.4 /** 25.5 * Constructor 25.6 * 25.7 - * @param token token 25.8 - * @param finish finish 25.9 - * @param test test, or null if infinite loop 25.10 - * @param body loop body 25.11 + * @param lineNumber lineNumber 25.12 + * @param token token 25.13 + * @param finish finish 25.14 + * @param test test, or null if infinite loop 25.15 + * @param body loop body 25.16 * @param controlFlowEscapes controlFlowEscapes 25.17 */ 25.18 - protected LoopNode(final long token, final int finish, final Node test, final Block body, final boolean controlFlowEscapes) { 25.19 - super(token, finish, new Label("while_break")); 25.20 + protected LoopNode(final int lineNumber, final long token, final int finish, final Node test, final Block body, final boolean controlFlowEscapes) { 25.21 + super(lineNumber, token, finish, new Label("while_break")); 25.22 this.continueLabel = new Label("while_continue"); 25.23 this.test = test; 25.24 this.body = body;
26.1 --- a/src/jdk/nashorn/internal/ir/Node.java Tue May 07 14:36:57 2013 +0200 26.2 +++ b/src/jdk/nashorn/internal/ir/Node.java Tue May 07 14:43:17 2013 +0200 26.3 @@ -154,15 +154,6 @@ 26.4 } 26.5 26.6 /** 26.7 - * Is this a debug info node like LineNumberNode etc? 26.8 - * 26.9 - * @return true if this is a debug node 26.10 - */ 26.11 - public boolean isDebug() { 26.12 - return false; 26.13 - } 26.14 - 26.15 - /** 26.16 * For reference copies - ensure that labels in the copy node are unique 26.17 * using an appropriate copy constructor 26.18 * @param lc lexical context
27.1 --- a/src/jdk/nashorn/internal/ir/ReturnNode.java Tue May 07 14:36:57 2013 +0200 27.2 +++ b/src/jdk/nashorn/internal/ir/ReturnNode.java Tue May 07 14:43:17 2013 +0200 27.3 @@ -34,19 +34,20 @@ 27.4 * IR representation for RETURN or YIELD statements. 27.5 */ 27.6 @Immutable 27.7 -public class ReturnNode extends Node { 27.8 +public class ReturnNode extends Statement { 27.9 /** Optional expression. */ 27.10 private final Node expression; 27.11 27.12 /** 27.13 * Constructor 27.14 * 27.15 + * @param lineNumber line number 27.16 * @param token token 27.17 * @param finish finish 27.18 * @param expression expression to return 27.19 */ 27.20 - public ReturnNode(final long token, final int finish, final Node expression) { 27.21 - super(token, finish); 27.22 + public ReturnNode(final int lineNumber, final long token, final int finish, final Node expression) { 27.23 + super(lineNumber, token, finish); 27.24 this.expression = expression; 27.25 } 27.26 27.27 @@ -99,9 +100,9 @@ 27.28 27.29 @Override 27.30 public void toString(final StringBuilder sb) { 27.31 - sb.append(isYield() ? "yield" : "return "); 27.32 - 27.33 + sb.append(isYield() ? "yield" : "return"); 27.34 if (expression != null) { 27.35 + sb.append(' '); 27.36 expression.toString(sb); 27.37 } 27.38 }
28.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java Tue May 07 14:36:57 2013 +0200 28.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java Tue May 07 14:43:17 2013 +0200 28.3 @@ -46,12 +46,13 @@ 28.4 /** 28.5 * Constructor 28.6 * 28.7 + * @param lineNumber lineNumber 28.8 * @param name name of split node 28.9 * @param body body of split code 28.10 * @param compileUnit compile unit to use for the body 28.11 */ 28.12 - public SplitNode(final String name, final Node body, final CompileUnit compileUnit) { 28.13 - super(body.getToken(), body.getFinish()); 28.14 + public SplitNode(final int lineNumber, final String name, final Node body, final CompileUnit compileUnit) { 28.15 + super(lineNumber, body.getToken(), body.getFinish()); 28.16 this.name = name; 28.17 this.body = body; 28.18 this.compileUnit = compileUnit;
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/src/jdk/nashorn/internal/ir/Statement.java Tue May 07 14:43:17 2013 +0200 29.3 @@ -0,0 +1,80 @@ 29.4 +/* 29.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.7 + * 29.8 + * This code is free software; you can redistribute it and/or modify it 29.9 + * under the terms of the GNU General Public License version 2 only, as 29.10 + * published by the Free Software Foundation. Oracle designates this 29.11 + * particular file as subject to the "Classpath" exception as provided 29.12 + * by Oracle in the LICENSE file that accompanied this code. 29.13 + * 29.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 29.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 29.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29.17 + * version 2 for more details (a copy is included in the LICENSE file that 29.18 + * accompanied this code). 29.19 + * 29.20 + * You should have received a copy of the GNU General Public License version 29.21 + * 2 along with this work; if not, write to the Free Software Foundation, 29.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 29.23 + * 29.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 29.25 + * or visit www.oracle.com if you need additional information or have any 29.26 + * questions. 29.27 + */ 29.28 + 29.29 +package jdk.nashorn.internal.ir; 29.30 + 29.31 +/** 29.32 + * Statement is something that becomes code and can be stepped past. A block is 29.33 + * made up of statements. The only node subclass that needs to keep token and 29.34 + * location information is the Statement 29.35 + */ 29.36 +public abstract class Statement extends Node { 29.37 + 29.38 + private final int lineNumber; 29.39 + 29.40 + /** 29.41 + * Constructor 29.42 + * 29.43 + * @param lineNumber line number 29.44 + * @param token token 29.45 + * @param finish finish 29.46 + */ 29.47 + public Statement(final int lineNumber, final long token, final int finish) { 29.48 + super(token, finish); 29.49 + this.lineNumber = lineNumber; 29.50 + } 29.51 + 29.52 + /** 29.53 + * Constructor 29.54 + * 29.55 + * @param lineNumber line number 29.56 + * @param token token 29.57 + * @param start start 29.58 + * @param finish finish 29.59 + */ 29.60 + protected Statement(final int lineNumber, final long token, final int start, final int finish) { 29.61 + super(token, start, finish); 29.62 + this.lineNumber = lineNumber; 29.63 + } 29.64 + 29.65 + /** 29.66 + * Copy constructor 29.67 + * 29.68 + * @param node source node 29.69 + */ 29.70 + protected Statement(final Statement node) { 29.71 + super(node); 29.72 + this.lineNumber = node.lineNumber; 29.73 + } 29.74 + 29.75 + /** 29.76 + * Return the line number 29.77 + * @return line number 29.78 + */ 29.79 + public int getLineNumber() { 29.80 + return lineNumber; 29.81 + } 29.82 + 29.83 +}
30.1 --- a/src/jdk/nashorn/internal/ir/SwitchNode.java Tue May 07 14:36:57 2013 +0200 30.2 +++ b/src/jdk/nashorn/internal/ir/SwitchNode.java Tue May 07 14:43:17 2013 +0200 30.3 @@ -53,14 +53,15 @@ 30.4 /** 30.5 * Constructor 30.6 * 30.7 + * @param lineNumber lineNumber 30.8 * @param token token 30.9 * @param finish finish 30.10 * @param expression switch expression 30.11 * @param cases cases 30.12 * @param defaultCase the default case node - null if none, otherwise has to be present in cases list 30.13 */ 30.14 - public SwitchNode(final long token, final int finish, final Node expression, final List<CaseNode> cases, final CaseNode defaultCase) { 30.15 - super(token, finish, new Label("switch_break")); 30.16 + public SwitchNode(final int lineNumber, final long token, final int finish, final Node expression, final List<CaseNode> cases, final CaseNode defaultCase) { 30.17 + super(lineNumber, token, finish, new Label("switch_break")); 30.18 this.expression = expression; 30.19 this.cases = cases; 30.20 this.defaultCaseIndex = defaultCase == null ? -1 : cases.indexOf(defaultCase);
31.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java Tue May 07 14:36:57 2013 +0200 31.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Tue May 07 14:43:17 2013 +0200 31.3 @@ -263,32 +263,14 @@ 31.4 return type.isCategory2() ? 2 : 1; 31.5 } 31.6 31.7 - private static String type(final String desc) { 31.8 - switch (desc.charAt(desc.length() - 1)) { 31.9 - case ';': 31.10 - return desc;//"obj"; 31.11 - case 'D': 31.12 - return "double"; 31.13 - case 'I': 31.14 - return "int"; 31.15 - case 'J': 31.16 - return "long"; 31.17 - case 'Z': 31.18 - return "boolean"; 31.19 - default: 31.20 - return "UNKNOWN"; 31.21 - } 31.22 - } 31.23 - 31.24 @Override 31.25 public String toString() { 31.26 final StringBuilder sb = new StringBuilder(); 31.27 - final String desc = getSymbolType().getDescriptor(); 31.28 31.29 sb.append(name). 31.30 append(' '). 31.31 append('('). 31.32 - append(type(desc)). 31.33 + append(getSymbolType().getTypeClass().getSimpleName()). 31.34 append(')'); 31.35 31.36 if (hasSlot()) {
32.1 --- a/src/jdk/nashorn/internal/ir/ThrowNode.java Tue May 07 14:36:57 2013 +0200 32.2 +++ b/src/jdk/nashorn/internal/ir/ThrowNode.java Tue May 07 14:43:17 2013 +0200 32.3 @@ -32,23 +32,24 @@ 32.4 * IR representation for THROW statements. 32.5 */ 32.6 @Immutable 32.7 -public final class ThrowNode extends Node { 32.8 +public final class ThrowNode extends Statement { 32.9 /** Exception expression. */ 32.10 private final Node expression; 32.11 32.12 /** 32.13 * Constructor 32.14 * 32.15 + * @param lineNumber line number 32.16 * @param token token 32.17 * @param finish finish 32.18 * @param expression expression to throw 32.19 */ 32.20 - public ThrowNode(final long token, final int finish, final Node expression) { 32.21 - super(token, finish); 32.22 + public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression) { 32.23 + super(lineNumber, token, finish); 32.24 this.expression = expression; 32.25 } 32.26 32.27 - private ThrowNode(final Node node, final Node expression) { 32.28 + private ThrowNode(final ThrowNode node, final Node expression) { 32.29 super(node); 32.30 this.expression = expression; 32.31 }
33.1 --- a/src/jdk/nashorn/internal/ir/TryNode.java Tue May 07 14:36:57 2013 +0200 33.2 +++ b/src/jdk/nashorn/internal/ir/TryNode.java Tue May 07 14:43:17 2013 +0200 33.3 @@ -37,7 +37,7 @@ 33.4 * IR representation of a TRY statement. 33.5 */ 33.6 @Immutable 33.7 -public final class TryNode extends Node { 33.8 +public final class TryNode extends Statement { 33.9 /** Try statements. */ 33.10 private final Block body; 33.11 33.12 @@ -59,26 +59,27 @@ 33.13 /** 33.14 * Constructor 33.15 * 33.16 + * @param lineNumber lineNumber 33.17 * @param token token 33.18 * @param finish finish 33.19 * @param body try node body 33.20 * @param catchBlocks list of catch blocks in order 33.21 * @param finallyBody body of finally block or null if none 33.22 */ 33.23 - public TryNode(final long token, final int finish, final Block body, final List<Block> catchBlocks, final Block finallyBody) { 33.24 - super(token, finish); 33.25 - this.body = body; 33.26 + public TryNode(final int lineNumber, final long token, final int finish, final Block body, final List<Block> catchBlocks, final Block finallyBody) { 33.27 + super(lineNumber, token, finish); 33.28 + this.body = body; 33.29 this.catchBlocks = catchBlocks; 33.30 this.finallyBody = finallyBody; 33.31 - this.exit = new Label("exit"); 33.32 + this.exit = new Label("exit"); 33.33 } 33.34 33.35 private TryNode(final TryNode tryNode, final Block body, final List<Block> catchBlocks, final Block finallyBody) { 33.36 super(tryNode); 33.37 - this.body = body; 33.38 + this.body = body; 33.39 this.catchBlocks = catchBlocks; 33.40 this.finallyBody = finallyBody; 33.41 - this.exit = new Label(tryNode.exit); 33.42 + this.exit = new Label(tryNode.exit); 33.43 } 33.44 33.45 @Override
34.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java Tue May 07 14:36:57 2013 +0200 34.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java Tue May 07 14:43:17 2013 +0200 34.3 @@ -32,7 +32,7 @@ 34.4 * Node represents a var/let declaration. 34.5 */ 34.6 @Immutable 34.7 -public final class VarNode extends Node implements Assignment<IdentNode> { 34.8 +public final class VarNode extends Statement implements Assignment<IdentNode> { 34.9 /** Var name. */ 34.10 private final IdentNode name; 34.11 34.12 @@ -53,13 +53,14 @@ 34.13 /** 34.14 * Constructor 34.15 * 34.16 - * @param token token 34.17 - * @param finish finish 34.18 - * @param name name of variable 34.19 - * @param init init node or null if just a declaration 34.20 + * @param lineNumber line number 34.21 + * @param token token 34.22 + * @param finish finish 34.23 + * @param name name of variable 34.24 + * @param init init node or null if just a declaration 34.25 */ 34.26 - public VarNode(final long token, final int finish, final IdentNode name, final Node init) { 34.27 - this(token, finish, name, init, IS_STATEMENT); 34.28 + public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init) { 34.29 + this(lineNumber, token, finish, name, init, IS_STATEMENT); 34.30 } 34.31 34.32 private VarNode(final VarNode varNode, final IdentNode name, final Node init, final int flags) { 34.33 @@ -72,14 +73,15 @@ 34.34 /** 34.35 * Constructor 34.36 * 34.37 - * @param token token 34.38 - * @param finish finish 34.39 - * @param name name of variable 34.40 - * @param init init node or null if just a declaration 34.41 - * @param flags flags 34.42 + * @param lineNumber line number 34.43 + * @param token token 34.44 + * @param finish finish 34.45 + * @param name name of variable 34.46 + * @param init init node or null if just a declaration 34.47 + * @param flags flags 34.48 */ 34.49 - public VarNode(final long token, final int finish, final IdentNode name, final Node init, final int flags) { 34.50 - super(token, finish); 34.51 + public VarNode(final int lineNumber, final long token, final int finish, final IdentNode name, final Node init, final int flags) { 34.52 + super(lineNumber, token, finish); 34.53 34.54 this.name = init == null ? name : name.setIsInitializedHere(); 34.55 this.init = init;
35.1 --- a/src/jdk/nashorn/internal/ir/WhileNode.java Tue May 07 14:36:57 2013 +0200 35.2 +++ b/src/jdk/nashorn/internal/ir/WhileNode.java Tue May 07 14:43:17 2013 +0200 35.3 @@ -41,12 +41,13 @@ 35.4 /** 35.5 * Constructor 35.6 * 35.7 - * @param token token 35.8 - * @param finish finish 35.9 - * @param isDoWhile is this a do while loop? 35.10 + * @param lineNumber line number 35.11 + * @param token token 35.12 + * @param finish finish 35.13 + * @param isDoWhile is this a do while loop? 35.14 */ 35.15 - public WhileNode(final long token, final int finish, final boolean isDoWhile) { 35.16 - super(token, finish, null, null, false); 35.17 + public WhileNode(final int lineNumber, final long token, final int finish, final boolean isDoWhile) { 35.18 + super(lineNumber, token, finish, null, null, false); 35.19 this.isDoWhile = isDoWhile; 35.20 } 35.21 35.22 @@ -133,17 +134,9 @@ 35.23 35.24 @Override 35.25 public void toString(final StringBuilder sb) { 35.26 - if (isDoWhile()) { 35.27 - sb.append("do {"); 35.28 - body.toString(sb); 35.29 - sb.append("} while ("); 35.30 - test.toString(sb); 35.31 - sb.append(')'); 35.32 - } else { 35.33 - sb.append("while ("); 35.34 - test.toString(sb); 35.35 - sb.append(')'); 35.36 - } 35.37 + sb.append("while ("); 35.38 + test.toString(sb); 35.39 + sb.append(')'); 35.40 } 35.41 35.42 @Override
36.1 --- a/src/jdk/nashorn/internal/ir/WithNode.java Tue May 07 14:36:57 2013 +0200 36.2 +++ b/src/jdk/nashorn/internal/ir/WithNode.java Tue May 07 14:43:17 2013 +0200 36.3 @@ -42,11 +42,12 @@ 36.4 /** 36.5 * Constructor 36.6 * 36.7 + * @param lineNumber line number 36.8 * @param token token 36.9 * @param finish finish 36.10 */ 36.11 - public WithNode(final long token, final int finish) { 36.12 - super(token, finish); 36.13 + public WithNode(final int lineNumber, final long token, final int finish) { 36.14 + super(lineNumber, token, finish); 36.15 this.expression = null; 36.16 this.body = null; 36.17 }
37.1 --- a/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Tue May 07 14:36:57 2013 +0200 37.2 +++ b/src/jdk/nashorn/internal/ir/debug/JSONWriter.java Tue May 07 14:43:17 2013 +0200 37.3 @@ -27,6 +27,7 @@ 37.4 37.5 import java.util.Arrays; 37.6 import java.util.List; 37.7 + 37.8 import jdk.nashorn.internal.codegen.CompilerConstants; 37.9 import jdk.nashorn.internal.ir.AccessNode; 37.10 import jdk.nashorn.internal.ir.BinaryNode; 37.11 @@ -44,7 +45,6 @@ 37.12 import jdk.nashorn.internal.ir.IfNode; 37.13 import jdk.nashorn.internal.ir.IndexNode; 37.14 import jdk.nashorn.internal.ir.LabelNode; 37.15 -import jdk.nashorn.internal.ir.LineNumberNode; 37.16 import jdk.nashorn.internal.ir.LiteralNode; 37.17 import jdk.nashorn.internal.ir.Node; 37.18 import jdk.nashorn.internal.ir.ObjectNode; 37.19 @@ -52,6 +52,7 @@ 37.20 import jdk.nashorn.internal.ir.ReturnNode; 37.21 import jdk.nashorn.internal.ir.RuntimeNode; 37.22 import jdk.nashorn.internal.ir.SplitNode; 37.23 +import jdk.nashorn.internal.ir.Statement; 37.24 import jdk.nashorn.internal.ir.SwitchNode; 37.25 import jdk.nashorn.internal.ir.TernaryNode; 37.26 import jdk.nashorn.internal.ir.ThrowNode; 37.27 @@ -406,17 +407,15 @@ 37.28 } 37.29 37.30 // body consists of nested functions and statements 37.31 - final List<Node> stats = functionNode.getBody().getStatements(); 37.32 + final List<Statement> stats = functionNode.getBody().getStatements(); 37.33 final int size = stats.size(); 37.34 int idx = 0; 37.35 arrayStart("body"); 37.36 37.37 for (final Node stat : stats) { 37.38 - if (! stat.isDebug()) { 37.39 - stat.accept(this); 37.40 - if (idx != (size - 1)) { 37.41 - comma(); 37.42 - } 37.43 + stat.accept(this); 37.44 + if (idx != (size - 1)) { 37.45 + comma(); 37.46 } 37.47 idx++; 37.48 } 37.49 @@ -504,11 +503,6 @@ 37.50 return leave(); 37.51 } 37.52 37.53 - @Override 37.54 - public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) { 37.55 - return false; 37.56 - } 37.57 - 37.58 @SuppressWarnings("rawtypes") 37.59 @Override 37.60 public boolean enterLiteralNode(final LiteralNode literalNode) { 37.61 @@ -931,15 +925,13 @@ 37.62 int idx = 0; 37.63 arrayStart(name); 37.64 for (final Node node : nodes) { 37.65 - if (node == null || !node.isDebug()) { 37.66 - if (node != null) { 37.67 - node.accept(this); 37.68 - } else { 37.69 - nullValue(); 37.70 - } 37.71 - if (idx != (size - 1)) { 37.72 - comma(); 37.73 - } 37.74 + if (node != null) { 37.75 + node.accept(this); 37.76 + } else { 37.77 + nullValue(); 37.78 + } 37.79 + if (idx != (size - 1)) { 37.80 + comma(); 37.81 } 37.82 idx++; 37.83 }
38.1 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Tue May 07 14:36:57 2013 +0200 38.2 +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java Tue May 07 14:43:17 2013 +0200 38.3 @@ -36,9 +36,9 @@ 38.4 import jdk.nashorn.internal.ir.FunctionNode; 38.5 import jdk.nashorn.internal.ir.IfNode; 38.6 import jdk.nashorn.internal.ir.LabelNode; 38.7 -import jdk.nashorn.internal.ir.LineNumberNode; 38.8 import jdk.nashorn.internal.ir.Node; 38.9 import jdk.nashorn.internal.ir.SplitNode; 38.10 +import jdk.nashorn.internal.ir.Statement; 38.11 import jdk.nashorn.internal.ir.SwitchNode; 38.12 import jdk.nashorn.internal.ir.Symbol; 38.13 import jdk.nashorn.internal.ir.TryNode; 38.14 @@ -55,7 +55,7 @@ 38.15 */ 38.16 public final class PrintVisitor extends NodeVisitor { 38.17 /** Tab width */ 38.18 - private static final int TABWIDTH = 1; 38.19 + private static final int TABWIDTH = 4; 38.20 38.21 /** Composing buffer. */ 38.22 private final StringBuilder sb; 38.23 @@ -69,6 +69,8 @@ 38.24 /** Print line numbers */ 38.25 private final boolean printLineNumbers; 38.26 38.27 + private int lastLineNumber = -1; 38.28 + 38.29 /** 38.30 * Constructor. 38.31 */ 38.32 @@ -138,24 +140,27 @@ 38.33 @Override 38.34 public boolean enterBlock(final Block block) { 38.35 sb.append(' '); 38.36 + //sb.append(Debug.id(block)); 38.37 sb.append('{'); 38.38 38.39 indent += TABWIDTH; 38.40 38.41 - final List<Node> statements = block.getStatements(); 38.42 - 38.43 - boolean lastLineNumber = false; 38.44 + final List<Statement> statements = block.getStatements(); 38.45 38.46 for (final Node statement : statements) { 38.47 - if (printLineNumbers || !lastLineNumber) { 38.48 - sb.append(EOLN); 38.49 - indent(); 38.50 + if (printLineNumbers && (statement instanceof Statement)) { 38.51 + final int lineNumber = ((Statement)statement).getLineNumber(); 38.52 + sb.append('\n'); 38.53 + if (lineNumber != lastLineNumber) { 38.54 + indent(); 38.55 + sb.append("[|").append(lineNumber).append("|];").append('\n'); 38.56 + } 38.57 + lastLineNumber = lineNumber; 38.58 } 38.59 + indent(); 38.60 38.61 statement.accept(this); 38.62 38.63 - lastLineNumber = statement instanceof LineNumberNode; 38.64 - 38.65 if (statement instanceof FunctionNode) { 38.66 continue; 38.67 } 38.68 @@ -168,12 +173,14 @@ 38.69 sb.append(']'); 38.70 } 38.71 38.72 - final char lastChar = sb.charAt(sb.length() - 1); 38.73 + int lastIndex = sb.length() - 1; 38.74 + char lastChar = sb.charAt(lastIndex); 38.75 + while (Character.isWhitespace(lastChar) && lastIndex >= 0) { 38.76 + lastChar = sb.charAt(--lastIndex); 38.77 + } 38.78 38.79 if (lastChar != '}' && lastChar != ';') { 38.80 - if (printLineNumbers || !lastLineNumber) { 38.81 - sb.append(';'); 38.82 - } 38.83 + sb.append(';'); 38.84 } 38.85 38.86 if (statement.hasGoto()) { 38.87 @@ -189,7 +196,8 @@ 38.88 38.89 sb.append(EOLN); 38.90 indent(); 38.91 - sb.append("}"); 38.92 + sb.append('}'); 38.93 + // sb.append(Debug.id(block)); 38.94 38.95 return false; 38.96 } 38.97 @@ -221,7 +229,7 @@ 38.98 public boolean enterFunctionNode(final FunctionNode functionNode) { 38.99 functionNode.toString(sb); 38.100 enterBlock(functionNode.getBody()); 38.101 - sb.append(EOLN); 38.102 + //sb.append(EOLN); 38.103 return false; 38.104 } 38.105 38.106 @@ -252,15 +260,6 @@ 38.107 } 38.108 38.109 @Override 38.110 - public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) { 38.111 - if (printLineNumbers) { 38.112 - lineNumberNode.toString(sb); 38.113 - } 38.114 - 38.115 - return false; 38.116 - } 38.117 - 38.118 - @Override 38.119 public boolean enterSplitNode(final SplitNode splitNode) { 38.120 splitNode.toString(sb); 38.121 sb.append(EOLN); 38.122 @@ -334,6 +333,7 @@ 38.123 sb.append(" = "); 38.124 init.accept(this); 38.125 } 38.126 + 38.127 return false; 38.128 } 38.129
39.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Tue May 07 14:36:57 2013 +0200 39.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeOperatorVisitor.java Tue May 07 14:43:17 2013 +0200 39.3 @@ -149,7 +149,7 @@ 39.4 return enterASSIGN_SUB(binaryNode); 39.5 case BIND: 39.6 return enterBIND(binaryNode); 39.7 - case BIT_AND: 39.8 + case BIT_AND: 39.9 return enterBIT_AND(binaryNode); 39.10 case BIT_OR: 39.11 return enterBIT_OR(binaryNode);
40.1 --- a/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Tue May 07 14:36:57 2013 +0200 40.2 +++ b/src/jdk/nashorn/internal/ir/visitor/NodeVisitor.java Tue May 07 14:43:17 2013 +0200 40.3 @@ -42,7 +42,6 @@ 40.4 import jdk.nashorn.internal.ir.IndexNode; 40.5 import jdk.nashorn.internal.ir.LabelNode; 40.6 import jdk.nashorn.internal.ir.LexicalContext; 40.7 -import jdk.nashorn.internal.ir.LineNumberNode; 40.8 import jdk.nashorn.internal.ir.LiteralNode; 40.9 import jdk.nashorn.internal.ir.Node; 40.10 import jdk.nashorn.internal.ir.ObjectNode; 40.11 @@ -454,26 +453,6 @@ 40.12 } 40.13 40.14 /** 40.15 - * Callback for entering a LineNumberNode 40.16 - * 40.17 - * @param lineNumberNode the node 40.18 - * @return true if traversal should continue and node children be traversed, false otherwise 40.19 - */ 40.20 - public boolean enterLineNumberNode(final LineNumberNode lineNumberNode) { 40.21 - return enterDefault(lineNumberNode); 40.22 - } 40.23 - 40.24 - /** 40.25 - * Callback for leaving a LineNumberNode 40.26 - * 40.27 - * @param lineNumberNode the node 40.28 - * @return processed node, which will replace the original one, or the original node 40.29 - */ 40.30 - public Node leaveLineNumberNode(final LineNumberNode lineNumberNode) { 40.31 - return leaveDefault(lineNumberNode); 40.32 - } 40.33 - 40.34 - /** 40.35 * Callback for entering a LiteralNode 40.36 * 40.37 * @param literalNode the node
41.1 --- a/src/jdk/nashorn/internal/objects/Global.java Tue May 07 14:36:57 2013 +0200 41.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Tue May 07 14:43:17 2013 +0200 41.3 @@ -1625,6 +1625,7 @@ 41.4 this.addOwnProperty("Debug", Attribute.NOT_ENUMERABLE, initConstructor("Debug")); 41.5 } 41.6 41.7 + @SuppressWarnings("resource") 41.8 private static Object printImpl(final boolean newLine, final Object... objects) { 41.9 final PrintWriter out = Global.getEnv().getOut(); 41.10
42.1 --- a/src/jdk/nashorn/internal/objects/NativeDebug.java Tue May 07 14:36:57 2013 +0200 42.2 +++ b/src/jdk/nashorn/internal/objects/NativeDebug.java Tue May 07 14:43:17 2013 +0200 42.3 @@ -178,6 +178,7 @@ 42.4 * @param self self reference 42.5 * @return undefined 42.6 */ 42.7 + @SuppressWarnings("resource") 42.8 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 42.9 public static Object dumpCounters(final Object self) { 42.10 final PrintWriter out = Context.getCurrentErr();
43.1 --- a/src/jdk/nashorn/internal/parser/Parser.java Tue May 07 14:36:57 2013 +0200 43.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java Tue May 07 14:43:17 2013 +0200 43.3 @@ -59,9 +59,11 @@ 43.4 import java.util.LinkedHashMap; 43.5 import java.util.List; 43.6 import java.util.Map; 43.7 + 43.8 import jdk.nashorn.internal.codegen.CompilerConstants; 43.9 import jdk.nashorn.internal.codegen.Namespace; 43.10 import jdk.nashorn.internal.ir.AccessNode; 43.11 +import jdk.nashorn.internal.ir.BaseNode; 43.12 import jdk.nashorn.internal.ir.BinaryNode; 43.13 import jdk.nashorn.internal.ir.Block; 43.14 import jdk.nashorn.internal.ir.BlockLexicalContext; 43.15 @@ -81,7 +83,6 @@ 43.16 import jdk.nashorn.internal.ir.IndexNode; 43.17 import jdk.nashorn.internal.ir.LabelNode; 43.18 import jdk.nashorn.internal.ir.LexicalContext; 43.19 -import jdk.nashorn.internal.ir.LineNumberNode; 43.20 import jdk.nashorn.internal.ir.LiteralNode; 43.21 import jdk.nashorn.internal.ir.LoopNode; 43.22 import jdk.nashorn.internal.ir.Node; 43.23 @@ -90,6 +91,7 @@ 43.24 import jdk.nashorn.internal.ir.PropertyNode; 43.25 import jdk.nashorn.internal.ir.ReturnNode; 43.26 import jdk.nashorn.internal.ir.RuntimeNode; 43.27 +import jdk.nashorn.internal.ir.Statement; 43.28 import jdk.nashorn.internal.ir.SwitchNode; 43.29 import jdk.nashorn.internal.ir.TernaryNode; 43.30 import jdk.nashorn.internal.ir.ThrowNode; 43.31 @@ -117,7 +119,7 @@ 43.32 /** Is scripting mode. */ 43.33 private final boolean scripting; 43.34 43.35 - private List<Node> functionDeclarations; 43.36 + private List<Statement> functionDeclarations; 43.37 43.38 private final BlockLexicalContext lc = new BlockLexicalContext(); 43.39 43.40 @@ -275,7 +277,7 @@ 43.41 * @return New block. 43.42 */ 43.43 private Block newBlock() { 43.44 - return lc.push(new Block(token, Token.descPosition(token))); 43.45 + return lc.push(new Block(line, token, Token.descPosition(token))); 43.46 } 43.47 43.48 /** 43.49 @@ -314,6 +316,7 @@ 43.50 FunctionNode functionNode = 43.51 new FunctionNode( 43.52 source, 43.53 + line, //TODO? 43.54 token, 43.55 Token.descPosition(token), 43.56 startToken, 43.57 @@ -680,8 +683,6 @@ 43.58 * @param topLevel does this statement occur at the "top level" of a script or a function? 43.59 */ 43.60 private void statement(final boolean topLevel) { 43.61 - final LineNumberNode lineNumberNode = lineNumber(); 43.62 - 43.63 if (type == FUNCTION) { 43.64 // As per spec (ECMA section 12), function declarations as arbitrary statement 43.65 // is not "portable". Implementation can issue a warning or disallow the same. 43.66 @@ -689,10 +690,6 @@ 43.67 return; 43.68 } 43.69 43.70 - if (lineNumberNode != null) { 43.71 - appendStatement(lineNumberNode); 43.72 - } 43.73 - 43.74 switch (type) { 43.75 case LBRACE: 43.76 block(); 43.77 @@ -773,7 +770,7 @@ 43.78 private void block() { 43.79 final Block newBlock = getBlock(true); 43.80 // Force block execution. 43.81 - appendStatement(new ExecuteNode(newBlock.getToken(), finish, newBlock)); 43.82 + appendStatement(new ExecuteNode(newBlock.getLineNumber(), newBlock.getToken(), finish, newBlock)); 43.83 } 43.84 43.85 /** 43.86 @@ -849,6 +846,7 @@ 43.87 43.88 while (true) { 43.89 // Get starting token. 43.90 + final int varLine = line; 43.91 final long varToken = token; 43.92 // Get name of var. 43.93 final IdentNode name = getIdent(); 43.94 @@ -866,7 +864,7 @@ 43.95 } 43.96 43.97 // Allocate var node. 43.98 - final VarNode var = new VarNode(varToken, finish, name, init); 43.99 + final VarNode var = new VarNode(varLine, varToken, finish, name, init); 43.100 vars.add(var); 43.101 appendStatement(var); 43.102 43.103 @@ -898,7 +896,7 @@ 43.104 */ 43.105 private void emptyStatement() { 43.106 if (env._empty_statements) { 43.107 - appendStatement(new EmptyNode(token, Token.descPosition(token) + Token.descLength(token))); 43.108 + appendStatement(new EmptyNode(line, token, Token.descPosition(token) + Token.descLength(token))); 43.109 } 43.110 43.111 // SEMICOLON checked in caller. 43.112 @@ -915,6 +913,7 @@ 43.113 */ 43.114 private void expressionStatement() { 43.115 // Lookahead checked in caller. 43.116 + final int expressionLine = line; 43.117 final long expressionToken = token; 43.118 43.119 // Get expression and add as statement. 43.120 @@ -922,7 +921,7 @@ 43.121 43.122 ExecuteNode executeNode = null; 43.123 if (expression != null) { 43.124 - executeNode = new ExecuteNode(expressionToken, finish, expression); 43.125 + executeNode = new ExecuteNode(expressionLine, expressionToken, finish, expression); 43.126 appendStatement(executeNode); 43.127 } else { 43.128 expect(null); 43.129 @@ -947,6 +946,7 @@ 43.130 */ 43.131 private void ifStatement() { 43.132 // Capture IF token. 43.133 + final int ifLine = line; 43.134 final long ifToken = token; 43.135 // IF tested in caller. 43.136 next(); 43.137 @@ -962,7 +962,7 @@ 43.138 fail = getStatement(); 43.139 } 43.140 43.141 - appendStatement(new IfNode(ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail)); 43.142 + appendStatement(new IfNode(ifLine, ifToken, fail != null ? fail.getFinish() : pass.getFinish(), test, pass, fail)); 43.143 } 43.144 43.145 /** 43.146 @@ -979,8 +979,7 @@ 43.147 */ 43.148 private void forStatement() { 43.149 // Create FOR node, capturing FOR token. 43.150 - ForNode forNode = new ForNode(token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR); 43.151 - 43.152 + ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, null, null, null, ForNode.IS_FOR); 43.153 43.154 // Set up new block for scope of vars. Captures first token. 43.155 Block outer = newBlock(); 43.156 @@ -1083,7 +1082,7 @@ 43.157 outer = restoreBlock(outer); 43.158 } 43.159 43.160 - appendStatement(new ExecuteNode(outer.getToken(), outer.getFinish(), outer)); 43.161 + appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer)); 43.162 } 43.163 43.164 /** 43.165 @@ -1114,12 +1113,13 @@ 43.166 */ 43.167 private void whileStatement() { 43.168 // Capture WHILE token. 43.169 + final int whileLine = line; 43.170 final long whileToken = token; 43.171 // WHILE tested in caller. 43.172 next(); 43.173 43.174 // Construct WHILE node. 43.175 - WhileNode whileNode = new WhileNode(whileToken, Token.descPosition(whileToken), false); 43.176 + WhileNode whileNode = new WhileNode(whileLine, whileToken, Token.descPosition(whileToken), false); 43.177 lc.push(whileNode); 43.178 43.179 try { 43.180 @@ -1145,11 +1145,12 @@ 43.181 */ 43.182 private void doStatement() { 43.183 // Capture DO token. 43.184 + final int doLine = line; 43.185 final long doToken = token; 43.186 // DO tested in the caller. 43.187 next(); 43.188 43.189 - WhileNode doWhileNode = new WhileNode(doToken, Token.descPosition(doToken), true); 43.190 + WhileNode doWhileNode = new WhileNode(doLine, doToken, Token.descPosition(doToken), true); 43.191 lc.push(doWhileNode); 43.192 43.193 try { 43.194 @@ -1181,6 +1182,7 @@ 43.195 */ 43.196 private void continueStatement() { 43.197 // Capture CONTINUE token. 43.198 + final int continueLine = line; 43.199 final long continueToken = token; 43.200 // CONTINUE tested in caller. 43.201 nextOrEOL(); 43.202 @@ -1215,7 +1217,7 @@ 43.203 endOfLine(); 43.204 43.205 // Construct and add CONTINUE node. 43.206 - appendStatement(new ContinueNode(continueToken, finish, label == null ? null : new IdentNode(label))); 43.207 + appendStatement(new ContinueNode(continueLine, continueToken, finish, label == null ? null : new IdentNode(label))); 43.208 } 43.209 43.210 /** 43.211 @@ -1227,6 +1229,7 @@ 43.212 */ 43.213 private void breakStatement() { 43.214 // Capture BREAK token. 43.215 + final int breakLine = line; 43.216 final long breakToken = token; 43.217 // BREAK tested in caller. 43.218 nextOrEOL(); 43.219 @@ -1262,7 +1265,7 @@ 43.220 endOfLine(); 43.221 43.222 // Construct and add BREAK node. 43.223 - appendStatement(new BreakNode(breakToken, finish, label == null ? null : new IdentNode(label))); 43.224 + appendStatement(new BreakNode(breakLine, breakToken, finish, label == null ? null : new IdentNode(label))); 43.225 } 43.226 43.227 /** 43.228 @@ -1280,6 +1283,7 @@ 43.229 } 43.230 43.231 // Capture RETURN token. 43.232 + final int returnLine = line; 43.233 final long returnToken = token; 43.234 // RETURN tested in caller. 43.235 nextOrEOL(); 43.236 @@ -1301,7 +1305,7 @@ 43.237 endOfLine(); 43.238 43.239 // Construct and add RETURN node. 43.240 - appendStatement(new ReturnNode(returnToken, finish, expression)); 43.241 + appendStatement(new ReturnNode(returnLine, returnToken, finish, expression)); 43.242 } 43.243 43.244 /** 43.245 @@ -1314,6 +1318,7 @@ 43.246 */ 43.247 private void yieldStatement() { 43.248 // Capture YIELD token. 43.249 + final int yieldLine = line; 43.250 final long yieldToken = token; 43.251 // YIELD tested in caller. 43.252 nextOrEOL(); 43.253 @@ -1335,7 +1340,7 @@ 43.254 endOfLine(); 43.255 43.256 // Construct and add YIELD node. 43.257 - appendStatement(new ReturnNode(yieldToken, finish, expression)); 43.258 + appendStatement(new ReturnNode(yieldLine, yieldToken, finish, expression)); 43.259 } 43.260 43.261 /** 43.262 @@ -1348,6 +1353,7 @@ 43.263 */ 43.264 private void withStatement() { 43.265 // Capture WITH token. 43.266 + final int withLine = line; 43.267 final long withToken = token; 43.268 // WITH tested in caller. 43.269 next(); 43.270 @@ -1358,7 +1364,7 @@ 43.271 } 43.272 43.273 // Get WITH expression. 43.274 - WithNode withNode = new WithNode(withToken, finish); 43.275 + WithNode withNode = new WithNode(withLine, withToken, finish); 43.276 43.277 try { 43.278 lc.push(withNode); 43.279 @@ -1396,12 +1402,13 @@ 43.280 * Parse SWITCH statement. 43.281 */ 43.282 private void switchStatement() { 43.283 + final int switchLine = line; 43.284 final long switchToken = token; 43.285 // SWITCH tested in caller. 43.286 next(); 43.287 43.288 // Create and add switch statement. 43.289 - SwitchNode switchNode = new SwitchNode(switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null); 43.290 + SwitchNode switchNode = new SwitchNode(switchLine, switchToken, Token.descPosition(switchToken), null, new ArrayList<CaseNode>(), null); 43.291 lc.push(switchNode); 43.292 43.293 try { 43.294 @@ -1483,7 +1490,7 @@ 43.295 throw error(AbstractParser.message("duplicate.label", ident.getName()), labelToken); 43.296 } 43.297 43.298 - LabelNode labelNode = new LabelNode(labelToken, finish, ident, null); 43.299 + LabelNode labelNode = new LabelNode(line, labelToken, finish, ident, null); 43.300 try { 43.301 lc.push(labelNode); 43.302 labelNode = labelNode.setBody(lc, getStatement()); 43.303 @@ -1505,6 +1512,7 @@ 43.304 */ 43.305 private void throwStatement() { 43.306 // Capture THROW token. 43.307 + final int throwLine = line; 43.308 final long throwToken = token; 43.309 // THROW tested in caller. 43.310 nextOrEOL(); 43.311 @@ -1529,7 +1537,7 @@ 43.312 43.313 endOfLine(); 43.314 43.315 - appendStatement(new ThrowNode(throwToken, finish, expression)); 43.316 + appendStatement(new ThrowNode(throwLine, throwToken, finish, expression)); 43.317 } 43.318 43.319 /** 43.320 @@ -1551,6 +1559,7 @@ 43.321 */ 43.322 private void tryStatement() { 43.323 // Capture TRY token. 43.324 + final int tryLine = line; 43.325 final long tryToken = token; 43.326 // TRY tested in caller. 43.327 next(); 43.328 @@ -1565,6 +1574,7 @@ 43.329 final List<Block> catchBlocks = new ArrayList<>(); 43.330 43.331 while (type == CATCH) { 43.332 + final int catchLine = line; 43.333 final long catchToken = token; 43.334 next(); 43.335 expect(LPAREN); 43.336 @@ -1587,7 +1597,7 @@ 43.337 try { 43.338 // Get CATCH body. 43.339 final Block catchBody = getBlock(true); 43.340 - final CatchNode catchNode = new CatchNode(catchToken, finish, exception, ifExpression, catchBody); 43.341 + final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody); 43.342 appendStatement(catchNode); 43.343 } finally { 43.344 catchBlock = restoreBlock(catchBlock); 43.345 @@ -1613,7 +1623,7 @@ 43.346 throw error(AbstractParser.message("missing.catch.or.finally"), tryToken); 43.347 } 43.348 43.349 - final TryNode tryNode = new TryNode(tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements); 43.350 + final TryNode tryNode = new TryNode(tryLine, tryToken, Token.descPosition(tryToken), tryBody, catchBlocks, finallyStatements); 43.351 // Add try. 43.352 assert lc.peek() == outer; 43.353 appendStatement(tryNode); 43.354 @@ -1625,7 +1635,7 @@ 43.355 outer = restoreBlock(outer); 43.356 } 43.357 43.358 - appendStatement(new ExecuteNode(outer.getToken(), outer.getFinish(), outer)); 43.359 + appendStatement(new ExecuteNode(outer.getLineNumber(), outer.getToken(), outer.getFinish(), outer)); 43.360 } 43.361 43.362 /** 43.363 @@ -1638,11 +1648,12 @@ 43.364 */ 43.365 private void debuggerStatement() { 43.366 // Capture DEBUGGER token. 43.367 + final int debuggerLine = line; 43.368 final long debuggerToken = token; 43.369 // DEBUGGER tested in caller. 43.370 next(); 43.371 endOfLine(); 43.372 - appendStatement(new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>())); 43.373 + appendStatement(new ExecuteNode(debuggerLine, debuggerToken, finish, new RuntimeNode(debuggerToken, finish, RuntimeNode.Request.DEBUGGER, new ArrayList<Node>()))); 43.374 } 43.375 43.376 /** 43.377 @@ -1662,6 +1673,7 @@ 43.378 @SuppressWarnings("fallthrough") 43.379 private Node primaryExpression() { 43.380 // Capture first token. 43.381 + final int primaryLine = line; 43.382 final long primaryToken = token; 43.383 43.384 switch (type) { 43.385 @@ -1689,7 +1701,7 @@ 43.386 case XML: 43.387 return getLiteral(); 43.388 case EXECSTRING: 43.389 - return execString(primaryToken); 43.390 + return execString(primaryLine, primaryToken); 43.391 case FALSE: 43.392 next(); 43.393 return LiteralNode.newInstance(primaryToken, finish, false); 43.394 @@ -1733,7 +1745,7 @@ 43.395 * @param primaryToken Original string token. 43.396 * @return callNode to $EXEC. 43.397 */ 43.398 - Node execString(final long primaryToken) { 43.399 + Node execString(final int primaryLine, final long primaryToken) { 43.400 // Synthesize an ident to call $EXEC. 43.401 final IdentNode execIdent = new IdentNode(primaryToken, finish, ScriptingFunctions.EXEC_NAME); 43.402 // Skip over EXECSTRING. 43.403 @@ -1747,7 +1759,7 @@ 43.404 // Skip ending of edit string expression. 43.405 expect(RBRACE); 43.406 43.407 - return new CallNode(primaryToken, finish, execIdent, arguments); 43.408 + return new CallNode(primaryLine, primaryToken, finish, execIdent, arguments); 43.409 } 43.410 43.411 /** 43.412 @@ -2063,6 +2075,7 @@ 43.413 * @return Expression node. 43.414 */ 43.415 private Node leftHandSideExpression() { 43.416 + int callLine = line; 43.417 long callToken = token; 43.418 43.419 Node lhs = memberExpression(); 43.420 @@ -2075,12 +2088,13 @@ 43.421 detectSpecialFunction((IdentNode)lhs); 43.422 } 43.423 43.424 - lhs = new CallNode(callToken, finish, lhs, arguments); 43.425 + lhs = new CallNode(callLine, callToken, finish, lhs, arguments); 43.426 } 43.427 43.428 loop: 43.429 while (true) { 43.430 // Capture token. 43.431 + callLine = line; 43.432 callToken = token; 43.433 43.434 switch (type) { 43.435 @@ -2089,7 +2103,7 @@ 43.436 final List<Node> arguments = argumentList(); 43.437 43.438 // Create call node. 43.439 - lhs = new CallNode(callToken, finish, lhs, arguments); 43.440 + lhs = new CallNode(callLine, callToken, finish, lhs, arguments); 43.441 43.442 break; 43.443 43.444 @@ -2140,6 +2154,7 @@ 43.445 next(); 43.446 43.447 // Get function base. 43.448 + final int callLine = line; 43.449 final Node constructor = memberExpression(); 43.450 if (constructor == null) { 43.451 return null; 43.452 @@ -2168,7 +2183,7 @@ 43.453 arguments.add(objectLiteral()); 43.454 } 43.455 43.456 - final CallNode callNode = new CallNode(constructor.getToken(), finish, constructor, arguments); 43.457 + final CallNode callNode = new CallNode(callLine, constructor.getToken(), finish, constructor, arguments); 43.458 43.459 return new UnaryNode(newToken, callNode); 43.460 } 43.461 @@ -2303,9 +2318,8 @@ 43.462 * @return Expression node. 43.463 */ 43.464 private Node functionExpression(final boolean isStatement, final boolean topLevel) { 43.465 - final LineNumberNode lineNumber = lineNumber(); 43.466 - 43.467 final long functionToken = token; 43.468 + final int functionLine = line; 43.469 // FUNCTION is tested in caller. 43.470 next(); 43.471 43.472 @@ -2388,12 +2402,10 @@ 43.473 } 43.474 43.475 if (isStatement) { 43.476 - final VarNode varNode = new VarNode(functionToken, finish, name, functionNode, VarNode.IS_STATEMENT); 43.477 + final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT); 43.478 if (topLevel) { 43.479 - functionDeclarations.add(lineNumber); 43.480 functionDeclarations.add(varNode); 43.481 } else { 43.482 - appendStatement(lineNumber); 43.483 appendStatement(varNode); 43.484 } 43.485 } 43.486 @@ -2468,7 +2480,7 @@ 43.487 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode); 43.488 // create a return statement - this creates code in itself and does not need to be 43.489 // wrapped into an ExecuteNode 43.490 - final ReturnNode returnNode = new ReturnNode(expr.getToken(), finish, expr); 43.491 + final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), finish, expr); 43.492 appendStatement(returnNode); 43.493 lastToken = token; 43.494 functionNode.setFinish(Token.descPosition(token) + Token.descLength(token)); 43.495 @@ -2477,7 +2489,7 @@ 43.496 expect(LBRACE); 43.497 43.498 // Gather the function elements. 43.499 - final List<Node> prevFunctionDecls = functionDeclarations; 43.500 + final List<Statement> prevFunctionDecls = functionDeclarations; 43.501 functionDeclarations = new ArrayList<>(); 43.502 try { 43.503 sourceElements(); 43.504 @@ -2501,7 +2513,7 @@ 43.505 assert lc.peek() == lc.getFunctionBody(functionNode); 43.506 VarNode lastDecl = null; 43.507 for (int i = functionDeclarations.size() - 1; i >= 0; i--) { 43.508 - Node decl = functionDeclarations.get(i); 43.509 + Statement decl = functionDeclarations.get(i); 43.510 if (lastDecl == null && decl instanceof VarNode) { 43.511 decl = lastDecl = ((VarNode)decl).setFlag(VarNode.IS_LAST_FUNCTION_DECLARATION); 43.512 lc.setFlag(functionNode, FunctionNode.HAS_FUNCTION_DECLARATIONS); 43.513 @@ -2557,10 +2569,19 @@ 43.514 * @return Expression node. 43.515 */ 43.516 private Node unaryExpression() { 43.517 + final int unaryLine = line; 43.518 final long unaryToken = token; 43.519 43.520 switch (type) { 43.521 - case DELETE: 43.522 + case DELETE: { 43.523 + next(); 43.524 + final Node expr = unaryExpression(); 43.525 + if (expr instanceof BaseNode || expr instanceof IdentNode) { 43.526 + return new UnaryNode(unaryToken, expr); 43.527 + } 43.528 + appendStatement(new ExecuteNode(unaryLine, unaryToken, finish, expr)); 43.529 + return LiteralNode.newInstance(unaryToken, finish, true); 43.530 + } 43.531 case VOID: 43.532 case TYPEOF: 43.533 case ADD: 43.534 @@ -2814,16 +2835,6 @@ 43.535 } 43.536 } 43.537 43.538 - /** 43.539 - * Add a line number node at current position 43.540 - */ 43.541 - private LineNumberNode lineNumber() { 43.542 - if (env._debug_lines) { 43.543 - return new LineNumberNode(token, line); 43.544 - } 43.545 - return null; 43.546 - } 43.547 - 43.548 @Override 43.549 public String toString() { 43.550 return "[JavaScript Parsing]"; 43.551 @@ -2844,11 +2855,11 @@ 43.552 } 43.553 } 43.554 43.555 - private void prependStatement(final Node statement) { 43.556 + private void prependStatement(final Statement statement) { 43.557 lc.prependStatement(statement); 43.558 } 43.559 43.560 - private void appendStatement(final Node statement) { 43.561 + private void appendStatement(final Statement statement) { 43.562 lc.appendStatement(statement); 43.563 } 43.564 }
44.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Tue May 07 14:36:57 2013 +0200 44.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Tue May 07 14:43:17 2013 +0200 44.3 @@ -171,6 +171,7 @@ 44.4 * @param str text to write 44.5 * @param crlf write a carriage return/new line after text 44.6 */ 44.7 + @SuppressWarnings("resource") 44.8 public static void err(final String str, final boolean crlf) { 44.9 final PrintWriter err = Context.getCurrentErr(); 44.10 if (err != null) { 44.11 @@ -509,7 +510,7 @@ 44.12 44.13 /** 44.14 * Lookup a Java class. This is used for JSR-223 stuff linking in from 44.15 - * {@link jdk.nashorn.internal.objects.NativeJava} and {@link jdk.nashorn.internal.runtime.NativeJavaPackage} 44.16 + * {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage} 44.17 * 44.18 * @param fullName full name of class to load 44.19 *
45.1 --- a/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java Tue May 07 14:36:57 2013 +0200 45.2 +++ b/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java Tue May 07 14:43:17 2013 +0200 45.3 @@ -275,9 +275,10 @@ 45.4 } 45.5 45.6 static class ProfileDumper implements Runnable { 45.7 + @SuppressWarnings("resource") 45.8 @Override 45.9 public void run() { 45.10 - PrintWriter out = null; 45.11 + PrintWriter out = null; 45.12 boolean fileOutput = false; 45.13 45.14 try { 45.15 @@ -446,7 +447,7 @@ 45.16 * 45.17 * @throws Throwable if invocation fails or throws exception/error 45.18 */ 45.19 - @SuppressWarnings("unused") 45.20 + @SuppressWarnings({"unused", "resource"}) 45.21 public Object traceObject(final MethodHandle mh, final Object... args) throws Throwable { 45.22 final PrintWriter out = Context.getCurrentErr(); 45.23 tracePrint(out, "ENTER ", args, null); 45.24 @@ -464,7 +465,7 @@ 45.25 * 45.26 * @throws Throwable if invocation fails or throws exception/error 45.27 */ 45.28 - @SuppressWarnings("unused") 45.29 + @SuppressWarnings({"unused", "resource"}) 45.30 public void traceVoid(final MethodHandle mh, final Object... args) throws Throwable { 45.31 final PrintWriter out = Context.getCurrentErr(); 45.32 tracePrint(out, "ENTER ", args, null);
46.1 --- a/src/jdk/nashorn/tools/Shell.java Tue May 07 14:36:57 2013 +0200 46.2 +++ b/src/jdk/nashorn/tools/Shell.java Tue May 07 14:43:17 2013 +0200 46.3 @@ -392,6 +392,7 @@ 46.4 * @param global global scope object to use 46.5 * @return return code 46.6 */ 46.7 + @SuppressWarnings("resource") 46.8 private static int readEvalPrint(final Context context, final ScriptObject global) { 46.9 final String prompt = bundle.getString("shell.prompt"); 46.10 final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/test/script/basic/no_line_numbers.js Tue May 07 14:43:17 2013 +0200 47.3 @@ -0,0 +1,125 @@ 47.4 +/* 47.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 47.7 + * 47.8 + * This code is free software; you can redistribute it and/or modify it 47.9 + * under the terms of the GNU General Public License version 2 only, as 47.10 + * published by the Free Software Foundation. 47.11 + * 47.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 47.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 47.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 47.15 + * version 2 for more details (a copy is included in the LICENSE file that 47.16 + * accompanied this code). 47.17 + * 47.18 + * You should have received a copy of the GNU General Public License version 47.19 + * 2 along with this work; if not, write to the Free Software Foundation, 47.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 47.21 + * 47.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 47.23 + * or visit www.oracle.com if you need additional information or have any 47.24 + * questions. 47.25 + */ 47.26 + 47.27 +/** 47.28 + * no_line_numbers.js - make sure that switching off line number generation 47.29 + * doesn't break. Otherwise, this is just NASHORN-73, a unit test particularly 47.30 + * prone to label bugs in CodeGenerator 47.31 + * 47.32 + * @test 47.33 + * @run 47.34 + * @option --debug-lines=false 47.35 + */ 47.36 + 47.37 +print("x = " + x); 47.38 +do { 47.39 + break; 47.40 + var x; 47.41 +} while (true); 47.42 + 47.43 + 47.44 +print("y = " + y); 47.45 +while (true) { 47.46 + break; 47.47 + var y; 47.48 +} 47.49 + 47.50 +print("z = " + z); 47.51 +for ( ; ; ) { 47.52 + break; 47.53 + var z; 47.54 + print("THIS SHOULD NEVER BE PRINTED!"); 47.55 +} 47.56 + 47.57 +while (true) { 47.58 + break; 47.59 + if (true) { 47.60 + var s; 47.61 + } 47.62 +} 47.63 + 47.64 +print("s = "+s); 47.65 + 47.66 +print("u = "+u); 47.67 +for ( ; ; ) { 47.68 + break; 47.69 + while (true) { 47.70 + do { 47.71 + var u; 47.72 + } while (true); 47.73 + } 47.74 +} 47.75 + 47.76 +function terminal() { 47.77 + print("r = "+r); 47.78 + print("t = "+t); 47.79 + for (;;) { 47.80 + var r; 47.81 + return; 47.82 + var t; 47.83 + print("THIS SHOULD NEVER BE PRINTED!"); 47.84 + } 47.85 + print("NEITHER SHOULD THIS"); 47.86 +} 47.87 + 47.88 +terminal(); 47.89 + 47.90 +function terminal2() { 47.91 + print("q = "+q); 47.92 + for (;;) { 47.93 + return; 47.94 + print("THIS SHOULD NEVER BE PRINTED!"); 47.95 + } 47.96 + print("NEITHER SHOULD THIS"); 47.97 +} 47.98 + 47.99 +try { 47.100 + terminal2(); 47.101 +} catch (e) { 47.102 + print(e); 47.103 +} 47.104 + 47.105 +function scope2() { 47.106 + var b = 10; 47.107 + print("b = "+b); 47.108 +} 47.109 + 47.110 +scope2(); 47.111 + 47.112 +try { 47.113 + print("b is = "+b); 47.114 +} catch (e) { 47.115 + print(e); 47.116 +} 47.117 + 47.118 + 47.119 +function disp_a() { 47.120 + var a = 20; 47.121 + print("Value of 'a' inside the function " + a); 47.122 +} 47.123 + 47.124 +var a = 10; 47.125 + 47.126 +disp_a(); 47.127 + 47.128 +print("Value of 'a' outside the function " + a);
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/test/script/basic/no_line_numbers.js.EXPECTED Tue May 07 14:43:17 2013 +0200 48.3 @@ -0,0 +1,12 @@ 48.4 +x = undefined 48.5 +y = undefined 48.6 +z = undefined 48.7 +s = undefined 48.8 +u = undefined 48.9 +r = undefined 48.10 +t = undefined 48.11 +ReferenceError: "q" is not defined 48.12 +b = 10 48.13 +ReferenceError: "b" is not defined 48.14 +Value of 'a' inside the function 20 48.15 +Value of 'a' outside the function 10