Merge

Tue, 09 Sep 2014 11:14:12 -0700

author
lana
date
Tue, 09 Sep 2014 11:14:12 -0700
changeset 996
f01257b46cf1
parent 988
2d75c391f61f
parent 995
33bde22b7740
child 997
5ad0607cf1a4

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;

mercurial