8051889: Implement block scoping in symbol assignment and scope computation

Thu, 04 Sep 2014 18:47:18 +0200

author
hannesw
date
Thu, 04 Sep 2014 18:47:18 +0200
changeset 991
b7a2db4de254
parent 990
46647c4943ff
child 992
7caec82669a4

8051889: Implement block scoping in symbol assignment and scope computation
Reviewed-by: attila, lagergren

make/build.xml file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/AssignSymbols.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/CodeGenerator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/Compiler.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/FieldObjectCreator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/MapCreator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/MethodEmitter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/codegen/TypeEvaluator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/FunctionNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/IdentNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/Symbol.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/ir/VarNode.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/parser/Parser.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/AccessorProperty.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Context.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/FindProperty.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Property.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptEnvironment.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptObject.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/ScriptRuntime.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/SetMethodCreator.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/resources/Messages.properties file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/resources/Options.properties file | annotate | diff | comparison | revisions
src/jdk/nashorn/tools/Shell.java file | annotate | diff | comparison | revisions
test/script/basic/es6/block-function-decl.js file | annotate | diff | comparison | revisions
test/script/basic/es6/block-function-decl.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const-empty.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const-empty.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const-reassign.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const-reassign.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const-redeclare.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const-redeclare.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const-self.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const-self.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const-tdz.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const-tdz.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/const.js file | annotate | diff | comparison | revisions
test/script/basic/es6/const.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/for-let.js file | annotate | diff | comparison | revisions
test/script/basic/es6/for-let.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-eval.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-eval.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-load-lib.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-load.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-load.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-nodeclare.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-nodeclare.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-redeclare.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-redeclare.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-self.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-self.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let-tdz.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let-tdz.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/es6/let.js file | annotate | diff | comparison | revisions
test/script/basic/es6/let.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/trusted/JDK-8006529.js file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/codegen/CompilerTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/parser/ParserTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/make/build.xml	Wed Sep 03 14:33:34 2014 +0200
     1.2 +++ b/make/build.xml	Thu Sep 04 18:47:18 2014 +0200
     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 14:33:34 2014 +0200
     2.2 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Thu Sep 04 18:47:18 2014 +0200
     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,8 +193,7 @@
    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 +        // This visitor will assign symbol to all declared variables, except "var" declarations in for loop initializers.
    2.44          //
    2.45          body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
    2.46              @Override
    2.47 @@ -204,8 +206,8 @@
    2.48              public Node leaveVarNode(final VarNode varNode) {
    2.49                  if (varNode.isStatement()) {
    2.50                      final IdentNode ident  = varNode.getName();
    2.51 -                    final Symbol    symbol = defineSymbol(body, ident.getName(), IS_VAR);
    2.52 -                    functionNode.addDeclaredSymbol(symbol);
    2.53 +                    final Block block = varNode.isBlockScoped() ? getLexicalContext().getCurrentBlock() : body;
    2.54 +                    final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags());
    2.55                      if (varNode.isFunctionDeclaration()) {
    2.56                          symbol.setIsFunctionDeclaration();
    2.57                      }
    2.58 @@ -303,23 +305,31 @@
    2.59          return functionNode.setBody(lc, body.setStatements(lc, newStatements));
    2.60      }
    2.61  
    2.62 -    private Symbol defineGlobalSymbol(final Block block, final String name) {
    2.63 -        return defineSymbol(block, name, IS_GLOBAL);
    2.64 -    }
    2.65 -
    2.66      /**
    2.67       * Defines a new symbol in the given block.
    2.68       *
    2.69       * @param block        the block in which to define the symbol
    2.70       * @param name         name of symbol.
    2.71 +     * @param origin       origin node
    2.72       * @param symbolFlags  Symbol flags.
    2.73       *
    2.74       * @return Symbol for given name or null for redefinition.
    2.75       */
    2.76 -    private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
    2.77 +    private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
    2.78          int    flags  = symbolFlags;
    2.79 -        Symbol symbol = findSymbol(block, name); // Locate symbol.
    2.80 -        final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
    2.81 +        final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
    2.82 +        final boolean isGlobal     = (flags & KINDMASK) == IS_GLOBAL;
    2.83 +
    2.84 +        Symbol symbol;
    2.85 +        final FunctionNode function;
    2.86 +        if (isBlockScope) {
    2.87 +            // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
    2.88 +            symbol = block.getExistingSymbol(name);
    2.89 +            function = lc.getCurrentFunction();
    2.90 +        } else {
    2.91 +            symbol = findSymbol(block, name);
    2.92 +            function = lc.getFunction(block);
    2.93 +        }
    2.94  
    2.95          // Global variables are implicitly always scope variables too.
    2.96          if (isGlobal) {
    2.97 @@ -333,7 +343,6 @@
    2.98          final boolean isParam = (flags & KINDMASK) == IS_PARAM;
    2.99          final boolean isVar =   (flags & KINDMASK) == IS_VAR;
   2.100  
   2.101 -        final FunctionNode function = lc.getFunction(block);
   2.102          if (symbol != null) {
   2.103              // Symbol was already defined. Check if it needs to be redefined.
   2.104              if (isParam) {
   2.105 @@ -345,10 +354,21 @@
   2.106                      throw new AssertionError("duplicate parameter");
   2.107                  }
   2.108              } else if (isVar) {
   2.109 -                if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
   2.110 +                if (isBlockScope) {
   2.111 +                    // Check redeclaration in same block
   2.112 +                    if (symbol.hasBeenDeclared()) {
   2.113 +                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
   2.114 +                    } else {
   2.115 +                        symbol.setHasBeenDeclared();
   2.116 +                    }
   2.117 +                } else if ((flags & IS_INTERNAL) != 0) {
   2.118                      // Always create a new definition.
   2.119                      symbol = null;
   2.120                  } else {
   2.121 +                    // Found LET or CONST in parent scope of same function - s SyntaxError
   2.122 +                    if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) {
   2.123 +                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
   2.124 +                    }
   2.125                      // Not defined in this function. Create a new definition.
   2.126                      if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
   2.127                          symbol = null;
   2.128 @@ -359,10 +379,10 @@
   2.129  
   2.130          if (symbol == null) {
   2.131              // If not found, then create a new one.
   2.132 -            Block symbolBlock;
   2.133 +            final Block symbolBlock;
   2.134  
   2.135              // Determine where to create it.
   2.136 -            if (isVar && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
   2.137 +            if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
   2.138                  symbolBlock = block; //internal vars are always defined in the block closest to them
   2.139              } else if (isGlobal) {
   2.140                  symbolBlock = lc.getOutermostFunction().getBody();
   2.141 @@ -420,9 +440,9 @@
   2.142      @Override
   2.143      public boolean enterBlock(final Block block) {
   2.144          start(block);
   2.145 -        block.clearSymbols();
   2.146  
   2.147          if (lc.isFunctionBody()) {
   2.148 +            block.clearSymbols();
   2.149              enterFunctionBody();
   2.150          }
   2.151  
   2.152 @@ -441,7 +461,10 @@
   2.153          // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its
   2.154          // symbol is naturally internal, and should be treated as such.
   2.155          final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName());
   2.156 -        defineSymbol(block, exname, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
   2.157 +        // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to
   2.158 +        // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block.
   2.159 +        final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
   2.160 +        symbol.clearFlag(IS_LET);
   2.161  
   2.162          return true;
   2.163      }
   2.164 @@ -452,15 +475,13 @@
   2.165  
   2.166          initFunctionWideVariables(functionNode, body);
   2.167  
   2.168 -        if (functionNode.isProgram()) {
   2.169 -            initGlobalSymbols(body);
   2.170 -        } else if (!functionNode.isDeclared() && !functionNode.isAnonymous()) {
   2.171 +        if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) {
   2.172              // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's
   2.173              // anonymous.
   2.174              final String name = functionNode.getIdent().getName();
   2.175              assert name != null;
   2.176              assert body.getExistingSymbol(name) == null;
   2.177 -            defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
   2.178 +            defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
   2.179              if(functionNode.allVarsInScope()) { // basically, has deep eval
   2.180                  lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
   2.181              }
   2.182 @@ -485,7 +506,8 @@
   2.183          if (functionNode.isDeclared()) {
   2.184              final Iterator<Block> blocks = lc.getBlocks();
   2.185              if (blocks.hasNext()) {
   2.186 -                defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
   2.187 +                final IdentNode ident = functionNode.getIdent();
   2.188 +                defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
   2.189              }
   2.190          }
   2.191  
   2.192 @@ -495,10 +517,16 @@
   2.193      @Override
   2.194      public boolean enterVarNode(final VarNode varNode) {
   2.195          start(varNode);
   2.196 -        defineSymbol(lc.getCurrentBlock(), varNode.getName().getName(), IS_VAR | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
   2.197          return true;
   2.198      }
   2.199  
   2.200 +    @Override
   2.201 +    public Node leaveVarNode(final VarNode varNode) {
   2.202 +        final IdentNode ident = varNode.getName();
   2.203 +        defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
   2.204 +        return super.leaveVarNode(varNode);
   2.205 +    }
   2.206 +
   2.207      private Symbol exceptionSymbol() {
   2.208          return newObjectInternal(EXCEPTION_PREFIX);
   2.209      }
   2.210 @@ -597,7 +625,7 @@
   2.211      }
   2.212  
   2.213      private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
   2.214 -        defineSymbol(block, cc.symbolName(), flags).setNeedsSlot(true);
   2.215 +        defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true);
   2.216      }
   2.217  
   2.218      private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
   2.219 @@ -608,7 +636,7 @@
   2.220              initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
   2.221              if (functionNode.needsArguments()) {
   2.222                  initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
   2.223 -                defineSymbol(body, ARGUMENTS_VAR.symbolName(), IS_VAR | HAS_OBJECT_VALUE);
   2.224 +                defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE);
   2.225              }
   2.226          }
   2.227  
   2.228 @@ -617,20 +645,6 @@
   2.229          initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL);
   2.230      }
   2.231  
   2.232 -
   2.233 -    /**
   2.234 -     * Move any properties from the global map into the scope of this function (which must be a program function).
   2.235 -     * @param block the function node body for which to init scope vars
   2.236 -     */
   2.237 -    private void initGlobalSymbols(final Block block) {
   2.238 -        final PropertyMap map = Context.getGlobalMap();
   2.239 -
   2.240 -        for (final Property property : map.getProperties()) {
   2.241 -            final Symbol symbol = defineGlobalSymbol(block, property.getKey());
   2.242 -            log.info("Added global symbol from property map ", symbol);
   2.243 -        }
   2.244 -    }
   2.245 -
   2.246      /**
   2.247       * Initialize parameters for function node.
   2.248       * @param functionNode the function node
   2.249 @@ -639,7 +653,7 @@
   2.250          final boolean isVarArg = functionNode.isVarArg();
   2.251          final boolean scopeParams = functionNode.allVarsInScope() || isVarArg;
   2.252          for (final IdentNode param : functionNode.getParameters()) {
   2.253 -            final Symbol symbol = defineSymbol(body, param.getName(), IS_PARAM);
   2.254 +            final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM);
   2.255              if(scopeParams) {
   2.256                  // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored.
   2.257                  // It will force creation of scopes where they would otherwise not necessarily be needed (functions
   2.258 @@ -665,10 +679,29 @@
   2.259          return definingFn == function;
   2.260      }
   2.261  
   2.262 +    private void checkConstAssignment(final IdentNode ident) {
   2.263 +        // Check for reassignment of constant
   2.264 +        final Symbol symbol = ident.getSymbol();
   2.265 +        if (symbol.isConst()) {
   2.266 +            throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident);
   2.267 +        }
   2.268 +    }
   2.269 +
   2.270      @Override
   2.271 -    public Node leaveASSIGN(final BinaryNode binaryNode) {
   2.272 +    public Node leaveBinaryNode(final BinaryNode binaryNode) {
   2.273 +        if (binaryNode.isAssignment() && binaryNode.lhs() instanceof IdentNode) {
   2.274 +            checkConstAssignment((IdentNode) binaryNode.lhs());
   2.275 +        }
   2.276 +        switch (binaryNode.tokenType()) {
   2.277 +        case ASSIGN:
   2.278 +            return leaveASSIGN(binaryNode);
   2.279 +        default:
   2.280 +            return super.leaveBinaryNode(binaryNode);
   2.281 +        }
   2.282 +    }
   2.283 +
   2.284 +    private Node leaveASSIGN(final BinaryNode binaryNode) {
   2.285          // If we're assigning a property of the this object ("this.foo = ..."), record it.
   2.286 -
   2.287          final Expression lhs = binaryNode.lhs();
   2.288          if (lhs instanceof AccessNode) {
   2.289              final AccessNode accessNode = (AccessNode) lhs;
   2.290 @@ -684,6 +717,21 @@
   2.291      }
   2.292  
   2.293      @Override
   2.294 +    public Node leaveUnaryNode(final UnaryNode unaryNode) {
   2.295 +        if (unaryNode.isAssignment() && unaryNode.getExpression() instanceof IdentNode) {
   2.296 +            checkConstAssignment((IdentNode) unaryNode.getExpression());
   2.297 +        }
   2.298 +        switch (unaryNode.tokenType()) {
   2.299 +        case DELETE:
   2.300 +            return leaveDELETE(unaryNode);
   2.301 +        case TYPEOF:
   2.302 +            return leaveTYPEOF(unaryNode);
   2.303 +        default:
   2.304 +            return super.leaveUnaryNode(unaryNode);
   2.305 +        }
   2.306 +    }
   2.307 +
   2.308 +    @Override
   2.309      public Node leaveBlock(final Block block) {
   2.310          // It's not necessary to guard the marking of symbols as locals with this "if"condition for correctness, it's
   2.311          // just an optimization -- runtime type calculation is not used when the compilation is not an on-demand
   2.312 @@ -699,8 +747,7 @@
   2.313          return block;
   2.314      }
   2.315  
   2.316 -    @Override
   2.317 -    public Node leaveDELETE(final UnaryNode unaryNode) {
   2.318 +    private Node leaveDELETE(final UnaryNode unaryNode) {
   2.319          final FunctionNode currentFunctionNode = lc.getCurrentFunction();
   2.320          final boolean      strictMode          = currentFunctionNode.isStrict();
   2.321          final Expression   rhs                 = unaryNode.getExpression();
   2.322 @@ -799,9 +846,8 @@
   2.323              // 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.324              maybeForceScope(symbol);
   2.325          } else {
   2.326 -            log.info("No symbol exists. Declare as global: ", symbol);
   2.327 -            symbol = defineGlobalSymbol(block, name);
   2.328 -            Symbol.setSymbolIsScope(lc, symbol);
   2.329 +            log.info("No symbol exists. Declare as global: ", name);
   2.330 +            symbol = defineSymbol(block, name, identNode, IS_GLOBAL | IS_SCOPE);
   2.331          }
   2.332  
   2.333          functionUsesSymbol(symbol);
   2.334 @@ -810,7 +856,15 @@
   2.335              symbol.increaseUseCount();
   2.336          }
   2.337  
   2.338 -        return end(identNode.setSymbol(symbol));
   2.339 +        IdentNode newIdentNode = identNode.setSymbol(symbol);
   2.340 +
   2.341 +        // If a block-scoped var is used before its declaration mark it as dead.
   2.342 +        // We can only statically detect this for local vars, cross-function symbols require runtime checks.
   2.343 +        if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
   2.344 +            newIdentNode = newIdentNode.markDead();
   2.345 +        }
   2.346 +
   2.347 +        return end(newIdentNode);
   2.348      }
   2.349  
   2.350      @Override
   2.351 @@ -834,8 +888,7 @@
   2.352          return tryNode;
   2.353      }
   2.354  
   2.355 -    @Override
   2.356 -    public Node leaveTYPEOF(final UnaryNode unaryNode) {
   2.357 +    private Node leaveTYPEOF(final UnaryNode unaryNode) {
   2.358          final Expression rhs = unaryNode.getExpression();
   2.359  
   2.360          final List<Expression> args = new ArrayList<>();
   2.361 @@ -875,7 +928,7 @@
   2.362      }
   2.363  
   2.364      private Symbol newInternal(final CompilerConstants cc, final int flags) {
   2.365 -        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), IS_VAR | IS_INTERNAL | flags); //NASHORN-73
   2.366 +        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73
   2.367      }
   2.368  
   2.369      private Symbol newObjectInternal(final CompilerConstants cc) {
   2.370 @@ -915,7 +968,8 @@
   2.371              return false;
   2.372          }
   2.373  
   2.374 -        if (lc.getCurrentFunction().allVarsInScope()) {
   2.375 +        final FunctionNode func = lc.getCurrentFunction();
   2.376 +        if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) {
   2.377              return true;
   2.378          }
   2.379  
   2.380 @@ -955,4 +1009,16 @@
   2.381          final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits();
   2.382          return !(units == null || units.isEmpty());
   2.383      }
   2.384 +
   2.385 +    private void throwParserException(final String message, final Node origin) {
   2.386 +        if (origin == null) {
   2.387 +            throw new ParserException(message);
   2.388 +        }
   2.389 +        final Source source = compiler.getSource();
   2.390 +        final long token = origin.getToken();
   2.391 +        final int line = source.getLine(origin.getStart());
   2.392 +        final int column = source.getColumn(origin.getStart());
   2.393 +        final String formatted = ErrorManager.format(message, source, line, column, token);
   2.394 +        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token);
   2.395 +    }
   2.396  }
     3.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Sep 03 14:33:34 2014 +0200
     3.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Sep 04 18:47:18 2014 +0200
     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 14:33:34 2014 +0200
     4.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Thu Sep 04 18:47:18 2014 +0200
     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 14:33:34 2014 +0200
     5.2 +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Thu Sep 04 18:47:18 2014 +0200
     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 14:33:34 2014 +0200
     6.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java	Thu Sep 04 18:47:18 2014 +0200
     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 14:33:34 2014 +0200
     7.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu Sep 04 18:47:18 2014 +0200
     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/TypeEvaluator.java	Wed Sep 03 14:33:34 2014 +0200
     8.2 +++ b/src/jdk/nashorn/internal/codegen/TypeEvaluator.java	Thu Sep 04 18:47:18 2014 +0200
     8.3 @@ -108,7 +108,7 @@
     8.4  
     8.5          // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed
     8.6          // integer).
     8.7 -        final Object value = property.getObjectValue(owner, owner);
     8.8 +        final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner);
     8.9          if (value == ScriptRuntime.UNDEFINED) {
    8.10              return null;
    8.11          }
     9.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Wed Sep 03 14:33:34 2014 +0200
     9.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Sep 04 18:47:18 2014 +0200
     9.3 @@ -138,10 +138,6 @@
     9.4      /** Last token of function. **/
     9.5      private final long lastToken;
     9.6  
     9.7 -    /** Declared symbols in this function node */
     9.8 -    @Ignore
     9.9 -    private final Set<Symbol> declaredSymbols;
    9.10 -
    9.11      /** Method's namespace. */
    9.12      private final Namespace namespace;
    9.13  
    9.14 @@ -330,7 +326,6 @@
    9.15          this.lastToken        = token;
    9.16          this.namespace        = namespace;
    9.17          this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
    9.18 -        this.declaredSymbols  = new HashSet<>();
    9.19          this.flags            = flags;
    9.20          this.compileUnit      = null;
    9.21          this.body             = null;
    9.22 @@ -369,7 +364,6 @@
    9.23          this.id              = functionNode.id;
    9.24          this.ident           = functionNode.ident;
    9.25          this.namespace       = functionNode.namespace;
    9.26 -        this.declaredSymbols = functionNode.declaredSymbols;
    9.27          this.kind            = functionNode.kind;
    9.28          this.firstToken      = functionNode.firstToken;
    9.29      }
    9.30 @@ -724,24 +718,6 @@
    9.31      }
    9.32  
    9.33      /**
    9.34 -     * Return a set of symbols declared in this function node. This
    9.35 -     * is only relevant after Attr, otherwise it will be an empty
    9.36 -     * set as no symbols have been introduced
    9.37 -     * @return set of declared symbols in function
    9.38 -     */
    9.39 -    public Set<Symbol> getDeclaredSymbols() {
    9.40 -        return Collections.unmodifiableSet(declaredSymbols);
    9.41 -    }
    9.42 -
    9.43 -    /**
    9.44 -     * Add a declared symbol to this function node
    9.45 -     * @param symbol symbol that is declared
    9.46 -     */
    9.47 -    public void addDeclaredSymbol(final Symbol symbol) {
    9.48 -        declaredSymbols.add(symbol);
    9.49 -    }
    9.50 -
    9.51 -    /**
    9.52       * Get the function body
    9.53       * @return the function body
    9.54       */
    9.55 @@ -970,13 +946,13 @@
    9.56      }
    9.57  
    9.58      /**
    9.59 -     * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
    9.60 +     * Check if this function should have all its variables in its own scope. Split sub-functions, and
    9.61       * functions having with and/or eval blocks are such.
    9.62       *
    9.63       * @return true if all variables should be in scope
    9.64       */
    9.65      public boolean allVarsInScope() {
    9.66 -        return isProgram() || getFlag(HAS_ALL_VARS_IN_SCOPE);
    9.67 +        return getFlag(HAS_ALL_VARS_IN_SCOPE);
    9.68      }
    9.69  
    9.70      /**
    10.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java	Wed Sep 03 14:33:34 2014 +0200
    10.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java	Thu Sep 04 18:47:18 2014 +0200
    10.3 @@ -46,6 +46,8 @@
    10.4      private static final int INITIALIZED_HERE  = 1 << 1;
    10.5      private static final int FUNCTION          = 1 << 2;
    10.6      private static final int FUTURESTRICT_NAME = 1 << 3;
    10.7 +    private static final int IS_DECLARED_HERE  = 1 << 4;
    10.8 +    private static final int IS_DEAD           = 1 << 5;
    10.9  
   10.10      /** Identifier. */
   10.11      private final String name;
   10.12 @@ -247,6 +249,45 @@
   10.13      }
   10.14  
   10.15      /**
   10.16 +     * Is this a LET or CONST identifier used before its declaration?
   10.17 +     *
   10.18 +     * @return true if identifier is dead
   10.19 +     */
   10.20 +    public boolean isDead() {
   10.21 +        return (flags & IS_DEAD) != 0;
   10.22 +    }
   10.23 +
   10.24 +    /**
   10.25 +     * Flag this IdentNode as a LET or CONST identifier used before its declaration.
   10.26 +     *
   10.27 +     * @return a new IdentNode equivalent to this but marked as dead.
   10.28 +     */
   10.29 +    public IdentNode markDead() {
   10.30 +        return new IdentNode(this, name, type, flags | IS_DEAD, programPoint, conversion);
   10.31 +    }
   10.32 +
   10.33 +    /**
   10.34 +     * Is this IdentNode declared here?
   10.35 +     *
   10.36 +     * @return true if identifier is declared here
   10.37 +     */
   10.38 +    public boolean isDeclaredHere() {
   10.39 +        return (flags & IS_DECLARED_HERE) != 0;
   10.40 +    }
   10.41 +
   10.42 +    /**
   10.43 +     * Flag this IdentNode as being declared here.
   10.44 +     *
   10.45 +     * @return a new IdentNode equivalent to this but marked as declared here.
   10.46 +     */
   10.47 +    public IdentNode setIsDeclaredHere() {
   10.48 +        if (isDeclaredHere()) {
   10.49 +            return this;
   10.50 +        }
   10.51 +        return new IdentNode(this, name, type, flags | IS_DECLARED_HERE, programPoint, conversion);
   10.52 +    }
   10.53 +
   10.54 +    /**
   10.55       * Check if the name of this IdentNode is same as that of a compile-time property (currently __DIR__, __FILE__, and
   10.56       * __LINE__).
   10.57       *
    11.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java	Wed Sep 03 14:33:34 2014 +0200
    11.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java	Thu Sep 04 18:47:18 2014 +0200
    11.3 @@ -54,17 +54,17 @@
    11.4      public static final int IS_VAR      = 2;
    11.5      /** Is this a parameter */
    11.6      public static final int IS_PARAM    = 3;
    11.7 -    /** Is this a constant */
    11.8 -    public static final int IS_CONSTANT = 4;
    11.9      /** Mask for kind flags */
   11.10 -    public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits
   11.11 +    public static final int KINDMASK = (1 << 2) - 1; // Kinds are represented by lower two bits
   11.12  
   11.13      /** Is this symbol in scope */
   11.14 -    public static final int IS_SCOPE                = 1 <<  3;
   11.15 +    public static final int IS_SCOPE                = 1 <<  2;
   11.16      /** Is this a this symbol */
   11.17 -    public static final int IS_THIS                 = 1 <<  4;
   11.18 +    public static final int IS_THIS                 = 1 <<  3;
   11.19      /** Is this a let */
   11.20 -    public static final int IS_LET                  = 1 <<  5;
   11.21 +    public static final int IS_LET                  = 1 <<  4;
   11.22 +    /** Is this a const */
   11.23 +    public static final int IS_CONST                = 1 <<  5;
   11.24      /** Is this an internal symbol, never represented explicitly in source code */
   11.25      public static final int IS_INTERNAL             = 1 <<  6;
   11.26      /** Is this a function self-reference symbol */
   11.27 @@ -83,6 +83,8 @@
   11.28      public static final int HAS_DOUBLE_VALUE        = 1 << 13;
   11.29      /** Is this symbol known to store an object value ? */
   11.30      public static final int HAS_OBJECT_VALUE        = 1 << 14;
   11.31 +    /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
   11.32 +    public static final int HAS_BEEN_DECLARED       = 1 << 15;
   11.33  
   11.34      /** Null or name identifying symbol. */
   11.35      private final String name;
   11.36 @@ -184,14 +186,17 @@
   11.37              sb.append(" global");
   11.38              break;
   11.39          case IS_VAR:
   11.40 -            sb.append(" var");
   11.41 +            if (isConst()) {
   11.42 +                sb.append(" const");
   11.43 +            } else if (isLet()) {
   11.44 +                sb.append(" let");
   11.45 +            } else {
   11.46 +                sb.append(" var");
   11.47 +            }
   11.48              break;
   11.49          case IS_PARAM:
   11.50              sb.append(" param");
   11.51              break;
   11.52 -        case IS_CONSTANT:
   11.53 -            sb.append(" const");
   11.54 -            break;
   11.55          default:
   11.56              break;
   11.57          }
   11.58 @@ -204,10 +209,6 @@
   11.59              sb.append(" internal");
   11.60          }
   11.61  
   11.62 -        if (isLet()) {
   11.63 -            sb.append(" let");
   11.64 -        }
   11.65 -
   11.66          if (isThis()) {
   11.67              sb.append(" this");
   11.68          }
   11.69 @@ -410,8 +411,8 @@
   11.70       * Check if this symbol is a constant
   11.71       * @return true if a constant
   11.72       */
   11.73 -    public boolean isConstant() {
   11.74 -        return (flags & KINDMASK) == IS_CONSTANT;
   11.75 +    public boolean isConst() {
   11.76 +        return (flags & IS_CONST) != 0;
   11.77      }
   11.78  
   11.79      /**
   11.80 @@ -440,15 +441,6 @@
   11.81      }
   11.82  
   11.83      /**
   11.84 -     * Flag this symbol as a let
   11.85 -     */
   11.86 -    public void setIsLet() {
   11.87 -        if (!isLet()) {
   11.88 -            flags |= IS_LET;
   11.89 -        }
   11.90 -    }
   11.91 -
   11.92 -    /**
   11.93       * Flag this symbol as a function's self-referencing symbol.
   11.94       * @return true if this symbol as a function's self-referencing symbol.
   11.95       */
   11.96 @@ -456,6 +448,20 @@
   11.97          return (flags & IS_FUNCTION_SELF) != 0;
   11.98      }
   11.99  
  11.100 +    public boolean isBlockScoped() {
  11.101 +        return isLet() || isConst();
  11.102 +    }
  11.103 +
  11.104 +    public boolean hasBeenDeclared() {
  11.105 +        return (flags & HAS_BEEN_DECLARED) != 0;
  11.106 +    }
  11.107 +
  11.108 +    public void setHasBeenDeclared() {
  11.109 +        if (!hasBeenDeclared()) {
  11.110 +            flags |= HAS_BEEN_DECLARED;
  11.111 +        }
  11.112 +    }
  11.113 +
  11.114      /**
  11.115       * Get the index of the field used to store this symbol, should it be an AccessorProperty
  11.116       * and get allocated in a JO-prefixed ScriptObject subclass.
    12.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java	Wed Sep 03 14:33:34 2014 +0200
    12.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java	Thu Sep 04 18:47:18 2014 +0200
    12.3 @@ -27,6 +27,7 @@
    12.4  
    12.5  import jdk.nashorn.internal.ir.annotations.Immutable;
    12.6  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    12.7 +import jdk.nashorn.internal.parser.Token;
    12.8  
    12.9  /**
   12.10   * Node represents a var/let declaration.
   12.11 @@ -43,12 +44,18 @@
   12.12      private final int flags;
   12.13  
   12.14      /** Flag that determines if this function node is a statement */
   12.15 -    public static final int IS_STATEMENT = 1 << 0;
   12.16 +    public static final int IS_STATEMENT                 = 1 << 0;
   12.17 +
   12.18 +    /** Flag for ES6 LET declaration */
   12.19 +    public static final int IS_LET                       = 1 << 1;
   12.20 +
   12.21 +    /** Flag for ES6 CONST declaration */
   12.22 +    public static final int IS_CONST                     = 1 << 2;
   12.23  
   12.24      /** Flag that determines if this is the last function declaration in a function
   12.25       *  This is used to micro optimize the placement of return value assignments for
   12.26       *  a program node */
   12.27 -    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1;
   12.28 +    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 3;
   12.29  
   12.30      /**
   12.31       * Constructor
   12.32 @@ -109,6 +116,43 @@
   12.33      }
   12.34  
   12.35      /**
   12.36 +     * Is this a VAR node block scoped? This returns true for ECMAScript 6 LET and CONST nodes.
   12.37 +     * @return true if an ES6 LET or CONST node
   12.38 +     */
   12.39 +    public boolean isBlockScoped() {
   12.40 +        return getFlag(IS_LET) || getFlag(IS_CONST);
   12.41 +    }
   12.42 +
   12.43 +    /**
   12.44 +     * Is this an ECMAScript 6 LET node?
   12.45 +     * @return true if LET node
   12.46 +     */
   12.47 +    public boolean isLet() {
   12.48 +        return getFlag(IS_LET);
   12.49 +    }
   12.50 +
   12.51 +    /**
   12.52 +     * Is this an ECMAScript 6 CONST node?
   12.53 +     * @return true if CONST node
   12.54 +     */
   12.55 +    public boolean isConst() {
   12.56 +        return getFlag(IS_CONST);
   12.57 +    }
   12.58 +
   12.59 +    /**
   12.60 +     * Return the flags to use for symbols for this declaration.
   12.61 +     * @return the symbol flags
   12.62 +     */
   12.63 +    public int getSymbolFlags() {
   12.64 +        if (isLet()) {
   12.65 +            return Symbol.IS_VAR | Symbol.IS_LET;
   12.66 +        } else if (isConst()) {
   12.67 +            return Symbol.IS_VAR | Symbol.IS_CONST;
   12.68 +        }
   12.69 +        return Symbol.IS_VAR;
   12.70 +    }
   12.71 +
   12.72 +    /**
   12.73       * Does this variable declaration have an init value
   12.74       * @return true if an init exists, false otherwise
   12.75       */
   12.76 @@ -139,7 +183,7 @@
   12.77  
   12.78      @Override
   12.79      public void toString(final StringBuilder sb, final boolean printType) {
   12.80 -        sb.append("var ");
   12.81 +        sb.append(Token.descType(getToken()).getName()).append(' ');
   12.82          name.toString(sb, printType);
   12.83  
   12.84          if (init != null) {
    13.1 --- a/src/jdk/nashorn/internal/parser/Parser.java	Wed Sep 03 14:33:34 2014 +0200
    13.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java	Thu Sep 04 18:47:18 2014 +0200
    13.3 @@ -45,6 +45,7 @@
    13.4  import static jdk.nashorn.internal.parser.TokenType.IF;
    13.5  import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    13.6  import static jdk.nashorn.internal.parser.TokenType.LBRACE;
    13.7 +import static jdk.nashorn.internal.parser.TokenType.LET;
    13.8  import static jdk.nashorn.internal.parser.TokenType.LPAREN;
    13.9  import static jdk.nashorn.internal.parser.TokenType.RBRACE;
   13.10  import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
   13.11 @@ -579,6 +580,10 @@
   13.12          }
   13.13      }
   13.14  
   13.15 +    private boolean useBlockScope() {
   13.16 +        return env._es6;
   13.17 +    }
   13.18 +
   13.19      private static boolean isArguments(final String name) {
   13.20          return ARGUMENTS_NAME.equals(name);
   13.21      }
   13.22 @@ -694,9 +699,20 @@
   13.23              FunctionNode.Kind.SCRIPT,
   13.24              functionLine);
   13.25  
   13.26 +        // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations.
   13.27 +        final int startLine = start;
   13.28 +        Block outer = useBlockScope() ? newBlock() : null;
   13.29          functionDeclarations = new ArrayList<>();
   13.30 -        sourceElements(allowPropertyFunction);
   13.31 -        addFunctionDeclarations(script);
   13.32 +
   13.33 +        try {
   13.34 +            sourceElements(allowPropertyFunction);
   13.35 +            addFunctionDeclarations(script);
   13.36 +        } finally {
   13.37 +            if (outer != null) {
   13.38 +                outer = restoreBlock(outer);
   13.39 +                appendStatement(new BlockStatement(startLine, outer));
   13.40 +            }
   13.41 +        }
   13.42          functionDeclarations = null;
   13.43  
   13.44          expect(EOF);
   13.45 @@ -868,7 +884,7 @@
   13.46              block();
   13.47              break;
   13.48          case VAR:
   13.49 -            variableStatement(true);
   13.50 +            variableStatement(type, true);
   13.51              break;
   13.52          case SEMICOLON:
   13.53              emptyStatement();
   13.54 @@ -918,8 +934,12 @@
   13.55              expect(SEMICOLON);
   13.56              break;
   13.57          default:
   13.58 +            if (useBlockScope() && (type == LET || type == CONST)) {
   13.59 +                variableStatement(type, true);
   13.60 +                break;
   13.61 +            }
   13.62              if (env._const_as_var && type == CONST) {
   13.63 -                variableStatement(true);
   13.64 +                variableStatement(TokenType.VAR, true);
   13.65                  break;
   13.66              }
   13.67  
   13.68 @@ -1035,11 +1055,17 @@
   13.69       * Parse a VAR statement.
   13.70       * @param isStatement True if a statement (not used in a FOR.)
   13.71       */
   13.72 -    private List<VarNode> variableStatement(final boolean isStatement) {
   13.73 +    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
   13.74          // VAR tested in caller.
   13.75          next();
   13.76  
   13.77          final List<VarNode> vars = new ArrayList<>();
   13.78 +        int varFlags = VarNode.IS_STATEMENT;
   13.79 +        if (varType == LET) {
   13.80 +            varFlags |= VarNode.IS_LET;
   13.81 +        } else if (varType == CONST) {
   13.82 +            varFlags |= VarNode.IS_CONST;
   13.83 +        }
   13.84  
   13.85          while (true) {
   13.86              // Get starting token.
   13.87 @@ -1063,10 +1089,12 @@
   13.88                  } finally {
   13.89                      defaultNames.pop();
   13.90                  }
   13.91 +            } else if (varType == CONST) {
   13.92 +                throw error(AbstractParser.message("missing.const.assignment", name.getName()));
   13.93              }
   13.94  
   13.95              // Allocate var node.
   13.96 -            final VarNode var = new VarNode(varLine, varToken, finish, name, init);
   13.97 +            final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
   13.98              vars.add(var);
   13.99              appendStatement(var);
  13.100  
  13.101 @@ -1180,9 +1208,12 @@
  13.102       * Parse a FOR statement.
  13.103       */
  13.104      private void forStatement() {
  13.105 +        // When ES6 for-let is enabled we create a container block to capture the LET.
  13.106 +        final int startLine = start;
  13.107 +        Block outer = useBlockScope() ? newBlock() : null;
  13.108 +
  13.109          // Create FOR node, capturing FOR token.
  13.110          ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR);
  13.111 -
  13.112          lc.push(forNode);
  13.113  
  13.114          try {
  13.115 @@ -1203,14 +1234,19 @@
  13.116              switch (type) {
  13.117              case VAR:
  13.118                  // Var statements captured in for outer block.
  13.119 -                vars = variableStatement(false);
  13.120 +                vars = variableStatement(type, false);
  13.121                  break;
  13.122              case SEMICOLON:
  13.123                  break;
  13.124              default:
  13.125 +                if (useBlockScope() && (type == LET || type == CONST)) {
  13.126 +                    // LET/CONST captured in container block created above.
  13.127 +                    vars = variableStatement(type, false);
  13.128 +                    break;
  13.129 +                }
  13.130                  if (env._const_as_var && type == CONST) {
  13.131                      // Var statements captured in for outer block.
  13.132 -                    vars = variableStatement(false);
  13.133 +                    vars = variableStatement(TokenType.VAR, false);
  13.134                      break;
  13.135                  }
  13.136  
  13.137 @@ -1290,8 +1326,13 @@
  13.138              appendStatement(forNode);
  13.139          } finally {
  13.140              lc.pop(forNode);
  13.141 +            if (outer != null) {
  13.142 +                outer.setFinish(forNode.getFinish());
  13.143 +                outer = restoreBlock(outer);
  13.144 +                appendStatement(new BlockStatement(startLine, outer));
  13.145 +            }
  13.146          }
  13.147 -     }
  13.148 +    }
  13.149  
  13.150      /**
  13.151       * ... IterationStatement :
  13.152 @@ -1722,7 +1763,7 @@
  13.153          }
  13.154      }
  13.155  
  13.156 -   /**
  13.157 +    /**
  13.158       * ThrowStatement :
  13.159       *      throw Expression ; // [no LineTerminator here]
  13.160       *
  13.161 @@ -2609,7 +2650,7 @@
  13.162          FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine);
  13.163  
  13.164          if (isStatement) {
  13.165 -            if (topLevel) {
  13.166 +            if (topLevel || useBlockScope()) {
  13.167                  functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
  13.168              } else if (isStrictMode) {
  13.169                  throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
  13.170 @@ -2661,9 +2702,16 @@
  13.171          }
  13.172  
  13.173          if (isStatement) {
  13.174 -            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
  13.175 +            int varFlags = VarNode.IS_STATEMENT;
  13.176 +            if (!topLevel && useBlockScope()) {
  13.177 +                // mark ES6 block functions as lexically scoped
  13.178 +                varFlags |= VarNode.IS_LET;
  13.179 +            }
  13.180 +            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags);
  13.181              if (topLevel) {
  13.182                  functionDeclarations.add(varNode);
  13.183 +            } else if (useBlockScope()) {
  13.184 +                prependStatement(varNode); // Hoist to beginning of current block
  13.185              } else {
  13.186                  appendStatement(varNode);
  13.187              }
  13.188 @@ -2838,7 +2886,6 @@
  13.189      }
  13.190  
  13.191      private void addFunctionDeclarations(final FunctionNode functionNode) {
  13.192 -        assert lc.peek() == lc.getFunctionBody(functionNode);
  13.193          VarNode lastDecl = null;
  13.194          for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
  13.195              Statement decl = functionDeclarations.get(i);
    14.1 --- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Wed Sep 03 14:33:34 2014 +0200
    14.2 +++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Thu Sep 04 18:47:18 2014 +0200
    14.3 @@ -549,6 +549,8 @@
    14.4                  type == Object.class :
    14.5                  "invalid getter type " + type + " for " + getKey();
    14.6  
    14.7 +        checkUndeclared();
    14.8 +
    14.9          //all this does is add a return value filter for object fields only
   14.10          final MethodHandle[] getterCache = GETTER_CACHE;
   14.11          final MethodHandle cachedGetter = getterCache[i];
   14.12 @@ -579,6 +581,8 @@
   14.13              return getOptimisticPrimitiveGetter(type, programPoint);
   14.14          }
   14.15  
   14.16 +        checkUndeclared();
   14.17 +
   14.18          return debug(
   14.19              createGetter(
   14.20                  getCurrentType(),
   14.21 @@ -608,6 +612,13 @@
   14.22          return newMap;
   14.23      }
   14.24  
   14.25 +    private void checkUndeclared() {
   14.26 +        if ((getFlags() & NEEDS_DECLARATION) != 0) {
   14.27 +            // a lexically defined variable that hasn't seen its declaration - throw ReferenceError
   14.28 +            throw ECMAErrors.referenceError("not.defined", getKey());
   14.29 +        }
   14.30 +    }
   14.31 +
   14.32      // the final three arguments are for debug printout purposes only
   14.33      @SuppressWarnings("unused")
   14.34      private static Object replaceMap(final Object sobj, final PropertyMap newMap) {
   14.35 @@ -635,13 +646,14 @@
   14.36  
   14.37      @Override
   14.38      public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
   14.39 -        final int      i       = getAccessorTypeIndex(type);
   14.40 -        final int      ci      = isUndefined() ? -1 : getAccessorTypeIndex(getCurrentType());
   14.41 -        final Class<?> forType = isUndefined() ? type : getCurrentType();
   14.42 +        checkUndeclared();
   14.43 +
   14.44 +        final int typeIndex        = getAccessorTypeIndex(type);
   14.45 +        final int currentTypeIndex = getAccessorTypeIndex(getCurrentType());
   14.46  
   14.47          //if we are asking for an object setter, but are still a primitive type, we might try to box it
   14.48          MethodHandle mh;
   14.49 -        if (needsInvalidator(i, ci)) {
   14.50 +        if (needsInvalidator(typeIndex, currentTypeIndex)) {
   14.51              final Property     newProperty = getWiderProperty(type);
   14.52              final PropertyMap  newMap      = getWiderMap(currentMap, newProperty);
   14.53  
   14.54 @@ -652,6 +664,7 @@
   14.55                   mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh);
   14.56              }
   14.57          } else {
   14.58 +            final Class<?> forType = isUndefined() ? type : getCurrentType();
   14.59              mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type);
   14.60          }
   14.61  
   14.62 @@ -692,11 +705,12 @@
   14.63          if (OBJECT_FIELDS_ONLY) {
   14.64              return false;
   14.65          }
   14.66 -        return getCurrentType() != Object.class && (isConfigurable() || isWritable());
   14.67 +        // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
   14.68 +        return getCurrentType() == null || (getCurrentType() != Object.class && (isConfigurable() || isWritable()));
   14.69      }
   14.70  
   14.71 -    private boolean needsInvalidator(final int ti, final int fti) {
   14.72 -        return canChangeType() && ti > fti;
   14.73 +    private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) {
   14.74 +        return canChangeType() && typeIndex > currentTypeIndex;
   14.75      }
   14.76  
   14.77      @Override
    15.1 --- a/src/jdk/nashorn/internal/runtime/Context.java	Wed Sep 03 14:33:34 2014 +0200
    15.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java	Thu Sep 04 18:47:18 2014 +0200
    15.3 @@ -1132,7 +1132,7 @@
    15.4          if (storedScript == null) {
    15.5              functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
    15.6  
    15.7 -            if (errors.hasErrors()) {
    15.8 +            if (errMan.hasErrors()) {
    15.9                  return null;
   15.10              }
   15.11  
   15.12 @@ -1162,9 +1162,13 @@
   15.13                      env,
   15.14                      installer,
   15.15                      source,
   15.16 +                    errMan,
   15.17                      strict | functionNode.isStrict());
   15.18  
   15.19              final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
   15.20 +            if (errMan.hasErrors()) {
   15.21 +                return null;
   15.22 +            }
   15.23              script = compiledFunction.getRootClass();
   15.24              compiler.persistClassInfo(cacheKey, compiledFunction);
   15.25          } else {
    16.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Wed Sep 03 14:33:34 2014 +0200
    16.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Thu Sep 04 18:47:18 2014 +0200
    16.3 @@ -58,6 +58,18 @@
    16.4      }
    16.5  
    16.6      /**
    16.7 +     * Return a copy of this FindProperty with a different property.
    16.8 +     *
    16.9 +     * @param newProperty the new property
   16.10 +     * @return the new FindProperty instance
   16.11 +     */
   16.12 +    public FindProperty replaceProperty(final Property newProperty) {
   16.13 +        assert this.property.getKey().equals(newProperty.getKey());
   16.14 +        assert this.property.getSlot() == newProperty.getSlot();
   16.15 +        return new FindProperty(self, prototype, newProperty);
   16.16 +    }
   16.17 +
   16.18 +    /**
   16.19       * Ask for a getter that returns the given type. The type has nothing to do with the
   16.20       * internal representation of the property. It may be an Object (boxing primitives) or
   16.21       * a primitive (primitive fields with -Dnashorn.fields.dual=true)
    17.1 --- a/src/jdk/nashorn/internal/runtime/Property.java	Wed Sep 03 14:33:34 2014 +0200
    17.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java	Thu Sep 04 18:47:18 2014 +0200
    17.3 @@ -82,11 +82,14 @@
    17.4       * is narrower than object, e.g. Math.PI which is declared
    17.5       * as a double
    17.6       */
    17.7 -    public static final int IS_NASGEN_PRIMITIVE = 1 << 6;
    17.8 +    public static final int IS_NASGEN_PRIMITIVE     = 1 << 6;
    17.9  
   17.10      /** Is this property bound to a receiver? This means get/set operations will be delegated to
   17.11       *  a statically defined object instead of the object passed as callsite parameter. */
   17.12 -    public static final int IS_BOUND = 1 << 8;
   17.13 +    public static final int IS_BOUND                = 1 << 7;
   17.14 +
   17.15 +    /** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */
   17.16 +    public static final int NEEDS_DECLARATION       = 1 << 8;
   17.17  
   17.18      /** Property key. */
   17.19      private final String key;
   17.20 @@ -287,6 +290,15 @@
   17.21      }
   17.22  
   17.23      /**
   17.24 +     * Is this a LET or CONST property that needs to see its declaration before being usable?
   17.25 +     *
   17.26 +     * @return true if this is a block-scoped variable
   17.27 +     */
   17.28 +    public boolean needsDeclaration() {
   17.29 +        return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION;
   17.30 +    }
   17.31 +
   17.32 +    /**
   17.33       * Add more property flags to the property. Properties are immutable here,
   17.34       * so any property change that results in a larger flag set results in the
   17.35       * property being cloned. Use only the return value
    18.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Wed Sep 03 14:33:34 2014 +0200
    18.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Sep 04 18:47:18 2014 +0200
    18.3 @@ -394,6 +394,7 @@
    18.4                  context.getEnv(),
    18.5                  installer,
    18.6                  functionNode.getSource(),  // source
    18.7 +                context.getErrorManager(),
    18.8                  isStrict() | functionNode.isStrict(), // is strict
    18.9                  true,       // is on demand
   18.10                  this,       // compiledFunction, i.e. this RecompilableScriptFunctionData
    19.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Wed Sep 03 14:33:34 2014 +0200
    19.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Thu Sep 04 18:47:18 2014 +0200
    19.3 @@ -94,6 +94,9 @@
    19.4      /** Use single Global instance per jsr223 engine instance. */
    19.5      public final boolean _global_per_engine;
    19.6  
    19.7 +    /** Enable experimental ECMAScript 6 features. */
    19.8 +    public final boolean _es6;
    19.9 +
   19.10      /** Argument passed to compile only if optimistic compilation should take place */
   19.11      public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
   19.12  
   19.13 @@ -258,6 +261,15 @@
   19.14          _version              = options.getBoolean("version");
   19.15          _verify_code          = options.getBoolean("verify.code");
   19.16  
   19.17 +        final String language = options.getString("language");
   19.18 +        if (language == null || language.equals("es5")) {
   19.19 +            _es6 = false;
   19.20 +        } else if (language.equals("es6")) {
   19.21 +            _es6 = true;
   19.22 +        } else {
   19.23 +            throw new RuntimeException("Unsupported language: " + language);
   19.24 +        }
   19.25 +
   19.26          String dir = null;
   19.27          String func = null;
   19.28          final String pc = options.getString("print.code");
    20.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Wed Sep 03 14:33:34 2014 +0200
    20.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Sep 04 18:47:18 2014 +0200
    20.3 @@ -158,6 +158,7 @@
    20.4  
    20.5      static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
    20.6      static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
    20.7 +    static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
    20.8  
    20.9      private static final MethodHandle TRUNCATINGFILTER   = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
   20.10      private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
   20.11 @@ -2027,6 +2028,22 @@
   20.12          return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
   20.13      }
   20.14  
   20.15 +    // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
   20.16 +    @SuppressWarnings("unused")
   20.17 +    private void declareAndSet(final String key, final Object value) {
   20.18 +        final PropertyMap map = getMap();
   20.19 +        final FindProperty find = findProperty(key, false);
   20.20 +        assert find != null;
   20.21 +
   20.22 +        final Property property = find.getProperty();
   20.23 +        assert property != null;
   20.24 +        assert property.needsDeclaration();
   20.25 +
   20.26 +        final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
   20.27 +        setMap(newMap);
   20.28 +        set(key, value, true);
   20.29 +    }
   20.30 +
   20.31      /**
   20.32       * Find the appropriate GETINDEX method for an invoke dynamic call.
   20.33       *
   20.34 @@ -2140,7 +2157,7 @@
   20.35          }
   20.36  
   20.37          if (find != null) {
   20.38 -            if (!find.getProperty().isWritable()) {
   20.39 +            if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) {
   20.40                  // Existing, non-writable property
   20.41                  return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
   20.42              }
    21.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Wed Sep 03 14:33:34 2014 +0200
    21.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Thu Sep 04 18:47:18 2014 +0200
    21.3 @@ -108,6 +108,11 @@
    21.4      public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
    21.5  
    21.6      /**
    21.7 +     * Throws a reference error for an undefined variable.
    21.8 +     */
    21.9 +    public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
   21.10 +
   21.11 +    /**
   21.12       * Converts a switch tag value to a simple integer. deflt value if it can't.
   21.13       *
   21.14       * @param tag   Switch statement tag value.
   21.15 @@ -382,6 +387,15 @@
   21.16      }
   21.17  
   21.18      /**
   21.19 +     * Throws a reference error for an undefined variable.
   21.20 +     *
   21.21 +     * @param name the variable name
   21.22 +     */
   21.23 +    public static void throwReferenceError(final String name) {
   21.24 +        throw referenceError("not.defined", name);
   21.25 +    }
   21.26 +
   21.27 +    /**
   21.28       * Call a script function as a constructor with given args.
   21.29       *
   21.30       * @param target ScriptFunction object.
    22.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Sep 03 14:33:34 2014 +0200
    22.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Thu Sep 04 18:47:18 2014 +0200
    22.3 @@ -140,7 +140,29 @@
    22.4  
    22.5      private SetMethod createExistingPropertySetter() {
    22.6          final Property property = find.getProperty();
    22.7 -        final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
    22.8 +        final MethodHandle methodHandle;
    22.9 +
   22.10 +        if (NashornCallSiteDescriptor.isDeclaration(desc)) {
   22.11 +            assert property.needsDeclaration();
   22.12 +            // This is a LET or CONST being declared. The property is already there but flagged as needing declaration.
   22.13 +            // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set
   22.14 +            // method if the pre-callsite map is stable (which should be the case for function scopes except for
   22.15 +            // non-strict functions containing eval() with var). Otherwise we have to use a slow setter that creates
   22.16 +            // a new PropertyMap on the fly.
   22.17 +            final PropertyMap oldMap = getMap();
   22.18 +            final Property newProperty = property.removeFlags(Property.NEEDS_DECLARATION);
   22.19 +            final PropertyMap newMap = oldMap.replaceProperty(property, newProperty);
   22.20 +            final MethodHandle fastSetter = find.replaceProperty(newProperty).getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
   22.21 +            final MethodHandle slowSetter = MH.insertArguments(ScriptObject.DECLARE_AND_SET, 1, getName()).asType(fastSetter.type());
   22.22 +
   22.23 +            // cas map used as guard, if true that means we can do the set fast
   22.24 +            MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
   22.25 +            casMap = MH.dropArguments(casMap, 1, type);
   22.26 +            casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
   22.27 +            methodHandle = MH.guardWithTest(casMap, fastSetter, slowSetter);
   22.28 +        } else {
   22.29 +            methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
   22.30 +        }
   22.31  
   22.32          assert methodHandle != null;
   22.33          assert property     != null;
    23.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Sep 03 14:33:34 2014 +0200
    23.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Sep 04 18:47:18 2014 +0200
    23.3 @@ -54,23 +54,25 @@
    23.4      public static final int CALLSITE_OPTIMISTIC    = 1 << 3;
    23.5      /** Is this really an apply that we try to call as a call? */
    23.6      public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;
    23.7 +    /** Does this a callsite for a variable declaration? */
    23.8 +    public static final int CALLSITE_DECLARE       = 1 << 5;
    23.9  
   23.10      /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
   23.11       * code where call sites have this flag set. */
   23.12 -    public static final int CALLSITE_PROFILE        = 1 << 5;
   23.13 +    public static final int CALLSITE_PROFILE         = 1 << 6;
   23.14      /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
   23.15       * call sites have this flag set. */
   23.16 -    public static final int CALLSITE_TRACE          = 1 << 6;
   23.17 +    public static final int CALLSITE_TRACE           = 1 << 7;
   23.18      /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
   23.19       * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   23.20 -    public static final int CALLSITE_TRACE_MISSES   = 1 << 7;
   23.21 +    public static final int CALLSITE_TRACE_MISSES    = 1 << 8;
   23.22      /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
   23.23       * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   23.24 -    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 8;
   23.25 +    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 9;
   23.26      /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
   23.27       * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
   23.28       * have this flag set. */
   23.29 -    public static final int CALLSITE_TRACE_VALUES   = 1 << 9;
   23.30 +    public static final int CALLSITE_TRACE_VALUES    = 1 << 10;
   23.31  
   23.32      //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
   23.33      //right now given the program points
   23.34 @@ -82,10 +84,10 @@
   23.35       * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
   23.36       * trace/profile settings.
   23.37       */
   23.38 -    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 10;
   23.39 +    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 11;
   23.40  
   23.41      /**
   23.42 -     * Maximum program point value. 22 bits should be enough for anyone
   23.43 +     * Maximum program point value. 21 bits should be enough for anyone
   23.44       */
   23.45      public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1;
   23.46  
   23.47 @@ -123,6 +125,9 @@
   23.48                  assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
   23.49                  sb.append("scope ");
   23.50              }
   23.51 +            if ((flags & CALLSITE_DECLARE) != 0) {
   23.52 +                sb.append("declare ");
   23.53 +            }
   23.54          }
   23.55          if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
   23.56              sb.append("apply2call ");
   23.57 @@ -329,6 +334,15 @@
   23.58      }
   23.59  
   23.60      /**
   23.61 +     * Does this callsite contain a declaration for its target?
   23.62 +     * @param desc descriptor
   23.63 +     * @return true if contains declaration
   23.64 +     */
   23.65 +    public static boolean isDeclaration(final CallSiteDescriptor desc) {
   23.66 +        return isFlag(desc, CALLSITE_DECLARE);
   23.67 +    }
   23.68 +
   23.69 +    /**
   23.70       * Get a program point from a descriptor (must be optimistic)
   23.71       * @param desc descriptor
   23.72       * @return program point
    24.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Wed Sep 03 14:33:34 2014 +0200
    24.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu Sep 04 18:47:18 2014 +0200
    24.3 @@ -58,6 +58,7 @@
    24.4  parser.error.regex.repeated.flag=Repeated RegExp flag: {0}
    24.5  parser.error.regex.syntax={0}
    24.6  parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
    24.7 +parser.error.missing.const.assignment=Missing assignment to constant "{0}"
    24.8  
    24.9  # strict mode error messages
   24.10  parser.error.strict.no.with="with" statement cannot be used in strict mode
   24.11 @@ -162,6 +163,8 @@
   24.12  
   24.13  syntax.error.invalid.json=Invalid JSON: {0}
   24.14  syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
   24.15 +syntax.error.redeclare.variable=Variable "{0}" has already been declared
   24.16 +syntax.error.assign.constant=Assignment to constant "{0}"
   24.17  
   24.18  io.error.cant.write=cannot write "{0}"
   24.19  config.error.no.dest=no destination directory supplied
    25.1 --- a/src/jdk/nashorn/internal/runtime/resources/Options.properties	Wed Sep 03 14:33:34 2014 +0200
    25.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties	Thu Sep 04 18:47:18 2014 +0200
    25.3 @@ -329,6 +329,14 @@
    25.4      desc="Enable scripting features."   \
    25.5  }
    25.6  
    25.7 +nashorn.option.language = {                      \
    25.8 +    name="--language",                           \
    25.9 +    type=String,                                 \
   25.10 +    params=[es5|es6],                            \
   25.11 +    default=es5,                                 \
   25.12 +    desc="Specify ECMAScript language version."  \
   25.13 +}
   25.14 +
   25.15  nashorn.option.stdout = {                                                \
   25.16      name="--stdout",                                                     \
   25.17      is_undocumented=true,                                                \
    26.1 --- a/src/jdk/nashorn/tools/Shell.java	Wed Sep 03 14:33:34 2014 +0200
    26.2 +++ b/src/jdk/nashorn/tools/Shell.java	Thu Sep 04 18:47:18 2014 +0200
    26.3 @@ -252,6 +252,15 @@
    26.4                      return COMPILATION_ERROR;
    26.5                  }
    26.6  
    26.7 +                new Compiler(
    26.8 +                       context,
    26.9 +                       env,
   26.10 +                       null, //null - pass no code installer - this is compile only
   26.11 +                       functionNode.getSource(),
   26.12 +                       context.getErrorManager(),
   26.13 +                       env._strict | functionNode.isStrict()).
   26.14 +                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
   26.15 +
   26.16                  if (env._print_ast) {
   26.17                      context.getErr().println(new ASTWriter(functionNode));
   26.18                  }
   26.19 @@ -260,14 +269,9 @@
   26.20                      context.getErr().println(new PrintVisitor(functionNode));
   26.21                  }
   26.22  
   26.23 -                //null - pass no code installer - this is compile only
   26.24 -                new Compiler(
   26.25 -                       context,
   26.26 -                       env,
   26.27 -                       null,
   26.28 -                       functionNode.getSource(),
   26.29 -                       env._strict | functionNode.isStrict()).
   26.30 -                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
   26.31 +                if (errors.getNumberOfErrors() != 0) {
   26.32 +                    return COMPILATION_ERROR;
   26.33 +                }
   26.34              }
   26.35          } finally {
   26.36              env.getOut().flush();
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/script/basic/es6/block-function-decl.js	Thu Sep 04 18:47:18 2014 +0200
    27.3 @@ -0,0 +1,51 @@
    27.4 +/*
    27.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.7 + *
    27.8 + * This code is free software; you can redistribute it and/or modify it
    27.9 + * under the terms of the GNU General Public License version 2 only, as
   27.10 + * published by the Free Software Foundation.
   27.11 + *
   27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.15 + * version 2 for more details (a copy is included in the LICENSE file that
   27.16 + * accompanied this code).
   27.17 + *
   27.18 + * You should have received a copy of the GNU General Public License version
   27.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.21 + *
   27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.23 + * or visit www.oracle.com if you need additional information or have any
   27.24 + * questions.
   27.25 + */
   27.26 +
   27.27 +/**
   27.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   27.29 + *
   27.30 + * @test
   27.31 + * @run
   27.32 + * @option --language=es6
   27.33 + */
   27.34 +
   27.35 +"use strict";
   27.36 +
   27.37 +{
   27.38 +    // f is defined on block level
   27.39 +    print(f);
   27.40 +    f();
   27.41 +    function f() {
   27.42 +        print("in f");
   27.43 +    }
   27.44 +    print(f);
   27.45 +    f();
   27.46 +}
   27.47 +
   27.48 +try {
   27.49 +    print(typeof f);
   27.50 +    f();
   27.51 +} catch (e) {
   27.52 +    print(e);
   27.53 +}
   27.54 +
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/test/script/basic/es6/block-function-decl.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    28.3 @@ -0,0 +1,10 @@
    28.4 +function f() {
    28.5 +        print("in f");
    28.6 +    }
    28.7 +in f
    28.8 +function f() {
    28.9 +        print("in f");
   28.10 +    }
   28.11 +in f
   28.12 +undefined
   28.13 +ReferenceError: "f" is not defined
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/script/basic/es6/const-empty.js	Thu Sep 04 18:47:18 2014 +0200
    29.3 @@ -0,0 +1,37 @@
    29.4 +/*
    29.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    29.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    29.7 + * 
    29.8 + * This code is free software; you can redistribute it and/or modify it
    29.9 + * under the terms of the GNU General Public License version 2 only, as
   29.10 + * published by the Free Software Foundation.
   29.11 + * 
   29.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   29.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   29.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   29.15 + * version 2 for more details (a copy is included in the LICENSE file that
   29.16 + * accompanied this code).
   29.17 + * 
   29.18 + * You should have received a copy of the GNU General Public License version
   29.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   29.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   29.21 + * 
   29.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   29.23 + * or visit www.oracle.com if you need additional information or have any
   29.24 + * questions.
   29.25 + */
   29.26 +
   29.27 +/**
   29.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   29.29 + *
   29.30 + * @test
   29.31 + * @run
   29.32 + * @option --language=es6
   29.33 + */
   29.34 +
   29.35 +try {
   29.36 +    eval('"use strict";\n' +
   29.37 +        'const x;\n');
   29.38 +} catch (e) {
   29.39 +    print(e);
   29.40 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/script/basic/es6/const-empty.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    30.3 @@ -0,0 +1,3 @@
    30.4 +SyntaxError: test/script/basic/es6/const-empty.js#33:4<eval>@1:2:7 Missing assignment to constant "x"
    30.5 +const x;
    30.6 +       ^
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/test/script/basic/es6/const-reassign.js	Thu Sep 04 18:47:18 2014 +0200
    31.3 @@ -0,0 +1,174 @@
    31.4 +/*
    31.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.7 + *
    31.8 + * This code is free software; you can redistribute it and/or modify it
    31.9 + * under the terms of the GNU General Public License version 2 only, as
   31.10 + * published by the Free Software Foundation.
   31.11 + *
   31.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   31.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   31.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   31.15 + * version 2 for more details (a copy is included in the LICENSE file that
   31.16 + * accompanied this code).
   31.17 + *
   31.18 + * You should have received a copy of the GNU General Public License version
   31.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   31.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   31.21 + *
   31.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   31.23 + * or visit www.oracle.com if you need additional information or have any
   31.24 + * questions.
   31.25 + */
   31.26 +
   31.27 +/**
   31.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   31.29 + *
   31.30 + * @test
   31.31 + * @run
   31.32 + * @option --language=es6 */
   31.33 +
   31.34 +"use strict";
   31.35 +
   31.36 +try {
   31.37 +    eval('"use strict";\n' +
   31.38 +        'const x = 2;\n' +
   31.39 +        'x = 1;\n');
   31.40 +} catch (e) {
   31.41 +    print(e.name);
   31.42 +}
   31.43 +
   31.44 +try {
   31.45 +    eval('"use strict";\n' +
   31.46 +        'const x = 2;\n' +
   31.47 +        'x++;\n');
   31.48 +    fail("const assignment didn't throw");
   31.49 +} catch (e) {
   31.50 +    print(e.name);
   31.51 +}
   31.52 +
   31.53 +try {
   31.54 +    eval('"use strict";\n' +
   31.55 +        'const x = 2;\n' +
   31.56 +        'x--;\n');
   31.57 +    fail("const assignment didn't throw");
   31.58 +} catch (e) {
   31.59 +    print(e.name);
   31.60 +}
   31.61 +
   31.62 +try {
   31.63 +    eval('"use strict";\n' +
   31.64 +        'const x = 2;\n' +
   31.65 +        '++x;\n');
   31.66 +    fail("const assignment didn't throw");
   31.67 +} catch (e) {
   31.68 +    print(e.name);
   31.69 +}
   31.70 +
   31.71 +try {
   31.72 +    eval('"use strict";\n' +
   31.73 +        'const x = 2;\n' +
   31.74 +        '--x;\n');
   31.75 +    fail("const assignment didn't throw");
   31.76 +} catch (e) {
   31.77 +    print(e.name);
   31.78 +}
   31.79 +
   31.80 +try {
   31.81 +    eval('"use strict";\n' +
   31.82 +        'const x = 2;\n' +
   31.83 +        'x += 1;\n');
   31.84 +    fail("const assignment didn't throw");
   31.85 +} catch (e) {
   31.86 +    print(e.name);
   31.87 +}
   31.88 +
   31.89 +try {
   31.90 +    eval('"use strict";\n' +
   31.91 +        'const x = 2;\n' +
   31.92 +        'x *= 1;\n');
   31.93 +    fail("const assignment didn't throw");
   31.94 +} catch (e) {
   31.95 +    print(e.name);
   31.96 +}
   31.97 +
   31.98 +try {
   31.99 +    eval('"use strict";\n' +
  31.100 +        'const x = 2;\n' +
  31.101 +        'x /= 1;\n');
  31.102 +    fail("const assignment didn't throw");
  31.103 +} catch (e) {
  31.104 +    print(e.name);
  31.105 +}
  31.106 +
  31.107 +try {
  31.108 +    eval('"use strict";\n' +
  31.109 +        'const x = 2;\n' +
  31.110 +        'x %= 1;\n');
  31.111 +    fail("const assignment didn't throw");
  31.112 +} catch (e) {
  31.113 +    print(e.name);
  31.114 +}
  31.115 +
  31.116 +try {
  31.117 +    eval('"use strict";\n' +
  31.118 +        'const x = 2;\n' +
  31.119 +        'x |= 1;\n');
  31.120 +    fail("const assignment didn't throw");
  31.121 +} catch (e) {
  31.122 +    print(e.name);
  31.123 +}
  31.124 +
  31.125 +try {
  31.126 +    eval('"use strict";\n' +
  31.127 +        'const x = 2;\n' +
  31.128 +        'x &= 1;\n');
  31.129 +    fail("const assignment didn't throw");
  31.130 +} catch (e) {
  31.131 +    print(e.name);
  31.132 +}
  31.133 +
  31.134 +try {
  31.135 +    eval('"use strict";\n' +
  31.136 +        'const x = 2;\n' +
  31.137 +        'x ^= 1;\n');
  31.138 +    fail("const assignment didn't throw");
  31.139 +} catch (e) {
  31.140 +    print(e.name);
  31.141 +}
  31.142 +
  31.143 +try {
  31.144 +    eval('"use strict";\n' +
  31.145 +        'const x = 2;\n' +
  31.146 +        'x <<= 1;\n');
  31.147 +    fail("const assignment didn't throw");
  31.148 +} catch (e) {
  31.149 +    print(e.name);
  31.150 +}
  31.151 +
  31.152 +try {
  31.153 +    eval('"use strict";\n' +
  31.154 +        'const x = 2;\n' +
  31.155 +        'x >>= 1;\n');
  31.156 +    fail("const assignment didn't throw");
  31.157 +} catch (e) {
  31.158 +    print(e.name);
  31.159 +}
  31.160 +
  31.161 +try {
  31.162 +    eval('"use strict";\n' +
  31.163 +        'const x = 2;\n' +
  31.164 +        'x >>>= 1;\n');
  31.165 +    fail("const assignment didn't throw");
  31.166 +} catch (e) {
  31.167 +    print(e.name);
  31.168 +}
  31.169 +
  31.170 +try {
  31.171 +    eval('"use strict";\n' +
  31.172 +        'const x = 2;\n' +
  31.173 +        'delete x;\n');
  31.174 +    fail("const assignment didn't throw");
  31.175 +} catch (e) {
  31.176 +    print(e.name);
  31.177 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/script/basic/es6/const-reassign.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    32.3 @@ -0,0 +1,16 @@
    32.4 +SyntaxError
    32.5 +SyntaxError
    32.6 +SyntaxError
    32.7 +SyntaxError
    32.8 +SyntaxError
    32.9 +SyntaxError
   32.10 +SyntaxError
   32.11 +SyntaxError
   32.12 +SyntaxError
   32.13 +SyntaxError
   32.14 +SyntaxError
   32.15 +SyntaxError
   32.16 +SyntaxError
   32.17 +SyntaxError
   32.18 +SyntaxError
   32.19 +SyntaxError
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/test/script/basic/es6/const-redeclare.js	Thu Sep 04 18:47:18 2014 +0200
    33.3 @@ -0,0 +1,38 @@
    33.4 +/*
    33.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    33.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    33.7 + * 
    33.8 + * This code is free software; you can redistribute it and/or modify it
    33.9 + * under the terms of the GNU General Public License version 2 only, as
   33.10 + * published by the Free Software Foundation.
   33.11 + * 
   33.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   33.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   33.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   33.15 + * version 2 for more details (a copy is included in the LICENSE file that
   33.16 + * accompanied this code).
   33.17 + * 
   33.18 + * You should have received a copy of the GNU General Public License version
   33.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   33.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   33.21 + * 
   33.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   33.23 + * or visit www.oracle.com if you need additional information or have any
   33.24 + * questions.
   33.25 + */
   33.26 +
   33.27 +/**
   33.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   33.29 + *
   33.30 + * @test
   33.31 + * @run
   33.32 + * @option --language=es6
   33.33 + */
   33.34 +
   33.35 +try {
   33.36 +    eval('"use strict";\n' +
   33.37 +         'const x = 2;\n' +
   33.38 +         'const x = 2;\n');
   33.39 +} catch (e) {
   33.40 +    print(e);
   33.41 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/test/script/basic/es6/const-redeclare.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    34.3 @@ -0,0 +1,3 @@
    34.4 +SyntaxError: test/script/basic/es6/const-redeclare.js#33:4<eval>@1:2:6 Variable "x" has already been declared
    34.5 +const x = 2;
    34.6 +      ^
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/test/script/basic/es6/const-self.js	Thu Sep 04 18:47:18 2014 +0200
    35.3 @@ -0,0 +1,42 @@
    35.4 +/*
    35.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    35.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    35.7 + *
    35.8 + * This code is free software; you can redistribute it and/or modify it
    35.9 + * under the terms of the GNU General Public License version 2 only, as
   35.10 + * published by the Free Software Foundation.
   35.11 + *
   35.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   35.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   35.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   35.15 + * version 2 for more details (a copy is included in the LICENSE file that
   35.16 + * accompanied this code).
   35.17 + *
   35.18 + * You should have received a copy of the GNU General Public License version
   35.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   35.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   35.21 + *
   35.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   35.23 + * or visit www.oracle.com if you need additional information or have any
   35.24 + * questions.
   35.25 + */
   35.26 +
   35.27 +/**
   35.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   35.29 + *
   35.30 + * @test
   35.31 + * @run
   35.32 + * @option --language=es6 */
   35.33 +
   35.34 +"use strict";
   35.35 +
   35.36 +const a = 1, b = a;
   35.37 +
   35.38 +print(a, b);
   35.39 +
   35.40 +try {
   35.41 +    eval('"use strict";\n' +
   35.42 +         'const a = a;\n');
   35.43 +} catch (e) {
   35.44 +    print(e);
   35.45 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/test/script/basic/es6/const-self.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    36.3 @@ -0,0 +1,2 @@
    36.4 +1 1
    36.5 +ReferenceError: "a" is not defined
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/test/script/basic/es6/const-tdz.js	Thu Sep 04 18:47:18 2014 +0200
    37.3 @@ -0,0 +1,81 @@
    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-8051889: Implement block scoping in symbol assignment and scope computation
   37.29 + *
   37.30 + * @test
   37.31 + * @run
   37.32 + * @option --language=es6 */
   37.33 +
   37.34 +"use strict";
   37.35 +
   37.36 +{
   37.37 +    print("test 1");
   37.38 +
   37.39 +    function f() {
   37.40 +        try {
   37.41 +            print(a);
   37.42 +        } catch (a) {
   37.43 +            print(a);
   37.44 +        }
   37.45 +    }
   37.46 +
   37.47 +    f();
   37.48 +    const a = 1;
   37.49 +    f();
   37.50 +}
   37.51 +
   37.52 +{
   37.53 +    print("test 2");
   37.54 +
   37.55 +    function f() {
   37.56 +        try {
   37.57 +            print(a);
   37.58 +        } catch (a) {
   37.59 +            print(a);
   37.60 +        }
   37.61 +    }
   37.62 +
   37.63 +    f();
   37.64 +    const a = 2;
   37.65 +    f();
   37.66 +}
   37.67 +
   37.68 +{
   37.69 +    print("test 3");
   37.70 +    {
   37.71 +        try {
   37.72 +            print(a);
   37.73 +        } catch (a) {
   37.74 +            print(a);
   37.75 +        }
   37.76 +    }
   37.77 +
   37.78 +    const a = 3;
   37.79 +
   37.80 +    {
   37.81 +        print(a);
   37.82 +    }
   37.83 +}
   37.84 +
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/test/script/basic/es6/const-tdz.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    38.3 @@ -0,0 +1,9 @@
    38.4 +test 1
    38.5 +ReferenceError: "a" is not defined
    38.6 +1
    38.7 +test 2
    38.8 +ReferenceError: "a" is not defined
    38.9 +2
   38.10 +test 3
   38.11 +ReferenceError: "a" is not defined
   38.12 +3
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/test/script/basic/es6/const.js	Thu Sep 04 18:47:18 2014 +0200
    39.3 @@ -0,0 +1,69 @@
    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-8051889: Implement block scoping in symbol assignment and scope computation
   39.29 + *
   39.30 + * @test
   39.31 + * @run
   39.32 + * @option --language=es6
   39.33 + */
   39.34 +
   39.35 +"use strict";
   39.36 +
   39.37 +const a = 2;
   39.38 +const c = 2;
   39.39 +print(a, c);
   39.40 +
   39.41 +function f(x) {
   39.42 +    const a = 5;
   39.43 +    const c = 10;
   39.44 +    print(a, c);
   39.45 +    if (x) {
   39.46 +        const a = 42;
   39.47 +        const c = 43;
   39.48 +        print(a, c);
   39.49 +    }
   39.50 +    print(a, c);
   39.51 +
   39.52 +    function inner() {
   39.53 +        (function() {
   39.54 +            print(a, c);
   39.55 +        })();
   39.56 +    }
   39.57 +    inner();
   39.58 +}
   39.59 +
   39.60 +f(true);
   39.61 +f(false);
   39.62 +
   39.63 +(function() {
   39.64 +    (function() {
   39.65 +        print(a, c);
   39.66 +    })();
   39.67 +})();
   39.68 +
   39.69 +function outer() {
   39.70 +    print(a, c);
   39.71 +}
   39.72 +outer();
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/script/basic/es6/const.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    40.3 @@ -0,0 +1,10 @@
    40.4 +2 2
    40.5 +5 10
    40.6 +42 43
    40.7 +5 10
    40.8 +5 10
    40.9 +5 10
   40.10 +5 10
   40.11 +5 10
   40.12 +2 2
   40.13 +2 2
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/test/script/basic/es6/for-let.js	Thu Sep 04 18:47:18 2014 +0200
    41.3 @@ -0,0 +1,41 @@
    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-8051889: Implement block scoping in symbol assignment and scope computation
   41.29 + *
   41.30 + * @test
   41.31 + * @run
   41.32 + * @option --language=es6 */
   41.33 +
   41.34 +"use strict";
   41.35 +
   41.36 +for (let i = 0; i < 10; i++) {
   41.37 +    print(i);
   41.38 +}
   41.39 +
   41.40 +try {
   41.41 +    print(i);
   41.42 +} catch (e) {
   41.43 +    print(e);
   41.44 +}
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/test/script/basic/es6/for-let.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    42.3 @@ -0,0 +1,11 @@
    42.4 +0
    42.5 +1
    42.6 +2
    42.7 +3
    42.8 +4
    42.9 +5
   42.10 +6
   42.11 +7
   42.12 +8
   42.13 +9
   42.14 +ReferenceError: "i" is not defined
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/test/script/basic/es6/let-eval.js	Thu Sep 04 18:47:18 2014 +0200
    43.3 @@ -0,0 +1,98 @@
    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-8051889: Implement block scoping in symbol assignment and scope computation
   43.29 + *
   43.30 + * @test
   43.31 + * @run
   43.32 + * @option --language=es6 */
   43.33 +
   43.34 +"use strict";
   43.35 +
   43.36 +function f() {
   43.37 +    var a;
   43.38 +    let b;
   43.39 +    const c = 0;
   43.40 +
   43.41 +    print(a, b, c);
   43.42 +
   43.43 +    try {
   43.44 +        eval("x = 1; print('x: ' + x);");
   43.45 +        print("assignment to x succeeded");
   43.46 +    } catch (e) {
   43.47 +        print(e);
   43.48 +    }
   43.49 +    try {
   43.50 +        eval("'use strict'; let z = 1; print('z: ' + z);");
   43.51 +        print("assignment to z succeeded");
   43.52 +        eval("print('z: ' + z);");
   43.53 +    } catch (e) {
   43.54 +        print(e);
   43.55 +    }
   43.56 +
   43.57 +    try {
   43.58 +        eval("a = 1; print(a);");
   43.59 +        print("assignment to a succeeded");
   43.60 +    } catch (e) {
   43.61 +        print(e);
   43.62 +    }
   43.63 +    print("a: " + a);
   43.64 +
   43.65 +    try {
   43.66 +        eval("b = 1; print('b: ' + b);");
   43.67 +        print("assignment to b succeeded");
   43.68 +    } catch (e) {
   43.69 +        print(e);
   43.70 +    }
   43.71 +    print("b: " + b);
   43.72 +
   43.73 +    try {
   43.74 +        eval("c = 1; print('c: ' + c);");
   43.75 +        print("assignment to c succeeded");
   43.76 +    } catch (e) {
   43.77 +        print(e);
   43.78 +    }
   43.79 +    print("c: " + c);
   43.80 +
   43.81 +    eval("a = 2; let b = 3;");
   43.82 +
   43.83 +    try {
   43.84 +        print(a, b, c);
   43.85 +    } catch (e) {
   43.86 +        print(e);
   43.87 +    }
   43.88 +
   43.89 +    let x;
   43.90 +
   43.91 +    try {
   43.92 +        print(a, b, c, x);
   43.93 +    } catch (e) {
   43.94 +        print(e);
   43.95 +    }
   43.96 +
   43.97 +}
   43.98 +
   43.99 +f();
  43.100 +
  43.101 +print(typeof a, typeof b, typeof c, typeof x, typeof z);
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/script/basic/es6/let-eval.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    44.3 @@ -0,0 +1,16 @@
    44.4 +undefined undefined 0
    44.5 +ReferenceError: "x" is not defined
    44.6 +z: 1
    44.7 +assignment to z succeeded
    44.8 +ReferenceError: "z" is not defined
    44.9 +1
   44.10 +assignment to a succeeded
   44.11 +a: 1
   44.12 +b: 1
   44.13 +assignment to b succeeded
   44.14 +b: 1
   44.15 +TypeError: "c" is not a writable property of [object Object]
   44.16 +c: 0
   44.17 +2 1 0
   44.18 +2 1 0 undefined
   44.19 +undefined undefined undefined undefined undefined
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/test/script/basic/es6/let-load-lib.js	Thu Sep 04 18:47:18 2014 +0200
    45.3 @@ -0,0 +1,48 @@
    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 + * @subtest
   45.29 + */
   45.30 +
   45.31 +"use strict";
   45.32 +
   45.33 +// var should be visible in other script, let and const not
   45.34 +var a = 1;
   45.35 +let b = 2;
   45.36 +const c = 3;
   45.37 +
   45.38 +// top level function should be visible
   45.39 +function top() {
   45.40 +    print("top level function");
   45.41 +}
   45.42 +
   45.43 +// block level function not visible outside script
   45.44 +{
   45.45 +    function block() {
   45.46 +        print("block function");
   45.47 +    }
   45.48 +
   45.49 +    top();
   45.50 +    block();
   45.51 +}
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/test/script/basic/es6/let-load.js	Thu Sep 04 18:47:18 2014 +0200
    46.3 @@ -0,0 +1,62 @@
    46.4 +/*
    46.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    46.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    46.7 + *
    46.8 + * This code is free software; you can redistribute it and/or modify it
    46.9 + * under the terms of the GNU General Public License version 2 only, as
   46.10 + * published by the Free Software Foundation.
   46.11 + *
   46.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   46.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   46.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   46.15 + * version 2 for more details (a copy is included in the LICENSE file that
   46.16 + * accompanied this code).
   46.17 + *
   46.18 + * You should have received a copy of the GNU General Public License version
   46.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   46.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   46.21 + *
   46.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   46.23 + * or visit www.oracle.com if you need additional information or have any
   46.24 + * questions.
   46.25 + */
   46.26 +
   46.27 +/**
   46.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   46.29 + *
   46.30 + * @test
   46.31 + * @run
   46.32 + * @option --language=es6 */
   46.33 +
   46.34 +"use strict";
   46.35 +
   46.36 +load(__DIR__ + "let-load-lib.js");
   46.37 +
   46.38 +{
   46.39 +    let a = 20;
   46.40 +    const c = 30;
   46.41 +    print("print local defs: " + a, c);
   46.42 +}
   46.43 +
   46.44 +print("imported var: " + a);
   46.45 +try {
   46.46 +    print("imported let: " + b);
   46.47 +} catch (e) {
   46.48 +    print(e);
   46.49 +}
   46.50 +
   46.51 +try {
   46.52 +    print("imported const: " + c);
   46.53 +} catch (e) {
   46.54 +    print(e);
   46.55 +}
   46.56 +
   46.57 +top();
   46.58 +
   46.59 +try {
   46.60 +    block();
   46.61 +} catch (e) {
   46.62 +    print(e);
   46.63 +}
   46.64 +
   46.65 +
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/test/script/basic/es6/let-load.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    47.3 @@ -0,0 +1,8 @@
    47.4 +top level function
    47.5 +block function
    47.6 +print local defs: 20 30
    47.7 +imported var: 1
    47.8 +ReferenceError: "b" is not defined
    47.9 +ReferenceError: "c" is not defined
   47.10 +top level function
   47.11 +ReferenceError: "block" is not defined
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/test/script/basic/es6/let-nodeclare.js	Thu Sep 04 18:47:18 2014 +0200
    48.3 @@ -0,0 +1,52 @@
    48.4 +/*
    48.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    48.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    48.7 + *
    48.8 + * This code is free software; you can redistribute it and/or modify it
    48.9 + * under the terms of the GNU General Public License version 2 only, as
   48.10 + * published by the Free Software Foundation.
   48.11 + *
   48.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   48.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   48.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   48.15 + * version 2 for more details (a copy is included in the LICENSE file that
   48.16 + * accompanied this code).
   48.17 + *
   48.18 + * You should have received a copy of the GNU General Public License version
   48.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   48.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   48.21 + *
   48.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   48.23 + * or visit www.oracle.com if you need additional information or have any
   48.24 + * questions.
   48.25 + */
   48.26 +
   48.27 +/**
   48.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   48.29 + *
   48.30 + * @test
   48.31 + * @run
   48.32 + * @option --language=es6 */
   48.33 +
   48.34 +"use strict";
   48.35 +
   48.36 +try {
   48.37 +    if (true) {
   48.38 +        let x = 2;
   48.39 +        print(x);
   48.40 +    }
   48.41 +    print(x);
   48.42 +} catch (e) {
   48.43 +    print(e);
   48.44 +}
   48.45 +
   48.46 +
   48.47 +try {
   48.48 +    if (true) {
   48.49 +        const x = 2;
   48.50 +        print(x);
   48.51 +    }
   48.52 +    print(x);
   48.53 +} catch (e) {
   48.54 +    print(e);
   48.55 +}
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/test/script/basic/es6/let-nodeclare.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    49.3 @@ -0,0 +1,4 @@
    49.4 +2
    49.5 +ReferenceError: "x" is not defined
    49.6 +2
    49.7 +ReferenceError: "x" is not defined
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/test/script/basic/es6/let-redeclare.js	Thu Sep 04 18:47:18 2014 +0200
    50.3 @@ -0,0 +1,38 @@
    50.4 +/*
    50.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    50.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    50.7 + * 
    50.8 + * This code is free software; you can redistribute it and/or modify it
    50.9 + * under the terms of the GNU General Public License version 2 only, as
   50.10 + * published by the Free Software Foundation.
   50.11 + * 
   50.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   50.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   50.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   50.15 + * version 2 for more details (a copy is included in the LICENSE file that
   50.16 + * accompanied this code).
   50.17 + * 
   50.18 + * You should have received a copy of the GNU General Public License version
   50.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   50.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   50.21 + * 
   50.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   50.23 + * or visit www.oracle.com if you need additional information or have any
   50.24 + * questions.
   50.25 + */
   50.26 +
   50.27 +/**
   50.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   50.29 + *
   50.30 + * @test
   50.31 + * @run
   50.32 + * @option --language=es6
   50.33 + */
   50.34 +
   50.35 +try {
   50.36 +    eval('"use strict";\n' +
   50.37 +         'let x = 2;\n' +
   50.38 +         'let x = 2;\n');
   50.39 +} catch (e) {
   50.40 +    print(e);
   50.41 +}
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/test/script/basic/es6/let-redeclare.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    51.3 @@ -0,0 +1,3 @@
    51.4 +SyntaxError: test/script/basic/es6/let-redeclare.js#33:4<eval>@1:2:4 Variable "x" has already been declared
    51.5 +let x = 2;
    51.6 +    ^
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/test/script/basic/es6/let-self.js	Thu Sep 04 18:47:18 2014 +0200
    52.3 @@ -0,0 +1,42 @@
    52.4 +/*
    52.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    52.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    52.7 + *
    52.8 + * This code is free software; you can redistribute it and/or modify it
    52.9 + * under the terms of the GNU General Public License version 2 only, as
   52.10 + * published by the Free Software Foundation.
   52.11 + *
   52.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   52.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   52.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   52.15 + * version 2 for more details (a copy is included in the LICENSE file that
   52.16 + * accompanied this code).
   52.17 + *
   52.18 + * You should have received a copy of the GNU General Public License version
   52.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   52.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   52.21 + *
   52.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   52.23 + * or visit www.oracle.com if you need additional information or have any
   52.24 + * questions.
   52.25 + */
   52.26 +
   52.27 +/**
   52.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   52.29 + *
   52.30 + * @test
   52.31 + * @run
   52.32 + * @option --language=es6 */
   52.33 +
   52.34 +"use strict";
   52.35 +
   52.36 +let a, b = a;
   52.37 +
   52.38 +print(a, b);
   52.39 +
   52.40 +try {
   52.41 +    eval('"use strict";\n' +
   52.42 +         'let a = a;\n');
   52.43 +} catch (e) {
   52.44 +    print(e);
   52.45 +}
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/test/script/basic/es6/let-self.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    53.3 @@ -0,0 +1,2 @@
    53.4 +undefined undefined
    53.5 +ReferenceError: "a" is not defined
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/test/script/basic/es6/let-tdz.js	Thu Sep 04 18:47:18 2014 +0200
    54.3 @@ -0,0 +1,97 @@
    54.4 +/*
    54.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    54.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    54.7 + *
    54.8 + * This code is free software; you can redistribute it and/or modify it
    54.9 + * under the terms of the GNU General Public License version 2 only, as
   54.10 + * published by the Free Software Foundation.
   54.11 + *
   54.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   54.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   54.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   54.15 + * version 2 for more details (a copy is included in the LICENSE file that
   54.16 + * accompanied this code).
   54.17 + *
   54.18 + * You should have received a copy of the GNU General Public License version
   54.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   54.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   54.21 + *
   54.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   54.23 + * or visit www.oracle.com if you need additional information or have any
   54.24 + * questions.
   54.25 + */
   54.26 +
   54.27 +/**
   54.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   54.29 + *
   54.30 + * @test
   54.31 + * @run
   54.32 + * @option --language=es6 */
   54.33 +
   54.34 +"use strict";
   54.35 +
   54.36 +{
   54.37 +    print("test 1");
   54.38 +
   54.39 +    function f() {
   54.40 +        try {
   54.41 +            print(a);
   54.42 +        } catch (a) {
   54.43 +            print(a);
   54.44 +        }
   54.45 +    }
   54.46 +
   54.47 +    f();
   54.48 +    let a = 1;
   54.49 +    f();
   54.50 +}
   54.51 +
   54.52 +{
   54.53 +    print("test 2");
   54.54 +
   54.55 +    function f() {
   54.56 +        try {
   54.57 +            print(a);
   54.58 +        } catch (a) {
   54.59 +            print(a);
   54.60 +        }
   54.61 +    }
   54.62 +
   54.63 +    f();
   54.64 +    let a = 2;
   54.65 +    f();
   54.66 +}
   54.67 +
   54.68 +{
   54.69 +    print("test 3");
   54.70 +
   54.71 +    {
   54.72 +        try {
   54.73 +            print(a);
   54.74 +        } catch (a) {
   54.75 +            print(a);
   54.76 +        }
   54.77 +    }
   54.78 +
   54.79 +    let a = 3;
   54.80 +
   54.81 +    {
   54.82 +        print(a);
   54.83 +    }
   54.84 +}
   54.85 +
   54.86 +{
   54.87 +    print("test 4");
   54.88 +    let a;
   54.89 +
   54.90 +    {
   54.91 +        print(a);
   54.92 +    }
   54.93 +
   54.94 +    a = 4;
   54.95 +
   54.96 +    {
   54.97 +        print(a);
   54.98 +    }
   54.99 +}
  54.100 +
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/test/script/basic/es6/let-tdz.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    55.3 @@ -0,0 +1,12 @@
    55.4 +test 1
    55.5 +ReferenceError: "a" is not defined
    55.6 +1
    55.7 +test 2
    55.8 +ReferenceError: "a" is not defined
    55.9 +2
   55.10 +test 3
   55.11 +ReferenceError: "a" is not defined
   55.12 +3
   55.13 +test 4
   55.14 +undefined
   55.15 +4
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/test/script/basic/es6/let.js	Thu Sep 04 18:47:18 2014 +0200
    56.3 @@ -0,0 +1,69 @@
    56.4 +/*
    56.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    56.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    56.7 + * 
    56.8 + * This code is free software; you can redistribute it and/or modify it
    56.9 + * under the terms of the GNU General Public License version 2 only, as
   56.10 + * published by the Free Software Foundation.
   56.11 + * 
   56.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   56.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   56.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   56.15 + * version 2 for more details (a copy is included in the LICENSE file that
   56.16 + * accompanied this code).
   56.17 + * 
   56.18 + * You should have received a copy of the GNU General Public License version
   56.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   56.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   56.21 + * 
   56.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   56.23 + * or visit www.oracle.com if you need additional information or have any
   56.24 + * questions.
   56.25 + */
   56.26 +
   56.27 +/**
   56.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   56.29 + *
   56.30 + * @test
   56.31 + * @run
   56.32 + * @option --language=es6 */
   56.33 +
   56.34 +"use strict";
   56.35 +
   56.36 +let a = 2;
   56.37 +let c = 2;
   56.38 +print(a, c);
   56.39 +
   56.40 +function f(x) {
   56.41 +    let a = 5;
   56.42 +    const c = 10;
   56.43 +    print(a, c);
   56.44 +    if (x) {
   56.45 +        let a = 42;
   56.46 +        const c = 43;
   56.47 +        print(a, c);
   56.48 +    }
   56.49 +    print(a, c);
   56.50 +
   56.51 +    function inner() {
   56.52 +        (function() {
   56.53 +            print(a, c);
   56.54 +        })();
   56.55 +    }
   56.56 +    inner();
   56.57 +}
   56.58 +
   56.59 +f(true);
   56.60 +f(false);
   56.61 +
   56.62 +(function() {
   56.63 +    (function() {
   56.64 +        print(a, c);
   56.65 +    })();
   56.66 +})();
   56.67 +
   56.68 +function outer() {
   56.69 +    print(a, c);
   56.70 +}
   56.71 +outer();
   56.72 +
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/test/script/basic/es6/let.js.EXPECTED	Thu Sep 04 18:47:18 2014 +0200
    57.3 @@ -0,0 +1,10 @@
    57.4 +2 2
    57.5 +5 10
    57.6 +42 43
    57.7 +5 10
    57.8 +5 10
    57.9 +5 10
   57.10 +5 10
   57.11 +5 10
   57.12 +2 2
   57.13 +2 2
    58.1 --- a/test/script/trusted/JDK-8006529.js	Wed Sep 03 14:33:34 2014 +0200
    58.2 +++ b/test/script/trusted/JDK-8006529.js	Thu Sep 04 18:47:18 2014 +0200
    58.3 @@ -120,7 +120,7 @@
    58.4  
    58.5  var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
    58.6  var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
    58.7 -var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, boolean.class);
    58.8 +var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class);
    58.9  
   58.10  // compile(script) -- compiles a script specified as a string with its
   58.11  // source code, returns a jdk.nashorn.internal.ir.FunctionNode object
   58.12 @@ -134,7 +134,7 @@
   58.13      var parser   = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
   58.14      var func     = parseMethod.invoke(parser);
   58.15  
   58.16 -    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, false);
   58.17 +    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false);
   58.18  
   58.19      return compileMethod.invoke(compiler, func, phases);
   58.20  };
    59.1 --- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Wed Sep 03 14:33:34 2014 +0200
    59.2 +++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Thu Sep 04 18:47:18 2014 +0200
    59.3 @@ -98,11 +98,16 @@
    59.4              compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() {
    59.5                  @Override
    59.6                  public boolean exclude(final File file, final String content) {
    59.7 -                    return content.indexOf("@negative") != -1;
    59.8 +                    return content != null && content.contains("@negative");
    59.9                  }
   59.10              });
   59.11          }
   59.12 -        compileTestSet(new File(TEST_BASIC_DIR), null);
   59.13 +        compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() {
   59.14 +            @Override
   59.15 +            public boolean exclude(final File file, final String content) {
   59.16 +                return file.getName().equals("es6");
   59.17 +            }
   59.18 +        });
   59.19          compileTestSet(new File(TEST_NODE_DIR, "node"), null);
   59.20          compileTestSet(new File(TEST_NODE_DIR, "src"), null);
   59.21      }
   59.22 @@ -136,6 +141,9 @@
   59.23      private int skipped;
   59.24  
   59.25      private void compileJSDirectory(final File dir, final TestFilter filter) {
   59.26 +        if (filter != null && filter.exclude(dir, null)) {
   59.27 +            return;
   59.28 +        }
   59.29          for (final File f : dir.listFiles()) {
   59.30              if (f.isDirectory()) {
   59.31                  compileJSDirectory(f, filter);
    60.1 --- a/test/src/jdk/nashorn/internal/parser/ParserTest.java	Wed Sep 03 14:33:34 2014 +0200
    60.2 +++ b/test/src/jdk/nashorn/internal/parser/ParserTest.java	Thu Sep 04 18:47:18 2014 +0200
    60.3 @@ -82,11 +82,16 @@
    60.4              parseTestSet(TEST262_SUITE_DIR, new TestFilter() {
    60.5                  @Override
    60.6                  public boolean exclude(final File file, final String content) {
    60.7 -                    return content.indexOf("@negative") != -1;
    60.8 +                    return content != null && content.contains("@negative");
    60.9                  }
   60.10              });
   60.11          }
   60.12 -        parseTestSet(TEST_BASIC_DIR, null);
   60.13 +        parseTestSet(TEST_BASIC_DIR,  new TestFilter() {
   60.14 +            @Override
   60.15 +            public boolean exclude(final File file, final String content) {
   60.16 +                return file.getName().equals("es6");
   60.17 +            }
   60.18 +        });
   60.19      }
   60.20  
   60.21      private void parseTestSet(final String testSet, final TestFilter filter) {
   60.22 @@ -120,6 +125,9 @@
   60.23      private int skipped;
   60.24  
   60.25      private void parseJSDirectory(final File dir, final TestFilter filter) {
   60.26 +        if (filter != null && filter.exclude(dir, null)) {
   60.27 +            return;
   60.28 +        }
   60.29          for (final File f : dir.listFiles()) {
   60.30              if (f.isDirectory()) {
   60.31                  parseJSDirectory(f, filter);

mercurial