Tue, 09 Sep 2014 11:14:12 -0700
Merge
test/script/basic/JDK-8048079_1.js | file | annotate | diff | comparison | revisions | |
test/script/basic/JDK-8048079_1.js.EXPECTED | file | annotate | diff | comparison | revisions | |
test/script/basic/JDK-8048079_2.js | file | annotate | diff | comparison | revisions | |
test/script/basic/JDK-8048079_2.js.EXPECTED | file | annotate | diff | comparison | revisions |
1.1 --- a/make/build.xml Wed Sep 03 13:20:05 2014 -0700 1.2 +++ b/make/build.xml Tue Sep 09 11:14:12 2014 -0700 1.3 @@ -340,6 +340,13 @@ 1.4 permission java.util.PropertyPermission "nashorn.test.*", "read"; 1.5 }; 1.6 1.7 +grant codeBase "file:/${basedir}/test/script/basic/es6/*" { 1.8 + permission java.io.FilePermission "${basedir}/test/script/-", "read"; 1.9 + permission java.io.FilePermission "$${user.dir}", "read"; 1.10 + permission java.util.PropertyPermission "user.dir", "read"; 1.11 + permission java.util.PropertyPermission "nashorn.test.*", "read"; 1.12 +}; 1.13 + 1.14 grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" { 1.15 permission java.util.PropertyPermission "java.security.policy", "read"; 1.16 };
2.1 --- a/src/jdk/nashorn/internal/codegen/AssignSymbols.java Wed Sep 03 13:20:05 2014 -0700 2.2 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java Tue Sep 09 11:14:12 2014 -0700 2.3 @@ -36,6 +36,7 @@ 2.4 import static jdk.nashorn.internal.codegen.CompilerConstants.THIS; 2.5 import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS; 2.6 import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE; 2.7 +import static jdk.nashorn.internal.ir.Symbol.IS_CONST; 2.8 import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF; 2.9 import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL; 2.10 import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; 2.11 @@ -83,11 +84,13 @@ 2.12 import jdk.nashorn.internal.ir.UnaryNode; 2.13 import jdk.nashorn.internal.ir.VarNode; 2.14 import jdk.nashorn.internal.ir.WithNode; 2.15 -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor; 2.16 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 2.17 import jdk.nashorn.internal.runtime.Context; 2.18 -import jdk.nashorn.internal.runtime.Property; 2.19 -import jdk.nashorn.internal.runtime.PropertyMap; 2.20 +import jdk.nashorn.internal.runtime.ECMAErrors; 2.21 +import jdk.nashorn.internal.runtime.ErrorManager; 2.22 +import jdk.nashorn.internal.runtime.JSErrorType; 2.23 +import jdk.nashorn.internal.runtime.ParserException; 2.24 +import jdk.nashorn.internal.runtime.Source; 2.25 import jdk.nashorn.internal.runtime.logging.DebugLogger; 2.26 import jdk.nashorn.internal.runtime.logging.Loggable; 2.27 import jdk.nashorn.internal.runtime.logging.Logger; 2.28 @@ -101,7 +104,7 @@ 2.29 * visitor. 2.30 */ 2.31 @Logger(name="symbols") 2.32 -final class AssignSymbols extends NodeOperatorVisitor<LexicalContext> implements Loggable { 2.33 +final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggable { 2.34 private final DebugLogger log; 2.35 private final boolean debug; 2.36 2.37 @@ -190,22 +193,21 @@ 2.38 * @param body the body of the FunctionNode we are entering 2.39 */ 2.40 private void acceptDeclarations(final FunctionNode functionNode, final Block body) { 2.41 - // This visitor will assign symbol to all declared variables, except function declarations (which are taken care 2.42 - // in a separate step above) and "var" declarations in for loop initializers. 2.43 - // 2.44 + // This visitor will assign symbol to all declared variables, except "var" declarations in for loop initializers. 2.45 body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { 2.46 @Override 2.47 - public boolean enterFunctionNode(final FunctionNode nestedFn) { 2.48 - // Don't descend into nested functions 2.49 - return false; 2.50 + protected boolean enterDefault(final Node node) { 2.51 + // Don't bother visiting expressions; var is a statement, it can't be inside an expression. 2.52 + // This will also prevent visiting nested functions (as FunctionNode is an expression). 2.53 + return !(node instanceof Expression); 2.54 } 2.55 2.56 @Override 2.57 public Node leaveVarNode(final VarNode varNode) { 2.58 if (varNode.isStatement()) { 2.59 final IdentNode ident = varNode.getName(); 2.60 - final Symbol symbol = defineSymbol(body, ident.getName(), IS_VAR); 2.61 - functionNode.addDeclaredSymbol(symbol); 2.62 + final Block block = varNode.isBlockScoped() ? getLexicalContext().getCurrentBlock() : body; 2.63 + final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags()); 2.64 if (varNode.isFunctionDeclaration()) { 2.65 symbol.setIsFunctionDeclaration(); 2.66 } 2.67 @@ -303,23 +305,31 @@ 2.68 return functionNode.setBody(lc, body.setStatements(lc, newStatements)); 2.69 } 2.70 2.71 - private Symbol defineGlobalSymbol(final Block block, final String name) { 2.72 - return defineSymbol(block, name, IS_GLOBAL); 2.73 - } 2.74 - 2.75 /** 2.76 * Defines a new symbol in the given block. 2.77 * 2.78 * @param block the block in which to define the symbol 2.79 * @param name name of symbol. 2.80 + * @param origin origin node 2.81 * @param symbolFlags Symbol flags. 2.82 * 2.83 * @return Symbol for given name or null for redefinition. 2.84 */ 2.85 - private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) { 2.86 + private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) { 2.87 int flags = symbolFlags; 2.88 - Symbol symbol = findSymbol(block, name); // Locate symbol. 2.89 - final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL; 2.90 + final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0; 2.91 + final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL; 2.92 + 2.93 + Symbol symbol; 2.94 + final FunctionNode function; 2.95 + if (isBlockScope) { 2.96 + // block scoped variables always live in current block, no need to look for existing symbols in parent blocks. 2.97 + symbol = block.getExistingSymbol(name); 2.98 + function = lc.getCurrentFunction(); 2.99 + } else { 2.100 + symbol = findSymbol(block, name); 2.101 + function = lc.getFunction(block); 2.102 + } 2.103 2.104 // Global variables are implicitly always scope variables too. 2.105 if (isGlobal) { 2.106 @@ -333,7 +343,6 @@ 2.107 final boolean isParam = (flags & KINDMASK) == IS_PARAM; 2.108 final boolean isVar = (flags & KINDMASK) == IS_VAR; 2.109 2.110 - final FunctionNode function = lc.getFunction(block); 2.111 if (symbol != null) { 2.112 // Symbol was already defined. Check if it needs to be redefined. 2.113 if (isParam) { 2.114 @@ -345,10 +354,21 @@ 2.115 throw new AssertionError("duplicate parameter"); 2.116 } 2.117 } else if (isVar) { 2.118 - if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) { 2.119 + if (isBlockScope) { 2.120 + // Check redeclaration in same block 2.121 + if (symbol.hasBeenDeclared()) { 2.122 + throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin); 2.123 + } else { 2.124 + symbol.setHasBeenDeclared(); 2.125 + } 2.126 + } else if ((flags & IS_INTERNAL) != 0) { 2.127 // Always create a new definition. 2.128 symbol = null; 2.129 } else { 2.130 + // Found LET or CONST in parent scope of same function - s SyntaxError 2.131 + if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) { 2.132 + throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin); 2.133 + } 2.134 // Not defined in this function. Create a new definition. 2.135 if (!isLocal(function, symbol) || symbol.less(IS_VAR)) { 2.136 symbol = null; 2.137 @@ -359,10 +379,10 @@ 2.138 2.139 if (symbol == null) { 2.140 // If not found, then create a new one. 2.141 - Block symbolBlock; 2.142 + final Block symbolBlock; 2.143 2.144 // Determine where to create it. 2.145 - if (isVar && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { 2.146 + if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) { 2.147 symbolBlock = block; //internal vars are always defined in the block closest to them 2.148 } else if (isGlobal) { 2.149 symbolBlock = lc.getOutermostFunction().getBody(); 2.150 @@ -420,15 +440,30 @@ 2.151 @Override 2.152 public boolean enterBlock(final Block block) { 2.153 start(block); 2.154 - block.clearSymbols(); 2.155 2.156 if (lc.isFunctionBody()) { 2.157 + block.clearSymbols(); 2.158 + final FunctionNode fn = lc.getCurrentFunction(); 2.159 + if (isUnparsedFunction(fn)) { 2.160 + // It's a skipped nested function. Just mark the symbols being used by it as being in use. 2.161 + for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) { 2.162 + nameIsUsed(name, null); 2.163 + } 2.164 + // Don't bother descending into it, it must be empty anyway. 2.165 + assert block.getStatements().isEmpty(); 2.166 + return false; 2.167 + } 2.168 + 2.169 enterFunctionBody(); 2.170 } 2.171 2.172 return true; 2.173 } 2.174 2.175 + private boolean isUnparsedFunction(final FunctionNode fn) { 2.176 + return compiler.isOnDemandCompilation() && fn != lc.getOutermostFunction(); 2.177 + } 2.178 + 2.179 @Override 2.180 public boolean enterCatchNode(final CatchNode catchNode) { 2.181 final IdentNode exception = catchNode.getException(); 2.182 @@ -441,7 +476,10 @@ 2.183 // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its 2.184 // symbol is naturally internal, and should be treated as such. 2.185 final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName()); 2.186 - defineSymbol(block, exname, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE); 2.187 + // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to 2.188 + // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block. 2.189 + final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE); 2.190 + symbol.clearFlag(IS_LET); 2.191 2.192 return true; 2.193 } 2.194 @@ -452,15 +490,13 @@ 2.195 2.196 initFunctionWideVariables(functionNode, body); 2.197 2.198 - if (functionNode.isProgram()) { 2.199 - initGlobalSymbols(body); 2.200 - } else if (!functionNode.isDeclared() && !functionNode.isAnonymous()) { 2.201 + if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) { 2.202 // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's 2.203 // anonymous. 2.204 final String name = functionNode.getIdent().getName(); 2.205 assert name != null; 2.206 assert body.getExistingSymbol(name) == null; 2.207 - defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE); 2.208 + defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE); 2.209 if(functionNode.allVarsInScope()) { // basically, has deep eval 2.210 lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL); 2.211 } 2.212 @@ -471,41 +507,48 @@ 2.213 2.214 @Override 2.215 public boolean enterFunctionNode(final FunctionNode functionNode) { 2.216 - // TODO: once we have information on symbols used by nested functions, we can stop descending into nested 2.217 - // functions with on-demand compilation, e.g. add 2.218 - // if(!thisProperties.isEmpty() && env.isOnDemandCompilation()) { 2.219 - // return false; 2.220 - // } 2.221 start(functionNode, false); 2.222 2.223 thisProperties.push(new HashSet<String>()); 2.224 2.225 - //an outermost function in our lexical context that is not a program 2.226 - //is possible - it is a function being compiled lazily 2.227 if (functionNode.isDeclared()) { 2.228 + // Can't use lc.getCurrentBlock() as we can have an outermost function in our lexical context that 2.229 + // is not a program - it is a function being compiled on-demand. 2.230 final Iterator<Block> blocks = lc.getBlocks(); 2.231 if (blocks.hasNext()) { 2.232 - defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0)); 2.233 + final IdentNode ident = functionNode.getIdent(); 2.234 + defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0)); 2.235 } 2.236 } 2.237 2.238 + // Every function has a body, even the ones skipped on reparse (they have an empty one). We're 2.239 + // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that 2.240 + // are used in them. 2.241 + assert functionNode.getBody() != null; 2.242 + 2.243 return true; 2.244 } 2.245 2.246 @Override 2.247 public boolean enterVarNode(final VarNode varNode) { 2.248 start(varNode); 2.249 - defineSymbol(lc.getCurrentBlock(), varNode.getName().getName(), IS_VAR | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0)); 2.250 return true; 2.251 } 2.252 2.253 + @Override 2.254 + public Node leaveVarNode(final VarNode varNode) { 2.255 + final IdentNode ident = varNode.getName(); 2.256 + defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0)); 2.257 + return super.leaveVarNode(varNode); 2.258 + } 2.259 + 2.260 private Symbol exceptionSymbol() { 2.261 return newObjectInternal(EXCEPTION_PREFIX); 2.262 } 2.263 2.264 /** 2.265 * This has to run before fix assignment types, store any type specializations for 2.266 - * paramters, then turn then to objects for the generic version of this method 2.267 + * parameters, then turn them into objects for the generic version of this method. 2.268 * 2.269 * @param functionNode functionNode 2.270 */ 2.271 @@ -597,7 +640,7 @@ 2.272 } 2.273 2.274 private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) { 2.275 - defineSymbol(block, cc.symbolName(), flags).setNeedsSlot(true); 2.276 + defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true); 2.277 } 2.278 2.279 private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) { 2.280 @@ -608,7 +651,7 @@ 2.281 initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE); 2.282 if (functionNode.needsArguments()) { 2.283 initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE); 2.284 - defineSymbol(body, ARGUMENTS_VAR.symbolName(), IS_VAR | HAS_OBJECT_VALUE); 2.285 + defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE); 2.286 } 2.287 } 2.288 2.289 @@ -617,20 +660,6 @@ 2.290 initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL); 2.291 } 2.292 2.293 - 2.294 - /** 2.295 - * Move any properties from the global map into the scope of this function (which must be a program function). 2.296 - * @param block the function node body for which to init scope vars 2.297 - */ 2.298 - private void initGlobalSymbols(final Block block) { 2.299 - final PropertyMap map = Context.getGlobalMap(); 2.300 - 2.301 - for (final Property property : map.getProperties()) { 2.302 - final Symbol symbol = defineGlobalSymbol(block, property.getKey()); 2.303 - log.info("Added global symbol from property map ", symbol); 2.304 - } 2.305 - } 2.306 - 2.307 /** 2.308 * Initialize parameters for function node. 2.309 * @param functionNode the function node 2.310 @@ -639,7 +668,7 @@ 2.311 final boolean isVarArg = functionNode.isVarArg(); 2.312 final boolean scopeParams = functionNode.allVarsInScope() || isVarArg; 2.313 for (final IdentNode param : functionNode.getParameters()) { 2.314 - final Symbol symbol = defineSymbol(body, param.getName(), IS_PARAM); 2.315 + final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM); 2.316 if(scopeParams) { 2.317 // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored. 2.318 // It will force creation of scopes where they would otherwise not necessarily be needed (functions 2.319 @@ -665,10 +694,29 @@ 2.320 return definingFn == function; 2.321 } 2.322 2.323 + private void checkConstAssignment(final IdentNode ident) { 2.324 + // Check for reassignment of constant 2.325 + final Symbol symbol = ident.getSymbol(); 2.326 + if (symbol.isConst()) { 2.327 + throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident); 2.328 + } 2.329 + } 2.330 + 2.331 @Override 2.332 - public Node leaveASSIGN(final BinaryNode binaryNode) { 2.333 + public Node leaveBinaryNode(final BinaryNode binaryNode) { 2.334 + if (binaryNode.isAssignment() && binaryNode.lhs() instanceof IdentNode) { 2.335 + checkConstAssignment((IdentNode) binaryNode.lhs()); 2.336 + } 2.337 + switch (binaryNode.tokenType()) { 2.338 + case ASSIGN: 2.339 + return leaveASSIGN(binaryNode); 2.340 + default: 2.341 + return super.leaveBinaryNode(binaryNode); 2.342 + } 2.343 + } 2.344 + 2.345 + private Node leaveASSIGN(final BinaryNode binaryNode) { 2.346 // If we're assigning a property of the this object ("this.foo = ..."), record it. 2.347 - 2.348 final Expression lhs = binaryNode.lhs(); 2.349 if (lhs instanceof AccessNode) { 2.350 final AccessNode accessNode = (AccessNode) lhs; 2.351 @@ -684,23 +732,43 @@ 2.352 } 2.353 2.354 @Override 2.355 + public Node leaveUnaryNode(final UnaryNode unaryNode) { 2.356 + if (unaryNode.isAssignment() && unaryNode.getExpression() instanceof IdentNode) { 2.357 + checkConstAssignment((IdentNode) unaryNode.getExpression()); 2.358 + } 2.359 + switch (unaryNode.tokenType()) { 2.360 + case DELETE: 2.361 + return leaveDELETE(unaryNode); 2.362 + case TYPEOF: 2.363 + return leaveTYPEOF(unaryNode); 2.364 + default: 2.365 + return super.leaveUnaryNode(unaryNode); 2.366 + } 2.367 + } 2.368 + 2.369 + @Override 2.370 public Node leaveBlock(final Block block) { 2.371 - // It's not necessary to guard the marking of symbols as locals with this "if"condition for correctness, it's 2.372 - // just an optimization -- runtime type calculation is not used when the compilation is not an on-demand 2.373 - // optimistic compilation, so we can skip locals marking then. 2.374 + // It's not necessary to guard the marking of symbols as locals with this "if" condition for 2.375 + // correctness, it's just an optimization -- runtime type calculation is not used when the compilation 2.376 + // is not an on-demand optimistic compilation, so we can skip locals marking then. 2.377 if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) { 2.378 - for (final Symbol symbol: block.getSymbols()) { 2.379 - if (!symbol.isScope()) { 2.380 - assert symbol.isVar() || symbol.isParam(); 2.381 - compiler.declareLocalSymbol(symbol.getName()); 2.382 + // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand 2.383 + // compilation, and we're skipping parsing the function bodies for nested functions, this 2.384 + // basically only means their parameters. It'd be enough to mistakenly declare to be a local a 2.385 + // symbol in the outer function named the same as one of the parameters, though. 2.386 + if (lc.getFunction(block) == lc.getOutermostFunction()) { 2.387 + for (final Symbol symbol: block.getSymbols()) { 2.388 + if (!symbol.isScope()) { 2.389 + assert symbol.isVar() || symbol.isParam(); 2.390 + compiler.declareLocalSymbol(symbol.getName()); 2.391 + } 2.392 } 2.393 } 2.394 } 2.395 return block; 2.396 } 2.397 2.398 - @Override 2.399 - public Node leaveDELETE(final UnaryNode unaryNode) { 2.400 + private Node leaveDELETE(final UnaryNode unaryNode) { 2.401 final FunctionNode currentFunctionNode = lc.getCurrentFunction(); 2.402 final boolean strictMode = currentFunctionNode.isStrict(); 2.403 final Expression rhs = unaryNode.getExpression(); 2.404 @@ -764,24 +832,45 @@ 2.405 2.406 @Override 2.407 public Node leaveFunctionNode(final FunctionNode functionNode) { 2.408 - 2.409 - return markProgramBlock( 2.410 + final FunctionNode finalizedFunction; 2.411 + if (isUnparsedFunction(functionNode)) { 2.412 + finalizedFunction = functionNode; 2.413 + } else { 2.414 + finalizedFunction = 2.415 + markProgramBlock( 2.416 removeUnusedSlots( 2.417 createSyntheticInitializers( 2.418 finalizeParameters( 2.419 lc.applyTopFlags(functionNode)))) 2.420 - .setThisProperties(lc, thisProperties.pop().size()) 2.421 - .setState(lc, CompilationState.SYMBOLS_ASSIGNED)); 2.422 + .setThisProperties(lc, thisProperties.pop().size())); 2.423 + } 2.424 + return finalizedFunction.setState(lc, CompilationState.SYMBOLS_ASSIGNED); 2.425 } 2.426 2.427 @Override 2.428 public Node leaveIdentNode(final IdentNode identNode) { 2.429 - final String name = identNode.getName(); 2.430 - 2.431 if (identNode.isPropertyName()) { 2.432 return identNode; 2.433 } 2.434 2.435 + final Symbol symbol = nameIsUsed(identNode.getName(), identNode); 2.436 + 2.437 + if (!identNode.isInitializedHere()) { 2.438 + symbol.increaseUseCount(); 2.439 + } 2.440 + 2.441 + IdentNode newIdentNode = identNode.setSymbol(symbol); 2.442 + 2.443 + // If a block-scoped var is used before its declaration mark it as dead. 2.444 + // We can only statically detect this for local vars, cross-function symbols require runtime checks. 2.445 + if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) { 2.446 + newIdentNode = newIdentNode.markDead(); 2.447 + } 2.448 + 2.449 + return end(newIdentNode); 2.450 + } 2.451 + 2.452 + private Symbol nameIsUsed(final String name, final IdentNode origin) { 2.453 final Block block = lc.getCurrentBlock(); 2.454 2.455 Symbol symbol = findSymbol(block, name); 2.456 @@ -799,18 +888,12 @@ 2.457 // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already) 2.458 maybeForceScope(symbol); 2.459 } else { 2.460 - log.info("No symbol exists. Declare as global: ", symbol); 2.461 - symbol = defineGlobalSymbol(block, name); 2.462 - Symbol.setSymbolIsScope(lc, symbol); 2.463 + log.info("No symbol exists. Declare as global: ", name); 2.464 + symbol = defineSymbol(block, name, origin, IS_GLOBAL | IS_SCOPE); 2.465 } 2.466 2.467 functionUsesSymbol(symbol); 2.468 - 2.469 - if (!identNode.isInitializedHere()) { 2.470 - symbol.increaseUseCount(); 2.471 - } 2.472 - 2.473 - return end(identNode.setSymbol(symbol)); 2.474 + return symbol; 2.475 } 2.476 2.477 @Override 2.478 @@ -834,8 +917,7 @@ 2.479 return tryNode; 2.480 } 2.481 2.482 - @Override 2.483 - public Node leaveTYPEOF(final UnaryNode unaryNode) { 2.484 + private Node leaveTYPEOF(final UnaryNode unaryNode) { 2.485 final Expression rhs = unaryNode.getExpression(); 2.486 2.487 final List<Expression> args = new ArrayList<>(); 2.488 @@ -859,7 +941,6 @@ 2.489 return functionNode; 2.490 } 2.491 2.492 - assert functionNode.getId() == 1; 2.493 return functionNode.setBody(lc, functionNode.getBody().setFlag(lc, Block.IS_GLOBAL_SCOPE)); 2.494 } 2.495 2.496 @@ -875,7 +956,7 @@ 2.497 } 2.498 2.499 private Symbol newInternal(final CompilerConstants cc, final int flags) { 2.500 - return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), IS_VAR | IS_INTERNAL | flags); //NASHORN-73 2.501 + return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73 2.502 } 2.503 2.504 private Symbol newObjectInternal(final CompilerConstants cc) { 2.505 @@ -915,7 +996,8 @@ 2.506 return false; 2.507 } 2.508 2.509 - if (lc.getCurrentFunction().allVarsInScope()) { 2.510 + final FunctionNode func = lc.getCurrentFunction(); 2.511 + if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) { 2.512 return true; 2.513 } 2.514 2.515 @@ -955,4 +1037,16 @@ 2.516 final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits(); 2.517 return !(units == null || units.isEmpty()); 2.518 } 2.519 + 2.520 + private void throwParserException(final String message, final Node origin) { 2.521 + if (origin == null) { 2.522 + throw new ParserException(message); 2.523 + } 2.524 + final Source source = compiler.getSource(); 2.525 + final long token = origin.getToken(); 2.526 + final int line = source.getLine(origin.getStart()); 2.527 + final int column = source.getColumn(origin.getStart()); 2.528 + final String formatted = ErrorManager.format(message, source, line, column, token); 2.529 + throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token); 2.530 + } 2.531 }
3.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Sep 03 13:20:05 2014 -0700 3.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Sep 09 11:14:12 2014 -0700 3.3 @@ -52,6 +52,7 @@ 3.4 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; 3.5 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid; 3.6 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL; 3.7 +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_DECLARE; 3.8 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE; 3.9 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC; 3.10 import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT; 3.11 @@ -302,6 +303,7 @@ 3.12 * @return the method generator used 3.13 */ 3.14 private MethodEmitter loadIdent(final IdentNode identNode, final TypeBounds resultBounds) { 3.15 + checkTemporalDeadZone(identNode); 3.16 final Symbol symbol = identNode.getSymbol(); 3.17 3.18 if (!symbol.isScope()) { 3.19 @@ -334,6 +336,15 @@ 3.20 return method; 3.21 } 3.22 3.23 + // Any access to LET and CONST variables before their declaration must throw ReferenceError. 3.24 + // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a 3.25 + private void checkTemporalDeadZone(final IdentNode identNode) { 3.26 + if (identNode.isDead()) { 3.27 + method.load(identNode.getSymbol().getName()); 3.28 + method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR); 3.29 + } 3.30 + } 3.31 + 3.32 private boolean isRestOf() { 3.33 return continuationEntryPoints != null; 3.34 } 3.35 @@ -3216,27 +3227,34 @@ 3.36 return false; 3.37 } 3.38 final Expression init = varNode.getInit(); 3.39 - 3.40 - if (init == null) { 3.41 - return false; 3.42 - } 3.43 - 3.44 - enterStatement(varNode); 3.45 - 3.46 final IdentNode identNode = varNode.getName(); 3.47 final Symbol identSymbol = identNode.getSymbol(); 3.48 assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol"; 3.49 - 3.50 + final boolean needsScope = identSymbol.isScope(); 3.51 + 3.52 + if (init == null) { 3.53 + if (needsScope && varNode.isBlockScoped()) { 3.54 + // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ) 3.55 + method.loadCompilerConstant(SCOPE); 3.56 + method.loadUndefined(Type.OBJECT); 3.57 + final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); 3.58 + assert isFastScope(identSymbol); 3.59 + storeFastScopeVar(identSymbol, flags); 3.60 + } 3.61 + return false; 3.62 + } 3.63 + 3.64 + enterStatement(varNode); 3.65 assert method != null; 3.66 3.67 - final boolean needsScope = identSymbol.isScope(); 3.68 if (needsScope) { 3.69 method.loadCompilerConstant(SCOPE); 3.70 } 3.71 3.72 if (needsScope) { 3.73 loadExpressionUnbounded(init); 3.74 - final int flags = CALLSITE_SCOPE | getCallSiteFlags(); 3.75 + // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ) 3.76 + final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); 3.77 if (isFastScope(identSymbol)) { 3.78 storeFastScopeVar(identSymbol, flags); 3.79 } else { 3.80 @@ -4343,6 +4361,9 @@ 3.81 protected abstract void evaluate(); 3.82 3.83 void store() { 3.84 + if (target instanceof IdentNode) { 3.85 + checkTemporalDeadZone((IdentNode)target); 3.86 + } 3.87 prologue(); 3.88 evaluate(); // leaves an operation of whatever the operationType was on the stack 3.89 storeNonDiscard();
4.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java Wed Sep 03 13:20:05 2014 -0700 4.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java Tue Sep 09 11:14:12 2014 -0700 4.3 @@ -59,7 +59,9 @@ 4.4 import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator; 4.5 import jdk.nashorn.internal.runtime.CodeInstaller; 4.6 import jdk.nashorn.internal.runtime.Context; 4.7 +import jdk.nashorn.internal.runtime.ErrorManager; 4.8 import jdk.nashorn.internal.runtime.FunctionInitializer; 4.9 +import jdk.nashorn.internal.runtime.ParserException; 4.10 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; 4.11 import jdk.nashorn.internal.runtime.ScriptEnvironment; 4.12 import jdk.nashorn.internal.runtime.ScriptObject; 4.13 @@ -89,6 +91,8 @@ 4.14 4.15 private final String sourceName; 4.16 4.17 + private final ErrorManager errors; 4.18 + 4.19 private final boolean optimistic; 4.20 4.21 private final Map<String, byte[]> bytecode; 4.22 @@ -311,6 +315,7 @@ 4.23 * @param env script environment 4.24 * @param installer code installer 4.25 * @param source source to compile 4.26 + * @param errors error manager 4.27 * @param isStrict is this a strict compilation 4.28 */ 4.29 public Compiler( 4.30 @@ -318,8 +323,9 @@ 4.31 final ScriptEnvironment env, 4.32 final CodeInstaller<ScriptEnvironment> installer, 4.33 final Source source, 4.34 + final ErrorManager errors, 4.35 final boolean isStrict) { 4.36 - this(context, env, installer, source, isStrict, false, null, null, null, null, null, null); 4.37 + this(context, env, installer, source, errors, isStrict, false, null, null, null, null, null, null); 4.38 } 4.39 4.40 /** 4.41 @@ -329,6 +335,7 @@ 4.42 * @param env script environment 4.43 * @param installer code installer 4.44 * @param source source to compile 4.45 + * @param errors error manager 4.46 * @param isStrict is this a strict compilation 4.47 * @param isOnDemand is this an on demand compilation 4.48 * @param compiledFunction compiled function, if any 4.49 @@ -343,6 +350,7 @@ 4.50 final ScriptEnvironment env, 4.51 final CodeInstaller<ScriptEnvironment> installer, 4.52 final Source source, 4.53 + final ErrorManager errors, 4.54 final boolean isStrict, 4.55 final boolean isOnDemand, 4.56 final RecompilableScriptFunctionData compiledFunction, 4.57 @@ -359,6 +367,7 @@ 4.58 this.bytecode = new LinkedHashMap<>(); 4.59 this.log = initLogger(context); 4.60 this.source = source; 4.61 + this.errors = errors; 4.62 this.sourceName = FunctionNode.getSourceName(source); 4.63 this.onDemand = isOnDemand; 4.64 this.compiledFunction = compiledFunction; 4.65 @@ -524,7 +533,17 @@ 4.66 4.67 for (final CompilationPhase phase : phases) { 4.68 log.fine(phase, " starting for ", quote(name)); 4.69 - newFunctionNode = phase.apply(this, phases, newFunctionNode); 4.70 + 4.71 + try { 4.72 + newFunctionNode = phase.apply(this, phases, newFunctionNode); 4.73 + } catch (final ParserException error) { 4.74 + errors.error(error); 4.75 + if (env._dump_on_error) { 4.76 + error.printStackTrace(env.getErr()); 4.77 + } 4.78 + return null; 4.79 + } 4.80 + 4.81 log.fine(phase, " done for function ", quote(name)); 4.82 4.83 if (env._print_mem_usage) {
5.1 --- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Wed Sep 03 13:20:05 2014 -0700 5.2 +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Tue Sep 09 11:14:12 2014 -0700 5.3 @@ -69,9 +69,7 @@ 5.4 * Constructor 5.5 * 5.6 * @param codegen code generator 5.7 - * @param keys keys for fields in object 5.8 - * @param symbols symbols for fields in object 5.9 - * @param values list of values corresponding to keys 5.10 + * @param tuples tuples for fields in object 5.11 */ 5.12 FieldObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples) { 5.13 this(codegen, tuples, false, false); 5.14 @@ -81,9 +79,7 @@ 5.15 * Constructor 5.16 * 5.17 * @param codegen code generator 5.18 - * @param keys keys for fields in object 5.19 - * @param symbols symbols for fields in object 5.20 - * @param values values (or null where no value) to be written to the fields 5.21 + * @param tuples tuples for fields in object 5.22 * @param isScope is this a scope object 5.23 * @param hasArguments does the created object have an "arguments" property 5.24 */ 5.25 @@ -165,7 +161,7 @@ 5.26 * @param method Script method. 5.27 * @param key Property key. 5.28 * @param fieldIndex Field number. 5.29 - * @param value Value to store. 5.30 + * @param tuple Tuple to store. 5.31 */ 5.32 private void putField(final MethodEmitter method, final String key, final int fieldIndex, final MapTuple<T> tuple) { 5.33 method.dup(); 5.34 @@ -188,7 +184,7 @@ 5.35 * 5.36 * @param method Script method. 5.37 * @param index Slot index. 5.38 - * @param value Value to store. 5.39 + * @param tuple Tuple to store. 5.40 */ 5.41 private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) { 5.42 method.dup();
6.1 --- a/src/jdk/nashorn/internal/codegen/MapCreator.java Wed Sep 03 13:20:05 2014 -0700 6.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java Tue Sep 09 11:14:12 2014 -0700 6.3 @@ -52,8 +52,7 @@ 6.4 * Constructor 6.5 * 6.6 * @param structure structure to generate map for (a JO subclass) 6.7 - * @param keys list of keys for map 6.8 - * @param symbols list of symbols for map 6.9 + * @param tuples list of tuples for map 6.10 */ 6.11 MapCreator(final Class<? extends ScriptObject> structure, final List<MapTuple<T>> tuples) { 6.12 this.structure = structure; 6.13 @@ -149,6 +148,15 @@ 6.14 flags |= Property.IS_FUNCTION_DECLARATION; 6.15 } 6.16 6.17 + if (symbol.isConst()) { 6.18 + flags |= Property.NOT_WRITABLE; 6.19 + } 6.20 + 6.21 + // Mark symbol as needing declaration. Access before declaration will throw a ReferenceError. 6.22 + if (symbol.isBlockScoped() && symbol.isScope()) { 6.23 + flags |= Property.NEEDS_DECLARATION; 6.24 + } 6.25 + 6.26 return flags; 6.27 } 6.28 }
7.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java Wed Sep 03 13:20:05 2014 -0700 7.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java Tue Sep 09 11:14:12 2014 -0700 7.3 @@ -2233,9 +2233,8 @@ 7.4 /** 7.5 * Generate dynamic setter. Pop receiver and property from stack. 7.6 * 7.7 - * @param valueType the type of the value to set 7.8 - * @param name name of property 7.9 - * @param flags call site flags 7.10 + * @param name name of property 7.11 + * @param flags call site flags 7.12 */ 7.13 void dynamicSet(final String name, final int flags) { 7.14 assert !isOptimistic(flags); 7.15 @@ -2462,7 +2461,6 @@ 7.16 * Register line number at a label 7.17 * 7.18 * @param line line number 7.19 - * @param label label 7.20 */ 7.21 void lineNumber(final int line) { 7.22 if (context.getEnv()._debug_lines) {
8.1 --- a/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Wed Sep 03 13:20:05 2014 -0700 8.2 +++ b/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Tue Sep 09 11:14:12 2014 -0700 8.3 @@ -31,9 +31,11 @@ 8.4 import java.io.File; 8.5 import java.io.FileInputStream; 8.6 import java.io.FileOutputStream; 8.7 +import java.io.IOException; 8.8 import java.io.InputStream; 8.9 import java.net.URL; 8.10 import java.nio.file.Files; 8.11 +import java.nio.file.Path; 8.12 import java.security.AccessController; 8.13 import java.security.MessageDigest; 8.14 import java.security.PrivilegedAction; 8.15 @@ -41,6 +43,14 @@ 8.16 import java.util.Base64; 8.17 import java.util.Date; 8.18 import java.util.Map; 8.19 +import java.util.Timer; 8.20 +import java.util.TimerTask; 8.21 +import java.util.concurrent.TimeUnit; 8.22 +import java.util.concurrent.atomic.AtomicBoolean; 8.23 +import java.util.function.Function; 8.24 +import java.util.function.IntFunction; 8.25 +import java.util.function.Predicate; 8.26 +import java.util.stream.Stream; 8.27 import jdk.nashorn.internal.codegen.types.Type; 8.28 import jdk.nashorn.internal.runtime.Context; 8.29 import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; 8.30 @@ -49,30 +59,66 @@ 8.31 import jdk.nashorn.internal.runtime.options.Options; 8.32 8.33 /** 8.34 - * Static utility that encapsulates persistence of decompilation information for functions. Normally, the type info 8.35 - * persistence feature is enabled and operates in an operating-system specific per-user cache directory. You can 8.36 - * override the directory by specifying it in the {@code nashorn.typeInfo.cacheDir} directory. Also, you can disable the 8.37 - * type info persistence altogether by specifying the {@code nashorn.typeInfo.disabled} system property. 8.38 + * Static utility that encapsulates persistence of type information for functions compiled with optimistic 8.39 + * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized, 8.40 + * the type information for deoptimization is stored in a cache file. If the same function is compiled in a 8.41 + * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system 8.42 + * to skip a lot of intermediate recompilations and immediately emit a version of the code that has its 8.43 + * optimistic types at (or near) the steady state. 8.44 + * </p><p> 8.45 + * Normally, the type info persistence feature is disabled. When the {@code nashorn.typeInfo.maxFiles} system 8.46 + * property is specified with a value greater than 0, it is enabled and operates in an operating-system 8.47 + * specific per-user cache directory. You can override the directory by specifying it in the 8.48 + * {@code nashorn.typeInfo.cacheDir} directory. The maximum number of files is softly enforced by a task that 8.49 + * cleans up the directory periodically on a separate thread. It is run after some delay after a new file is 8.50 + * added to the cache. The default delay is 20 seconds, and can be set using the 8.51 + * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word 8.52 + * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is 8.53 + * allowed to grow without limits. 8.54 */ 8.55 public final class OptimisticTypesPersistence { 8.56 + // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is 8.57 + // dependent on the application; setting it to e.g. 20000 is probably good enough for most uses and will 8.58 + // usually cap the cache directory to about 80MB presuming a 4kB filesystem allocation unit. There is one 8.59 + // file per JavaScript function. 8.60 + private static final int DEFAULT_MAX_FILES = 0; 8.61 + // Constants for signifying that the cache should not be limited 8.62 + private static final int UNLIMITED_FILES = -1; 8.63 + // Maximum number of files that should be cached on disk. The maximum will be softly enforced. 8.64 + private static final int MAX_FILES = getMaxFiles(); 8.65 + // Number of seconds to wait between adding a new file to the cache and running a cleanup process 8.66 + private static final int DEFAULT_CLEANUP_DELAY = 20; 8.67 + private static final int CLEANUP_DELAY = Math.max(0, Options.getIntProperty( 8.68 + "nashorn.typeInfo.cleanupDelaySeconds", DEFAULT_CLEANUP_DELAY)); 8.69 // The name of the default subdirectory within the system cache directory where we store type info. 8.70 private static final String DEFAULT_CACHE_SUBDIR_NAME = "com.oracle.java.NashornTypeInfo"; 8.71 // The directory where we cache type info 8.72 - private static final File cacheDir = createCacheDir(); 8.73 + private static final File baseCacheDir = createBaseCacheDir(); 8.74 + private static final File cacheDir = createCacheDir(baseCacheDir); 8.75 // In-process locks to make sure we don't have a cross-thread race condition manipulating any file. 8.76 private static final Object[] locks = cacheDir == null ? null : createLockArray(); 8.77 - 8.78 // Only report one read/write error every minute 8.79 private static final long ERROR_REPORT_THRESHOLD = 60000L; 8.80 8.81 private static volatile long lastReportedError; 8.82 - 8.83 + private static final AtomicBoolean scheduledCleanup; 8.84 + private static final Timer cleanupTimer; 8.85 + static { 8.86 + if (baseCacheDir == null || MAX_FILES == UNLIMITED_FILES) { 8.87 + scheduledCleanup = null; 8.88 + cleanupTimer = null; 8.89 + } else { 8.90 + scheduledCleanup = new AtomicBoolean(); 8.91 + cleanupTimer = new Timer(true); 8.92 + } 8.93 + } 8.94 /** 8.95 - * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed to 8.96 - * {@link #load(Object)} and {@link #store(Object, Map)} methods. 8.97 + * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed 8.98 + * to {@link #load(Object)} and {@link #store(Object, Map)} methods. 8.99 * @param source the source where the function comes from 8.100 * @param functionId the unique ID number of the function within the source 8.101 - * @param paramTypes the types of the function parameters (as persistence is per parameter type specialization). 8.102 + * @param paramTypes the types of the function parameters (as persistence is per parameter type 8.103 + * specialization). 8.104 * @return an opaque descriptor for the persistence location. Can be null if persistence is disabled. 8.105 */ 8.106 public static Object getLocationDescriptor(final Source source, final int functionId, final Type[] paramTypes) { 8.107 @@ -82,7 +128,8 @@ 8.108 final StringBuilder b = new StringBuilder(48); 8.109 // Base64-encode the digest of the source, and append the function id. 8.110 b.append(source.getDigest()).append('-').append(functionId); 8.111 - // Finally, if this is a parameter-type specialized version of the function, add the parameter types to the file name. 8.112 + // Finally, if this is a parameter-type specialized version of the function, add the parameter types 8.113 + // to the file name. 8.114 if(paramTypes != null && paramTypes.length > 0) { 8.115 b.append('-'); 8.116 for(final Type t: paramTypes) { 8.117 @@ -118,6 +165,11 @@ 8.118 @Override 8.119 public Void run() { 8.120 synchronized(getFileLock(file)) { 8.121 + if (!file.exists()) { 8.122 + // If the file already exists, we aren't increasing the number of cached files, so 8.123 + // don't schedule cleanup. 8.124 + scheduleCleanup(); 8.125 + } 8.126 try (final FileOutputStream out = new FileOutputStream(file)) { 8.127 out.getChannel().lock(); // lock exclusive 8.128 final DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out)); 8.129 @@ -174,19 +226,19 @@ 8.130 } 8.131 } 8.132 8.133 - private static File createCacheDir() { 8.134 - if(Options.getBooleanProperty("nashorn.typeInfo.disabled")) { 8.135 + private static File createBaseCacheDir() { 8.136 + if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) { 8.137 return null; 8.138 } 8.139 try { 8.140 - return createCacheDirPrivileged(); 8.141 + return createBaseCacheDirPrivileged(); 8.142 } catch(final Exception e) { 8.143 getLogger().warning("Failed to create cache dir", e); 8.144 return null; 8.145 } 8.146 } 8.147 8.148 - private static File createCacheDirPrivileged() { 8.149 + private static File createBaseCacheDirPrivileged() { 8.150 return AccessController.doPrivileged(new PrivilegedAction<File>() { 8.151 @Override 8.152 public File run() { 8.153 @@ -195,14 +247,35 @@ 8.154 if(explicitDir != null) { 8.155 dir = new File(explicitDir); 8.156 } else { 8.157 - // When no directory is explicitly specified, get an operating system specific cache directory, 8.158 - // and create "com.oracle.java.NashornTypeInfo" in it. 8.159 + // When no directory is explicitly specified, get an operating system specific cache 8.160 + // directory, and create "com.oracle.java.NashornTypeInfo" in it. 8.161 final File systemCacheDir = getSystemCacheDir(); 8.162 dir = new File(systemCacheDir, DEFAULT_CACHE_SUBDIR_NAME); 8.163 if (isSymbolicLink(dir)) { 8.164 return null; 8.165 } 8.166 } 8.167 + return dir; 8.168 + } 8.169 + }); 8.170 + } 8.171 + 8.172 + private static File createCacheDir(final File baseDir) { 8.173 + if (baseDir == null) { 8.174 + return null; 8.175 + } 8.176 + try { 8.177 + return createCacheDirPrivileged(baseDir); 8.178 + } catch(final Exception e) { 8.179 + getLogger().warning("Failed to create cache dir", e); 8.180 + return null; 8.181 + } 8.182 + } 8.183 + 8.184 + private static File createCacheDirPrivileged(final File baseDir) { 8.185 + return AccessController.doPrivileged(new PrivilegedAction<File>() { 8.186 + @Override 8.187 + public File run() { 8.188 final String versionDirName; 8.189 try { 8.190 versionDirName = getVersionDirName(); 8.191 @@ -210,12 +283,12 @@ 8.192 getLogger().warning("Failed to calculate version dir name", e); 8.193 return null; 8.194 } 8.195 - final File versionDir = new File(dir, versionDirName); 8.196 + final File versionDir = new File(baseDir, versionDirName); 8.197 if (isSymbolicLink(versionDir)) { 8.198 return null; 8.199 } 8.200 versionDir.mkdirs(); 8.201 - if(versionDir.isDirectory()) { 8.202 + if (versionDir.isDirectory()) { 8.203 getLogger().info("Optimistic type persistence directory is " + versionDir); 8.204 return versionDir; 8.205 } 8.206 @@ -235,12 +308,12 @@ 8.207 // Mac OS X stores caches in ~/Library/Caches 8.208 return new File(new File(System.getProperty("user.home"), "Library"), "Caches"); 8.209 } else if(os.startsWith("Windows")) { 8.210 - // On Windows, temp directory is the best approximation of a cache directory, as its contents persist across 8.211 - // reboots and various cleanup utilities know about it. java.io.tmpdir normally points to a user-specific 8.212 - // temp directory, %HOME%\LocalSettings\Temp. 8.213 + // On Windows, temp directory is the best approximation of a cache directory, as its contents 8.214 + // persist across reboots and various cleanup utilities know about it. java.io.tmpdir normally 8.215 + // points to a user-specific temp directory, %HOME%\LocalSettings\Temp. 8.216 return new File(System.getProperty("java.io.tmpdir")); 8.217 } else { 8.218 - // In all other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache" 8.219 + // In other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache" 8.220 return new File(System.getProperty("user.home"), ".cache"); 8.221 } 8.222 } 8.223 @@ -278,7 +351,8 @@ 8.224 final int packageNameLen = className.lastIndexOf('.'); 8.225 final String dirStr = fileStr.substring(0, fileStr.length() - packageNameLen - 1); 8.226 final File dir = new File(dirStr); 8.227 - return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(dir, 0L))); 8.228 + return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile( 8.229 + dir, 0L))); 8.230 } else { 8.231 throw new AssertionError(); 8.232 } 8.233 @@ -335,4 +409,108 @@ 8.234 return DebugLogger.DISABLED_LOGGER; 8.235 } 8.236 } 8.237 + 8.238 + private static void scheduleCleanup() { 8.239 + if (MAX_FILES != UNLIMITED_FILES && scheduledCleanup.compareAndSet(false, true)) { 8.240 + cleanupTimer.schedule(new TimerTask() { 8.241 + @Override 8.242 + public void run() { 8.243 + scheduledCleanup.set(false); 8.244 + try { 8.245 + doCleanup(); 8.246 + } catch (final IOException e) { 8.247 + // Ignore it. While this is unfortunate, we don't have good facility for reporting 8.248 + // this, as we're running in a thread that has no access to Context, so we can't grab 8.249 + // a DebugLogger. 8.250 + } 8.251 + } 8.252 + }, TimeUnit.SECONDS.toMillis(CLEANUP_DELAY)); 8.253 + } 8.254 + } 8.255 + 8.256 + private static void doCleanup() throws IOException { 8.257 + final long start = System.nanoTime(); 8.258 + final Path[] files = getAllRegularFilesInLastModifiedOrder(); 8.259 + final int nFiles = files.length; 8.260 + final int filesToDelete = Math.max(0, nFiles - MAX_FILES); 8.261 + int filesDeleted = 0; 8.262 + for (int i = 0; i < nFiles && filesDeleted < filesToDelete; ++i) { 8.263 + try { 8.264 + Files.deleteIfExists(files[i]); 8.265 + // Even if it didn't exist, we increment filesDeleted; it existed a moment earlier; something 8.266 + // else deleted it for us; that's okay with us. 8.267 + filesDeleted++; 8.268 + } catch (final Exception e) { 8.269 + // does not increase filesDeleted 8.270 + } 8.271 + files[i] = null; // gc eligible 8.272 + }; 8.273 + final long duration = System.nanoTime() - start; 8.274 + } 8.275 + 8.276 + private static Path[] getAllRegularFilesInLastModifiedOrder() throws IOException { 8.277 + try (final Stream<Path> filesStream = Files.walk(baseCacheDir.toPath())) { 8.278 + // TODO: rewrite below once we can use JDK8 syntactic constructs 8.279 + return filesStream 8.280 + .filter(new Predicate<Path>() { 8.281 + @Override 8.282 + public boolean test(final Path path) { 8.283 + return !Files.isDirectory(path); 8.284 + }; 8.285 + }) 8.286 + .map(new Function<Path, PathAndTime>() { 8.287 + @Override 8.288 + public PathAndTime apply(final Path path) { 8.289 + return new PathAndTime(path); 8.290 + } 8.291 + }) 8.292 + .sorted() 8.293 + .map(new Function<PathAndTime, Path>() { 8.294 + @Override 8.295 + public Path apply(final PathAndTime pathAndTime) { 8.296 + return pathAndTime.path; 8.297 + } 8.298 + }) 8.299 + .toArray(new IntFunction<Path[]>() { // Replace with Path::new 8.300 + @Override 8.301 + public Path[] apply(final int length) { 8.302 + return new Path[length]; 8.303 + } 8.304 + }); 8.305 + } 8.306 + } 8.307 + 8.308 + private static class PathAndTime implements Comparable<PathAndTime> { 8.309 + private final Path path; 8.310 + private final long time; 8.311 + 8.312 + PathAndTime(final Path path) { 8.313 + this.path = path; 8.314 + this.time = getTime(path); 8.315 + } 8.316 + 8.317 + @Override 8.318 + public int compareTo(final PathAndTime other) { 8.319 + return Long.compare(time, other.time); 8.320 + } 8.321 + 8.322 + private static long getTime(final Path path) { 8.323 + try { 8.324 + return Files.getLastModifiedTime(path).toMillis(); 8.325 + } catch (IOException e) { 8.326 + // All files for which we can't retrieve the last modified date will be considered oldest. 8.327 + return -1L; 8.328 + } 8.329 + } 8.330 + } 8.331 + 8.332 + private static int getMaxFiles() { 8.333 + final String str = Options.getStringProperty("nashorn.typeInfo.maxFiles", null); 8.334 + if (str == null) { 8.335 + return DEFAULT_MAX_FILES; 8.336 + } else if ("unlimited".equals(str)) { 8.337 + return UNLIMITED_FILES; 8.338 + } 8.339 + return Math.max(0, Integer.parseInt(str)); 8.340 + } 8.341 }
9.1 --- a/src/jdk/nashorn/internal/codegen/TypeEvaluator.java Wed Sep 03 13:20:05 2014 -0700 9.2 +++ b/src/jdk/nashorn/internal/codegen/TypeEvaluator.java Tue Sep 09 11:14:12 2014 -0700 9.3 @@ -108,7 +108,7 @@ 9.4 9.5 // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed 9.6 // integer). 9.7 - final Object value = property.getObjectValue(owner, owner); 9.8 + final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner); 9.9 if (value == ScriptRuntime.UNDEFINED) { 9.10 return null; 9.11 }
10.1 --- a/src/jdk/nashorn/internal/codegen/types/Type.java Wed Sep 03 13:20:05 2014 -0700 10.2 +++ b/src/jdk/nashorn/internal/codegen/types/Type.java Tue Sep 09 11:14:12 2014 -0700 10.3 @@ -333,7 +333,7 @@ 10.4 */ 10.5 public static Map<Integer, Type> readTypeMap(final DataInput input) throws IOException { 10.6 final int size = input.readInt(); 10.7 - if (size == 0) { 10.8 + if (size <= 0) { 10.9 return null; 10.10 } 10.11 final Map<Integer, Type> map = new TreeMap<>(); 10.12 @@ -345,7 +345,7 @@ 10.13 case 'L': type = Type.OBJECT; break; 10.14 case 'D': type = Type.NUMBER; break; 10.15 case 'J': type = Type.LONG; break; 10.16 - default: throw new AssertionError(); 10.17 + default: continue; 10.18 } 10.19 map.put(pp, type); 10.20 }
11.1 --- a/src/jdk/nashorn/internal/ir/Block.java Wed Sep 03 13:20:05 2014 -0700 11.2 +++ b/src/jdk/nashorn/internal/ir/Block.java Tue Sep 09 11:14:12 2014 -0700 11.3 @@ -277,6 +277,14 @@ 11.4 } 11.5 11.6 /** 11.7 + * Returns the number of statements in the block. 11.8 + * @return the number of statements in the block. 11.9 + */ 11.10 + public int getStatementCount() { 11.11 + return statements.size(); 11.12 + } 11.13 + 11.14 + /** 11.15 * Returns the line number of the first statement in the block. 11.16 * @return the line number of the first statement in the block, or -1 if the block has no statements. 11.17 */
12.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java Wed Sep 03 13:20:05 2014 -0700 12.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java Tue Sep 09 11:14:12 2014 -0700 12.3 @@ -48,6 +48,7 @@ 12.4 import jdk.nashorn.internal.ir.annotations.Ignore; 12.5 import jdk.nashorn.internal.ir.annotations.Immutable; 12.6 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 12.7 +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData; 12.8 import jdk.nashorn.internal.runtime.ScriptFunction; 12.9 import jdk.nashorn.internal.runtime.Source; 12.10 import jdk.nashorn.internal.runtime.UserAccessorProperty; 12.11 @@ -110,8 +111,11 @@ 12.12 /** Source of entity. */ 12.13 private final Source source; 12.14 12.15 - /** Unique ID used for recompilation among other things */ 12.16 - private final int id; 12.17 + /** 12.18 + * Opaque object representing parser state at the end of the function. Used when reparsing outer functions 12.19 + * to skip parsing inner functions. 12.20 + */ 12.21 + private final Object endParserState; 12.22 12.23 /** External function identifier. */ 12.24 @Ignore 12.25 @@ -138,10 +142,6 @@ 12.26 /** Last token of function. **/ 12.27 private final long lastToken; 12.28 12.29 - /** Declared symbols in this function node */ 12.30 - @Ignore 12.31 - private final Set<Symbol> declaredSymbols; 12.32 - 12.33 /** Method's namespace. */ 12.34 private final Namespace namespace; 12.35 12.36 @@ -260,6 +260,14 @@ 12.37 /** trace callsite values in this function? */ 12.38 public static final int IS_TRACE_VALUES = 1 << 26; 12.39 12.40 + /** 12.41 + * Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a 12.42 + * parameter on invocation. Note that we aren't, in fact using this flag in function nodes. 12.43 + * Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData} 12.44 + * will, however, cache the value of this flag. 12.45 + */ 12.46 + public static final int NEEDS_CALLEE = 1 << 27; 12.47 + 12.48 /** extension callsite flags mask */ 12.49 public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE | 12.50 IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST | 12.51 @@ -275,16 +283,9 @@ 12.52 /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */ 12.53 private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL; 12.54 12.55 - /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval. 12.56 - * We also pessimistically need a parent scope if we have lazy children that have not yet been compiled */ 12.57 + /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval. */ 12.58 private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL; 12.59 12.60 - /** Used to signify "null", e.g. if someone asks for the parent of the program node */ 12.61 - public static final int NO_FUNCTION_ID = 0; 12.62 - 12.63 - /** Where to start assigning global and unique function node ids */ 12.64 - public static final int FIRST_FUNCTION_ID = NO_FUNCTION_ID + 1; 12.65 - 12.66 /** What is the return type of this function? */ 12.67 private Type returnType = Type.UNKNOWN; 12.68 12.69 @@ -292,11 +293,10 @@ 12.70 * Constructor 12.71 * 12.72 * @param source the source 12.73 - * @param id unique id 12.74 * @param lineNumber line number 12.75 * @param token token 12.76 * @param finish finish 12.77 - * @param firstToken first token of the funtion node (including the function declaration) 12.78 + * @param firstToken first token of the function node (including the function declaration) 12.79 * @param namespace the namespace 12.80 * @param ident the identifier 12.81 * @param name the name of the function 12.82 @@ -306,7 +306,6 @@ 12.83 */ 12.84 public FunctionNode( 12.85 final Source source, 12.86 - final int id, 12.87 final int lineNumber, 12.88 final long token, 12.89 final int finish, 12.90 @@ -320,7 +319,6 @@ 12.91 super(token, finish); 12.92 12.93 this.source = source; 12.94 - this.id = id; 12.95 this.lineNumber = lineNumber; 12.96 this.ident = ident; 12.97 this.name = name; 12.98 @@ -330,17 +328,18 @@ 12.99 this.lastToken = token; 12.100 this.namespace = namespace; 12.101 this.compilationState = EnumSet.of(CompilationState.INITIALIZED); 12.102 - this.declaredSymbols = new HashSet<>(); 12.103 this.flags = flags; 12.104 this.compileUnit = null; 12.105 this.body = null; 12.106 this.thisProperties = 0; 12.107 this.rootClass = null; 12.108 + this.endParserState = null; 12.109 } 12.110 12.111 private FunctionNode( 12.112 final FunctionNode functionNode, 12.113 final long lastToken, 12.114 + Object endParserState, 12.115 final int flags, 12.116 final String name, 12.117 final Type returnType, 12.118 @@ -352,6 +351,7 @@ 12.119 final Class<?> rootClass) { 12.120 super(functionNode); 12.121 12.122 + this.endParserState = endParserState; 12.123 this.lineNumber = functionNode.lineNumber; 12.124 this.flags = flags; 12.125 this.name = name; 12.126 @@ -366,10 +366,8 @@ 12.127 12.128 // the fields below never change - they are final and assigned in constructor 12.129 this.source = functionNode.source; 12.130 - this.id = functionNode.id; 12.131 this.ident = functionNode.ident; 12.132 this.namespace = functionNode.namespace; 12.133 - this.declaredSymbols = functionNode.declaredSymbols; 12.134 this.kind = functionNode.kind; 12.135 this.firstToken = functionNode.firstToken; 12.136 } 12.137 @@ -435,11 +433,11 @@ 12.138 } 12.139 12.140 /** 12.141 - * Get the unique ID for this function 12.142 + * Get the unique ID for this function within the script file. 12.143 * @return the id 12.144 */ 12.145 public int getId() { 12.146 - return id; 12.147 + return position(); 12.148 } 12.149 12.150 /** 12.151 @@ -541,6 +539,7 @@ 12.152 new FunctionNode( 12.153 this, 12.154 lastToken, 12.155 + endParserState, 12.156 flags, 12.157 name, 12.158 returnType, 12.159 @@ -612,6 +611,7 @@ 12.160 new FunctionNode( 12.161 this, 12.162 lastToken, 12.163 + endParserState, 12.164 flags, 12.165 name, 12.166 returnType, 12.167 @@ -650,15 +650,24 @@ 12.168 } 12.169 12.170 /** 12.171 - * Check if the {@code eval} keyword is used in this function 12.172 + * Check if this function has a call expression for the identifier "eval" (that is, {@code eval(...)}). 12.173 * 12.174 - * @return true if {@code eval} is used 12.175 + * @return true if {@code eval} is called. 12.176 */ 12.177 public boolean hasEval() { 12.178 return getFlag(HAS_EVAL); 12.179 } 12.180 12.181 /** 12.182 + * Returns true if a function nested (directly or transitively) within this function {@link #hasEval()}. 12.183 + * 12.184 + * @return true if a nested function calls {@code eval}. 12.185 + */ 12.186 + public boolean hasNestedEval() { 12.187 + return getFlag(HAS_NESTED_EVAL); 12.188 + } 12.189 + 12.190 + /** 12.191 * Get the first token for this function 12.192 * @return the first token 12.193 */ 12.194 @@ -724,24 +733,6 @@ 12.195 } 12.196 12.197 /** 12.198 - * Return a set of symbols declared in this function node. This 12.199 - * is only relevant after Attr, otherwise it will be an empty 12.200 - * set as no symbols have been introduced 12.201 - * @return set of declared symbols in function 12.202 - */ 12.203 - public Set<Symbol> getDeclaredSymbols() { 12.204 - return Collections.unmodifiableSet(declaredSymbols); 12.205 - } 12.206 - 12.207 - /** 12.208 - * Add a declared symbol to this function node 12.209 - * @param symbol symbol that is declared 12.210 - */ 12.211 - public void addDeclaredSymbol(final Symbol symbol) { 12.212 - declaredSymbols.add(symbol); 12.213 - } 12.214 - 12.215 - /** 12.216 * Get the function body 12.217 * @return the function body 12.218 */ 12.219 @@ -765,6 +756,7 @@ 12.220 new FunctionNode( 12.221 this, 12.222 lastToken, 12.223 + endParserState, 12.224 flags | 12.225 (body.needsScope() ? 12.226 FunctionNode.HAS_SCOPE_BLOCK : 12.227 @@ -863,6 +855,7 @@ 12.228 new FunctionNode( 12.229 this, 12.230 lastToken, 12.231 + endParserState, 12.232 flags, 12.233 name, 12.234 returnType, 12.235 @@ -923,6 +916,7 @@ 12.236 new FunctionNode( 12.237 this, 12.238 lastToken, 12.239 + endParserState, 12.240 flags, 12.241 name, 12.242 returnType, 12.243 @@ -935,6 +929,41 @@ 12.244 } 12.245 12.246 /** 12.247 + * Returns the end parser state for this function. 12.248 + * @return the end parser state for this function. 12.249 + */ 12.250 + public Object getEndParserState() { 12.251 + return endParserState; 12.252 + } 12.253 + 12.254 + /** 12.255 + * Set the end parser state for this function. 12.256 + * @param lc lexical context 12.257 + * @param endParserState the parser state to set 12.258 + * @return function node or a new one if state was changed 12.259 + */ 12.260 + public FunctionNode setEndParserState(final LexicalContext lc, final Object endParserState) { 12.261 + if (this.endParserState == endParserState) { 12.262 + return this; 12.263 + } 12.264 + return Node.replaceInLexicalContext( 12.265 + lc, 12.266 + this, 12.267 + new FunctionNode( 12.268 + this, 12.269 + lastToken, 12.270 + endParserState, 12.271 + flags, 12.272 + name, 12.273 + returnType, 12.274 + compileUnit, 12.275 + compilationState, 12.276 + body, 12.277 + parameters, 12.278 + thisProperties, rootClass)); 12.279 + } 12.280 + 12.281 + /** 12.282 * Get the name of this function 12.283 * @return the name 12.284 */ 12.285 @@ -958,6 +987,7 @@ 12.286 new FunctionNode( 12.287 this, 12.288 lastToken, 12.289 + endParserState, 12.290 flags, 12.291 name, 12.292 returnType, 12.293 @@ -970,13 +1000,13 @@ 12.294 } 12.295 12.296 /** 12.297 - * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and 12.298 + * Check if this function should have all its variables in its own scope. Split sub-functions, and 12.299 * functions having with and/or eval blocks are such. 12.300 * 12.301 * @return true if all variables should be in scope 12.302 */ 12.303 public boolean allVarsInScope() { 12.304 - return isProgram() || getFlag(HAS_ALL_VARS_IN_SCOPE); 12.305 + return getFlag(HAS_ALL_VARS_IN_SCOPE); 12.306 } 12.307 12.308 /** 12.309 @@ -1023,6 +1053,7 @@ 12.310 new FunctionNode( 12.311 this, 12.312 lastToken, 12.313 + endParserState, 12.314 flags, 12.315 name, 12.316 returnType, 12.317 @@ -1101,6 +1132,7 @@ 12.318 new FunctionNode( 12.319 this, 12.320 lastToken, 12.321 + endParserState, 12.322 flags, 12.323 name, 12.324 type, 12.325 @@ -1147,6 +1179,7 @@ 12.326 new FunctionNode( 12.327 this, 12.328 lastToken, 12.329 + endParserState, 12.330 flags, 12.331 name, 12.332 returnType, 12.333 @@ -1202,6 +1235,7 @@ 12.334 new FunctionNode( 12.335 this, 12.336 lastToken, 12.337 + endParserState, 12.338 flags, 12.339 name, 12.340 returnType,
13.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java Wed Sep 03 13:20:05 2014 -0700 13.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java Tue Sep 09 11:14:12 2014 -0700 13.3 @@ -46,6 +46,8 @@ 13.4 private static final int INITIALIZED_HERE = 1 << 1; 13.5 private static final int FUNCTION = 1 << 2; 13.6 private static final int FUTURESTRICT_NAME = 1 << 3; 13.7 + private static final int IS_DECLARED_HERE = 1 << 4; 13.8 + private static final int IS_DEAD = 1 << 5; 13.9 13.10 /** Identifier. */ 13.11 private final String name; 13.12 @@ -247,6 +249,45 @@ 13.13 } 13.14 13.15 /** 13.16 + * Is this a LET or CONST identifier used before its declaration? 13.17 + * 13.18 + * @return true if identifier is dead 13.19 + */ 13.20 + public boolean isDead() { 13.21 + return (flags & IS_DEAD) != 0; 13.22 + } 13.23 + 13.24 + /** 13.25 + * Flag this IdentNode as a LET or CONST identifier used before its declaration. 13.26 + * 13.27 + * @return a new IdentNode equivalent to this but marked as dead. 13.28 + */ 13.29 + public IdentNode markDead() { 13.30 + return new IdentNode(this, name, type, flags | IS_DEAD, programPoint, conversion); 13.31 + } 13.32 + 13.33 + /** 13.34 + * Is this IdentNode declared here? 13.35 + * 13.36 + * @return true if identifier is declared here 13.37 + */ 13.38 + public boolean isDeclaredHere() { 13.39 + return (flags & IS_DECLARED_HERE) != 0; 13.40 + } 13.41 + 13.42 + /** 13.43 + * Flag this IdentNode as being declared here. 13.44 + * 13.45 + * @return a new IdentNode equivalent to this but marked as declared here. 13.46 + */ 13.47 + public IdentNode setIsDeclaredHere() { 13.48 + if (isDeclaredHere()) { 13.49 + return this; 13.50 + } 13.51 + return new IdentNode(this, name, type, flags | IS_DECLARED_HERE, programPoint, conversion); 13.52 + } 13.53 + 13.54 + /** 13.55 * Check if the name of this IdentNode is same as that of a compile-time property (currently __DIR__, __FILE__, and 13.56 * __LINE__). 13.57 *
14.1 --- a/src/jdk/nashorn/internal/ir/LexicalContext.java Wed Sep 03 13:20:05 2014 -0700 14.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java Tue Sep 09 11:14:12 2014 -0700 14.3 @@ -351,8 +351,7 @@ 14.4 } 14.5 14.6 /** 14.7 - * Get the function for this block. If the block is itself a function 14.8 - * this returns identity 14.9 + * Get the function for this block. 14.10 * @param block block for which to get function 14.11 * @return function for block 14.12 */
15.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java Wed Sep 03 13:20:05 2014 -0700 15.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Tue Sep 09 11:14:12 2014 -0700 15.3 @@ -54,17 +54,17 @@ 15.4 public static final int IS_VAR = 2; 15.5 /** Is this a parameter */ 15.6 public static final int IS_PARAM = 3; 15.7 - /** Is this a constant */ 15.8 - public static final int IS_CONSTANT = 4; 15.9 /** Mask for kind flags */ 15.10 - public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits 15.11 + public static final int KINDMASK = (1 << 2) - 1; // Kinds are represented by lower two bits 15.12 15.13 /** Is this symbol in scope */ 15.14 - public static final int IS_SCOPE = 1 << 3; 15.15 + public static final int IS_SCOPE = 1 << 2; 15.16 /** Is this a this symbol */ 15.17 - public static final int IS_THIS = 1 << 4; 15.18 + public static final int IS_THIS = 1 << 3; 15.19 /** Is this a let */ 15.20 - public static final int IS_LET = 1 << 5; 15.21 + public static final int IS_LET = 1 << 4; 15.22 + /** Is this a const */ 15.23 + public static final int IS_CONST = 1 << 5; 15.24 /** Is this an internal symbol, never represented explicitly in source code */ 15.25 public static final int IS_INTERNAL = 1 << 6; 15.26 /** Is this a function self-reference symbol */ 15.27 @@ -83,6 +83,8 @@ 15.28 public static final int HAS_DOUBLE_VALUE = 1 << 13; 15.29 /** Is this symbol known to store an object value ? */ 15.30 public static final int HAS_OBJECT_VALUE = 1 << 14; 15.31 + /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */ 15.32 + public static final int HAS_BEEN_DECLARED = 1 << 15; 15.33 15.34 /** Null or name identifying symbol. */ 15.35 private final String name; 15.36 @@ -184,14 +186,17 @@ 15.37 sb.append(" global"); 15.38 break; 15.39 case IS_VAR: 15.40 - sb.append(" var"); 15.41 + if (isConst()) { 15.42 + sb.append(" const"); 15.43 + } else if (isLet()) { 15.44 + sb.append(" let"); 15.45 + } else { 15.46 + sb.append(" var"); 15.47 + } 15.48 break; 15.49 case IS_PARAM: 15.50 sb.append(" param"); 15.51 break; 15.52 - case IS_CONSTANT: 15.53 - sb.append(" const"); 15.54 - break; 15.55 default: 15.56 break; 15.57 } 15.58 @@ -204,10 +209,6 @@ 15.59 sb.append(" internal"); 15.60 } 15.61 15.62 - if (isLet()) { 15.63 - sb.append(" let"); 15.64 - } 15.65 - 15.66 if (isThis()) { 15.67 sb.append(" this"); 15.68 } 15.69 @@ -410,8 +411,8 @@ 15.70 * Check if this symbol is a constant 15.71 * @return true if a constant 15.72 */ 15.73 - public boolean isConstant() { 15.74 - return (flags & KINDMASK) == IS_CONSTANT; 15.75 + public boolean isConst() { 15.76 + return (flags & IS_CONST) != 0; 15.77 } 15.78 15.79 /** 15.80 @@ -440,15 +441,6 @@ 15.81 } 15.82 15.83 /** 15.84 - * Flag this symbol as a let 15.85 - */ 15.86 - public void setIsLet() { 15.87 - if (!isLet()) { 15.88 - flags |= IS_LET; 15.89 - } 15.90 - } 15.91 - 15.92 - /** 15.93 * Flag this symbol as a function's self-referencing symbol. 15.94 * @return true if this symbol as a function's self-referencing symbol. 15.95 */ 15.96 @@ -456,6 +448,20 @@ 15.97 return (flags & IS_FUNCTION_SELF) != 0; 15.98 } 15.99 15.100 + public boolean isBlockScoped() { 15.101 + return isLet() || isConst(); 15.102 + } 15.103 + 15.104 + public boolean hasBeenDeclared() { 15.105 + return (flags & HAS_BEEN_DECLARED) != 0; 15.106 + } 15.107 + 15.108 + public void setHasBeenDeclared() { 15.109 + if (!hasBeenDeclared()) { 15.110 + flags |= HAS_BEEN_DECLARED; 15.111 + } 15.112 + } 15.113 + 15.114 /** 15.115 * Get the index of the field used to store this symbol, should it be an AccessorProperty 15.116 * and get allocated in a JO-prefixed ScriptObject subclass.
16.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java Wed Sep 03 13:20:05 2014 -0700 16.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java Tue Sep 09 11:14:12 2014 -0700 16.3 @@ -27,6 +27,7 @@ 16.4 16.5 import jdk.nashorn.internal.ir.annotations.Immutable; 16.6 import jdk.nashorn.internal.ir.visitor.NodeVisitor; 16.7 +import jdk.nashorn.internal.parser.Token; 16.8 16.9 /** 16.10 * Node represents a var/let declaration. 16.11 @@ -43,12 +44,18 @@ 16.12 private final int flags; 16.13 16.14 /** Flag that determines if this function node is a statement */ 16.15 - public static final int IS_STATEMENT = 1 << 0; 16.16 + public static final int IS_STATEMENT = 1 << 0; 16.17 + 16.18 + /** Flag for ES6 LET declaration */ 16.19 + public static final int IS_LET = 1 << 1; 16.20 + 16.21 + /** Flag for ES6 CONST declaration */ 16.22 + public static final int IS_CONST = 1 << 2; 16.23 16.24 /** Flag that determines if this is the last function declaration in a function 16.25 * This is used to micro optimize the placement of return value assignments for 16.26 * a program node */ 16.27 - public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1; 16.28 + public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 3; 16.29 16.30 /** 16.31 * Constructor 16.32 @@ -109,6 +116,43 @@ 16.33 } 16.34 16.35 /** 16.36 + * Is this a VAR node block scoped? This returns true for ECMAScript 6 LET and CONST nodes. 16.37 + * @return true if an ES6 LET or CONST node 16.38 + */ 16.39 + public boolean isBlockScoped() { 16.40 + return getFlag(IS_LET) || getFlag(IS_CONST); 16.41 + } 16.42 + 16.43 + /** 16.44 + * Is this an ECMAScript 6 LET node? 16.45 + * @return true if LET node 16.46 + */ 16.47 + public boolean isLet() { 16.48 + return getFlag(IS_LET); 16.49 + } 16.50 + 16.51 + /** 16.52 + * Is this an ECMAScript 6 CONST node? 16.53 + * @return true if CONST node 16.54 + */ 16.55 + public boolean isConst() { 16.56 + return getFlag(IS_CONST); 16.57 + } 16.58 + 16.59 + /** 16.60 + * Return the flags to use for symbols for this declaration. 16.61 + * @return the symbol flags 16.62 + */ 16.63 + public int getSymbolFlags() { 16.64 + if (isLet()) { 16.65 + return Symbol.IS_VAR | Symbol.IS_LET; 16.66 + } else if (isConst()) { 16.67 + return Symbol.IS_VAR | Symbol.IS_CONST; 16.68 + } 16.69 + return Symbol.IS_VAR; 16.70 + } 16.71 + 16.72 + /** 16.73 * Does this variable declaration have an init value 16.74 * @return true if an init exists, false otherwise 16.75 */ 16.76 @@ -139,7 +183,7 @@ 16.77 16.78 @Override 16.79 public void toString(final StringBuilder sb, final boolean printType) { 16.80 - sb.append("var "); 16.81 + sb.append(Token.descType(getToken()).getName()).append(' '); 16.82 name.toString(sb, printType); 16.83 16.84 if (init != null) {
17.1 --- a/src/jdk/nashorn/internal/parser/Parser.java Wed Sep 03 13:20:05 2014 -0700 17.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java Tue Sep 09 11:14:12 2014 -0700 17.3 @@ -45,6 +45,7 @@ 17.4 import static jdk.nashorn.internal.parser.TokenType.IF; 17.5 import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX; 17.6 import static jdk.nashorn.internal.parser.TokenType.LBRACE; 17.7 +import static jdk.nashorn.internal.parser.TokenType.LET; 17.8 import static jdk.nashorn.internal.parser.TokenType.LPAREN; 17.9 import static jdk.nashorn.internal.parser.TokenType.RBRACE; 17.10 import static jdk.nashorn.internal.parser.TokenType.RBRACKET; 17.11 @@ -147,7 +148,7 @@ 17.12 /** to receive line information from Lexer when scanning multine literals. */ 17.13 protected final Lexer.LineInfoReceiver lineInfoReceiver; 17.14 17.15 - private int nextFunctionId; 17.16 + private RecompilableScriptFunctionData reparsedFunction; 17.17 17.18 /** 17.19 * Constructor 17.20 @@ -170,7 +171,7 @@ 17.21 * @param log debug logger if one is needed 17.22 */ 17.23 public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) { 17.24 - this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0, log); 17.25 + this(env, source, errors, strict, 0, log); 17.26 } 17.27 17.28 /** 17.29 @@ -180,15 +181,13 @@ 17.30 * @param source source to parse 17.31 * @param errors error manager 17.32 * @param strict parser created with strict mode enabled. 17.33 - * @param nextFunctionId starting value for assigning new unique ids to function nodes 17.34 * @param lineOffset line offset to start counting lines from 17.35 * @param log debug logger if one is needed 17.36 */ 17.37 - public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int nextFunctionId, final int lineOffset, final DebugLogger log) { 17.38 + public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int lineOffset, final DebugLogger log) { 17.39 super(source, errors, strict, lineOffset); 17.40 this.env = env; 17.41 this.namespace = new Namespace(env.getNamespace()); 17.42 - this.nextFunctionId = nextFunctionId; 17.43 this.scripting = env._scripting; 17.44 if (this.scripting) { 17.45 this.lineInfoReceiver = new Lexer.LineInfoReceiver() { 17.46 @@ -227,6 +226,16 @@ 17.47 } 17.48 17.49 /** 17.50 + * Sets the {@link RecompilableScriptFunctionData} representing the function being reparsed (when this 17.51 + * parser instance is used to reparse a previously parsed function, as part of its on-demand compilation). 17.52 + * This will trigger various special behaviors, such as skipping nested function bodies. 17.53 + * @param reparsedFunction the function being reparsed. 17.54 + */ 17.55 + public void setReparsedFunction(final RecompilableScriptFunctionData reparsedFunction) { 17.56 + this.reparsedFunction = reparsedFunction; 17.57 + } 17.58 + 17.59 + /** 17.60 * Execute parse and return the resulting function node. 17.61 * Errors will be thrown and the error manager will contain information 17.62 * if parsing should fail 17.63 @@ -471,7 +480,6 @@ 17.64 final FunctionNode functionNode = 17.65 new FunctionNode( 17.66 source, 17.67 - nextFunctionId++, 17.68 functionLine, 17.69 token, 17.70 Token.descPosition(token), 17.71 @@ -579,6 +587,10 @@ 17.72 } 17.73 } 17.74 17.75 + private boolean useBlockScope() { 17.76 + return env._es6; 17.77 + } 17.78 + 17.79 private static boolean isArguments(final String name) { 17.80 return ARGUMENTS_NAME.equals(name); 17.81 } 17.82 @@ -694,9 +706,20 @@ 17.83 FunctionNode.Kind.SCRIPT, 17.84 functionLine); 17.85 17.86 + // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations. 17.87 + final int startLine = start; 17.88 + Block outer = useBlockScope() ? newBlock() : null; 17.89 functionDeclarations = new ArrayList<>(); 17.90 - sourceElements(allowPropertyFunction); 17.91 - addFunctionDeclarations(script); 17.92 + 17.93 + try { 17.94 + sourceElements(allowPropertyFunction); 17.95 + addFunctionDeclarations(script); 17.96 + } finally { 17.97 + if (outer != null) { 17.98 + outer = restoreBlock(outer); 17.99 + appendStatement(new BlockStatement(startLine, outer)); 17.100 + } 17.101 + } 17.102 functionDeclarations = null; 17.103 17.104 expect(EOF); 17.105 @@ -868,7 +891,7 @@ 17.106 block(); 17.107 break; 17.108 case VAR: 17.109 - variableStatement(true); 17.110 + variableStatement(type, true); 17.111 break; 17.112 case SEMICOLON: 17.113 emptyStatement(); 17.114 @@ -918,8 +941,12 @@ 17.115 expect(SEMICOLON); 17.116 break; 17.117 default: 17.118 + if (useBlockScope() && (type == LET || type == CONST)) { 17.119 + variableStatement(type, true); 17.120 + break; 17.121 + } 17.122 if (env._const_as_var && type == CONST) { 17.123 - variableStatement(true); 17.124 + variableStatement(TokenType.VAR, true); 17.125 break; 17.126 } 17.127 17.128 @@ -1035,11 +1062,17 @@ 17.129 * Parse a VAR statement. 17.130 * @param isStatement True if a statement (not used in a FOR.) 17.131 */ 17.132 - private List<VarNode> variableStatement(final boolean isStatement) { 17.133 + private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) { 17.134 // VAR tested in caller. 17.135 next(); 17.136 17.137 final List<VarNode> vars = new ArrayList<>(); 17.138 + int varFlags = VarNode.IS_STATEMENT; 17.139 + if (varType == LET) { 17.140 + varFlags |= VarNode.IS_LET; 17.141 + } else if (varType == CONST) { 17.142 + varFlags |= VarNode.IS_CONST; 17.143 + } 17.144 17.145 while (true) { 17.146 // Get starting token. 17.147 @@ -1063,10 +1096,12 @@ 17.148 } finally { 17.149 defaultNames.pop(); 17.150 } 17.151 + } else if (varType == CONST) { 17.152 + throw error(AbstractParser.message("missing.const.assignment", name.getName())); 17.153 } 17.154 17.155 // Allocate var node. 17.156 - final VarNode var = new VarNode(varLine, varToken, finish, name, init); 17.157 + final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags); 17.158 vars.add(var); 17.159 appendStatement(var); 17.160 17.161 @@ -1180,9 +1215,12 @@ 17.162 * Parse a FOR statement. 17.163 */ 17.164 private void forStatement() { 17.165 + // When ES6 for-let is enabled we create a container block to capture the LET. 17.166 + final int startLine = start; 17.167 + Block outer = useBlockScope() ? newBlock() : null; 17.168 + 17.169 // Create FOR node, capturing FOR token. 17.170 ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR); 17.171 - 17.172 lc.push(forNode); 17.173 17.174 try { 17.175 @@ -1203,14 +1241,19 @@ 17.176 switch (type) { 17.177 case VAR: 17.178 // Var statements captured in for outer block. 17.179 - vars = variableStatement(false); 17.180 + vars = variableStatement(type, false); 17.181 break; 17.182 case SEMICOLON: 17.183 break; 17.184 default: 17.185 + if (useBlockScope() && (type == LET || type == CONST)) { 17.186 + // LET/CONST captured in container block created above. 17.187 + vars = variableStatement(type, false); 17.188 + break; 17.189 + } 17.190 if (env._const_as_var && type == CONST) { 17.191 // Var statements captured in for outer block. 17.192 - vars = variableStatement(false); 17.193 + vars = variableStatement(TokenType.VAR, false); 17.194 break; 17.195 } 17.196 17.197 @@ -1290,8 +1333,13 @@ 17.198 appendStatement(forNode); 17.199 } finally { 17.200 lc.pop(forNode); 17.201 + if (outer != null) { 17.202 + outer.setFinish(forNode.getFinish()); 17.203 + outer = restoreBlock(outer); 17.204 + appendStatement(new BlockStatement(startLine, outer)); 17.205 + } 17.206 } 17.207 - } 17.208 + } 17.209 17.210 /** 17.211 * ... IterationStatement : 17.212 @@ -1722,7 +1770,7 @@ 17.213 } 17.214 } 17.215 17.216 - /** 17.217 + /** 17.218 * ThrowStatement : 17.219 * throw Expression ; // [no LineTerminator here] 17.220 * 17.221 @@ -2609,7 +2657,7 @@ 17.222 FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine); 17.223 17.224 if (isStatement) { 17.225 - if (topLevel) { 17.226 + if (topLevel || useBlockScope()) { 17.227 functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED); 17.228 } else if (isStrictMode) { 17.229 throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken); 17.230 @@ -2661,9 +2709,16 @@ 17.231 } 17.232 17.233 if (isStatement) { 17.234 - final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT); 17.235 + int varFlags = VarNode.IS_STATEMENT; 17.236 + if (!topLevel && useBlockScope()) { 17.237 + // mark ES6 block functions as lexically scoped 17.238 + varFlags |= VarNode.IS_LET; 17.239 + } 17.240 + final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags); 17.241 if (topLevel) { 17.242 functionDeclarations.add(varNode); 17.243 + } else if (useBlockScope()) { 17.244 + prependStatement(varNode); // Hoist to beginning of current block 17.245 } else { 17.246 appendStatement(varNode); 17.247 } 17.248 @@ -2780,10 +2835,14 @@ 17.249 FunctionNode functionNode = null; 17.250 long lastToken = 0L; 17.251 17.252 + final boolean parseBody; 17.253 + Object endParserState = null; 17.254 try { 17.255 // Create a new function block. 17.256 functionNode = newFunctionNode(firstToken, ident, parameters, kind, functionLine); 17.257 - 17.258 + assert functionNode != null; 17.259 + final int functionId = functionNode.getId(); 17.260 + parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId(); 17.261 // Nashorn extension: expression closures 17.262 if (!env._no_syntax_extensions && type != LBRACE) { 17.263 /* 17.264 @@ -2799,34 +2858,152 @@ 17.265 assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode); 17.266 // EOL uses length field to store the line number 17.267 final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken)); 17.268 - final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr); 17.269 - appendStatement(returnNode); 17.270 + // Only create the return node if we aren't skipping nested functions. Note that we aren't 17.271 + // skipping parsing of these extended functions; they're considered to be small anyway. Also, 17.272 + // they don't end with a single well known token, so it'd be very hard to get correctly (see 17.273 + // the note below for reasoning on skipping happening before instead of after RBRACE for 17.274 + // details). 17.275 + if (parseBody) { 17.276 + final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr); 17.277 + appendStatement(returnNode); 17.278 + } 17.279 functionNode.setFinish(lastFinish); 17.280 - 17.281 } else { 17.282 expect(LBRACE); 17.283 - 17.284 - // Gather the function elements. 17.285 - final List<Statement> prevFunctionDecls = functionDeclarations; 17.286 - functionDeclarations = new ArrayList<>(); 17.287 - try { 17.288 - sourceElements(false); 17.289 - addFunctionDeclarations(functionNode); 17.290 - } finally { 17.291 - functionDeclarations = prevFunctionDecls; 17.292 + final int lastLexed = stream.last(); 17.293 + if (parseBody || !skipFunctionBody(functionNode)) { 17.294 + // Gather the function elements. 17.295 + final List<Statement> prevFunctionDecls = functionDeclarations; 17.296 + functionDeclarations = new ArrayList<>(); 17.297 + try { 17.298 + sourceElements(false); 17.299 + addFunctionDeclarations(functionNode); 17.300 + } finally { 17.301 + functionDeclarations = prevFunctionDecls; 17.302 + } 17.303 + 17.304 + lastToken = token; 17.305 + // Avoiding storing parser state if the function body was small (that is, the next token 17.306 + // to be read from the token stream is before the last token lexed before we entered 17.307 + // function body). That'll force the function to be reparsed instead of skipped. Skipping 17.308 + // involves throwing away and recreating the lexer and the token stream, so for small 17.309 + // functions it is likely more economical to not bother with skipping (both in terms of 17.310 + // storing the state, and in terms of throwing away lexer and token stream). 17.311 + if (parseBody && lastLexed < stream.first()) { 17.312 + // Since the lexer can read ahead and lexify some number of tokens in advance and have 17.313 + // them buffered in the TokenStream, we need to produce a lexer state as it was just 17.314 + // before it lexified RBRACE, and not whatever is its current (quite possibly well read 17.315 + // ahead) state. 17.316 + endParserState = new ParserState(Token.descPosition(token), line, linePosition); 17.317 + 17.318 + // NOTE: you might wonder why do we capture/restore parser state before RBRACE instead of 17.319 + // after RBRACE; after all, we could skip the below "expect(RBRACE);" if we captured the 17.320 + // state after it. The reason is that RBRACE is a well-known token that we can expect and 17.321 + // will never involve us getting into a weird lexer state, and as such is a great reparse 17.322 + // point. Typical example of a weird lexer state after RBRACE would be: 17.323 + // function this_is_skipped() { ... } "use strict"; 17.324 + // because lexer is doing weird off-by-one maneuvers around string literal quotes. Instead 17.325 + // of compensating for the possibility of a string literal (or similar) after RBRACE, 17.326 + // we'll rather just restart parsing from this well-known, friendly token instead. 17.327 + } 17.328 } 17.329 - 17.330 - lastToken = token; 17.331 expect(RBRACE); 17.332 functionNode.setFinish(finish); 17.333 } 17.334 } finally { 17.335 functionNode = restoreFunctionNode(functionNode, lastToken); 17.336 } 17.337 + 17.338 + // NOTE: we can only do alterations to the function node after restoreFunctionNode. 17.339 + 17.340 + if (parseBody) { 17.341 + functionNode = functionNode.setEndParserState(lc, endParserState); 17.342 + } else if (functionNode.getBody().getStatementCount() > 0){ 17.343 + // This is to ensure the body is empty when !parseBody but we couldn't skip parsing it (see 17.344 + // skipFunctionBody() for possible reasons). While it is not strictly necessary for correctness to 17.345 + // enforce empty bodies in nested functions that were supposed to be skipped, we do assert it as 17.346 + // an invariant in few places in the compiler pipeline, so for consistency's sake we'll throw away 17.347 + // nested bodies early if we were supposed to skip 'em. 17.348 + functionNode = functionNode.setBody(null, functionNode.getBody().setStatements(null, 17.349 + Collections.<Statement>emptyList())); 17.350 + } 17.351 + 17.352 + if (reparsedFunction != null) { 17.353 + // We restore the flags stored in the function's ScriptFunctionData that we got when we first 17.354 + // eagerly parsed the code. We're doing it because some flags would be set based on the 17.355 + // content of the function, or even content of its nested functions, most of which are normally 17.356 + // skipped during an on-demand compilation. 17.357 + final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId()); 17.358 + if (data != null) { 17.359 + // Data can be null if when we originally parsed the file, we removed the function declaration 17.360 + // as it was dead code. 17.361 + functionNode = functionNode.setFlags(lc, data.getFunctionFlags()); 17.362 + // This compensates for missing markEval() in case the function contains an inner function 17.363 + // that contains eval(), that now we didn't discover since we skipped the inner function. 17.364 + if (functionNode.hasNestedEval()) { 17.365 + assert functionNode.hasScopeBlock(); 17.366 + functionNode = functionNode.setBody(lc, functionNode.getBody().setNeedsScope(null)); 17.367 + } 17.368 + } 17.369 + } 17.370 printAST(functionNode); 17.371 return functionNode; 17.372 } 17.373 17.374 + private boolean skipFunctionBody(final FunctionNode functionNode) { 17.375 + if (reparsedFunction == null) { 17.376 + // Not reparsing, so don't skip any function body. 17.377 + return false; 17.378 + } 17.379 + // Skip to the RBRACE of this function, and continue parsing from there. 17.380 + final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId()); 17.381 + if (data == null) { 17.382 + // Nested function is not known to the reparsed function. This can happen if the FunctionNode was 17.383 + // in dead code that was removed. Both FoldConstants and Lower prune dead code. In that case, the 17.384 + // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it. 17.385 + return false; 17.386 + } 17.387 + final ParserState parserState = (ParserState)data.getEndParserState(); 17.388 + if (parserState == null) { 17.389 + // The function has no stored parser state; it was deemed too small to be skipped. 17.390 + return false; 17.391 + } 17.392 + 17.393 + stream.reset(); 17.394 + lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions); 17.395 + line = parserState.line; 17.396 + linePosition = parserState.linePosition; 17.397 + // Doesn't really matter, but it's safe to treat it as if there were a semicolon before 17.398 + // the RBRACE. 17.399 + type = SEMICOLON; 17.400 + k = -1; 17.401 + next(); 17.402 + 17.403 + return true; 17.404 + } 17.405 + 17.406 + /** 17.407 + * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer 17.408 + * for resuming parsing after skipping a function body. 17.409 + */ 17.410 + private static class ParserState { 17.411 + private final int position; 17.412 + private final int line; 17.413 + private final int linePosition; 17.414 + 17.415 + ParserState(final int position, final int line, final int linePosition) { 17.416 + this.position = position; 17.417 + this.line = line; 17.418 + this.linePosition = linePosition; 17.419 + } 17.420 + 17.421 + Lexer createLexer(final Source source, final Lexer lexer, final TokenStream stream, final boolean scripting) { 17.422 + final Lexer newLexer = new Lexer(source, position, lexer.limit - position, stream, scripting); 17.423 + newLexer.restoreState(new Lexer.State(position, Integer.MAX_VALUE, line, -1, linePosition, SEMICOLON)); 17.424 + return newLexer; 17.425 + } 17.426 + } 17.427 + 17.428 private void printAST(final FunctionNode functionNode) { 17.429 if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) { 17.430 env.getErr().println(new ASTWriter(functionNode)); 17.431 @@ -2838,7 +3015,6 @@ 17.432 } 17.433 17.434 private void addFunctionDeclarations(final FunctionNode functionNode) { 17.435 - assert lc.peek() == lc.getFunctionBody(functionNode); 17.436 VarNode lastDecl = null; 17.437 for (int i = functionDeclarations.size() - 1; i >= 0; i--) { 17.438 Statement decl = functionDeclarations.get(i); 17.439 @@ -3200,6 +3376,9 @@ 17.440 } else { 17.441 lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL); 17.442 } 17.443 + // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip 17.444 + // parsing a nested function. functionBody() contains code to compensate for the lack of invoking 17.445 + // this method when the parser skips a nested function. 17.446 lc.setBlockNeedsScope(lc.getFunctionBody(fn)); 17.447 } 17.448 }
18.1 --- a/src/jdk/nashorn/internal/parser/TokenStream.java Wed Sep 03 13:20:05 2014 -0700 18.2 +++ b/src/jdk/nashorn/internal/parser/TokenStream.java Tue Sep 09 11:14:12 2014 -0700 18.3 @@ -209,4 +209,8 @@ 18.4 in = count; 18.5 buffer = newBuffer; 18.6 } 18.7 + 18.8 + void reset() { 18.9 + in = out = count = base = 0; 18.10 + } 18.11 }
19.1 --- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java Wed Sep 03 13:20:05 2014 -0700 19.2 +++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java Tue Sep 09 11:14:12 2014 -0700 19.3 @@ -549,6 +549,8 @@ 19.4 type == Object.class : 19.5 "invalid getter type " + type + " for " + getKey(); 19.6 19.7 + checkUndeclared(); 19.8 + 19.9 //all this does is add a return value filter for object fields only 19.10 final MethodHandle[] getterCache = GETTER_CACHE; 19.11 final MethodHandle cachedGetter = getterCache[i]; 19.12 @@ -579,6 +581,8 @@ 19.13 return getOptimisticPrimitiveGetter(type, programPoint); 19.14 } 19.15 19.16 + checkUndeclared(); 19.17 + 19.18 return debug( 19.19 createGetter( 19.20 getCurrentType(), 19.21 @@ -608,6 +612,13 @@ 19.22 return newMap; 19.23 } 19.24 19.25 + private void checkUndeclared() { 19.26 + if ((getFlags() & NEEDS_DECLARATION) != 0) { 19.27 + // a lexically defined variable that hasn't seen its declaration - throw ReferenceError 19.28 + throw ECMAErrors.referenceError("not.defined", getKey()); 19.29 + } 19.30 + } 19.31 + 19.32 // the final three arguments are for debug printout purposes only 19.33 @SuppressWarnings("unused") 19.34 private static Object replaceMap(final Object sobj, final PropertyMap newMap) { 19.35 @@ -635,13 +646,14 @@ 19.36 19.37 @Override 19.38 public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) { 19.39 - final int i = getAccessorTypeIndex(type); 19.40 - final int ci = isUndefined() ? -1 : getAccessorTypeIndex(getCurrentType()); 19.41 - final Class<?> forType = isUndefined() ? type : getCurrentType(); 19.42 + checkUndeclared(); 19.43 + 19.44 + final int typeIndex = getAccessorTypeIndex(type); 19.45 + final int currentTypeIndex = getAccessorTypeIndex(getCurrentType()); 19.46 19.47 //if we are asking for an object setter, but are still a primitive type, we might try to box it 19.48 MethodHandle mh; 19.49 - if (needsInvalidator(i, ci)) { 19.50 + if (needsInvalidator(typeIndex, currentTypeIndex)) { 19.51 final Property newProperty = getWiderProperty(type); 19.52 final PropertyMap newMap = getWiderMap(currentMap, newProperty); 19.53 19.54 @@ -652,6 +664,7 @@ 19.55 mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh); 19.56 } 19.57 } else { 19.58 + final Class<?> forType = isUndefined() ? type : getCurrentType(); 19.59 mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type); 19.60 } 19.61 19.62 @@ -692,11 +705,12 @@ 19.63 if (OBJECT_FIELDS_ONLY) { 19.64 return false; 19.65 } 19.66 - return getCurrentType() != Object.class && (isConfigurable() || isWritable()); 19.67 + // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST. 19.68 + return getCurrentType() == null || (getCurrentType() != Object.class && (isConfigurable() || isWritable())); 19.69 } 19.70 19.71 - private boolean needsInvalidator(final int ti, final int fti) { 19.72 - return canChangeType() && ti > fti; 19.73 + private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) { 19.74 + return canChangeType() && typeIndex > currentTypeIndex; 19.75 } 19.76 19.77 @Override
20.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Wed Sep 03 13:20:05 2014 -0700 20.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Tue Sep 09 11:14:12 2014 -0700 20.3 @@ -1132,7 +1132,7 @@ 20.4 if (storedScript == null) { 20.5 functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse(); 20.6 20.7 - if (errors.hasErrors()) { 20.8 + if (errMan.hasErrors()) { 20.9 return null; 20.10 } 20.11 20.12 @@ -1162,9 +1162,13 @@ 20.13 env, 20.14 installer, 20.15 source, 20.16 + errMan, 20.17 strict | functionNode.isStrict()); 20.18 20.19 final FunctionNode compiledFunction = compiler.compile(functionNode, phases); 20.20 + if (errMan.hasErrors()) { 20.21 + return null; 20.22 + } 20.23 script = compiledFunction.getRootClass(); 20.24 compiler.persistClassInfo(cacheKey, compiledFunction); 20.25 } else {
21.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java Wed Sep 03 13:20:05 2014 -0700 21.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java Tue Sep 09 11:14:12 2014 -0700 21.3 @@ -58,6 +58,18 @@ 21.4 } 21.5 21.6 /** 21.7 + * Return a copy of this FindProperty with a different property. 21.8 + * 21.9 + * @param newProperty the new property 21.10 + * @return the new FindProperty instance 21.11 + */ 21.12 + public FindProperty replaceProperty(final Property newProperty) { 21.13 + assert this.property.getKey().equals(newProperty.getKey()); 21.14 + assert this.property.getSlot() == newProperty.getSlot(); 21.15 + return new FindProperty(self, prototype, newProperty); 21.16 + } 21.17 + 21.18 + /** 21.19 * Ask for a getter that returns the given type. The type has nothing to do with the 21.20 * internal representation of the property. It may be an Object (boxing primitives) or 21.21 * a primitive (primitive fields with -Dnashorn.fields.dual=true)
22.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java Wed Sep 03 13:20:05 2014 -0700 22.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Tue Sep 09 11:14:12 2014 -0700 22.3 @@ -938,11 +938,8 @@ 22.4 * @return double 22.5 */ 22.6 public static int toInt32Optimistic(final Object obj, final int programPoint) { 22.7 - if (obj != null) { 22.8 - final Class<?> clz = obj.getClass(); 22.9 - if (clz == Integer.class) { 22.10 - return ((Integer)obj).intValue(); 22.11 - } 22.12 + if (obj != null && obj.getClass() == Integer.class) { 22.13 + return ((Integer)obj).intValue(); 22.14 } 22.15 throw new UnwarrantedOptimismException(obj, programPoint); 22.16 }
23.1 --- a/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java Wed Sep 03 13:20:05 2014 -0700 23.2 +++ b/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java Tue Sep 09 11:14:12 2014 -0700 23.3 @@ -191,19 +191,20 @@ 23.4 } 23.5 23.6 /** 23.7 - * Returns the argument value as an int. If the argument is not a Number object that can be exactly represented as 23.8 - * an int, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code 23.9 - * can use it. See {code CodeGenerator.ENSURE_INT}. 23.10 + * Returns the argument value as an int. If the argument is not a wrapper for a primitive numeric type 23.11 + * with a value that can be exactly represented as an int, throw an {@link UnwarrantedOptimismException}. 23.12 + * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_INT}. 23.13 * @param arg the original argument. 23.14 * @param programPoint the program point used in the exception 23.15 * @return the value of the argument as an int. 23.16 - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as an int. 23.17 + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with 23.18 + * a value that can be exactly represented as an int. 23.19 */ 23.20 public static int ensureInt(final Object arg, final int programPoint) { 23.21 // NOTE: this doesn't delegate to ensureInt(double, int) as in that case if arg were a Long, it would throw a 23.22 // (potentially imprecise) Double in the UnwarrantedOptimismException. This way, it will put the correct valued 23.23 // Long into the exception. 23.24 - if (arg instanceof Number) { 23.25 + if (isPrimitiveNumberWrapper(arg)) { 23.26 final double d = ((Number)arg).doubleValue(); 23.27 if (JSType.isRepresentableAsInt(d) && !JSType.isNegativeZero(d)) { 23.28 return (int)d; 23.29 @@ -212,6 +213,15 @@ 23.30 throw new UnwarrantedOptimismException(arg, programPoint); 23.31 } 23.32 23.33 + private static boolean isPrimitiveNumberWrapper(final Object obj) { 23.34 + if (obj == null) { 23.35 + return false; 23.36 + } 23.37 + final Class<?> c = obj.getClass(); 23.38 + return c == Integer.class || c == Double.class || c == Long.class || 23.39 + c == Float.class || c == Short.class || c == Byte.class; 23.40 + } 23.41 + 23.42 @SuppressWarnings("unused") 23.43 private static int ensureInt(final boolean arg, final int programPoint) { 23.44 throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT); 23.45 @@ -236,35 +246,40 @@ 23.46 } 23.47 23.48 /** 23.49 - * Returns the argument value as a long. If the argument is not a Number object that can be exactly represented as 23.50 - * a long, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code 23.51 - * can use it. See {code CodeGenerator.ENSURE_LONG}. 23.52 + * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type 23.53 + * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}. 23.54 + * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}. 23.55 * @param arg the original argument. 23.56 * @param programPoint the program point used in the exception 23.57 * @return the value of the argument as a long. 23.58 - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long. 23.59 + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with 23.60 + * a value that can be exactly represented as a long 23.61 */ 23.62 public static long ensureLong(final Object arg, final int programPoint) { 23.63 - if (arg instanceof Long) { 23.64 - // Must check for Long separately, as Long.doubleValue() isn't precise. 23.65 - return ((Long)arg).longValue(); 23.66 - } else if (arg instanceof Number) { 23.67 - return ensureLong(((Number)arg).doubleValue(), programPoint); 23.68 + if (arg != null) { 23.69 + final Class<?> c = arg.getClass(); 23.70 + if (c == Long.class) { 23.71 + // Must check for Long separately, as Long.doubleValue() isn't precise. 23.72 + return ((Long)arg).longValue(); 23.73 + } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class || 23.74 + c == Byte.class) { 23.75 + return ensureLong(((Number)arg).doubleValue(), programPoint); 23.76 + } 23.77 } 23.78 throw new UnwarrantedOptimismException(arg, programPoint); 23.79 } 23.80 23.81 /** 23.82 - * Returns the argument value as a double. If the argument is not a Number object, throw an 23.83 - * {@link UnwarrantedOptimismException}.This method is only public so that generated script code can use it. See 23.84 - * {code CodeGenerator.ENSURE_NUMBER}. 23.85 + * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type 23.86 + * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code 23.87 + * can use it. See {code CodeGenerator.ENSURE_NUMBER}. 23.88 * @param arg the original argument. 23.89 * @param programPoint the program point used in the exception 23.90 * @return the value of the argument as a double. 23.91 - * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long. 23.92 + * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type. 23.93 */ 23.94 public static double ensureNumber(final Object arg, final int programPoint) { 23.95 - if (arg instanceof Number) { // arg == null -> false 23.96 + if (isPrimitiveNumberWrapper(arg)) { 23.97 return ((Number)arg).doubleValue(); 23.98 } 23.99 throw new UnwarrantedOptimismException(arg, programPoint);
24.1 --- a/src/jdk/nashorn/internal/runtime/Property.java Wed Sep 03 13:20:05 2014 -0700 24.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java Tue Sep 09 11:14:12 2014 -0700 24.3 @@ -82,11 +82,14 @@ 24.4 * is narrower than object, e.g. Math.PI which is declared 24.5 * as a double 24.6 */ 24.7 - public static final int IS_NASGEN_PRIMITIVE = 1 << 6; 24.8 + public static final int IS_NASGEN_PRIMITIVE = 1 << 6; 24.9 24.10 /** Is this property bound to a receiver? This means get/set operations will be delegated to 24.11 * a statically defined object instead of the object passed as callsite parameter. */ 24.12 - public static final int IS_BOUND = 1 << 8; 24.13 + public static final int IS_BOUND = 1 << 7; 24.14 + 24.15 + /** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */ 24.16 + public static final int NEEDS_DECLARATION = 1 << 8; 24.17 24.18 /** Property key. */ 24.19 private final String key; 24.20 @@ -287,6 +290,15 @@ 24.21 } 24.22 24.23 /** 24.24 + * Is this a LET or CONST property that needs to see its declaration before being usable? 24.25 + * 24.26 + * @return true if this is a block-scoped variable 24.27 + */ 24.28 + public boolean needsDeclaration() { 24.29 + return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION; 24.30 + } 24.31 + 24.32 + /** 24.33 * Add more property flags to the property. Properties are immutable here, 24.34 * so any property change that results in a larger flag set results in the 24.35 * property being cloned. Use only the return value
25.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Wed Sep 03 13:20:05 2014 -0700 25.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java Tue Sep 09 11:14:12 2014 -0700 25.3 @@ -84,6 +84,12 @@ 25.4 /** Allocator map from makeMap() */ 25.5 private final PropertyMap allocatorMap; 25.6 25.7 + /** 25.8 + * Opaque object representing parser state at the end of the function. Used when reparsing outer function 25.9 + * to help with skipping parsing inner functions. 25.10 + */ 25.11 + private final Object endParserState; 25.12 + 25.13 /** Code installer used for all further recompilation/specialization of this ScriptFunction */ 25.14 private transient CodeInstaller<ScriptEnvironment> installer; 25.15 25.16 @@ -98,9 +104,8 @@ 25.17 /** Id to parent function if one exists */ 25.18 private RecompilableScriptFunctionData parent; 25.19 25.20 - private final boolean isDeclared; 25.21 - private final boolean isAnonymous; 25.22 - private final boolean needsCallee; 25.23 + /** Copy of the {@link FunctionNode} flags. */ 25.24 + private final int functionFlags; 25.25 25.26 private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup(); 25.27 25.28 @@ -136,15 +141,14 @@ 25.29 25.30 super(functionName(functionNode), 25.31 Math.min(functionNode.getParameters().size(), MAX_ARITY), 25.32 - getFlags(functionNode)); 25.33 + getDataFlags(functionNode)); 25.34 25.35 this.functionName = functionNode.getName(); 25.36 this.lineNumber = functionNode.getLineNumber(); 25.37 - this.isDeclared = functionNode.isDeclared(); 25.38 - this.needsCallee = functionNode.needsCallee(); 25.39 - this.isAnonymous = functionNode.isAnonymous(); 25.40 + this.functionFlags = functionNode.getFlags() | (functionNode.needsCallee() ? FunctionNode.NEEDS_CALLEE : 0); 25.41 this.functionNodeId = functionNode.getId(); 25.42 this.source = functionNode.getSource(); 25.43 + this.endParserState = functionNode.getEndParserState(); 25.44 this.token = tokenFor(functionNode); 25.45 this.installer = installer; 25.46 this.allocatorClassName = allocatorClassName; 25.47 @@ -202,6 +206,24 @@ 25.48 } 25.49 25.50 /** 25.51 + * Returns the names of all external symbols this function uses. 25.52 + * @return the names of all external symbols this function uses. 25.53 + */ 25.54 + public Set<String> getExternalSymbolNames() { 25.55 + return externalScopeDepths == null ? Collections.<String>emptySet() : 25.56 + Collections.unmodifiableSet(externalScopeDepths.keySet()); 25.57 + } 25.58 + 25.59 + /** 25.60 + * Returns the opaque object representing the parser state at the end of this function's body, used to 25.61 + * skip parsing this function when reparsing its containing outer function. 25.62 + * @return the object representing the end parser state 25.63 + */ 25.64 + public Object getEndParserState() { 25.65 + return endParserState; 25.66 + } 25.67 + 25.68 + /** 25.69 * Get the parent of this RecompilableScriptFunctionData. If we are 25.70 * a nested function, we have a parent. Note that "null" return value 25.71 * can also mean that we have a parent but it is unknown, so this can 25.72 @@ -269,7 +291,7 @@ 25.73 25.74 @Override 25.75 public boolean inDynamicContext() { 25.76 - return (flags & IN_DYNAMIC_CONTEXT) != 0; 25.77 + return getFunctionFlag(FunctionNode.IN_DYNAMIC_CONTEXT); 25.78 } 25.79 25.80 private static String functionName(final FunctionNode fn) { 25.81 @@ -293,7 +315,7 @@ 25.82 return Token.toDesc(TokenType.FUNCTION, position, length); 25.83 } 25.84 25.85 - private static int getFlags(final FunctionNode functionNode) { 25.86 + private static int getDataFlags(final FunctionNode functionNode) { 25.87 int flags = IS_CONSTRUCTOR; 25.88 if (functionNode.isStrict()) { 25.89 flags |= IS_STRICT; 25.90 @@ -307,9 +329,6 @@ 25.91 if (functionNode.isVarArg()) { 25.92 flags |= IS_VARIABLE_ARITY; 25.93 } 25.94 - if (functionNode.inDynamicContext()) { 25.95 - flags |= IN_DYNAMIC_CONTEXT; 25.96 - } 25.97 return flags; 25.98 } 25.99 25.100 @@ -337,7 +356,6 @@ 25.101 } 25.102 25.103 FunctionNode reparse() { 25.104 - final boolean isProgram = functionNodeId == FunctionNode.FIRST_FUNCTION_ID; 25.105 // NOTE: If we aren't recompiling the top-level program, we decrease functionNodeId 'cause we'll have a synthetic program node 25.106 final int descPosition = Token.descPosition(token); 25.107 final Context context = Context.getContextTrusted(); 25.108 @@ -346,18 +364,27 @@ 25.109 source, 25.110 new Context.ThrowErrorManager(), 25.111 isStrict(), 25.112 - functionNodeId - (isProgram ? 0 : 1), 25.113 lineNumber - 1, 25.114 context.getLogger(Parser.class)); // source starts at line 0, so even though lineNumber is the correct declaration line, back off one to make it exclusive 25.115 25.116 - if (isAnonymous) { 25.117 + if (getFunctionFlag(FunctionNode.IS_ANONYMOUS)) { 25.118 parser.setFunctionName(functionName); 25.119 } 25.120 + parser.setReparsedFunction(this); 25.121 25.122 - final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition, Token.descLength(token), true); 25.123 - // Parser generates a program AST even if we're recompiling a single function, so when we are only recompiling a 25.124 - // single function, extract it from the program. 25.125 - return (isProgram ? program : extractFunctionFromScript(program)).setName(null, functionName); 25.126 + final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition, 25.127 + Token.descLength(token), true); 25.128 + // Parser generates a program AST even if we're recompiling a single function, so when we are only 25.129 + // recompiling a single function, extract it from the program. 25.130 + return (isProgram() ? program : extractFunctionFromScript(program)).setName(null, functionName); 25.131 + } 25.132 + 25.133 + private boolean getFunctionFlag(final int flag) { 25.134 + return (functionFlags & flag) != 0; 25.135 + } 25.136 + 25.137 + private boolean isProgram() { 25.138 + return getFunctionFlag(FunctionNode.IS_PROGRAM); 25.139 } 25.140 25.141 TypeMap typeMap(final MethodType fnCallSiteType) { 25.142 @@ -394,6 +421,7 @@ 25.143 context.getEnv(), 25.144 installer, 25.145 functionNode.getSource(), // source 25.146 + context.getErrorManager(), 25.147 isStrict() | functionNode.isStrict(), // is strict 25.148 true, // is on demand 25.149 this, // compiledFunction, i.e. this RecompilableScriptFunctionData 25.150 @@ -545,7 +573,7 @@ 25.151 assert fns.size() == 1 : "got back more than one method in recompilation"; 25.152 final FunctionNode f = fns.iterator().next(); 25.153 assert f.getId() == functionNodeId; 25.154 - if (!isDeclared && f.isDeclared()) { 25.155 + if (!getFunctionFlag(FunctionNode.IS_DECLARED) && f.isDeclared()) { 25.156 return f.clearFlag(null, FunctionNode.IS_DECLARED); 25.157 } 25.158 return f; 25.159 @@ -668,7 +696,15 @@ 25.160 25.161 @Override 25.162 public boolean needsCallee() { 25.163 - return needsCallee; 25.164 + return getFunctionFlag(FunctionNode.NEEDS_CALLEE); 25.165 + } 25.166 + 25.167 + /** 25.168 + * Returns the {@link FunctionNode} flags associated with this function data. 25.169 + * @return the {@link FunctionNode} flags associated with this function data. 25.170 + */ 25.171 + public int getFunctionFlags() { 25.172 + return functionFlags; 25.173 } 25.174 25.175 @Override
26.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Wed Sep 03 13:20:05 2014 -0700 26.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java Tue Sep 09 11:14:12 2014 -0700 26.3 @@ -94,6 +94,9 @@ 26.4 /** Use single Global instance per jsr223 engine instance. */ 26.5 public final boolean _global_per_engine; 26.6 26.7 + /** Enable experimental ECMAScript 6 features. */ 26.8 + public final boolean _es6; 26.9 + 26.10 /** Argument passed to compile only if optimistic compilation should take place */ 26.11 public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic"; 26.12 26.13 @@ -258,6 +261,15 @@ 26.14 _version = options.getBoolean("version"); 26.15 _verify_code = options.getBoolean("verify.code"); 26.16 26.17 + final String language = options.getString("language"); 26.18 + if (language == null || language.equals("es5")) { 26.19 + _es6 = false; 26.20 + } else if (language.equals("es6")) { 26.21 + _es6 = true; 26.22 + } else { 26.23 + throw new RuntimeException("Unsupported language: " + language); 26.24 + } 26.25 + 26.26 String dir = null; 26.27 String func = null; 26.28 final String pc = options.getString("print.code");
27.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Wed Sep 03 13:20:05 2014 -0700 27.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Tue Sep 09 11:14:12 2014 -0700 27.3 @@ -90,8 +90,6 @@ 27.4 public static final int USES_THIS = 1 << 4; 27.5 /** Is this a variable arity function? */ 27.6 public static final int IS_VARIABLE_ARITY = 1 << 5; 27.7 - /** Is this declared in a dynamic context */ 27.8 - public static final int IN_DYNAMIC_CONTEXT = 1 << 6; 27.9 27.10 /** Flag for strict or built-in functions */ 27.11 public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
28.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Sep 03 13:20:05 2014 -0700 28.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Sep 09 11:14:12 2014 -0700 28.3 @@ -158,6 +158,7 @@ 28.4 28.5 static final MethodHandle MEGAMORPHIC_GET = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class); 28.6 static final MethodHandle GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class); 28.7 + static final MethodHandle DECLARE_AND_SET = findOwnMH_V("declareAndSet", void.class, String.class, Object.class); 28.8 28.9 private static final MethodHandle TRUNCATINGFILTER = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class); 28.10 private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class); 28.11 @@ -2027,6 +2028,22 @@ 28.12 return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT); 28.13 } 28.14 28.15 + // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST 28.16 + @SuppressWarnings("unused") 28.17 + private void declareAndSet(final String key, final Object value) { 28.18 + final PropertyMap map = getMap(); 28.19 + final FindProperty find = findProperty(key, false); 28.20 + assert find != null; 28.21 + 28.22 + final Property property = find.getProperty(); 28.23 + assert property != null; 28.24 + assert property.needsDeclaration(); 28.25 + 28.26 + final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION)); 28.27 + setMap(newMap); 28.28 + set(key, value, true); 28.29 + } 28.30 + 28.31 /** 28.32 * Find the appropriate GETINDEX method for an invoke dynamic call. 28.33 * 28.34 @@ -2140,7 +2157,7 @@ 28.35 } 28.36 28.37 if (find != null) { 28.38 - if (!find.getProperty().isWritable()) { 28.39 + if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) { 28.40 // Existing, non-writable property 28.41 return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true); 28.42 }
29.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Wed Sep 03 13:20:05 2014 -0700 29.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Tue Sep 09 11:14:12 2014 -0700 29.3 @@ -108,6 +108,11 @@ 29.4 public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class); 29.5 29.6 /** 29.7 + * Throws a reference error for an undefined variable. 29.8 + */ 29.9 + public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class); 29.10 + 29.11 + /** 29.12 * Converts a switch tag value to a simple integer. deflt value if it can't. 29.13 * 29.14 * @param tag Switch statement tag value. 29.15 @@ -382,6 +387,15 @@ 29.16 } 29.17 29.18 /** 29.19 + * Throws a reference error for an undefined variable. 29.20 + * 29.21 + * @param name the variable name 29.22 + */ 29.23 + public static void throwReferenceError(final String name) { 29.24 + throw referenceError("not.defined", name); 29.25 + } 29.26 + 29.27 + /** 29.28 * Call a script function as a constructor with given args. 29.29 * 29.30 * @param target ScriptFunction object.
30.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Wed Sep 03 13:20:05 2014 -0700 30.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Tue Sep 09 11:14:12 2014 -0700 30.3 @@ -140,7 +140,29 @@ 30.4 30.5 private SetMethod createExistingPropertySetter() { 30.6 final Property property = find.getProperty(); 30.7 - final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc)); 30.8 + final MethodHandle methodHandle; 30.9 + 30.10 + if (NashornCallSiteDescriptor.isDeclaration(desc)) { 30.11 + assert property.needsDeclaration(); 30.12 + // This is a LET or CONST being declared. The property is already there but flagged as needing declaration. 30.13 + // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set 30.14 + // method if the pre-callsite map is stable (which should be the case for function scopes except for 30.15 + // non-strict functions containing eval() with var). Otherwise we have to use a slow setter that creates 30.16 + // a new PropertyMap on the fly. 30.17 + final PropertyMap oldMap = getMap(); 30.18 + final Property newProperty = property.removeFlags(Property.NEEDS_DECLARATION); 30.19 + final PropertyMap newMap = oldMap.replaceProperty(property, newProperty); 30.20 + final MethodHandle fastSetter = find.replaceProperty(newProperty).getSetter(type, NashornCallSiteDescriptor.isStrict(desc)); 30.21 + final MethodHandle slowSetter = MH.insertArguments(ScriptObject.DECLARE_AND_SET, 1, getName()).asType(fastSetter.type()); 30.22 + 30.23 + // cas map used as guard, if true that means we can do the set fast 30.24 + MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap); 30.25 + casMap = MH.dropArguments(casMap, 1, type); 30.26 + casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class)); 30.27 + methodHandle = MH.guardWithTest(casMap, fastSetter, slowSetter); 30.28 + } else { 30.29 + methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc)); 30.30 + } 30.31 30.32 assert methodHandle != null; 30.33 assert property != null;
31.1 --- a/src/jdk/nashorn/internal/runtime/Timing.java Wed Sep 03 13:20:05 2014 -0700 31.2 +++ b/src/jdk/nashorn/internal/runtime/Timing.java Tue Sep 09 11:14:12 2014 -0700 31.3 @@ -189,7 +189,7 @@ 31.4 maxKeyLength++; 31.5 31.6 final StringBuilder sb = new StringBuilder(); 31.7 - sb.append("Accumulated complation phase Timings:\n\n"); 31.8 + sb.append("Accumulated compilation phase timings:\n\n"); 31.9 for (final Map.Entry<String, Long> entry : timings.entrySet()) { 31.10 int len; 31.11
32.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Wed Sep 03 13:20:05 2014 -0700 32.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java Tue Sep 09 11:14:12 2014 -0700 32.3 @@ -628,18 +628,20 @@ 32.4 Class<?> widest = Integer.class; 32.5 32.6 for (final Object item : items) { 32.7 - final Class<?> itemClass = item == null ? null : item.getClass(); 32.8 + if (item == null) { 32.9 + return Object.class; 32.10 + } 32.11 + final Class<?> itemClass = item.getClass(); 32.12 if (itemClass == Long.class) { 32.13 if (widest == Integer.class) { 32.14 widest = Long.class; 32.15 } 32.16 - } else if (itemClass == Double.class) { 32.17 + } else if (itemClass == Double.class || itemClass == Float.class) { 32.18 if (widest == Integer.class || widest == Long.class) { 32.19 widest = Double.class; 32.20 } 32.21 - } else if (!(item instanceof Number)) { 32.22 - widest = Object.class; 32.23 - break; 32.24 + } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) { 32.25 + return Object.class; 32.26 } 32.27 } 32.28
33.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Wed Sep 03 13:20:05 2014 -0700 33.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Tue Sep 09 11:14:12 2014 -0700 33.3 @@ -54,23 +54,25 @@ 33.4 public static final int CALLSITE_OPTIMISTIC = 1 << 3; 33.5 /** Is this really an apply that we try to call as a call? */ 33.6 public static final int CALLSITE_APPLY_TO_CALL = 1 << 4; 33.7 + /** Does this a callsite for a variable declaration? */ 33.8 + public static final int CALLSITE_DECLARE = 1 << 5; 33.9 33.10 /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit 33.11 * code where call sites have this flag set. */ 33.12 - public static final int CALLSITE_PROFILE = 1 << 5; 33.13 + public static final int CALLSITE_PROFILE = 1 << 6; 33.14 /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where 33.15 * call sites have this flag set. */ 33.16 - public static final int CALLSITE_TRACE = 1 << 6; 33.17 + public static final int CALLSITE_TRACE = 1 << 7; 33.18 /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword 33.19 * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */ 33.20 - public static final int CALLSITE_TRACE_MISSES = 1 << 7; 33.21 + public static final int CALLSITE_TRACE_MISSES = 1 << 8; 33.22 /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword 33.23 * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */ 33.24 - public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 8; 33.25 + public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 9; 33.26 /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts 33.27 * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites 33.28 * have this flag set. */ 33.29 - public static final int CALLSITE_TRACE_VALUES = 1 << 9; 33.30 + public static final int CALLSITE_TRACE_VALUES = 1 << 10; 33.31 33.32 //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious 33.33 //right now given the program points 33.34 @@ -82,10 +84,10 @@ 33.35 * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its 33.36 * trace/profile settings. 33.37 */ 33.38 - public static final int CALLSITE_PROGRAM_POINT_SHIFT = 10; 33.39 + public static final int CALLSITE_PROGRAM_POINT_SHIFT = 11; 33.40 33.41 /** 33.42 - * Maximum program point value. 22 bits should be enough for anyone 33.43 + * Maximum program point value. 21 bits should be enough for anyone 33.44 */ 33.45 public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1; 33.46 33.47 @@ -123,6 +125,9 @@ 33.48 assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope"; 33.49 sb.append("scope "); 33.50 } 33.51 + if ((flags & CALLSITE_DECLARE) != 0) { 33.52 + sb.append("declare "); 33.53 + } 33.54 } 33.55 if ((flags & CALLSITE_APPLY_TO_CALL) != 0) { 33.56 sb.append("apply2call "); 33.57 @@ -329,6 +334,15 @@ 33.58 } 33.59 33.60 /** 33.61 + * Does this callsite contain a declaration for its target? 33.62 + * @param desc descriptor 33.63 + * @return true if contains declaration 33.64 + */ 33.65 + public static boolean isDeclaration(final CallSiteDescriptor desc) { 33.66 + return isFlag(desc, CALLSITE_DECLARE); 33.67 + } 33.68 + 33.69 + /** 33.70 * Get a program point from a descriptor (must be optimistic) 33.71 * @param desc descriptor 33.72 * @return program point
34.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Sep 03 13:20:05 2014 -0700 34.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Tue Sep 09 11:14:12 2014 -0700 34.3 @@ -58,6 +58,7 @@ 34.4 parser.error.regex.repeated.flag=Repeated RegExp flag: {0} 34.5 parser.error.regex.syntax={0} 34.6 parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON 34.7 +parser.error.missing.const.assignment=Missing assignment to constant "{0}" 34.8 34.9 # strict mode error messages 34.10 parser.error.strict.no.with="with" statement cannot be used in strict mode 34.11 @@ -162,6 +163,8 @@ 34.12 34.13 syntax.error.invalid.json=Invalid JSON: {0} 34.14 syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode 34.15 +syntax.error.redeclare.variable=Variable "{0}" has already been declared 34.16 +syntax.error.assign.constant=Assignment to constant "{0}" 34.17 34.18 io.error.cant.write=cannot write "{0}" 34.19 config.error.no.dest=no destination directory supplied
35.1 --- a/src/jdk/nashorn/internal/runtime/resources/Options.properties Wed Sep 03 13:20:05 2014 -0700 35.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties Tue Sep 09 11:14:12 2014 -0700 35.3 @@ -329,6 +329,14 @@ 35.4 desc="Enable scripting features." \ 35.5 } 35.6 35.7 +nashorn.option.language = { \ 35.8 + name="--language", \ 35.9 + type=String, \ 35.10 + params=[es5|es6], \ 35.11 + default=es5, \ 35.12 + desc="Specify ECMAScript language version." \ 35.13 +} 35.14 + 35.15 nashorn.option.stdout = { \ 35.16 name="--stdout", \ 35.17 is_undocumented=true, \
36.1 --- a/src/jdk/nashorn/tools/Shell.java Wed Sep 03 13:20:05 2014 -0700 36.2 +++ b/src/jdk/nashorn/tools/Shell.java Tue Sep 09 11:14:12 2014 -0700 36.3 @@ -246,12 +246,21 @@ 36.4 36.5 // For each file on the command line. 36.6 for (final String fileName : files) { 36.7 - final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors, env._strict, FunctionNode.FIRST_FUNCTION_ID, 0, context.getLogger(Parser.class)).parse(); 36.8 + final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors, env._strict, 0, context.getLogger(Parser.class)).parse(); 36.9 36.10 if (errors.getNumberOfErrors() != 0) { 36.11 return COMPILATION_ERROR; 36.12 } 36.13 36.14 + new Compiler( 36.15 + context, 36.16 + env, 36.17 + null, //null - pass no code installer - this is compile only 36.18 + functionNode.getSource(), 36.19 + context.getErrorManager(), 36.20 + env._strict | functionNode.isStrict()). 36.21 + compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL); 36.22 + 36.23 if (env._print_ast) { 36.24 context.getErr().println(new ASTWriter(functionNode)); 36.25 } 36.26 @@ -260,14 +269,9 @@ 36.27 context.getErr().println(new PrintVisitor(functionNode)); 36.28 } 36.29 36.30 - //null - pass no code installer - this is compile only 36.31 - new Compiler( 36.32 - context, 36.33 - env, 36.34 - null, 36.35 - functionNode.getSource(), 36.36 - env._strict | functionNode.isStrict()). 36.37 - compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL); 36.38 + if (errors.getNumberOfErrors() != 0) { 36.39 + return COMPILATION_ERROR; 36.40 + } 36.41 } 36.42 } finally { 36.43 env.getOut().flush();
37.1 --- a/test/script/basic/JDK-8048079_1.js Wed Sep 03 13:20:05 2014 -0700 37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 37.3 @@ -1,35 +0,0 @@ 37.4 -/* 37.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 37.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.7 - * 37.8 - * This code is free software; you can redistribute it and/or modify it 37.9 - * under the terms of the GNU General Public License version 2 only, as 37.10 - * published by the Free Software Foundation. 37.11 - * 37.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 37.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 37.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 37.15 - * version 2 for more details (a copy is included in the LICENSE file that 37.16 - * accompanied this code). 37.17 - * 37.18 - * You should have received a copy of the GNU General Public License version 37.19 - * 2 along with this work; if not, write to the Free Software Foundation, 37.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 37.21 - * 37.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 37.23 - * or visit www.oracle.com if you need additional information or have any 37.24 - * questions. 37.25 - */ 37.26 - 37.27 -/** 37.28 - * JDK-8048079: Persistent code store is broken after optimistic types merge 37.29 - * 37.30 - * @test 37.31 - * @run 37.32 - * @option -pcc 37.33 - * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 37.34 - * @fork 37.35 - */ 37.36 - 37.37 -load(__DIR__ + 'prototype.js'); 37.38 -load(__DIR__ + 'yui.js');
38.1 --- a/test/script/basic/JDK-8048079_1.js.EXPECTED Wed Sep 03 13:20:05 2014 -0700 38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 38.3 @@ -1,3 +0,0 @@ 38.4 -parsed and compiled ok prototype.js 38.5 -parsed and compiled ok yui-min.js 38.6 -parsed and compiled ok yui.js
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/test/script/basic/JDK-8048079_1a.js Tue Sep 09 11:14:12 2014 -0700 39.3 @@ -0,0 +1,34 @@ 39.4 +/* 39.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 39.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.7 + * 39.8 + * This code is free software; you can redistribute it and/or modify it 39.9 + * under the terms of the GNU General Public License version 2 only, as 39.10 + * published by the Free Software Foundation. 39.11 + * 39.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 39.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 39.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 39.15 + * version 2 for more details (a copy is included in the LICENSE file that 39.16 + * accompanied this code). 39.17 + * 39.18 + * You should have received a copy of the GNU General Public License version 39.19 + * 2 along with this work; if not, write to the Free Software Foundation, 39.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 39.21 + * 39.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 39.23 + * or visit www.oracle.com if you need additional information or have any 39.24 + * questions. 39.25 + */ 39.26 + 39.27 +/** 39.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge 39.29 + * 39.30 + * @test 39.31 + * @runif external.prototype 39.32 + * @option -pcc 39.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 39.34 + * @fork 39.35 + */ 39.36 + 39.37 +load(__DIR__ + 'prototype.js');
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/test/script/basic/JDK-8048079_1a.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 40.3 @@ -0,0 +1,1 @@ 40.4 +parsed and compiled ok prototype.js
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/script/basic/JDK-8048079_1b.js Tue Sep 09 11:14:12 2014 -0700 41.3 @@ -0,0 +1,34 @@ 41.4 +/* 41.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 41.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.7 + * 41.8 + * This code is free software; you can redistribute it and/or modify it 41.9 + * under the terms of the GNU General Public License version 2 only, as 41.10 + * published by the Free Software Foundation. 41.11 + * 41.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 41.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 41.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 41.15 + * version 2 for more details (a copy is included in the LICENSE file that 41.16 + * accompanied this code). 41.17 + * 41.18 + * You should have received a copy of the GNU General Public License version 41.19 + * 2 along with this work; if not, write to the Free Software Foundation, 41.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 41.21 + * 41.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 41.23 + * or visit www.oracle.com if you need additional information or have any 41.24 + * questions. 41.25 + */ 41.26 + 41.27 +/** 41.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge 41.29 + * 41.30 + * @test 41.31 + * @runif external.yui 41.32 + * @option -pcc 41.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 41.34 + * @fork 41.35 + */ 41.36 + 41.37 +load(__DIR__ + 'yui.js');
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/script/basic/JDK-8048079_1b.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 42.3 @@ -0,0 +1,2 @@ 42.4 +parsed and compiled ok yui-min.js 42.5 +parsed and compiled ok yui.js
43.1 --- a/test/script/basic/JDK-8048079_2.js Wed Sep 03 13:20:05 2014 -0700 43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 43.3 @@ -1,35 +0,0 @@ 43.4 -/* 43.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 43.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.7 - * 43.8 - * This code is free software; you can redistribute it and/or modify it 43.9 - * under the terms of the GNU General Public License version 2 only, as 43.10 - * published by the Free Software Foundation. 43.11 - * 43.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 43.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 43.15 - * version 2 for more details (a copy is included in the LICENSE file that 43.16 - * accompanied this code). 43.17 - * 43.18 - * You should have received a copy of the GNU General Public License version 43.19 - * 2 along with this work; if not, write to the Free Software Foundation, 43.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 43.21 - * 43.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 43.23 - * or visit www.oracle.com if you need additional information or have any 43.24 - * questions. 43.25 - */ 43.26 - 43.27 -/** 43.28 - * JDK-8048079: Persistent code store is broken after optimistic types merge 43.29 - * 43.30 - * @test 43.31 - * @run 43.32 - * @option -pcc 43.33 - * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 43.34 - * @fork 43.35 - */ 43.36 - 43.37 -load(__DIR__ + 'prototype.js'); 43.38 -load(__DIR__ + 'yui.js');
44.1 --- a/test/script/basic/JDK-8048079_2.js.EXPECTED Wed Sep 03 13:20:05 2014 -0700 44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 44.3 @@ -1,3 +0,0 @@ 44.4 -parsed and compiled ok prototype.js 44.5 -parsed and compiled ok yui-min.js 44.6 -parsed and compiled ok yui.js
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/test/script/basic/JDK-8048079_2a.js Tue Sep 09 11:14:12 2014 -0700 45.3 @@ -0,0 +1,34 @@ 45.4 +/* 45.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 45.7 + * 45.8 + * This code is free software; you can redistribute it and/or modify it 45.9 + * under the terms of the GNU General Public License version 2 only, as 45.10 + * published by the Free Software Foundation. 45.11 + * 45.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 45.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 45.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 45.15 + * version 2 for more details (a copy is included in the LICENSE file that 45.16 + * accompanied this code). 45.17 + * 45.18 + * You should have received a copy of the GNU General Public License version 45.19 + * 2 along with this work; if not, write to the Free Software Foundation, 45.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 45.21 + * 45.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 45.23 + * or visit www.oracle.com if you need additional information or have any 45.24 + * questions. 45.25 + */ 45.26 + 45.27 +/** 45.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge. 45.29 + * Same script as JDK-8048079_1a.js to exercise code cache. 45.30 + * @test 45.31 + * @runif external.prototype 45.32 + * @option -pcc 45.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 45.34 + * @fork 45.35 + */ 45.36 + 45.37 +load(__DIR__ + 'prototype.js');
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/test/script/basic/JDK-8048079_2a.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 46.3 @@ -0,0 +1,1 @@ 46.4 +parsed and compiled ok prototype.js
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/test/script/basic/JDK-8048079_2b.js Tue Sep 09 11:14:12 2014 -0700 47.3 @@ -0,0 +1,34 @@ 47.4 +/* 47.5 + * Copyright (c) 2010, 2014, 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 + * JDK-8048079: Persistent code store is broken after optimistic types merge 47.29 + * Same script as JDK-8048079_1b.js to exercise code cache again. 47.30 + * @test 47.31 + * @runif external.yui 47.32 + * @option -pcc 47.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache 47.34 + * @fork 47.35 + */ 47.36 + 47.37 +load(__DIR__ + 'yui.js');
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/test/script/basic/JDK-8048079_2b.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 48.3 @@ -0,0 +1,2 @@ 48.4 +parsed and compiled ok yui-min.js 48.5 +parsed and compiled ok yui.js
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/test/script/basic/JDK-8056129.js Tue Sep 09 11:14:12 2014 -0700 49.3 @@ -0,0 +1,42 @@ 49.4 +/* 49.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 49.7 + * 49.8 + * This code is free software; you can redistribute it and/or modify it 49.9 + * under the terms of the GNU General Public License version 2 only, as 49.10 + * published by the Free Software Foundation. 49.11 + * 49.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 49.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 49.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 49.15 + * version 2 for more details (a copy is included in the LICENSE file that 49.16 + * accompanied this code). 49.17 + * 49.18 + * You should have received a copy of the GNU General Public License version 49.19 + * 2 along with this work; if not, write to the Free Software Foundation, 49.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 49.21 + * 49.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 49.23 + * or visit www.oracle.com if you need additional information or have any 49.24 + * questions. 49.25 + */ 49.26 + 49.27 +/** 49.28 + * JDK-8056129: AtomicInteger is treated as primitive number with optimistic compilation 49.29 + * 49.30 + * @test 49.31 + * @run 49.32 + */ 49.33 + 49.34 +var AtomicInteger = java.util.concurrent.atomic.AtomicInteger; 49.35 + 49.36 +function getAtomic() { 49.37 + return new AtomicInteger() 49.38 +} 49.39 +var x = getAtomic() 49.40 +print(x instanceof AtomicInteger) 49.41 + 49.42 +var a = [] 49.43 +a.push(x) 49.44 +var y = a[0] 49.45 +print(y instanceof AtomicInteger)
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/test/script/basic/JDK-8056129.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 50.3 @@ -0,0 +1,2 @@ 50.4 +true 50.5 +true
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/test/script/basic/es6/block-function-decl.js Tue Sep 09 11:14:12 2014 -0700 51.3 @@ -0,0 +1,51 @@ 51.4 +/* 51.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 51.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 51.7 + * 51.8 + * This code is free software; you can redistribute it and/or modify it 51.9 + * under the terms of the GNU General Public License version 2 only, as 51.10 + * published by the Free Software Foundation. 51.11 + * 51.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 51.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 51.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 51.15 + * version 2 for more details (a copy is included in the LICENSE file that 51.16 + * accompanied this code). 51.17 + * 51.18 + * You should have received a copy of the GNU General Public License version 51.19 + * 2 along with this work; if not, write to the Free Software Foundation, 51.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 51.21 + * 51.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 51.23 + * or visit www.oracle.com if you need additional information or have any 51.24 + * questions. 51.25 + */ 51.26 + 51.27 +/** 51.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 51.29 + * 51.30 + * @test 51.31 + * @run 51.32 + * @option --language=es6 51.33 + */ 51.34 + 51.35 +"use strict"; 51.36 + 51.37 +{ 51.38 + // f is defined on block level 51.39 + print(f); 51.40 + f(); 51.41 + function f() { 51.42 + print("in f"); 51.43 + } 51.44 + print(f); 51.45 + f(); 51.46 +} 51.47 + 51.48 +try { 51.49 + print(typeof f); 51.50 + f(); 51.51 +} catch (e) { 51.52 + print(e); 51.53 +} 51.54 +
52.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 52.2 +++ b/test/script/basic/es6/block-function-decl.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 52.3 @@ -0,0 +1,10 @@ 52.4 +function f() { 52.5 + print("in f"); 52.6 + } 52.7 +in f 52.8 +function f() { 52.9 + print("in f"); 52.10 + } 52.11 +in f 52.12 +undefined 52.13 +ReferenceError: "f" is not defined
53.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 53.2 +++ b/test/script/basic/es6/const-empty.js Tue Sep 09 11:14:12 2014 -0700 53.3 @@ -0,0 +1,37 @@ 53.4 +/* 53.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 53.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 53.7 + * 53.8 + * This code is free software; you can redistribute it and/or modify it 53.9 + * under the terms of the GNU General Public License version 2 only, as 53.10 + * published by the Free Software Foundation. 53.11 + * 53.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 53.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 53.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 53.15 + * version 2 for more details (a copy is included in the LICENSE file that 53.16 + * accompanied this code). 53.17 + * 53.18 + * You should have received a copy of the GNU General Public License version 53.19 + * 2 along with this work; if not, write to the Free Software Foundation, 53.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 53.21 + * 53.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 53.23 + * or visit www.oracle.com if you need additional information or have any 53.24 + * questions. 53.25 + */ 53.26 + 53.27 +/** 53.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 53.29 + * 53.30 + * @test 53.31 + * @run 53.32 + * @option --language=es6 53.33 + */ 53.34 + 53.35 +try { 53.36 + eval('"use strict";\n' + 53.37 + 'const x;\n'); 53.38 +} catch (e) { 53.39 + print(e); 53.40 +}
54.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 54.2 +++ b/test/script/basic/es6/const-empty.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 54.3 @@ -0,0 +1,3 @@ 54.4 +SyntaxError: test/script/basic/es6/const-empty.js#33:4<eval>@1:2:7 Missing assignment to constant "x" 54.5 +const x; 54.6 + ^
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/test/script/basic/es6/const-reassign.js Tue Sep 09 11:14:12 2014 -0700 55.3 @@ -0,0 +1,174 @@ 55.4 +/* 55.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 55.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 55.7 + * 55.8 + * This code is free software; you can redistribute it and/or modify it 55.9 + * under the terms of the GNU General Public License version 2 only, as 55.10 + * published by the Free Software Foundation. 55.11 + * 55.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 55.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 55.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 55.15 + * version 2 for more details (a copy is included in the LICENSE file that 55.16 + * accompanied this code). 55.17 + * 55.18 + * You should have received a copy of the GNU General Public License version 55.19 + * 2 along with this work; if not, write to the Free Software Foundation, 55.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 55.21 + * 55.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 55.23 + * or visit www.oracle.com if you need additional information or have any 55.24 + * questions. 55.25 + */ 55.26 + 55.27 +/** 55.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 55.29 + * 55.30 + * @test 55.31 + * @run 55.32 + * @option --language=es6 */ 55.33 + 55.34 +"use strict"; 55.35 + 55.36 +try { 55.37 + eval('"use strict";\n' + 55.38 + 'const x = 2;\n' + 55.39 + 'x = 1;\n'); 55.40 +} catch (e) { 55.41 + print(e.name); 55.42 +} 55.43 + 55.44 +try { 55.45 + eval('"use strict";\n' + 55.46 + 'const x = 2;\n' + 55.47 + 'x++;\n'); 55.48 + fail("const assignment didn't throw"); 55.49 +} catch (e) { 55.50 + print(e.name); 55.51 +} 55.52 + 55.53 +try { 55.54 + eval('"use strict";\n' + 55.55 + 'const x = 2;\n' + 55.56 + 'x--;\n'); 55.57 + fail("const assignment didn't throw"); 55.58 +} catch (e) { 55.59 + print(e.name); 55.60 +} 55.61 + 55.62 +try { 55.63 + eval('"use strict";\n' + 55.64 + 'const x = 2;\n' + 55.65 + '++x;\n'); 55.66 + fail("const assignment didn't throw"); 55.67 +} catch (e) { 55.68 + print(e.name); 55.69 +} 55.70 + 55.71 +try { 55.72 + eval('"use strict";\n' + 55.73 + 'const x = 2;\n' + 55.74 + '--x;\n'); 55.75 + fail("const assignment didn't throw"); 55.76 +} catch (e) { 55.77 + print(e.name); 55.78 +} 55.79 + 55.80 +try { 55.81 + eval('"use strict";\n' + 55.82 + 'const x = 2;\n' + 55.83 + 'x += 1;\n'); 55.84 + fail("const assignment didn't throw"); 55.85 +} catch (e) { 55.86 + print(e.name); 55.87 +} 55.88 + 55.89 +try { 55.90 + eval('"use strict";\n' + 55.91 + 'const x = 2;\n' + 55.92 + 'x *= 1;\n'); 55.93 + fail("const assignment didn't throw"); 55.94 +} catch (e) { 55.95 + print(e.name); 55.96 +} 55.97 + 55.98 +try { 55.99 + eval('"use strict";\n' + 55.100 + 'const x = 2;\n' + 55.101 + 'x /= 1;\n'); 55.102 + fail("const assignment didn't throw"); 55.103 +} catch (e) { 55.104 + print(e.name); 55.105 +} 55.106 + 55.107 +try { 55.108 + eval('"use strict";\n' + 55.109 + 'const x = 2;\n' + 55.110 + 'x %= 1;\n'); 55.111 + fail("const assignment didn't throw"); 55.112 +} catch (e) { 55.113 + print(e.name); 55.114 +} 55.115 + 55.116 +try { 55.117 + eval('"use strict";\n' + 55.118 + 'const x = 2;\n' + 55.119 + 'x |= 1;\n'); 55.120 + fail("const assignment didn't throw"); 55.121 +} catch (e) { 55.122 + print(e.name); 55.123 +} 55.124 + 55.125 +try { 55.126 + eval('"use strict";\n' + 55.127 + 'const x = 2;\n' + 55.128 + 'x &= 1;\n'); 55.129 + fail("const assignment didn't throw"); 55.130 +} catch (e) { 55.131 + print(e.name); 55.132 +} 55.133 + 55.134 +try { 55.135 + eval('"use strict";\n' + 55.136 + 'const x = 2;\n' + 55.137 + 'x ^= 1;\n'); 55.138 + fail("const assignment didn't throw"); 55.139 +} catch (e) { 55.140 + print(e.name); 55.141 +} 55.142 + 55.143 +try { 55.144 + eval('"use strict";\n' + 55.145 + 'const x = 2;\n' + 55.146 + 'x <<= 1;\n'); 55.147 + fail("const assignment didn't throw"); 55.148 +} catch (e) { 55.149 + print(e.name); 55.150 +} 55.151 + 55.152 +try { 55.153 + eval('"use strict";\n' + 55.154 + 'const x = 2;\n' + 55.155 + 'x >>= 1;\n'); 55.156 + fail("const assignment didn't throw"); 55.157 +} catch (e) { 55.158 + print(e.name); 55.159 +} 55.160 + 55.161 +try { 55.162 + eval('"use strict";\n' + 55.163 + 'const x = 2;\n' + 55.164 + 'x >>>= 1;\n'); 55.165 + fail("const assignment didn't throw"); 55.166 +} catch (e) { 55.167 + print(e.name); 55.168 +} 55.169 + 55.170 +try { 55.171 + eval('"use strict";\n' + 55.172 + 'const x = 2;\n' + 55.173 + 'delete x;\n'); 55.174 + fail("const assignment didn't throw"); 55.175 +} catch (e) { 55.176 + print(e.name); 55.177 +}
56.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 56.2 +++ b/test/script/basic/es6/const-reassign.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 56.3 @@ -0,0 +1,16 @@ 56.4 +SyntaxError 56.5 +SyntaxError 56.6 +SyntaxError 56.7 +SyntaxError 56.8 +SyntaxError 56.9 +SyntaxError 56.10 +SyntaxError 56.11 +SyntaxError 56.12 +SyntaxError 56.13 +SyntaxError 56.14 +SyntaxError 56.15 +SyntaxError 56.16 +SyntaxError 56.17 +SyntaxError 56.18 +SyntaxError 56.19 +SyntaxError
57.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 57.2 +++ b/test/script/basic/es6/const-redeclare-extra.js Tue Sep 09 11:14:12 2014 -0700 57.3 @@ -0,0 +1,59 @@ 57.4 +/* 57.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 57.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 57.7 + * 57.8 + * This code is free software; you can redistribute it and/or modify it 57.9 + * under the terms of the GNU General Public License version 2 only, as 57.10 + * published by the Free Software Foundation. 57.11 + * 57.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 57.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 57.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 57.15 + * version 2 for more details (a copy is included in the LICENSE file that 57.16 + * accompanied this code). 57.17 + * 57.18 + * You should have received a copy of the GNU General Public License version 57.19 + * 2 along with this work; if not, write to the Free Software Foundation, 57.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 57.21 + * 57.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 57.23 + * or visit www.oracle.com if you need additional information or have any 57.24 + * questions. 57.25 + */ 57.26 + 57.27 +/** 57.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 57.29 + * 57.30 + * @test 57.31 + * @run 57.32 + * @option --language=es6 57.33 + * @option -scripting 57.34 + */ 57.35 + 57.36 + 57.37 +function tryIt (code) { 57.38 + try { 57.39 + eval(code) 57.40 + } catch (e) { 57.41 + print(e) 57.42 + } 57.43 +} 57.44 + 57.45 +tryIt(<<CODE 57.46 + "use strict"; 57.47 + const x = 2; 57.48 + var x = {}; 57.49 +CODE) 57.50 + 57.51 +tryIt(<<CODE 57.52 + "use strict"; 57.53 + var x = 2; 57.54 + const x = {}; 57.55 +CODE) 57.56 + 57.57 +tryIt(<<CODE 57.58 + "use strict"; 57.59 + function x () {} 57.60 + const x = 5; 57.61 +CODE) 57.62 +
58.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 58.2 +++ b/test/script/basic/es6/const-redeclare-extra.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 58.3 @@ -0,0 +1,9 @@ 58.4 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>@2:3:8 Variable "x" has already been declared 58.5 + var x = {}; 58.6 + ^ 58.7 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>@4:2:8 Variable "x" has already been declared 58.8 + var x = 2; 58.9 + ^ 58.10 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>@4:2:13 Variable "x" has already been declared 58.11 + function x () {} 58.12 + ^
59.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 59.2 +++ b/test/script/basic/es6/const-redeclare.js Tue Sep 09 11:14:12 2014 -0700 59.3 @@ -0,0 +1,38 @@ 59.4 +/* 59.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 59.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 59.7 + * 59.8 + * This code is free software; you can redistribute it and/or modify it 59.9 + * under the terms of the GNU General Public License version 2 only, as 59.10 + * published by the Free Software Foundation. 59.11 + * 59.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 59.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 59.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 59.15 + * version 2 for more details (a copy is included in the LICENSE file that 59.16 + * accompanied this code). 59.17 + * 59.18 + * You should have received a copy of the GNU General Public License version 59.19 + * 2 along with this work; if not, write to the Free Software Foundation, 59.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 59.21 + * 59.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 59.23 + * or visit www.oracle.com if you need additional information or have any 59.24 + * questions. 59.25 + */ 59.26 + 59.27 +/** 59.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 59.29 + * 59.30 + * @test 59.31 + * @run 59.32 + * @option --language=es6 59.33 + */ 59.34 + 59.35 +try { 59.36 + eval('"use strict";\n' + 59.37 + 'const x = 2;\n' + 59.38 + 'const x = 2;\n'); 59.39 +} catch (e) { 59.40 + print(e); 59.41 +}
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/test/script/basic/es6/const-redeclare.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 60.3 @@ -0,0 +1,3 @@ 60.4 +SyntaxError: test/script/basic/es6/const-redeclare.js#33:4<eval>@1:2:6 Variable "x" has already been declared 60.5 +const x = 2; 60.6 + ^
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/test/script/basic/es6/const-self.js Tue Sep 09 11:14:12 2014 -0700 61.3 @@ -0,0 +1,42 @@ 61.4 +/* 61.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 61.7 + * 61.8 + * This code is free software; you can redistribute it and/or modify it 61.9 + * under the terms of the GNU General Public License version 2 only, as 61.10 + * published by the Free Software Foundation. 61.11 + * 61.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 61.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 61.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 61.15 + * version 2 for more details (a copy is included in the LICENSE file that 61.16 + * accompanied this code). 61.17 + * 61.18 + * You should have received a copy of the GNU General Public License version 61.19 + * 2 along with this work; if not, write to the Free Software Foundation, 61.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 61.21 + * 61.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 61.23 + * or visit www.oracle.com if you need additional information or have any 61.24 + * questions. 61.25 + */ 61.26 + 61.27 +/** 61.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 61.29 + * 61.30 + * @test 61.31 + * @run 61.32 + * @option --language=es6 */ 61.33 + 61.34 +"use strict"; 61.35 + 61.36 +const a = 1, b = a; 61.37 + 61.38 +print(a, b); 61.39 + 61.40 +try { 61.41 + eval('"use strict";\n' + 61.42 + 'const a = a;\n'); 61.43 +} catch (e) { 61.44 + print(e); 61.45 +}
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/test/script/basic/es6/const-self.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 62.3 @@ -0,0 +1,2 @@ 62.4 +1 1 62.5 +ReferenceError: "a" is not defined
63.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 63.2 +++ b/test/script/basic/es6/const-tdz.js Tue Sep 09 11:14:12 2014 -0700 63.3 @@ -0,0 +1,81 @@ 63.4 +/* 63.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 63.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 63.7 + * 63.8 + * This code is free software; you can redistribute it and/or modify it 63.9 + * under the terms of the GNU General Public License version 2 only, as 63.10 + * published by the Free Software Foundation. 63.11 + * 63.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 63.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 63.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 63.15 + * version 2 for more details (a copy is included in the LICENSE file that 63.16 + * accompanied this code). 63.17 + * 63.18 + * You should have received a copy of the GNU General Public License version 63.19 + * 2 along with this work; if not, write to the Free Software Foundation, 63.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 63.21 + * 63.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 63.23 + * or visit www.oracle.com if you need additional information or have any 63.24 + * questions. 63.25 + */ 63.26 + 63.27 +/** 63.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 63.29 + * 63.30 + * @test 63.31 + * @run 63.32 + * @option --language=es6 */ 63.33 + 63.34 +"use strict"; 63.35 + 63.36 +{ 63.37 + print("test 1"); 63.38 + 63.39 + function f() { 63.40 + try { 63.41 + print(a); 63.42 + } catch (a) { 63.43 + print(a); 63.44 + } 63.45 + } 63.46 + 63.47 + f(); 63.48 + const a = 1; 63.49 + f(); 63.50 +} 63.51 + 63.52 +{ 63.53 + print("test 2"); 63.54 + 63.55 + function f() { 63.56 + try { 63.57 + print(a); 63.58 + } catch (a) { 63.59 + print(a); 63.60 + } 63.61 + } 63.62 + 63.63 + f(); 63.64 + const a = 2; 63.65 + f(); 63.66 +} 63.67 + 63.68 +{ 63.69 + print("test 3"); 63.70 + { 63.71 + try { 63.72 + print(a); 63.73 + } catch (a) { 63.74 + print(a); 63.75 + } 63.76 + } 63.77 + 63.78 + const a = 3; 63.79 + 63.80 + { 63.81 + print(a); 63.82 + } 63.83 +} 63.84 +
64.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 64.2 +++ b/test/script/basic/es6/const-tdz.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 64.3 @@ -0,0 +1,9 @@ 64.4 +test 1 64.5 +ReferenceError: "a" is not defined 64.6 +1 64.7 +test 2 64.8 +ReferenceError: "a" is not defined 64.9 +2 64.10 +test 3 64.11 +ReferenceError: "a" is not defined 64.12 +3
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/test/script/basic/es6/const.js Tue Sep 09 11:14:12 2014 -0700 65.3 @@ -0,0 +1,69 @@ 65.4 +/* 65.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 65.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 65.7 + * 65.8 + * This code is free software; you can redistribute it and/or modify it 65.9 + * under the terms of the GNU General Public License version 2 only, as 65.10 + * published by the Free Software Foundation. 65.11 + * 65.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 65.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 65.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 65.15 + * version 2 for more details (a copy is included in the LICENSE file that 65.16 + * accompanied this code). 65.17 + * 65.18 + * You should have received a copy of the GNU General Public License version 65.19 + * 2 along with this work; if not, write to the Free Software Foundation, 65.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 65.21 + * 65.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 65.23 + * or visit www.oracle.com if you need additional information or have any 65.24 + * questions. 65.25 + */ 65.26 + 65.27 +/** 65.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 65.29 + * 65.30 + * @test 65.31 + * @run 65.32 + * @option --language=es6 65.33 + */ 65.34 + 65.35 +"use strict"; 65.36 + 65.37 +const a = 2; 65.38 +const c = 2; 65.39 +print(a, c); 65.40 + 65.41 +function f(x) { 65.42 + const a = 5; 65.43 + const c = 10; 65.44 + print(a, c); 65.45 + if (x) { 65.46 + const a = 42; 65.47 + const c = 43; 65.48 + print(a, c); 65.49 + } 65.50 + print(a, c); 65.51 + 65.52 + function inner() { 65.53 + (function() { 65.54 + print(a, c); 65.55 + })(); 65.56 + } 65.57 + inner(); 65.58 +} 65.59 + 65.60 +f(true); 65.61 +f(false); 65.62 + 65.63 +(function() { 65.64 + (function() { 65.65 + print(a, c); 65.66 + })(); 65.67 +})(); 65.68 + 65.69 +function outer() { 65.70 + print(a, c); 65.71 +} 65.72 +outer();
66.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 66.2 +++ b/test/script/basic/es6/const.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 66.3 @@ -0,0 +1,10 @@ 66.4 +2 2 66.5 +5 10 66.6 +42 43 66.7 +5 10 66.8 +5 10 66.9 +5 10 66.10 +5 10 66.11 +5 10 66.12 +2 2 66.13 +2 2
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/test/script/basic/es6/for-let.js Tue Sep 09 11:14:12 2014 -0700 67.3 @@ -0,0 +1,41 @@ 67.4 +/* 67.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 67.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 67.7 + * 67.8 + * This code is free software; you can redistribute it and/or modify it 67.9 + * under the terms of the GNU General Public License version 2 only, as 67.10 + * published by the Free Software Foundation. 67.11 + * 67.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 67.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 67.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 67.15 + * version 2 for more details (a copy is included in the LICENSE file that 67.16 + * accompanied this code). 67.17 + * 67.18 + * You should have received a copy of the GNU General Public License version 67.19 + * 2 along with this work; if not, write to the Free Software Foundation, 67.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 67.21 + * 67.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 67.23 + * or visit www.oracle.com if you need additional information or have any 67.24 + * questions. 67.25 + */ 67.26 + 67.27 +/** 67.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 67.29 + * 67.30 + * @test 67.31 + * @run 67.32 + * @option --language=es6 */ 67.33 + 67.34 +"use strict"; 67.35 + 67.36 +for (let i = 0; i < 10; i++) { 67.37 + print(i); 67.38 +} 67.39 + 67.40 +try { 67.41 + print(i); 67.42 +} catch (e) { 67.43 + print(e); 67.44 +}
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/test/script/basic/es6/for-let.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 68.3 @@ -0,0 +1,11 @@ 68.4 +0 68.5 +1 68.6 +2 68.7 +3 68.8 +4 68.9 +5 68.10 +6 68.11 +7 68.12 +8 68.13 +9 68.14 +ReferenceError: "i" is not defined
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/test/script/basic/es6/let-eval.js Tue Sep 09 11:14:12 2014 -0700 69.3 @@ -0,0 +1,98 @@ 69.4 +/* 69.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 69.7 + * 69.8 + * This code is free software; you can redistribute it and/or modify it 69.9 + * under the terms of the GNU General Public License version 2 only, as 69.10 + * published by the Free Software Foundation. 69.11 + * 69.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 69.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 69.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 69.15 + * version 2 for more details (a copy is included in the LICENSE file that 69.16 + * accompanied this code). 69.17 + * 69.18 + * You should have received a copy of the GNU General Public License version 69.19 + * 2 along with this work; if not, write to the Free Software Foundation, 69.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 69.21 + * 69.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 69.23 + * or visit www.oracle.com if you need additional information or have any 69.24 + * questions. 69.25 + */ 69.26 + 69.27 +/** 69.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 69.29 + * 69.30 + * @test 69.31 + * @run 69.32 + * @option --language=es6 */ 69.33 + 69.34 +"use strict"; 69.35 + 69.36 +function f() { 69.37 + var a; 69.38 + let b; 69.39 + const c = 0; 69.40 + 69.41 + print(a, b, c); 69.42 + 69.43 + try { 69.44 + eval("x = 1; print('x: ' + x);"); 69.45 + print("assignment to x succeeded"); 69.46 + } catch (e) { 69.47 + print(e); 69.48 + } 69.49 + try { 69.50 + eval("'use strict'; let z = 1; print('z: ' + z);"); 69.51 + print("assignment to z succeeded"); 69.52 + eval("print('z: ' + z);"); 69.53 + } catch (e) { 69.54 + print(e); 69.55 + } 69.56 + 69.57 + try { 69.58 + eval("a = 1; print(a);"); 69.59 + print("assignment to a succeeded"); 69.60 + } catch (e) { 69.61 + print(e); 69.62 + } 69.63 + print("a: " + a); 69.64 + 69.65 + try { 69.66 + eval("b = 1; print('b: ' + b);"); 69.67 + print("assignment to b succeeded"); 69.68 + } catch (e) { 69.69 + print(e); 69.70 + } 69.71 + print("b: " + b); 69.72 + 69.73 + try { 69.74 + eval("c = 1; print('c: ' + c);"); 69.75 + print("assignment to c succeeded"); 69.76 + } catch (e) { 69.77 + print(e); 69.78 + } 69.79 + print("c: " + c); 69.80 + 69.81 + eval("a = 2; let b = 3;"); 69.82 + 69.83 + try { 69.84 + print(a, b, c); 69.85 + } catch (e) { 69.86 + print(e); 69.87 + } 69.88 + 69.89 + let x; 69.90 + 69.91 + try { 69.92 + print(a, b, c, x); 69.93 + } catch (e) { 69.94 + print(e); 69.95 + } 69.96 + 69.97 +} 69.98 + 69.99 +f(); 69.100 + 69.101 +print(typeof a, typeof b, typeof c, typeof x, typeof z);
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/test/script/basic/es6/let-eval.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 70.3 @@ -0,0 +1,16 @@ 70.4 +undefined undefined 0 70.5 +ReferenceError: "x" is not defined 70.6 +z: 1 70.7 +assignment to z succeeded 70.8 +ReferenceError: "z" is not defined 70.9 +1 70.10 +assignment to a succeeded 70.11 +a: 1 70.12 +b: 1 70.13 +assignment to b succeeded 70.14 +b: 1 70.15 +TypeError: "c" is not a writable property of [object Object] 70.16 +c: 0 70.17 +2 1 0 70.18 +2 1 0 undefined 70.19 +undefined undefined undefined undefined undefined
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/test/script/basic/es6/let-load-lib.js Tue Sep 09 11:14:12 2014 -0700 71.3 @@ -0,0 +1,48 @@ 71.4 +/* 71.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 71.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 71.7 + * 71.8 + * This code is free software; you can redistribute it and/or modify it 71.9 + * under the terms of the GNU General Public License version 2 only, as 71.10 + * published by the Free Software Foundation. 71.11 + * 71.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 71.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 71.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 71.15 + * version 2 for more details (a copy is included in the LICENSE file that 71.16 + * accompanied this code). 71.17 + * 71.18 + * You should have received a copy of the GNU General Public License version 71.19 + * 2 along with this work; if not, write to the Free Software Foundation, 71.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 71.21 + * 71.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 71.23 + * or visit www.oracle.com if you need additional information or have any 71.24 + * questions. 71.25 + */ 71.26 + 71.27 +/** 71.28 + * @subtest 71.29 + */ 71.30 + 71.31 +"use strict"; 71.32 + 71.33 +// var should be visible in other script, let and const not 71.34 +var a = 1; 71.35 +let b = 2; 71.36 +const c = 3; 71.37 + 71.38 +// top level function should be visible 71.39 +function top() { 71.40 + print("top level function"); 71.41 +} 71.42 + 71.43 +// block level function not visible outside script 71.44 +{ 71.45 + function block() { 71.46 + print("block function"); 71.47 + } 71.48 + 71.49 + top(); 71.50 + block(); 71.51 +}
72.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 72.2 +++ b/test/script/basic/es6/let-load.js Tue Sep 09 11:14:12 2014 -0700 72.3 @@ -0,0 +1,62 @@ 72.4 +/* 72.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 72.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 72.7 + * 72.8 + * This code is free software; you can redistribute it and/or modify it 72.9 + * under the terms of the GNU General Public License version 2 only, as 72.10 + * published by the Free Software Foundation. 72.11 + * 72.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 72.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 72.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 72.15 + * version 2 for more details (a copy is included in the LICENSE file that 72.16 + * accompanied this code). 72.17 + * 72.18 + * You should have received a copy of the GNU General Public License version 72.19 + * 2 along with this work; if not, write to the Free Software Foundation, 72.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 72.21 + * 72.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 72.23 + * or visit www.oracle.com if you need additional information or have any 72.24 + * questions. 72.25 + */ 72.26 + 72.27 +/** 72.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 72.29 + * 72.30 + * @test 72.31 + * @run 72.32 + * @option --language=es6 */ 72.33 + 72.34 +"use strict"; 72.35 + 72.36 +load(__DIR__ + "let-load-lib.js"); 72.37 + 72.38 +{ 72.39 + let a = 20; 72.40 + const c = 30; 72.41 + print("print local defs: " + a, c); 72.42 +} 72.43 + 72.44 +print("imported var: " + a); 72.45 +try { 72.46 + print("imported let: " + b); 72.47 +} catch (e) { 72.48 + print(e); 72.49 +} 72.50 + 72.51 +try { 72.52 + print("imported const: " + c); 72.53 +} catch (e) { 72.54 + print(e); 72.55 +} 72.56 + 72.57 +top(); 72.58 + 72.59 +try { 72.60 + block(); 72.61 +} catch (e) { 72.62 + print(e); 72.63 +} 72.64 + 72.65 +
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/test/script/basic/es6/let-load.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 73.3 @@ -0,0 +1,8 @@ 73.4 +top level function 73.5 +block function 73.6 +print local defs: 20 30 73.7 +imported var: 1 73.8 +ReferenceError: "b" is not defined 73.9 +ReferenceError: "c" is not defined 73.10 +top level function 73.11 +ReferenceError: "block" is not defined
74.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 74.2 +++ b/test/script/basic/es6/let-nodeclare.js Tue Sep 09 11:14:12 2014 -0700 74.3 @@ -0,0 +1,52 @@ 74.4 +/* 74.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 74.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 74.7 + * 74.8 + * This code is free software; you can redistribute it and/or modify it 74.9 + * under the terms of the GNU General Public License version 2 only, as 74.10 + * published by the Free Software Foundation. 74.11 + * 74.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 74.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 74.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 74.15 + * version 2 for more details (a copy is included in the LICENSE file that 74.16 + * accompanied this code). 74.17 + * 74.18 + * You should have received a copy of the GNU General Public License version 74.19 + * 2 along with this work; if not, write to the Free Software Foundation, 74.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 74.21 + * 74.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 74.23 + * or visit www.oracle.com if you need additional information or have any 74.24 + * questions. 74.25 + */ 74.26 + 74.27 +/** 74.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 74.29 + * 74.30 + * @test 74.31 + * @run 74.32 + * @option --language=es6 */ 74.33 + 74.34 +"use strict"; 74.35 + 74.36 +try { 74.37 + if (true) { 74.38 + let x = 2; 74.39 + print(x); 74.40 + } 74.41 + print(x); 74.42 +} catch (e) { 74.43 + print(e); 74.44 +} 74.45 + 74.46 + 74.47 +try { 74.48 + if (true) { 74.49 + const x = 2; 74.50 + print(x); 74.51 + } 74.52 + print(x); 74.53 +} catch (e) { 74.54 + print(e); 74.55 +}
75.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 75.2 +++ b/test/script/basic/es6/let-nodeclare.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 75.3 @@ -0,0 +1,4 @@ 75.4 +2 75.5 +ReferenceError: "x" is not defined 75.6 +2 75.7 +ReferenceError: "x" is not defined
76.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 76.2 +++ b/test/script/basic/es6/let-redeclare-extra.js Tue Sep 09 11:14:12 2014 -0700 76.3 @@ -0,0 +1,70 @@ 76.4 +/* 76.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 76.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 76.7 + * 76.8 + * This code is free software; you can redistribute it and/or modify it 76.9 + * under the terms of the GNU General Public License version 2 only, as 76.10 + * published by the Free Software Foundation. 76.11 + * 76.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 76.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 76.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 76.15 + * version 2 for more details (a copy is included in the LICENSE file that 76.16 + * accompanied this code). 76.17 + * 76.18 + * You should have received a copy of the GNU General Public License version 76.19 + * 2 along with this work; if not, write to the Free Software Foundation, 76.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 76.21 + * 76.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 76.23 + * or visit www.oracle.com if you need additional information or have any 76.24 + * questions. 76.25 + */ 76.26 + 76.27 +/** 76.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 76.29 + * 76.30 + * @test 76.31 + * @run 76.32 + * @option --language=es6 76.33 + * @option -scripting 76.34 + */ 76.35 + 76.36 +function tryIt (code) { 76.37 + try { 76.38 + eval(code) 76.39 + } catch (e) { 76.40 + print(e) 76.41 + } 76.42 +} 76.43 + 76.44 +tryIt(<<CODE 76.45 + "use strict"; 76.46 + let x = 2; 76.47 + const x = function (a,b,c) {}; 76.48 +CODE) 76.49 + 76.50 +tryIt(<<CODE 76.51 + "use strict"; 76.52 + let x = {}; 76.53 + var x = 2; 76.54 +CODE) 76.55 + 76.56 +tryIt(<<CODE 76.57 + "use strict"; 76.58 + var x = 2; 76.59 + let x = undefined; 76.60 +CODE) 76.61 + 76.62 +tryIt(<<CODE 76.63 + "use strict"; 76.64 + const x = function (){}; 76.65 + let x = {}; 76.66 +CODE) 76.67 + 76.68 + 76.69 +tryIt(<<CODE 76.70 + "use strict"; 76.71 + let a = 2; 76.72 + function a () {}; 76.73 +CODE) 76.74 \ No newline at end of file
77.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 77.2 +++ b/test/script/basic/es6/let-redeclare-extra.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 77.3 @@ -0,0 +1,15 @@ 77.4 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>@2:2:8 Variable "x" has already been declared 77.5 + let x = 2; 77.6 + ^ 77.7 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>@4:3:8 Variable "x" has already been declared 77.8 + var x = 2; 77.9 + ^ 77.10 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>@4:2:8 Variable "x" has already been declared 77.11 + var x = 2; 77.12 + ^ 77.13 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>@4:2:10 Variable "x" has already been declared 77.14 + const x = function (){}; 77.15 + ^ 77.16 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>@4:3:13 Variable "a" has already been declared 77.17 + function a () {}; 77.18 + ^
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/test/script/basic/es6/let-redeclare.js Tue Sep 09 11:14:12 2014 -0700 78.3 @@ -0,0 +1,38 @@ 78.4 +/* 78.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 78.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 78.7 + * 78.8 + * This code is free software; you can redistribute it and/or modify it 78.9 + * under the terms of the GNU General Public License version 2 only, as 78.10 + * published by the Free Software Foundation. 78.11 + * 78.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 78.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 78.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 78.15 + * version 2 for more details (a copy is included in the LICENSE file that 78.16 + * accompanied this code). 78.17 + * 78.18 + * You should have received a copy of the GNU General Public License version 78.19 + * 2 along with this work; if not, write to the Free Software Foundation, 78.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 78.21 + * 78.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 78.23 + * or visit www.oracle.com if you need additional information or have any 78.24 + * questions. 78.25 + */ 78.26 + 78.27 +/** 78.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 78.29 + * 78.30 + * @test 78.31 + * @run 78.32 + * @option --language=es6 78.33 + */ 78.34 + 78.35 +try { 78.36 + eval('"use strict";\n' + 78.37 + 'let x = 2;\n' + 78.38 + 'let x = 2;\n'); 78.39 +} catch (e) { 78.40 + print(e); 78.41 +}
79.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 79.2 +++ b/test/script/basic/es6/let-redeclare.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 79.3 @@ -0,0 +1,3 @@ 79.4 +SyntaxError: test/script/basic/es6/let-redeclare.js#33:4<eval>@1:2:4 Variable "x" has already been declared 79.5 +let x = 2; 79.6 + ^
80.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 80.2 +++ b/test/script/basic/es6/let-self.js Tue Sep 09 11:14:12 2014 -0700 80.3 @@ -0,0 +1,42 @@ 80.4 +/* 80.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 80.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 80.7 + * 80.8 + * This code is free software; you can redistribute it and/or modify it 80.9 + * under the terms of the GNU General Public License version 2 only, as 80.10 + * published by the Free Software Foundation. 80.11 + * 80.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 80.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 80.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 80.15 + * version 2 for more details (a copy is included in the LICENSE file that 80.16 + * accompanied this code). 80.17 + * 80.18 + * You should have received a copy of the GNU General Public License version 80.19 + * 2 along with this work; if not, write to the Free Software Foundation, 80.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 80.21 + * 80.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 80.23 + * or visit www.oracle.com if you need additional information or have any 80.24 + * questions. 80.25 + */ 80.26 + 80.27 +/** 80.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 80.29 + * 80.30 + * @test 80.31 + * @run 80.32 + * @option --language=es6 */ 80.33 + 80.34 +"use strict"; 80.35 + 80.36 +let a, b = a; 80.37 + 80.38 +print(a, b); 80.39 + 80.40 +try { 80.41 + eval('"use strict";\n' + 80.42 + 'let a = a;\n'); 80.43 +} catch (e) { 80.44 + print(e); 80.45 +}
81.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 81.2 +++ b/test/script/basic/es6/let-self.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 81.3 @@ -0,0 +1,2 @@ 81.4 +undefined undefined 81.5 +ReferenceError: "a" is not defined
82.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 82.2 +++ b/test/script/basic/es6/let-tdz.js Tue Sep 09 11:14:12 2014 -0700 82.3 @@ -0,0 +1,97 @@ 82.4 +/* 82.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 82.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 82.7 + * 82.8 + * This code is free software; you can redistribute it and/or modify it 82.9 + * under the terms of the GNU General Public License version 2 only, as 82.10 + * published by the Free Software Foundation. 82.11 + * 82.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 82.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 82.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 82.15 + * version 2 for more details (a copy is included in the LICENSE file that 82.16 + * accompanied this code). 82.17 + * 82.18 + * You should have received a copy of the GNU General Public License version 82.19 + * 2 along with this work; if not, write to the Free Software Foundation, 82.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 82.21 + * 82.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 82.23 + * or visit www.oracle.com if you need additional information or have any 82.24 + * questions. 82.25 + */ 82.26 + 82.27 +/** 82.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 82.29 + * 82.30 + * @test 82.31 + * @run 82.32 + * @option --language=es6 */ 82.33 + 82.34 +"use strict"; 82.35 + 82.36 +{ 82.37 + print("test 1"); 82.38 + 82.39 + function f() { 82.40 + try { 82.41 + print(a); 82.42 + } catch (a) { 82.43 + print(a); 82.44 + } 82.45 + } 82.46 + 82.47 + f(); 82.48 + let a = 1; 82.49 + f(); 82.50 +} 82.51 + 82.52 +{ 82.53 + print("test 2"); 82.54 + 82.55 + function f() { 82.56 + try { 82.57 + print(a); 82.58 + } catch (a) { 82.59 + print(a); 82.60 + } 82.61 + } 82.62 + 82.63 + f(); 82.64 + let a = 2; 82.65 + f(); 82.66 +} 82.67 + 82.68 +{ 82.69 + print("test 3"); 82.70 + 82.71 + { 82.72 + try { 82.73 + print(a); 82.74 + } catch (a) { 82.75 + print(a); 82.76 + } 82.77 + } 82.78 + 82.79 + let a = 3; 82.80 + 82.81 + { 82.82 + print(a); 82.83 + } 82.84 +} 82.85 + 82.86 +{ 82.87 + print("test 4"); 82.88 + let a; 82.89 + 82.90 + { 82.91 + print(a); 82.92 + } 82.93 + 82.94 + a = 4; 82.95 + 82.96 + { 82.97 + print(a); 82.98 + } 82.99 +} 82.100 +
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/test/script/basic/es6/let-tdz.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 83.3 @@ -0,0 +1,12 @@ 83.4 +test 1 83.5 +ReferenceError: "a" is not defined 83.6 +1 83.7 +test 2 83.8 +ReferenceError: "a" is not defined 83.9 +2 83.10 +test 3 83.11 +ReferenceError: "a" is not defined 83.12 +3 83.13 +test 4 83.14 +undefined 83.15 +4
84.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 84.2 +++ b/test/script/basic/es6/let.js Tue Sep 09 11:14:12 2014 -0700 84.3 @@ -0,0 +1,69 @@ 84.4 +/* 84.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 84.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 84.7 + * 84.8 + * This code is free software; you can redistribute it and/or modify it 84.9 + * under the terms of the GNU General Public License version 2 only, as 84.10 + * published by the Free Software Foundation. 84.11 + * 84.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 84.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 84.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 84.15 + * version 2 for more details (a copy is included in the LICENSE file that 84.16 + * accompanied this code). 84.17 + * 84.18 + * You should have received a copy of the GNU General Public License version 84.19 + * 2 along with this work; if not, write to the Free Software Foundation, 84.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 84.21 + * 84.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 84.23 + * or visit www.oracle.com if you need additional information or have any 84.24 + * questions. 84.25 + */ 84.26 + 84.27 +/** 84.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation 84.29 + * 84.30 + * @test 84.31 + * @run 84.32 + * @option --language=es6 */ 84.33 + 84.34 +"use strict"; 84.35 + 84.36 +let a = 2; 84.37 +let c = 2; 84.38 +print(a, c); 84.39 + 84.40 +function f(x) { 84.41 + let a = 5; 84.42 + const c = 10; 84.43 + print(a, c); 84.44 + if (x) { 84.45 + let a = 42; 84.46 + const c = 43; 84.47 + print(a, c); 84.48 + } 84.49 + print(a, c); 84.50 + 84.51 + function inner() { 84.52 + (function() { 84.53 + print(a, c); 84.54 + })(); 84.55 + } 84.56 + inner(); 84.57 +} 84.58 + 84.59 +f(true); 84.60 +f(false); 84.61 + 84.62 +(function() { 84.63 + (function() { 84.64 + print(a, c); 84.65 + })(); 84.66 +})(); 84.67 + 84.68 +function outer() { 84.69 + print(a, c); 84.70 +} 84.71 +outer(); 84.72 +
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/test/script/basic/es6/let.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 85.3 @@ -0,0 +1,10 @@ 85.4 +2 2 85.5 +5 10 85.6 +42 43 85.7 +5 10 85.8 +5 10 85.9 +5 10 85.10 +5 10 85.11 +5 10 85.12 +2 2 85.13 +2 2
86.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 86.2 +++ b/test/script/basic/es6/let_const_closure.js Tue Sep 09 11:14:12 2014 -0700 86.3 @@ -0,0 +1,123 @@ 86.4 +/* 86.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 86.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 86.7 + * 86.8 + * This code is free software; you can redistribute it and/or modify it 86.9 + * under the terms of the GNU General Public License version 2 only, as 86.10 + * published by the Free Software Foundation. 86.11 + * 86.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 86.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 86.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 86.15 + * version 2 for more details (a copy is included in the LICENSE file that 86.16 + * accompanied this code). 86.17 + * 86.18 + * You should have received a copy of the GNU General Public License version 86.19 + * 2 along with this work; if not, write to the Free Software Foundation, 86.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 86.21 + * 86.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 86.23 + * or visit www.oracle.com if you need additional information or have any 86.24 + * questions. 86.25 + */ 86.26 + 86.27 +/** 86.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 86.29 + * 86.30 + * @test 86.31 + * @run 86.32 + * @option --language=es6 86.33 + * @option -scripting 86.34 + */ 86.35 + 86.36 +function tryIt(code) { 86.37 + try { 86.38 + eval(code) 86.39 + } catch (e) { 86.40 + print(e) 86.41 + } 86.42 +} 86.43 + 86.44 + 86.45 +tryIt(<<CODE 86.46 + function a () { 86.47 + this.val = 41 86.48 + let self = this 86.49 + this.b = function () { 86.50 + return self.val; 86.51 + } 86.52 + } 86.53 + c = new a() 86.54 + print(c.b.call(null)) 86.55 +CODE) 86.56 + 86.57 + 86.58 +tryIt(<<CODE 86.59 + function a () { 86.60 + this.val = 42 86.61 + let self = this 86.62 + this.b = function () { 86.63 + return this.val; 86.64 + }.bind(self) 86.65 + } 86.66 + c = new a() 86.67 + print(c.b.call(null)) 86.68 +CODE) 86.69 + 86.70 +tryIt(<<CODE 86.71 + function a () { 86.72 + this.val = 43 86.73 + const self = this 86.74 + this.b = function () { 86.75 + return self.val; 86.76 + } 86.77 + } 86.78 + c = new a() 86.79 + print(c.b.call(null)) 86.80 +CODE) 86.81 + 86.82 +tryIt(<<CODE 86.83 + function a () { 86.84 + this.val = 44 86.85 + const self = this 86.86 + this.b = function () { 86.87 + return this.val; 86.88 + }.bind(self) 86.89 + } 86.90 + c = new a() 86.91 + print(c.b.call(null)) 86.92 +CODE) 86.93 + 86.94 +tryIt(<<CODE 86.95 + let a = {name : 'test'} 86.96 + let f = function () { 86.97 + print(this.name) 86.98 + } 86.99 + let nf = f.bind(a) 86.100 + nf() 86.101 + if (true) { 86.102 + let a = null 86.103 + nf() 86.104 + } 86.105 + nf() 86.106 +CODE) 86.107 + 86.108 + 86.109 +tryIt(<<CODE 86.110 + let arr = [] 86.111 + for (let i = 0; i < 3; i++) { 86.112 + arr[i] = function(){return i;} 86.113 + } 86.114 + for (let i in arr) { 86.115 + print(arr[i]()) 86.116 + } 86.117 + arr = [] 86.118 + for (var i = 0; i < 3; i++) { 86.119 + (function(i){ 86.120 + arr[i] = function(){return i;} 86.121 + })(i) 86.122 + } 86.123 + for (let i in arr) { 86.124 + print(arr[i]()) 86.125 + } 86.126 +CODE) 86.127 \ No newline at end of file
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/test/script/basic/es6/let_const_closure.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 87.3 @@ -0,0 +1,13 @@ 87.4 +41 87.5 +42 87.6 +43 87.7 +44 87.8 +test 87.9 +test 87.10 +test 87.11 +3 87.12 +3 87.13 +3 87.14 +0 87.15 +1 87.16 +2
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/test/script/basic/es6/let_const_reuse.js Tue Sep 09 11:14:12 2014 -0700 88.3 @@ -0,0 +1,71 @@ 88.4 +/* 88.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 88.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 88.7 + * 88.8 + * This code is free software; you can redistribute it and/or modify it 88.9 + * under the terms of the GNU General Public License version 2 only, as 88.10 + * published by the Free Software Foundation. 88.11 + * 88.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 88.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 88.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 88.15 + * version 2 for more details (a copy is included in the LICENSE file that 88.16 + * accompanied this code). 88.17 + * 88.18 + * You should have received a copy of the GNU General Public License version 88.19 + * 2 along with this work; if not, write to the Free Software Foundation, 88.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 88.21 + * 88.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 88.23 + * or visit www.oracle.com if you need additional information or have any 88.24 + * questions. 88.25 + */ 88.26 + 88.27 +/** 88.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 88.29 + * 88.30 + * @test 88.31 + * @run 88.32 + * @option --language=es6 88.33 + * @option -scripting 88.34 + */ 88.35 + 88.36 +function tryIt (code) { 88.37 + try { 88.38 + eval(code) 88.39 + } catch (e) { 88.40 + print(e) 88.41 + } 88.42 +} 88.43 + 88.44 +tryIt(<<CODE 88.45 + let a = 23 88.46 + if (true) { 88.47 + a-- 88.48 + let a = 43; 88.49 + } 88.50 +CODE) 88.51 + 88.52 +tryIt(<<CODE 88.53 + const a = 23 88.54 + if (true) { 88.55 + a-- 88.56 + const a = 43; 88.57 + } 88.58 +CODE) 88.59 + 88.60 +tryIt(<<CODE 88.61 + let a = 23 88.62 + if (true) { 88.63 + a-- 88.64 + const a = 43; 88.65 + } 88.66 +CODE) 88.67 + 88.68 +tryIt(<<CODE 88.69 + const a = 23 88.70 + if (true) { 88.71 + a-- 88.72 + let a = 43; 88.73 + } 88.74 +CODE)
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/test/script/basic/es6/let_const_reuse.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 89.3 @@ -0,0 +1,8 @@ 89.4 +ReferenceError: "a" is not defined 89.5 +SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>@4:3:8 Assignment to constant "a" 89.6 + a-- 89.7 + ^ 89.8 +SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>@4:3:8 Assignment to constant "a" 89.9 + a-- 89.10 + ^ 89.11 +ReferenceError: "a" is not defined
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 90.2 +++ b/test/script/basic/es6/let_different_types.js Tue Sep 09 11:14:12 2014 -0700 90.3 @@ -0,0 +1,73 @@ 90.4 +/* 90.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 90.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 90.7 + * 90.8 + * This code is free software; you can redistribute it and/or modify it 90.9 + * under the terms of the GNU General Public License version 2 only, as 90.10 + * published by the Free Software Foundation. 90.11 + * 90.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 90.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 90.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 90.15 + * version 2 for more details (a copy is included in the LICENSE file that 90.16 + * accompanied this code). 90.17 + * 90.18 + * You should have received a copy of the GNU General Public License version 90.19 + * 2 along with this work; if not, write to the Free Software Foundation, 90.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 90.21 + * 90.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 90.23 + * or visit www.oracle.com if you need additional information or have any 90.24 + * questions. 90.25 + */ 90.26 + 90.27 +/** 90.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 90.29 + * 90.30 + * @test 90.31 + * @run 90.32 + * @option --language=es6 90.33 + * @option -scripting 90.34 + */ 90.35 + 90.36 +function tryIt (code) { 90.37 + try { 90.38 + eval(code) 90.39 + } catch (e) { 90.40 + print(e) 90.41 + } 90.42 +} 90.43 + 90.44 +tryIt(<<CODE 90.45 + let a = function () { var a = "Hello World!"; return a; } 90.46 + print(typeof a) 90.47 + { 90.48 + let a = 34; 90.49 + print(typeof a) 90.50 + if (true) { 90.51 + let c = 54.7 90.52 + var d = c 90.53 + print(typeof c) 90.54 + print(typeof d) 90.55 + } 90.56 + } 90.57 + print(typeof a) 90.58 + print(typeof a()) 90.59 + print(typeof c) 90.60 + print(typeof d) 90.61 + print(d) 90.62 +CODE) 90.63 + 90.64 +tryIt(<<CODE 90.65 + let a = {} 90.66 + if (true) { 90.67 + function a () { 90.68 + print (typeof a) 90.69 + return 'Hello World!' 90.70 + } 90.71 + print(typeof a) 90.72 + print(a()) 90.73 + } 90.74 + print(typeof a) 90.75 +CODE) 90.76 +
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 91.2 +++ b/test/script/basic/es6/let_different_types.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 91.3 @@ -0,0 +1,13 @@ 91.4 +function 91.5 +number 91.6 +number 91.7 +number 91.8 +function 91.9 +string 91.10 +undefined 91.11 +number 91.12 +54.7 91.13 +function 91.14 +function 91.15 +Hello World! 91.16 +object
92.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 92.2 +++ b/test/script/basic/es6/let_loops.js Tue Sep 09 11:14:12 2014 -0700 92.3 @@ -0,0 +1,80 @@ 92.4 +/* 92.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. 92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 92.7 + * 92.8 + * This code is free software; you can redistribute it and/or modify it 92.9 + * under the terms of the GNU General Public License version 2 only, as 92.10 + * published by the Free Software Foundation. 92.11 + * 92.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 92.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 92.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 92.15 + * version 2 for more details (a copy is included in the LICENSE file that 92.16 + * accompanied this code). 92.17 + * 92.18 + * You should have received a copy of the GNU General Public License version 92.19 + * 2 along with this work; if not, write to the Free Software Foundation, 92.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 92.21 + * 92.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 92.23 + * or visit www.oracle.com if you need additional information or have any 92.24 + * questions. 92.25 + */ 92.26 + 92.27 +/** 92.28 + * JDK-8057678: Tests for let&const keywords in Nashorn 92.29 + * 92.30 + * @test 92.31 + * @run 92.32 + * @option --language=es6 92.33 + * @option -scripting 92.34 + */ 92.35 + 92.36 + 92.37 +function tryIt (code) { 92.38 + try { 92.39 + eval(code) 92.40 + } catch (e) { 92.41 + print(e) 92.42 + } 92.43 +} 92.44 + 92.45 +tryIt(<<CODE 92.46 + let a = 2; 92.47 + do { 92.48 + a--; 92.49 + let b = a; 92.50 + } while (a > 0); 92.51 + print(a) 92.52 + print(b) 92.53 +CODE) 92.54 + 92.55 +tryIt(<<CODE 92.56 + let a = 2 92.57 + while(a > 0) { 92.58 + a-- 92.59 + let b = a 92.60 + } 92.61 + print(a) 92.62 + print(b) 92.63 +CODE) 92.64 + 92.65 +tryIt(<<CODE 92.66 + let a = 2 92.67 + while(a > 0) { 92.68 + a-- 92.69 + const b = a 92.70 + } 92.71 + print(a) 92.72 + print(b) 92.73 +CODE) 92.74 + 92.75 +tryIt(<<CODE 92.76 + let a = 2; 92.77 + do { 92.78 + a--; 92.79 + const b = a; 92.80 + } while (a > 0); 92.81 + print(a) 92.82 + print(b) 92.83 +CODE)
93.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 93.2 +++ b/test/script/basic/es6/let_loops.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 93.3 @@ -0,0 +1,8 @@ 93.4 +0 93.5 +ReferenceError: "b" is not defined 93.6 +0 93.7 +ReferenceError: "b" is not defined 93.8 +0 93.9 +ReferenceError: "b" is not defined 93.10 +0 93.11 +ReferenceError: "b" is not defined
94.1 --- a/test/script/basic/optimistic_check_type.js Wed Sep 03 13:20:05 2014 -0700 94.2 +++ b/test/script/basic/optimistic_check_type.js Tue Sep 09 11:14:12 2014 -0700 94.3 @@ -36,13 +36,18 @@ 94.4 94.5 // Testing conditional operator 94.6 print(inspect("" ? b : x.a, "ternary operator")) 94.7 -print(inspect(x.b ? b : x.a, "ternary operator")) 94.8 -print(inspect(c ? b : a, "ternary operator")) 94.9 -print(inspect(!c ? b : a, "ternary operator")) 94.10 -print(inspect(d ? b : x.c, "ternary operator")) 94.11 +var b1 = b; 94.12 +print(inspect(x.b ? b1 : x.a, "ternary operator")) 94.13 +var b2 = b; 94.14 +print(inspect(c ? b2 : a, "ternary operator")) 94.15 +var b3 = b; 94.16 +print(inspect(!c ? b3 : a, "ternary operator")) 94.17 +var b4 = b; 94.18 +print(inspect(d ? b4 : x.c, "ternary operator")) 94.19 print(inspect(x.c ? a : c, "ternary operator")) 94.20 print(inspect(c ? d : a, "ternary operator")) 94.21 -print(inspect(c ? +a : b, "ternary operator")) 94.22 +var b5 = b; 94.23 +print(inspect(c ? +a : b5, "ternary operator")) 94.24 94.25 // Testing format methods 94.26 print(inspect(b.toFixed(2), "global double toFixed()")) 94.27 @@ -53,11 +58,14 @@ 94.28 print(inspect(trees[1], "member object")) 94.29 trees[1] = undefined; 94.30 print(inspect(trees[1], "member undefined")) 94.31 -print(inspect(1 in trees ? b : a, "conditional on array member")) 94.32 +var b6=b; 94.33 +print(inspect(1 in trees ? b6 : a, "conditional on array member")) 94.34 delete trees[2] 94.35 -print(inspect(2 in trees ? b : a, "conditional on array member")) 94.36 +var b7=b; 94.37 +print(inspect(2 in trees ? b7 : a, "conditional on array member")) 94.38 print(inspect(3 in trees ? trees[2]="bay" : a, "conditional on array member")) 94.39 -print(inspect("oak" in trees ? b : a, "conditional on array member")) 94.40 +var b8=b; 94.41 +print(inspect("oak" in trees ? b8 : a, "conditional on array member")) 94.42 94.43 // Testing nested functions and return value 94.44 function f1() {
95.1 --- a/test/script/basic/splitter.js Wed Sep 03 13:20:05 2014 -0700 95.2 +++ b/test/script/basic/splitter.js Tue Sep 09 11:14:12 2014 -0700 95.3 @@ -30,7 +30,5 @@ 95.4 * @fork 95.5 */ 95.6 95.7 -load(__DIR__ + 'prototype.js'); 95.8 -load(__DIR__ + 'yui.js'); 95.9 load(__DIR__ + 'NASHORN-689.js'); 95.10 load(__DIR__ + 'NASHORN-58.js');
96.1 --- a/test/script/basic/splitter.js.EXPECTED Wed Sep 03 13:20:05 2014 -0700 96.2 +++ b/test/script/basic/splitter.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 96.3 @@ -1,6 +1,3 @@ 96.4 -parsed and compiled ok prototype.js 96.5 -parsed and compiled ok yui-min.js 96.6 -parsed and compiled ok yui.js 96.7 a=10 96.8 a=9 96.9 a=8
97.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 97.2 +++ b/test/script/basic/splitter_prototype.js Tue Sep 09 11:14:12 2014 -0700 97.3 @@ -0,0 +1,33 @@ 97.4 +/* 97.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 97.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 97.7 + * 97.8 + * This code is free software; you can redistribute it and/or modify it 97.9 + * under the terms of the GNU General Public License version 2 only, as 97.10 + * published by the Free Software Foundation. 97.11 + * 97.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 97.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 97.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 97.15 + * version 2 for more details (a copy is included in the LICENSE file that 97.16 + * accompanied this code). 97.17 + * 97.18 + * You should have received a copy of the GNU General Public License version 97.19 + * 2 along with this work; if not, write to the Free Software Foundation, 97.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 97.21 + * 97.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 97.23 + * or visit www.oracle.com if you need additional information or have any 97.24 + * questions. 97.25 + */ 97.26 + 97.27 +/** 97.28 + * Test various scripts with low splitter threshold 97.29 + * 97.30 + * @test 97.31 + * @option -Dnashorn.compiler.splitter.threshold=200 97.32 + * @runif external.prototype 97.33 + * @fork 97.34 + */ 97.35 + 97.36 +load(__DIR__ + 'prototype.js');
98.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 98.2 +++ b/test/script/basic/splitter_prototype.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 98.3 @@ -0,0 +1,1 @@ 98.4 +parsed and compiled ok prototype.js
99.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 99.2 +++ b/test/script/basic/splitter_yui.js Tue Sep 09 11:14:12 2014 -0700 99.3 @@ -0,0 +1,33 @@ 99.4 +/* 99.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 99.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 99.7 + * 99.8 + * This code is free software; you can redistribute it and/or modify it 99.9 + * under the terms of the GNU General Public License version 2 only, as 99.10 + * published by the Free Software Foundation. 99.11 + * 99.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 99.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 99.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 99.15 + * version 2 for more details (a copy is included in the LICENSE file that 99.16 + * accompanied this code). 99.17 + * 99.18 + * You should have received a copy of the GNU General Public License version 99.19 + * 2 along with this work; if not, write to the Free Software Foundation, 99.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 99.21 + * 99.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 99.23 + * or visit www.oracle.com if you need additional information or have any 99.24 + * questions. 99.25 + */ 99.26 + 99.27 +/** 99.28 + * Test various scripts with low splitter threshold 99.29 + * 99.30 + * @test 99.31 + * @option -Dnashorn.compiler.splitter.threshold=200 99.32 + * @runif external.yui 99.33 + * @fork 99.34 + */ 99.35 + 99.36 +load(__DIR__ + 'yui.js');
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 100.2 +++ b/test/script/basic/splitter_yui.js.EXPECTED Tue Sep 09 11:14:12 2014 -0700 100.3 @@ -0,0 +1,2 @@ 100.4 +parsed and compiled ok yui-min.js 100.5 +parsed and compiled ok yui.js
101.1 --- a/test/script/trusted/JDK-8006529.js Wed Sep 03 13:20:05 2014 -0700 101.2 +++ b/test/script/trusted/JDK-8006529.js Tue Sep 09 11:14:12 2014 -0700 101.3 @@ -120,7 +120,7 @@ 101.4 101.5 var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class) 101.6 var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class) 101.7 -var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, boolean.class); 101.8 +var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class); 101.9 101.10 // compile(script) -- compiles a script specified as a string with its 101.11 // source code, returns a jdk.nashorn.internal.ir.FunctionNode object 101.12 @@ -134,7 +134,7 @@ 101.13 var parser = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance()); 101.14 var func = parseMethod.invoke(parser); 101.15 101.16 - var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, false); 101.17 + var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false); 101.18 101.19 return compileMethod.invoke(compiler, func, phases); 101.20 };
102.1 --- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Wed Sep 03 13:20:05 2014 -0700 102.2 +++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Tue Sep 09 11:14:12 2014 -0700 102.3 @@ -98,11 +98,16 @@ 102.4 compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() { 102.5 @Override 102.6 public boolean exclude(final File file, final String content) { 102.7 - return content.indexOf("@negative") != -1; 102.8 + return content != null && content.contains("@negative"); 102.9 } 102.10 }); 102.11 } 102.12 - compileTestSet(new File(TEST_BASIC_DIR), null); 102.13 + compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() { 102.14 + @Override 102.15 + public boolean exclude(final File file, final String content) { 102.16 + return file.getName().equals("es6"); 102.17 + } 102.18 + }); 102.19 compileTestSet(new File(TEST_NODE_DIR, "node"), null); 102.20 compileTestSet(new File(TEST_NODE_DIR, "src"), null); 102.21 } 102.22 @@ -136,6 +141,9 @@ 102.23 private int skipped; 102.24 102.25 private void compileJSDirectory(final File dir, final TestFilter filter) { 102.26 + if (filter != null && filter.exclude(dir, null)) { 102.27 + return; 102.28 + } 102.29 for (final File f : dir.listFiles()) { 102.30 if (f.isDirectory()) { 102.31 compileJSDirectory(f, filter);
103.1 --- a/test/src/jdk/nashorn/internal/parser/ParserTest.java Wed Sep 03 13:20:05 2014 -0700 103.2 +++ b/test/src/jdk/nashorn/internal/parser/ParserTest.java Tue Sep 09 11:14:12 2014 -0700 103.3 @@ -82,11 +82,16 @@ 103.4 parseTestSet(TEST262_SUITE_DIR, new TestFilter() { 103.5 @Override 103.6 public boolean exclude(final File file, final String content) { 103.7 - return content.indexOf("@negative") != -1; 103.8 + return content != null && content.contains("@negative"); 103.9 } 103.10 }); 103.11 } 103.12 - parseTestSet(TEST_BASIC_DIR, null); 103.13 + parseTestSet(TEST_BASIC_DIR, new TestFilter() { 103.14 + @Override 103.15 + public boolean exclude(final File file, final String content) { 103.16 + return file.getName().equals("es6"); 103.17 + } 103.18 + }); 103.19 } 103.20 103.21 private void parseTestSet(final String testSet, final TestFilter filter) { 103.22 @@ -120,6 +125,9 @@ 103.23 private int skipped; 103.24 103.25 private void parseJSDirectory(final File dir, final TestFilter filter) { 103.26 + if (filter != null && filter.exclude(dir, null)) { 103.27 + return; 103.28 + } 103.29 for (final File f : dir.listFiles()) { 103.30 if (f.isDirectory()) { 103.31 parseJSDirectory(f, filter);
104.1 --- a/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Wed Sep 03 13:20:05 2014 -0700 104.2 +++ b/test/src/jdk/nashorn/internal/test/framework/TestFinder.java Tue Sep 09 11:14:12 2014 -0700 104.3 @@ -261,14 +261,17 @@ 104.4 isTest = false; 104.5 isNotTest = true; 104.6 break; 104.7 - case "@runif": 104.8 - if (System.getProperty(scanner.next()) != null) { 104.9 + case "@runif": { 104.10 + final String prop = scanner.next(); 104.11 + if (System.getProperty(prop) != null) { 104.12 shouldRun = true; 104.13 } else { 104.14 + factory.log("WARNING: (" + prop + ") skipping " + testFile); 104.15 isTest = false; 104.16 isNotTest = true; 104.17 } 104.18 break; 104.19 + } 104.20 case "@run": 104.21 shouldRun = true; 104.22 break;