Merge

Tue, 16 Sep 2014 13:59:37 -0700

author
asaha
date
Tue, 16 Sep 2014 13:59:37 -0700
changeset 1039
4af4491477eb
parent 1038
0bcc64d0d193
parent 1008
1196f17cf7bc
child 1041
83e53aa5acf2

Merge

bin/fixorphantests.sh file | annotate | diff | comparison | revisions
bin/fixwhitespace.sh file | annotate | diff | comparison | revisions
bin/jjsdebug.sh file | annotate | diff | comparison | revisions
bin/rm-non-tracked.sh file | annotate | diff | comparison | revisions
bin/run_octane.sh file | annotate | diff | comparison | revisions
test/script/basic/JDK-8048079_1.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8048079_1.js.EXPECTED file | annotate | diff | comparison | revisions
test/script/basic/JDK-8048079_2.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8048079_2.js.EXPECTED file | annotate | diff | comparison | revisions
     1.1 --- a/bin/fixorphantests.sh	Thu Sep 11 15:34:13 2014 -0700
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,52 +0,0 @@
     1.4 -#!/bin/sh
     1.5 -#
     1.6 -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 -# 
     1.9 -# This code is free software; you can redistribute it and/or modify it
    1.10 -# under the terms of the GNU General Public License version 2 only, as
    1.11 -# published by the Free Software Foundation.
    1.12 -# 
    1.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 -# version 2 for more details (a copy is included in the LICENSE file that
    1.17 -# accompanied this code).
    1.18 -# 
    1.19 -# You should have received a copy of the GNU General Public License version
    1.20 -# 2 along with this work; if not, write to the Free Software Foundation,
    1.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 -# 
    1.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 -# or visit www.oracle.com if you need additional information or have any
    1.25 -# questions.
    1.26 -#
    1.27 -
    1.28 -#ensure that all tests tagged with @test are also tagged with @run
    1.29 -
    1.30 -for f in $(find test/script/basic/*.js); do 
    1.31 -    grep @test $f >/dev/null
    1.32 -    TEST=$?
    1.33 -    grep @run $f >/dev/null
    1.34 -    RUN=$?    
    1.35 -
    1.36 -    if [ $TEST -eq 0 ] && [ ! $RUN -eq 0 ]; then		
    1.37 -	echo "repairing ${f}..."
    1.38 -	TEMP=$(mktemp /tmp/scratch.XXXXXX)
    1.39 -
    1.40 -	#IFS='', -raw flag to preserve white space
    1.41 -	while IFS='' read -r line; do 	    
    1.42 -	    echo $line | grep @test >/dev/null
    1.43 -	    TEST=$?
    1.44 -	    printf "%s\n" "$line" 
    1.45 -	    if [ $TEST -eq 0 ]; then
    1.46 -		printf "%s\n" "$line" | sed s/@test/@run/g 
    1.47 -	    fi	   
    1.48 -	done < $f >$TEMP
    1.49 -
    1.50 -	cp $TEMP $f
    1.51 -
    1.52 -	rm -fr $TEMP
    1.53 -    fi
    1.54 -
    1.55 -done
     2.1 --- a/bin/fixwhitespace.sh	Thu Sep 11 15:34:13 2014 -0700
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,37 +0,0 @@
     2.4 -#!/bin/bash
     2.5 -#
     2.6 -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     2.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8 -# 
     2.9 -# This code is free software; you can redistribute it and/or modify it
    2.10 -# under the terms of the GNU General Public License version 2 only, as
    2.11 -# published by the Free Software Foundation.
    2.12 -# 
    2.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
    2.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.16 -# version 2 for more details (a copy is included in the LICENSE file that
    2.17 -# accompanied this code).
    2.18 -# 
    2.19 -# You should have received a copy of the GNU General Public License version
    2.20 -# 2 along with this work; if not, write to the Free Software Foundation,
    2.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.22 -# 
    2.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.24 -# or visit www.oracle.com if you need additional information or have any
    2.25 -# questions.
    2.26 -#
    2.27 -
    2.28 -fix() {
    2.29 -    #convert tabs to spaces
    2.30 -    find . -name $1 -exec sed -i "" 's/	/    /g' {} \;
    2.31 -    #remove trailing whitespace
    2.32 -    find . -name $1 -exec sed -i "" 's/[ 	]*$//' \{} \;
    2.33 -}
    2.34 -
    2.35 -if [ ! -z $1 ]; then 
    2.36 -    fix $1;
    2.37 -else
    2.38 -    fix "*.java"
    2.39 -    fix "*.js"
    2.40 -fi
     3.1 --- a/bin/jjsdebug.sh	Thu Sep 11 15:34:13 2014 -0700
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,25 +0,0 @@
     3.4 -#!/bin/sh
     3.5 -#
     3.6 -# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
     3.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8 -# 
     3.9 -# This code is free software; you can redistribute it and/or modify it
    3.10 -# under the terms of the GNU General Public License version 2 only, as
    3.11 -# published by the Free Software Foundation.
    3.12 -# 
    3.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
    3.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.16 -# version 2 for more details (a copy is included in the LICENSE file that
    3.17 -# accompanied this code).
    3.18 -# 
    3.19 -# You should have received a copy of the GNU General Public License version
    3.20 -# 2 along with this work; if not, write to the Free Software Foundation,
    3.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.22 -# 
    3.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.24 -# or visit www.oracle.com if you need additional information or have any
    3.25 -# questions.
    3.26 -#
    3.27 -
    3.28 -$JAVA_HOME/bin/jjs -J-Djava.ext.dirs=`dirname $0`/../dist -J-agentlib:jdwp=transport=dt_socket,address=localhost:9009,server=y,suspend=y $*
     4.1 --- a/bin/rm-non-tracked.sh	Thu Sep 11 15:34:13 2014 -0700
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,24 +0,0 @@
     4.4 -#!/bin/bash
     4.5 -#
     4.6 -# Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     4.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8 -# 
     4.9 -# This code is free software; you can redistribute it and/or modify it
    4.10 -# under the terms of the GNU General Public License version 2 only, as
    4.11 -# published by the Free Software Foundation.
    4.12 -# 
    4.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
    4.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.16 -# version 2 for more details (a copy is included in the LICENSE file that
    4.17 -# accompanied this code).
    4.18 -# 
    4.19 -# You should have received a copy of the GNU General Public License version
    4.20 -# 2 along with this work; if not, write to the Free Software Foundation,
    4.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.22 -# 
    4.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    4.24 -# or visit www.oracle.com if you need additional information or have any
    4.25 -# questions.
    4.26 -#
    4.27 -hg status|grep ^\?|awk '{print $2}'|xargs rm
     5.1 --- a/bin/run_octane.sh	Thu Sep 11 15:34:13 2014 -0700
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,51 +0,0 @@
     5.4 -#!/bin/bash
     5.5 -#
     5.6 -# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
     5.7 -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8 -# 
     5.9 -# This code is free software; you can redistribute it and/or modify it
    5.10 -# under the terms of the GNU General Public License version 2 only, as
    5.11 -# published by the Free Software Foundation.
    5.12 -# 
    5.13 -# This code is distributed in the hope that it will be useful, but WITHOUT
    5.14 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.15 -# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.16 -# version 2 for more details (a copy is included in the LICENSE file that
    5.17 -# accompanied this code).
    5.18 -# 
    5.19 -# You should have received a copy of the GNU General Public License version
    5.20 -# 2 along with this work; if not, write to the Free Software Foundation,
    5.21 -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.22 -# 
    5.23 -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.24 -# or visit www.oracle.com if you need additional information or have any
    5.25 -# questions.
    5.26 -#
    5.27 -
    5.28 -LOG="./octane_$(date|sed "s/ /_/g"|sed "s/:/_/g").log"
    5.29 -
    5.30 -run_one() {
    5.31 -    sh ../bin/runopt.sh -scripting ../test/script/basic/run-octane.js -- $1 --verbose --iterations 25 | tee -a $LOG
    5.32 -}
    5.33 -
    5.34 -if [ -z $1 ]; then 
    5.35 -
    5.36 -    run_one "box2d"
    5.37 -    run_one "code-load"
    5.38 -    run_one "crypto"
    5.39 -    run_one "deltablue"
    5.40 -    run_one "earley-boyer"
    5.41 -    run_one "gbemu"
    5.42 -    run_one "mandreel"
    5.43 -    run_one "navier-stokes"
    5.44 -    run_one "pdfjs"
    5.45 -    run_one "raytrace"
    5.46 -    run_one "regexp"
    5.47 -    run_one "richards"
    5.48 -    run_one "splay"
    5.49 -    run_one "typescript"
    5.50 -    run_one "zlib"
    5.51 -
    5.52 -else
    5.53 -    run_one $1
    5.54 -fi
     6.1 --- a/make/build.xml	Thu Sep 11 15:34:13 2014 -0700
     6.2 +++ b/make/build.xml	Tue Sep 16 13:59:37 2014 -0700
     6.3 @@ -340,6 +340,13 @@
     6.4      permission java.util.PropertyPermission "nashorn.test.*", "read";
     6.5  };
     6.6  
     6.7 +grant codeBase "file:/${basedir}/test/script/basic/es6/*" {
     6.8 +    permission java.io.FilePermission "${basedir}/test/script/-", "read";
     6.9 +    permission java.io.FilePermission "$${user.dir}", "read";
    6.10 +    permission java.util.PropertyPermission "user.dir", "read";
    6.11 +    permission java.util.PropertyPermission "nashorn.test.*", "read";
    6.12 +};
    6.13 +
    6.14  grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" {
    6.15      permission java.util.PropertyPermission "java.security.policy", "read";
    6.16  };
     7.1 --- a/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Thu Sep 11 15:34:13 2014 -0700
     7.2 +++ b/src/jdk/nashorn/internal/codegen/AssignSymbols.java	Tue Sep 16 13:59:37 2014 -0700
     7.3 @@ -36,6 +36,7 @@
     7.4  import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
     7.5  import static jdk.nashorn.internal.codegen.CompilerConstants.VARARGS;
     7.6  import static jdk.nashorn.internal.ir.Symbol.HAS_OBJECT_VALUE;
     7.7 +import static jdk.nashorn.internal.ir.Symbol.IS_CONST;
     7.8  import static jdk.nashorn.internal.ir.Symbol.IS_FUNCTION_SELF;
     7.9  import static jdk.nashorn.internal.ir.Symbol.IS_GLOBAL;
    7.10  import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
    7.11 @@ -83,11 +84,13 @@
    7.12  import jdk.nashorn.internal.ir.UnaryNode;
    7.13  import jdk.nashorn.internal.ir.VarNode;
    7.14  import jdk.nashorn.internal.ir.WithNode;
    7.15 -import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
    7.16  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    7.17  import jdk.nashorn.internal.runtime.Context;
    7.18 -import jdk.nashorn.internal.runtime.Property;
    7.19 -import jdk.nashorn.internal.runtime.PropertyMap;
    7.20 +import jdk.nashorn.internal.runtime.ECMAErrors;
    7.21 +import jdk.nashorn.internal.runtime.ErrorManager;
    7.22 +import jdk.nashorn.internal.runtime.JSErrorType;
    7.23 +import jdk.nashorn.internal.runtime.ParserException;
    7.24 +import jdk.nashorn.internal.runtime.Source;
    7.25  import jdk.nashorn.internal.runtime.logging.DebugLogger;
    7.26  import jdk.nashorn.internal.runtime.logging.Loggable;
    7.27  import jdk.nashorn.internal.runtime.logging.Logger;
    7.28 @@ -101,7 +104,7 @@
    7.29   * visitor.
    7.30   */
    7.31  @Logger(name="symbols")
    7.32 -final class AssignSymbols extends NodeOperatorVisitor<LexicalContext> implements Loggable {
    7.33 +final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggable {
    7.34      private final DebugLogger log;
    7.35      private final boolean     debug;
    7.36  
    7.37 @@ -190,22 +193,21 @@
    7.38       * @param body the body of the FunctionNode we are entering
    7.39       */
    7.40      private void acceptDeclarations(final FunctionNode functionNode, final Block body) {
    7.41 -        // This visitor will assign symbol to all declared variables, except function declarations (which are taken care
    7.42 -        // in a separate step above) and "var" declarations in for loop initializers.
    7.43 -        //
    7.44 +        // This visitor will assign symbol to all declared variables, except "var" declarations in for loop initializers.
    7.45          body.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) {
    7.46              @Override
    7.47 -            public boolean enterFunctionNode(final FunctionNode nestedFn) {
    7.48 -                // Don't descend into nested functions
    7.49 -                return false;
    7.50 +            protected boolean enterDefault(final Node node) {
    7.51 +                // Don't bother visiting expressions; var is a statement, it can't be inside an expression.
    7.52 +                // This will also prevent visiting nested functions (as FunctionNode is an expression).
    7.53 +                return !(node instanceof Expression);
    7.54              }
    7.55  
    7.56              @Override
    7.57              public Node leaveVarNode(final VarNode varNode) {
    7.58                  if (varNode.isStatement()) {
    7.59                      final IdentNode ident  = varNode.getName();
    7.60 -                    final Symbol    symbol = defineSymbol(body, ident.getName(), IS_VAR);
    7.61 -                    functionNode.addDeclaredSymbol(symbol);
    7.62 +                    final Block block = varNode.isBlockScoped() ? getLexicalContext().getCurrentBlock() : body;
    7.63 +                    final Symbol symbol = defineSymbol(block, ident.getName(), ident, varNode.getSymbolFlags());
    7.64                      if (varNode.isFunctionDeclaration()) {
    7.65                          symbol.setIsFunctionDeclaration();
    7.66                      }
    7.67 @@ -303,23 +305,31 @@
    7.68          return functionNode.setBody(lc, body.setStatements(lc, newStatements));
    7.69      }
    7.70  
    7.71 -    private Symbol defineGlobalSymbol(final Block block, final String name) {
    7.72 -        return defineSymbol(block, name, IS_GLOBAL);
    7.73 -    }
    7.74 -
    7.75      /**
    7.76       * Defines a new symbol in the given block.
    7.77       *
    7.78       * @param block        the block in which to define the symbol
    7.79       * @param name         name of symbol.
    7.80 +     * @param origin       origin node
    7.81       * @param symbolFlags  Symbol flags.
    7.82       *
    7.83       * @return Symbol for given name or null for redefinition.
    7.84       */
    7.85 -    private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
    7.86 +    private Symbol defineSymbol(final Block block, final String name, final Node origin, final int symbolFlags) {
    7.87          int    flags  = symbolFlags;
    7.88 -        Symbol symbol = findSymbol(block, name); // Locate symbol.
    7.89 -        final boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
    7.90 +        final boolean isBlockScope = (flags & IS_LET) != 0 || (flags & IS_CONST) != 0;
    7.91 +        final boolean isGlobal     = (flags & KINDMASK) == IS_GLOBAL;
    7.92 +
    7.93 +        Symbol symbol;
    7.94 +        final FunctionNode function;
    7.95 +        if (isBlockScope) {
    7.96 +            // block scoped variables always live in current block, no need to look for existing symbols in parent blocks.
    7.97 +            symbol = block.getExistingSymbol(name);
    7.98 +            function = lc.getCurrentFunction();
    7.99 +        } else {
   7.100 +            symbol = findSymbol(block, name);
   7.101 +            function = lc.getFunction(block);
   7.102 +        }
   7.103  
   7.104          // Global variables are implicitly always scope variables too.
   7.105          if (isGlobal) {
   7.106 @@ -333,7 +343,6 @@
   7.107          final boolean isParam = (flags & KINDMASK) == IS_PARAM;
   7.108          final boolean isVar =   (flags & KINDMASK) == IS_VAR;
   7.109  
   7.110 -        final FunctionNode function = lc.getFunction(block);
   7.111          if (symbol != null) {
   7.112              // Symbol was already defined. Check if it needs to be redefined.
   7.113              if (isParam) {
   7.114 @@ -345,10 +354,21 @@
   7.115                      throw new AssertionError("duplicate parameter");
   7.116                  }
   7.117              } else if (isVar) {
   7.118 -                if ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET) {
   7.119 +                if (isBlockScope) {
   7.120 +                    // Check redeclaration in same block
   7.121 +                    if (symbol.hasBeenDeclared()) {
   7.122 +                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
   7.123 +                    } else {
   7.124 +                        symbol.setHasBeenDeclared();
   7.125 +                    }
   7.126 +                } else if ((flags & IS_INTERNAL) != 0) {
   7.127                      // Always create a new definition.
   7.128                      symbol = null;
   7.129                  } else {
   7.130 +                    // Found LET or CONST in parent scope of same function - s SyntaxError
   7.131 +                    if (symbol.isBlockScoped() && isLocal(lc.getCurrentFunction(), symbol)) {
   7.132 +                        throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
   7.133 +                    }
   7.134                      // Not defined in this function. Create a new definition.
   7.135                      if (!isLocal(function, symbol) || symbol.less(IS_VAR)) {
   7.136                          symbol = null;
   7.137 @@ -359,10 +379,10 @@
   7.138  
   7.139          if (symbol == null) {
   7.140              // If not found, then create a new one.
   7.141 -            Block symbolBlock;
   7.142 +            final Block symbolBlock;
   7.143  
   7.144              // Determine where to create it.
   7.145 -            if (isVar && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
   7.146 +            if (isVar && ((flags & IS_INTERNAL) != 0 || isBlockScope)) {
   7.147                  symbolBlock = block; //internal vars are always defined in the block closest to them
   7.148              } else if (isGlobal) {
   7.149                  symbolBlock = lc.getOutermostFunction().getBody();
   7.150 @@ -420,15 +440,30 @@
   7.151      @Override
   7.152      public boolean enterBlock(final Block block) {
   7.153          start(block);
   7.154 -        block.clearSymbols();
   7.155  
   7.156          if (lc.isFunctionBody()) {
   7.157 +            block.clearSymbols();
   7.158 +            final FunctionNode fn = lc.getCurrentFunction();
   7.159 +            if (isUnparsedFunction(fn)) {
   7.160 +                // It's a skipped nested function. Just mark the symbols being used by it as being in use.
   7.161 +                for(final String name: compiler.getScriptFunctionData(fn.getId()).getExternalSymbolNames()) {
   7.162 +                    nameIsUsed(name, null);
   7.163 +                }
   7.164 +                // Don't bother descending into it, it must be empty anyway.
   7.165 +                assert block.getStatements().isEmpty();
   7.166 +                return false;
   7.167 +            }
   7.168 +
   7.169              enterFunctionBody();
   7.170          }
   7.171  
   7.172          return true;
   7.173      }
   7.174  
   7.175 +    private boolean isUnparsedFunction(final FunctionNode fn) {
   7.176 +        return compiler.isOnDemandCompilation() && fn != lc.getOutermostFunction();
   7.177 +    }
   7.178 +
   7.179      @Override
   7.180      public boolean enterCatchNode(final CatchNode catchNode) {
   7.181          final IdentNode exception = catchNode.getException();
   7.182 @@ -441,7 +476,10 @@
   7.183          // If the name of the exception starts with ":e", this is a synthetic catch block, likely a catch-all. Its
   7.184          // symbol is naturally internal, and should be treated as such.
   7.185          final boolean isInternal = exname.startsWith(EXCEPTION_PREFIX.symbolName());
   7.186 -        defineSymbol(block, exname, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
   7.187 +        // IS_LET flag is required to make sure symbol is not visible outside catch block. However, we need to
   7.188 +        // clear the IS_LET flag after creation to allow redefinition of symbol inside the catch block.
   7.189 +        final Symbol symbol = defineSymbol(block, exname, catchNode, IS_VAR | IS_LET | (isInternal ? IS_INTERNAL : 0) | HAS_OBJECT_VALUE);
   7.190 +        symbol.clearFlag(IS_LET);
   7.191  
   7.192          return true;
   7.193      }
   7.194 @@ -452,15 +490,13 @@
   7.195  
   7.196          initFunctionWideVariables(functionNode, body);
   7.197  
   7.198 -        if (functionNode.isProgram()) {
   7.199 -            initGlobalSymbols(body);
   7.200 -        } else if (!functionNode.isDeclared() && !functionNode.isAnonymous()) {
   7.201 +        if (!functionNode.isProgram() && !functionNode.isDeclared() && !functionNode.isAnonymous()) {
   7.202              // It's neither declared nor program - it's a function expression then; assign it a self-symbol unless it's
   7.203              // anonymous.
   7.204              final String name = functionNode.getIdent().getName();
   7.205              assert name != null;
   7.206              assert body.getExistingSymbol(name) == null;
   7.207 -            defineSymbol(body, name, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
   7.208 +            defineSymbol(body, name, functionNode, IS_VAR | IS_FUNCTION_SELF | HAS_OBJECT_VALUE);
   7.209              if(functionNode.allVarsInScope()) { // basically, has deep eval
   7.210                  lc.setFlag(functionNode, FunctionNode.USES_SELF_SYMBOL);
   7.211              }
   7.212 @@ -471,41 +507,48 @@
   7.213  
   7.214      @Override
   7.215      public boolean enterFunctionNode(final FunctionNode functionNode) {
   7.216 -        // TODO: once we have information on symbols used by nested functions, we can stop descending into nested
   7.217 -        // functions with on-demand compilation, e.g. add
   7.218 -        // if(!thisProperties.isEmpty() && env.isOnDemandCompilation()) {
   7.219 -        //    return false;
   7.220 -        // }
   7.221          start(functionNode, false);
   7.222  
   7.223          thisProperties.push(new HashSet<String>());
   7.224  
   7.225 -        //an outermost function in our lexical context that is not a program
   7.226 -        //is possible - it is a function being compiled lazily
   7.227          if (functionNode.isDeclared()) {
   7.228 +            // Can't use lc.getCurrentBlock() as we can have an outermost function in our lexical context that
   7.229 +            // is not a program - it is a function being compiled on-demand.
   7.230              final Iterator<Block> blocks = lc.getBlocks();
   7.231              if (blocks.hasNext()) {
   7.232 -                defineSymbol(blocks.next(), functionNode.getIdent().getName(), IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
   7.233 +                final IdentNode ident = functionNode.getIdent();
   7.234 +                defineSymbol(blocks.next(), ident.getName(), ident, IS_VAR | (functionNode.isAnonymous()? IS_INTERNAL : 0));
   7.235              }
   7.236          }
   7.237  
   7.238 +        // Every function has a body, even the ones skipped on reparse (they have an empty one). We're
   7.239 +        // asserting this as even for those, enterBlock() must be invoked to correctly process symbols that
   7.240 +        // are used in them.
   7.241 +        assert functionNode.getBody() != null;
   7.242 +
   7.243          return true;
   7.244      }
   7.245  
   7.246      @Override
   7.247      public boolean enterVarNode(final VarNode varNode) {
   7.248          start(varNode);
   7.249 -        defineSymbol(lc.getCurrentBlock(), varNode.getName().getName(), IS_VAR | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
   7.250          return true;
   7.251      }
   7.252  
   7.253 +    @Override
   7.254 +    public Node leaveVarNode(final VarNode varNode) {
   7.255 +        final IdentNode ident = varNode.getName();
   7.256 +        defineSymbol(lc.getCurrentBlock(), ident.getName(), ident, varNode.getSymbolFlags() | (lc.getCurrentFunction().isProgram() ? IS_SCOPE : 0));
   7.257 +        return super.leaveVarNode(varNode);
   7.258 +    }
   7.259 +
   7.260      private Symbol exceptionSymbol() {
   7.261          return newObjectInternal(EXCEPTION_PREFIX);
   7.262      }
   7.263  
   7.264      /**
   7.265       * This has to run before fix assignment types, store any type specializations for
   7.266 -     * paramters, then turn then to objects for the generic version of this method
   7.267 +     * parameters, then turn them into objects for the generic version of this method.
   7.268       *
   7.269       * @param functionNode functionNode
   7.270       */
   7.271 @@ -597,7 +640,7 @@
   7.272      }
   7.273  
   7.274      private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) {
   7.275 -        defineSymbol(block, cc.symbolName(), flags).setNeedsSlot(true);
   7.276 +        defineSymbol(block, cc.symbolName(), null, flags).setNeedsSlot(true);
   7.277      }
   7.278  
   7.279      private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) {
   7.280 @@ -608,7 +651,7 @@
   7.281              initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL | HAS_OBJECT_VALUE);
   7.282              if (functionNode.needsArguments()) {
   7.283                  initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | HAS_OBJECT_VALUE);
   7.284 -                defineSymbol(body, ARGUMENTS_VAR.symbolName(), IS_VAR | HAS_OBJECT_VALUE);
   7.285 +                defineSymbol(body, ARGUMENTS_VAR.symbolName(), null, IS_VAR | HAS_OBJECT_VALUE);
   7.286              }
   7.287          }
   7.288  
   7.289 @@ -617,20 +660,6 @@
   7.290          initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL);
   7.291      }
   7.292  
   7.293 -
   7.294 -    /**
   7.295 -     * Move any properties from the global map into the scope of this function (which must be a program function).
   7.296 -     * @param block the function node body for which to init scope vars
   7.297 -     */
   7.298 -    private void initGlobalSymbols(final Block block) {
   7.299 -        final PropertyMap map = Context.getGlobalMap();
   7.300 -
   7.301 -        for (final Property property : map.getProperties()) {
   7.302 -            final Symbol symbol = defineGlobalSymbol(block, property.getKey());
   7.303 -            log.info("Added global symbol from property map ", symbol);
   7.304 -        }
   7.305 -    }
   7.306 -
   7.307      /**
   7.308       * Initialize parameters for function node.
   7.309       * @param functionNode the function node
   7.310 @@ -639,7 +668,7 @@
   7.311          final boolean isVarArg = functionNode.isVarArg();
   7.312          final boolean scopeParams = functionNode.allVarsInScope() || isVarArg;
   7.313          for (final IdentNode param : functionNode.getParameters()) {
   7.314 -            final Symbol symbol = defineSymbol(body, param.getName(), IS_PARAM);
   7.315 +            final Symbol symbol = defineSymbol(body, param.getName(), param, IS_PARAM);
   7.316              if(scopeParams) {
   7.317                  // NOTE: this "set is scope" is a poor substitute for clear expression of where the symbol is stored.
   7.318                  // It will force creation of scopes where they would otherwise not necessarily be needed (functions
   7.319 @@ -665,10 +694,29 @@
   7.320          return definingFn == function;
   7.321      }
   7.322  
   7.323 +    private void checkConstAssignment(final IdentNode ident) {
   7.324 +        // Check for reassignment of constant
   7.325 +        final Symbol symbol = ident.getSymbol();
   7.326 +        if (symbol.isConst()) {
   7.327 +            throwParserException(ECMAErrors.getMessage("syntax.error.assign.constant", symbol.getName()), ident);
   7.328 +        }
   7.329 +    }
   7.330 +
   7.331      @Override
   7.332 -    public Node leaveASSIGN(final BinaryNode binaryNode) {
   7.333 +    public Node leaveBinaryNode(final BinaryNode binaryNode) {
   7.334 +        if (binaryNode.isAssignment() && binaryNode.lhs() instanceof IdentNode) {
   7.335 +            checkConstAssignment((IdentNode) binaryNode.lhs());
   7.336 +        }
   7.337 +        switch (binaryNode.tokenType()) {
   7.338 +        case ASSIGN:
   7.339 +            return leaveASSIGN(binaryNode);
   7.340 +        default:
   7.341 +            return super.leaveBinaryNode(binaryNode);
   7.342 +        }
   7.343 +    }
   7.344 +
   7.345 +    private Node leaveASSIGN(final BinaryNode binaryNode) {
   7.346          // If we're assigning a property of the this object ("this.foo = ..."), record it.
   7.347 -
   7.348          final Expression lhs = binaryNode.lhs();
   7.349          if (lhs instanceof AccessNode) {
   7.350              final AccessNode accessNode = (AccessNode) lhs;
   7.351 @@ -684,23 +732,43 @@
   7.352      }
   7.353  
   7.354      @Override
   7.355 +    public Node leaveUnaryNode(final UnaryNode unaryNode) {
   7.356 +        if (unaryNode.isAssignment() && unaryNode.getExpression() instanceof IdentNode) {
   7.357 +            checkConstAssignment((IdentNode) unaryNode.getExpression());
   7.358 +        }
   7.359 +        switch (unaryNode.tokenType()) {
   7.360 +        case DELETE:
   7.361 +            return leaveDELETE(unaryNode);
   7.362 +        case TYPEOF:
   7.363 +            return leaveTYPEOF(unaryNode);
   7.364 +        default:
   7.365 +            return super.leaveUnaryNode(unaryNode);
   7.366 +        }
   7.367 +    }
   7.368 +
   7.369 +    @Override
   7.370      public Node leaveBlock(final Block block) {
   7.371 -        // It's not necessary to guard the marking of symbols as locals with this "if"condition for correctness, it's
   7.372 -        // just an optimization -- runtime type calculation is not used when the compilation is not an on-demand
   7.373 -        // optimistic compilation, so we can skip locals marking then.
   7.374 +        // It's not necessary to guard the marking of symbols as locals with this "if" condition for
   7.375 +        // correctness, it's just an optimization -- runtime type calculation is not used when the compilation
   7.376 +        // is not an on-demand optimistic compilation, so we can skip locals marking then.
   7.377          if (compiler.useOptimisticTypes() && compiler.isOnDemandCompilation()) {
   7.378 -            for (final Symbol symbol: block.getSymbols()) {
   7.379 -                if (!symbol.isScope()) {
   7.380 -                    assert symbol.isVar() || symbol.isParam();
   7.381 -                    compiler.declareLocalSymbol(symbol.getName());
   7.382 +            // OTOH, we must not declare symbols from nested functions to be locals. As we're doing on-demand
   7.383 +            // compilation, and we're skipping parsing the function bodies for nested functions, this
   7.384 +            // basically only means their parameters. It'd be enough to mistakenly declare to be a local a
   7.385 +            // symbol in the outer function named the same as one of the parameters, though.
   7.386 +            if (lc.getFunction(block) == lc.getOutermostFunction()) {
   7.387 +                for (final Symbol symbol: block.getSymbols()) {
   7.388 +                    if (!symbol.isScope()) {
   7.389 +                        assert symbol.isVar() || symbol.isParam();
   7.390 +                        compiler.declareLocalSymbol(symbol.getName());
   7.391 +                    }
   7.392                  }
   7.393              }
   7.394          }
   7.395          return block;
   7.396      }
   7.397  
   7.398 -    @Override
   7.399 -    public Node leaveDELETE(final UnaryNode unaryNode) {
   7.400 +    private Node leaveDELETE(final UnaryNode unaryNode) {
   7.401          final FunctionNode currentFunctionNode = lc.getCurrentFunction();
   7.402          final boolean      strictMode          = currentFunctionNode.isStrict();
   7.403          final Expression   rhs                 = unaryNode.getExpression();
   7.404 @@ -764,24 +832,45 @@
   7.405  
   7.406      @Override
   7.407      public Node leaveFunctionNode(final FunctionNode functionNode) {
   7.408 -
   7.409 -        return markProgramBlock(
   7.410 +        final FunctionNode finalizedFunction;
   7.411 +        if (isUnparsedFunction(functionNode)) {
   7.412 +            finalizedFunction = functionNode;
   7.413 +        } else {
   7.414 +            finalizedFunction =
   7.415 +               markProgramBlock(
   7.416                 removeUnusedSlots(
   7.417                 createSyntheticInitializers(
   7.418                 finalizeParameters(
   7.419                         lc.applyTopFlags(functionNode))))
   7.420 -                       .setThisProperties(lc, thisProperties.pop().size())
   7.421 -                       .setState(lc, CompilationState.SYMBOLS_ASSIGNED));
   7.422 +                       .setThisProperties(lc, thisProperties.pop().size()));
   7.423 +        }
   7.424 +        return finalizedFunction.setState(lc, CompilationState.SYMBOLS_ASSIGNED);
   7.425      }
   7.426  
   7.427      @Override
   7.428      public Node leaveIdentNode(final IdentNode identNode) {
   7.429 -        final String name = identNode.getName();
   7.430 -
   7.431          if (identNode.isPropertyName()) {
   7.432              return identNode;
   7.433          }
   7.434  
   7.435 +        final Symbol symbol = nameIsUsed(identNode.getName(), identNode);
   7.436 +
   7.437 +        if (!identNode.isInitializedHere()) {
   7.438 +            symbol.increaseUseCount();
   7.439 +        }
   7.440 +
   7.441 +        IdentNode newIdentNode = identNode.setSymbol(symbol);
   7.442 +
   7.443 +        // If a block-scoped var is used before its declaration mark it as dead.
   7.444 +        // We can only statically detect this for local vars, cross-function symbols require runtime checks.
   7.445 +        if (symbol.isBlockScoped() && !symbol.hasBeenDeclared() && !identNode.isDeclaredHere() && isLocal(lc.getCurrentFunction(), symbol)) {
   7.446 +            newIdentNode = newIdentNode.markDead();
   7.447 +        }
   7.448 +
   7.449 +        return end(newIdentNode);
   7.450 +    }
   7.451 +
   7.452 +    private Symbol nameIsUsed(final String name, final IdentNode origin) {
   7.453          final Block block = lc.getCurrentBlock();
   7.454  
   7.455          Symbol symbol = findSymbol(block, name);
   7.456 @@ -799,18 +888,12 @@
   7.457              // if symbol is non-local or we're in a with block, we need to put symbol in scope (if it isn't already)
   7.458              maybeForceScope(symbol);
   7.459          } else {
   7.460 -            log.info("No symbol exists. Declare as global: ", symbol);
   7.461 -            symbol = defineGlobalSymbol(block, name);
   7.462 -            Symbol.setSymbolIsScope(lc, symbol);
   7.463 +            log.info("No symbol exists. Declare as global: ", name);
   7.464 +            symbol = defineSymbol(block, name, origin, IS_GLOBAL | IS_SCOPE);
   7.465          }
   7.466  
   7.467          functionUsesSymbol(symbol);
   7.468 -
   7.469 -        if (!identNode.isInitializedHere()) {
   7.470 -            symbol.increaseUseCount();
   7.471 -        }
   7.472 -
   7.473 -        return end(identNode.setSymbol(symbol));
   7.474 +        return symbol;
   7.475      }
   7.476  
   7.477      @Override
   7.478 @@ -834,8 +917,7 @@
   7.479          return tryNode;
   7.480      }
   7.481  
   7.482 -    @Override
   7.483 -    public Node leaveTYPEOF(final UnaryNode unaryNode) {
   7.484 +    private Node leaveTYPEOF(final UnaryNode unaryNode) {
   7.485          final Expression rhs = unaryNode.getExpression();
   7.486  
   7.487          final List<Expression> args = new ArrayList<>();
   7.488 @@ -859,7 +941,6 @@
   7.489              return functionNode;
   7.490          }
   7.491  
   7.492 -        assert functionNode.getId() == 1;
   7.493          return functionNode.setBody(lc, functionNode.getBody().setFlag(lc, Block.IS_GLOBAL_SCOPE));
   7.494      }
   7.495  
   7.496 @@ -875,7 +956,7 @@
   7.497      }
   7.498  
   7.499      private Symbol newInternal(final CompilerConstants cc, final int flags) {
   7.500 -        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), IS_VAR | IS_INTERNAL | flags); //NASHORN-73
   7.501 +        return defineSymbol(lc.getCurrentBlock(), lc.getCurrentFunction().uniqueName(cc.symbolName()), null, IS_VAR | IS_INTERNAL | flags); //NASHORN-73
   7.502      }
   7.503  
   7.504      private Symbol newObjectInternal(final CompilerConstants cc) {
   7.505 @@ -915,7 +996,8 @@
   7.506              return false;
   7.507          }
   7.508  
   7.509 -        if (lc.getCurrentFunction().allVarsInScope()) {
   7.510 +        final FunctionNode func = lc.getCurrentFunction();
   7.511 +        if ( func.allVarsInScope() || (!symbol.isBlockScoped() && func.isProgram())) {
   7.512              return true;
   7.513          }
   7.514  
   7.515 @@ -955,4 +1037,16 @@
   7.516          final List<ArrayUnit> units = ((ArrayLiteralNode)expr).getUnits();
   7.517          return !(units == null || units.isEmpty());
   7.518      }
   7.519 +
   7.520 +    private void throwParserException(final String message, final Node origin) {
   7.521 +        if (origin == null) {
   7.522 +            throw new ParserException(message);
   7.523 +        }
   7.524 +        final Source source = compiler.getSource();
   7.525 +        final long token = origin.getToken();
   7.526 +        final int line = source.getLine(origin.getStart());
   7.527 +        final int column = source.getColumn(origin.getStart());
   7.528 +        final String formatted = ErrorManager.format(message, source, line, column, token);
   7.529 +        throw new ParserException(JSErrorType.SYNTAX_ERROR, formatted, source, line, column, token);
   7.530 +    }
   7.531  }
     8.1 --- a/src/jdk/nashorn/internal/codegen/ClassEmitter.java	Thu Sep 11 15:34:13 2014 -0700
     8.2 +++ b/src/jdk/nashorn/internal/codegen/ClassEmitter.java	Tue Sep 16 13:59:37 2014 -0700
     8.3 @@ -59,6 +59,7 @@
     8.4  import java.util.EnumSet;
     8.5  import java.util.HashSet;
     8.6  import java.util.Set;
     8.7 +
     8.8  import jdk.internal.org.objectweb.asm.ClassWriter;
     8.9  import jdk.internal.org.objectweb.asm.MethodVisitor;
    8.10  import jdk.internal.org.objectweb.asm.util.TraceClassVisitor;
    8.11 @@ -135,6 +136,16 @@
    8.12      /** Set of constants access methods required. */
    8.13      private Set<Class<?>> constantMethodNeeded;
    8.14  
    8.15 +    private int methodCount;
    8.16 +
    8.17 +    private int initCount;
    8.18 +
    8.19 +    private int clinitCount;
    8.20 +
    8.21 +    private int fieldCount;
    8.22 +
    8.23 +    private final Set<String> methodNames;
    8.24 +
    8.25      /**
    8.26       * Constructor - only used internally in this class as it breaks
    8.27       * abstraction towards ASM or other code generator below
    8.28 @@ -146,6 +157,11 @@
    8.29          this.context        = context;
    8.30          this.cw             = cw;
    8.31          this.methodsStarted = new HashSet<>();
    8.32 +        this.methodNames    = new HashSet<>();
    8.33 +    }
    8.34 +
    8.35 +    public Set<String> getMethodNames() {
    8.36 +        return methodNames;
    8.37      }
    8.38  
    8.39      /**
    8.40 @@ -209,6 +225,38 @@
    8.41      }
    8.42  
    8.43      /**
    8.44 +     * Get the method count, including init and clinit methods
    8.45 +     * @return method count
    8.46 +     */
    8.47 +    public int getMethodCount() {
    8.48 +        return methodCount;
    8.49 +    }
    8.50 +
    8.51 +    /**
    8.52 +     * Get the clinit count
    8.53 +     * @return clinit count
    8.54 +     */
    8.55 +    public int getClinitCount() {
    8.56 +        return clinitCount;
    8.57 +    }
    8.58 +
    8.59 +    /**
    8.60 +     * Get the init count
    8.61 +     * @return init count
    8.62 +     */
    8.63 +    public int getInitCount() {
    8.64 +        return initCount;
    8.65 +    }
    8.66 +
    8.67 +    /**
    8.68 +     * Get the field count
    8.69 +     * @return field count
    8.70 +     */
    8.71 +    public int getFieldCount() {
    8.72 +        return fieldCount;
    8.73 +    }
    8.74 +
    8.75 +    /**
    8.76       * Convert a binary name to a package/class name.
    8.77       *
    8.78       * @param name Binary name.
    8.79 @@ -359,9 +407,16 @@
    8.80       */
    8.81      @Override
    8.82      public void end() {
    8.83 -        assert classStarted;
    8.84 +        assert classStarted : "class not started for " + unitClassName;
    8.85  
    8.86          if (unitClassName != null) {
    8.87 +            final MethodEmitter initMethod = init(EnumSet.of(Flag.PRIVATE));
    8.88 +            initMethod.begin();
    8.89 +            initMethod.load(Type.OBJECT, 0);
    8.90 +            initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class);
    8.91 +            initMethod.returnVoid();
    8.92 +            initMethod.end();
    8.93 +
    8.94              defineCommonUtilities();
    8.95          }
    8.96  
    8.97 @@ -419,6 +474,8 @@
    8.98      }
    8.99  
   8.100      SplitMethodEmitter method(final SplitNode splitNode, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
   8.101 +        methodCount++;
   8.102 +        methodNames.add(methodName);
   8.103          return new SplitMethodEmitter(this, methodVisitor(EnumSet.of(Flag.PUBLIC, Flag.STATIC), methodName, rtype, ptypes), splitNode);
   8.104      }
   8.105  
   8.106 @@ -446,6 +503,8 @@
   8.107       * @return method emitter to use for weaving this method
   8.108       */
   8.109      MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final Class<?> rtype, final Class<?>... ptypes) {
   8.110 +        methodCount++;
   8.111 +        methodNames.add(methodName);
   8.112          return new MethodEmitter(this, methodVisitor(methodFlags, methodName, rtype, ptypes));
   8.113      }
   8.114  
   8.115 @@ -471,6 +530,8 @@
   8.116       * @return method emitter to use for weaving this method
   8.117       */
   8.118      MethodEmitter method(final EnumSet<Flag> methodFlags, final String methodName, final String descriptor) {
   8.119 +        methodCount++;
   8.120 +        methodNames.add(methodName);
   8.121          return new MethodEmitter(this, cw.visitMethod(Flag.getValue(methodFlags), methodName, descriptor, null, null));
   8.122      }
   8.123  
   8.124 @@ -481,6 +542,8 @@
   8.125       * @return method emitter to use for weaving this method
   8.126       */
   8.127      MethodEmitter method(final FunctionNode functionNode) {
   8.128 +        methodCount++;
   8.129 +        methodNames.add(functionNode.getName());
   8.130          final FunctionSignature signature = new FunctionSignature(functionNode);
   8.131          final MethodVisitor mv = cw.visitMethod(
   8.132              ACC_PUBLIC | ACC_STATIC | (functionNode.isVarArg() ? ACC_VARARGS : 0),
   8.133 @@ -499,6 +562,8 @@
   8.134       * @return method emitter to use for weaving this method
   8.135       */
   8.136      MethodEmitter restOfMethod(final FunctionNode functionNode) {
   8.137 +        methodCount++;
   8.138 +        methodNames.add(functionNode.getName());
   8.139          final MethodVisitor mv = cw.visitMethod(
   8.140              ACC_PUBLIC | ACC_STATIC,
   8.141              functionNode.getName(),
   8.142 @@ -516,6 +581,7 @@
   8.143       * @return method emitter to use for weaving <clinit>
   8.144       */
   8.145      MethodEmitter clinit() {
   8.146 +        clinitCount++;
   8.147          return method(EnumSet.of(Flag.STATIC), CLINIT.symbolName(), void.class);
   8.148      }
   8.149  
   8.150 @@ -525,6 +591,7 @@
   8.151       * @return method emitter to use for weaving <init>()V
   8.152       */
   8.153      MethodEmitter init() {
   8.154 +        initCount++;
   8.155          return method(INIT.symbolName(), void.class);
   8.156      }
   8.157  
   8.158 @@ -535,6 +602,7 @@
   8.159       * @return method emitter to use for weaving <init>()V
   8.160       */
   8.161      MethodEmitter init(final Class<?>... ptypes) {
   8.162 +        initCount++;
   8.163          return method(INIT.symbolName(), void.class, ptypes);
   8.164      }
   8.165  
   8.166 @@ -547,6 +615,7 @@
   8.167       * @return method emitter to use for weaving <init>(...)V
   8.168       */
   8.169      MethodEmitter init(final EnumSet<Flag> flags, final Class<?>... ptypes) {
   8.170 +        initCount++;
   8.171          return method(flags, INIT.symbolName(), void.class, ptypes);
   8.172      }
   8.173  
   8.174 @@ -561,6 +630,7 @@
   8.175       * @see ClassEmitter.Flag
   8.176       */
   8.177      final void field(final EnumSet<Flag> fieldFlags, final String fieldName, final Class<?> fieldType, final Object value) {
   8.178 +        fieldCount++;
   8.179          cw.visitField(Flag.getValue(fieldFlags), fieldName, typeDescriptor(fieldType), null, value).visitEnd();
   8.180      }
   8.181  
     9.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Thu Sep 11 15:34:13 2014 -0700
     9.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java	Tue Sep 16 13:59:37 2014 -0700
     9.3 @@ -52,6 +52,7 @@
     9.4  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
     9.5  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
     9.6  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_APPLY_TO_CALL;
     9.7 +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_DECLARE;
     9.8  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
     9.9  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_OPTIMISTIC;
    9.10  import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
    9.11 @@ -302,6 +303,7 @@
    9.12       * @return the method generator used
    9.13       */
    9.14      private MethodEmitter loadIdent(final IdentNode identNode, final TypeBounds resultBounds) {
    9.15 +        checkTemporalDeadZone(identNode);
    9.16          final Symbol symbol = identNode.getSymbol();
    9.17  
    9.18          if (!symbol.isScope()) {
    9.19 @@ -334,6 +336,15 @@
    9.20          return method;
    9.21      }
    9.22  
    9.23 +    // Any access to LET and CONST variables before their declaration must throw ReferenceError.
    9.24 +    // This is called the temporal dead zone (TDZ). See https://gist.github.com/rwaldron/f0807a758aa03bcdd58a
    9.25 +    private void checkTemporalDeadZone(final IdentNode identNode) {
    9.26 +        if (identNode.isDead()) {
    9.27 +            method.load(identNode.getSymbol().getName());
    9.28 +            method.invoke(ScriptRuntime.THROW_REFERENCE_ERROR);
    9.29 +        }
    9.30 +    }
    9.31 +
    9.32      private boolean isRestOf() {
    9.33          return continuationEntryPoints != null;
    9.34      }
    9.35 @@ -1611,9 +1622,18 @@
    9.36  
    9.37              @Override
    9.38              protected void evaluate() {
    9.39 -                method.load(ITERATOR_TYPE, iterSlot);
    9.40 -                // TODO: optimistic for-in iteration
    9.41 -                method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "next", Object.class));
    9.42 +                new OptimisticOperation((Optimistic)forNode.getInit(), TypeBounds.UNBOUNDED) {
    9.43 +                    @Override
    9.44 +                    void loadStack() {
    9.45 +                        method.load(ITERATOR_TYPE, iterSlot);
    9.46 +                    }
    9.47 +
    9.48 +                    @Override
    9.49 +                    void consumeStack() {
    9.50 +                        method.invoke(interfaceCallNoLookup(ITERATOR_CLASS, "next", Object.class));
    9.51 +                        convertOptimisticReturnValue();
    9.52 +                    }
    9.53 +                }.emit();
    9.54              }
    9.55          }.store();
    9.56          body.accept(this);
    9.57 @@ -3216,27 +3236,34 @@
    9.58              return false;
    9.59          }
    9.60          final Expression init = varNode.getInit();
    9.61 -
    9.62 -        if (init == null) {
    9.63 -            return false;
    9.64 -        }
    9.65 -
    9.66 -        enterStatement(varNode);
    9.67 -
    9.68          final IdentNode identNode = varNode.getName();
    9.69          final Symbol identSymbol = identNode.getSymbol();
    9.70          assert identSymbol != null : "variable node " + varNode + " requires a name with a symbol";
    9.71 -
    9.72 +        final boolean needsScope = identSymbol.isScope();
    9.73 +
    9.74 +        if (init == null) {
    9.75 +            if (needsScope && varNode.isBlockScoped()) {
    9.76 +                // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
    9.77 +                method.loadCompilerConstant(SCOPE);
    9.78 +                method.loadUndefined(Type.OBJECT);
    9.79 +                final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
    9.80 +                assert isFastScope(identSymbol);
    9.81 +                storeFastScopeVar(identSymbol, flags);
    9.82 +            }
    9.83 +            return false;
    9.84 +        }
    9.85 +
    9.86 +        enterStatement(varNode);
    9.87          assert method != null;
    9.88  
    9.89 -        final boolean needsScope = identSymbol.isScope();
    9.90          if (needsScope) {
    9.91              method.loadCompilerConstant(SCOPE);
    9.92          }
    9.93  
    9.94          if (needsScope) {
    9.95              loadExpressionUnbounded(init);
    9.96 -            final int flags = CALLSITE_SCOPE | getCallSiteFlags();
    9.97 +            // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
    9.98 +            final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
    9.99              if (isFastScope(identSymbol)) {
   9.100                  storeFastScopeVar(identSymbol, flags);
   9.101              } else {
   9.102 @@ -4343,6 +4370,9 @@
   9.103          protected abstract void evaluate();
   9.104  
   9.105          void store() {
   9.106 +            if (target instanceof IdentNode) {
   9.107 +                checkTemporalDeadZone((IdentNode)target);
   9.108 +            }
   9.109              prologue();
   9.110              evaluate(); // leaves an operation of whatever the operationType was on the stack
   9.111              storeNonDiscard();
    10.1 --- a/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Thu Sep 11 15:34:13 2014 -0700
    10.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGeneratorLexicalContext.java	Tue Sep 16 13:59:37 2014 -0700
    10.3 @@ -31,6 +31,7 @@
    10.4  import java.util.Deque;
    10.5  import java.util.HashMap;
    10.6  import java.util.Map;
    10.7 +
    10.8  import jdk.nashorn.internal.IntDeque;
    10.9  import jdk.nashorn.internal.codegen.types.Type;
   10.10  import jdk.nashorn.internal.ir.Block;
   10.11 @@ -158,7 +159,9 @@
   10.12  
   10.13      CompileUnit popCompileUnit(final CompileUnit oldUnit) {
   10.14          assert compileUnits.peek() == oldUnit;
   10.15 -        compileUnits.pop();
   10.16 +        final CompileUnit unit = compileUnits.pop();
   10.17 +        assert unit.hasCode() : "compile unit popped without code";
   10.18 +        unit.setUsed();
   10.19          return compileUnits.isEmpty() ? null : compileUnits.peek();
   10.20      }
   10.21  
    11.1 --- a/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Thu Sep 11 15:34:13 2014 -0700
    11.2 +++ b/src/jdk/nashorn/internal/codegen/CompilationPhase.java	Tue Sep 16 13:59:37 2014 -0700
    11.3 @@ -48,6 +48,7 @@
    11.4  import java.util.Map;
    11.5  import java.util.Map.Entry;
    11.6  import java.util.Set;
    11.7 +
    11.8  import jdk.nashorn.internal.AssertsEnabled;
    11.9  import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
   11.10  import jdk.nashorn.internal.ir.FunctionNode;
   11.11 @@ -300,6 +301,7 @@
   11.12          }
   11.13      },
   11.14  
   11.15 +
   11.16      /**
   11.17       * Reuse compile units, if they are already present. We are using the same compiler
   11.18       * to recompile stuff
   11.19 @@ -334,6 +336,8 @@
   11.20                  if (phases.isRestOfCompilation()) {
   11.21                      sb.append("$restOf");
   11.22                  }
   11.23 +                //it's ok to not copy the initCount, methodCount and clinitCount here, as codegen is what
   11.24 +                //fills those out anyway. Thus no need for a copy constructor
   11.25                  final CompileUnit newUnit = compiler.createCompileUnit(sb.toString(), oldUnit.getWeight());
   11.26                  log.fine("Creating new compile unit ", oldUnit, " => ", newUnit);
   11.27                  map.put(oldUnit, newUnit);
   11.28 @@ -430,8 +434,14 @@
   11.29  
   11.30              FunctionNode newFunctionNode = fn;
   11.31  
   11.32 +            //root class is special, as it is bootstrapped from createProgramFunction, thus it's skipped
   11.33 +            //in CodeGeneration - the rest can be used as a working "is compile unit used" metric
   11.34 +            fn.getCompileUnit().setUsed();
   11.35 +
   11.36              compiler.getLogger().fine("Starting bytecode generation for ", quote(fn.getName()), " - restOf=", phases.isRestOfCompilation());
   11.37 +
   11.38              final CodeGenerator codegen = new CodeGenerator(compiler, phases.isRestOfCompilation() ? compiler.getContinuationEntryPoints() : null);
   11.39 +
   11.40              try {
   11.41                  // Explicitly set BYTECODE_GENERATED here; it can not be set in case of skipping codegen for :program
   11.42                  // in the lazy + optimistic world. See CodeGenerator.skipFunction().
   11.43 @@ -455,12 +465,18 @@
   11.44                  final ClassEmitter classEmitter = compileUnit.getClassEmitter();
   11.45                  classEmitter.end();
   11.46  
   11.47 +                if (!compileUnit.isUsed()) {
   11.48 +                    compiler.getLogger().fine("Skipping unused compile unit ", compileUnit);
   11.49 +                    continue;
   11.50 +                }
   11.51 +
   11.52                  final byte[] bytecode = classEmitter.toByteArray();
   11.53                  assert bytecode != null;
   11.54  
   11.55                  final String className = compileUnit.getUnitClassName();
   11.56 +                compiler.addClass(className, bytecode); //classes are only added to the bytecode map if compile unit is used
   11.57  
   11.58 -                compiler.addClass(className, bytecode);
   11.59 +                CompileUnit.increaseEmitCount();
   11.60  
   11.61                  // should we verify the generated code?
   11.62                  if (senv._verify_code) {
   11.63 @@ -536,6 +552,9 @@
   11.64  
   11.65              // initialize function in the compile units
   11.66              for (final CompileUnit unit : compiler.getCompileUnits()) {
   11.67 +                if (!unit.isUsed()) {
   11.68 +                    continue;
   11.69 +                }
   11.70                  unit.setCode(installedClasses.get(unit.getUnitClassName()));
   11.71              }
   11.72  
    12.1 --- a/src/jdk/nashorn/internal/codegen/CompileUnit.java	Thu Sep 11 15:34:13 2014 -0700
    12.2 +++ b/src/jdk/nashorn/internal/codegen/CompileUnit.java	Tue Sep 16 13:59:37 2014 -0700
    12.3 @@ -42,6 +42,10 @@
    12.4  
    12.5      private Class<?> clazz;
    12.6  
    12.7 +    private boolean isUsed;
    12.8 +
    12.9 +    private static int emittedUnitCount;
   12.10 +
   12.11      CompileUnit(final String className, final ClassEmitter classEmitter, final long initialWeight) {
   12.12          this.className    = className;
   12.13          this.weight       = initialWeight;
   12.14 @@ -52,6 +56,33 @@
   12.15          return new TreeSet<>();
   12.16      }
   12.17  
   12.18 +    static void increaseEmitCount() {
   12.19 +        emittedUnitCount++;
   12.20 +    }
   12.21 +
   12.22 +    public static int getEmittedUnitCount() {
   12.23 +        return emittedUnitCount;
   12.24 +    }
   12.25 +
   12.26 +    /**
   12.27 +     * Check if this compile unit is used
   12.28 +     * @return true if tagged as in use - i.e active code that needs to be generated
   12.29 +     */
   12.30 +    public boolean isUsed() {
   12.31 +        return isUsed;
   12.32 +    }
   12.33 +
   12.34 +    public boolean hasCode() {
   12.35 +        return (classEmitter.getMethodCount() - classEmitter.getInitCount() - classEmitter.getClinitCount()) > 0;
   12.36 +    }
   12.37 +
   12.38 +    /**
   12.39 +     * Tag this compile unit as used
   12.40 +     */
   12.41 +    public void setUsed() {
   12.42 +        this.isUsed = true;
   12.43 +    }
   12.44 +
   12.45      /**
   12.46       * Return the class that contains the code for this unit, null if not
   12.47       * generated yet
   12.48 @@ -121,7 +152,8 @@
   12.49  
   12.50      @Override
   12.51      public String toString() {
   12.52 -        return "[CompileUnit className=" + shortName(className) + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + ']';
   12.53 +        final String methods = classEmitter != null ? classEmitter.getMethodNames().toString() : "<anon>";
   12.54 +        return "[CompileUnit className=" + shortName(className) + " weight=" + weight + '/' + Splitter.SPLIT_THRESHOLD + " hasCode=" + methods + ']';
   12.55      }
   12.56  
   12.57      @Override
    13.1 --- a/src/jdk/nashorn/internal/codegen/Compiler.java	Thu Sep 11 15:34:13 2014 -0700
    13.2 +++ b/src/jdk/nashorn/internal/codegen/Compiler.java	Tue Sep 16 13:59:37 2014 -0700
    13.3 @@ -38,7 +38,6 @@
    13.4  import java.util.Arrays;
    13.5  import java.util.Collections;
    13.6  import java.util.Comparator;
    13.7 -import java.util.EnumSet;
    13.8  import java.util.HashMap;
    13.9  import java.util.Iterator;
   13.10  import java.util.LinkedHashMap;
   13.11 @@ -51,18 +50,21 @@
   13.12  import java.util.function.Consumer;
   13.13  import java.util.logging.Level;
   13.14  import jdk.internal.dynalink.support.NameCodec;
   13.15 -import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
   13.16  import jdk.nashorn.internal.codegen.types.Type;
   13.17 +import jdk.nashorn.internal.ir.Expression;
   13.18  import jdk.nashorn.internal.ir.FunctionNode;
   13.19  import jdk.nashorn.internal.ir.Optimistic;
   13.20  import jdk.nashorn.internal.ir.debug.ClassHistogramElement;
   13.21  import jdk.nashorn.internal.ir.debug.ObjectSizeCalculator;
   13.22  import jdk.nashorn.internal.runtime.CodeInstaller;
   13.23  import jdk.nashorn.internal.runtime.Context;
   13.24 +import jdk.nashorn.internal.runtime.ErrorManager;
   13.25  import jdk.nashorn.internal.runtime.FunctionInitializer;
   13.26 +import jdk.nashorn.internal.runtime.ParserException;
   13.27  import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   13.28  import jdk.nashorn.internal.runtime.ScriptEnvironment;
   13.29  import jdk.nashorn.internal.runtime.ScriptObject;
   13.30 +import jdk.nashorn.internal.runtime.ScriptRuntime;
   13.31  import jdk.nashorn.internal.runtime.Source;
   13.32  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   13.33  import jdk.nashorn.internal.runtime.logging.Loggable;
   13.34 @@ -89,6 +91,8 @@
   13.35  
   13.36      private final String sourceName;
   13.37  
   13.38 +    private final ErrorManager errors;
   13.39 +
   13.40      private final boolean optimistic;
   13.41  
   13.42      private final Map<String, byte[]> bytecode;
   13.43 @@ -244,6 +248,15 @@
   13.44              return new CompilationPhases(desc, list.toArray(new CompilationPhase[list.size()]));
   13.45          }
   13.46  
   13.47 +        @SuppressWarnings("unused") //TODO I'll use this soon
   13.48 +        private CompilationPhases replace(final CompilationPhase phase, final CompilationPhase newPhase) {
   13.49 +            final LinkedList<CompilationPhase> list = new LinkedList<>();
   13.50 +            for (final CompilationPhase p : phases) {
   13.51 +                list.add(p == phase ? newPhase : p);
   13.52 +            }
   13.53 +            return new CompilationPhases(desc, list.toArray(new CompilationPhase[list.size()]));
   13.54 +        }
   13.55 +
   13.56          private CompilationPhases addAfter(final CompilationPhase phase, final CompilationPhase newPhase) {
   13.57              final LinkedList<CompilationPhase> list = new LinkedList<>();
   13.58              for (final CompilationPhase p : phases) {
   13.59 @@ -311,6 +324,7 @@
   13.60       * @param env       script environment
   13.61       * @param installer code installer
   13.62       * @param source    source to compile
   13.63 +     * @param errors    error manager
   13.64       * @param isStrict  is this a strict compilation
   13.65       */
   13.66      public Compiler(
   13.67 @@ -318,8 +332,9 @@
   13.68              final ScriptEnvironment env,
   13.69              final CodeInstaller<ScriptEnvironment> installer,
   13.70              final Source source,
   13.71 +            final ErrorManager errors,
   13.72              final boolean isStrict) {
   13.73 -        this(context, env, installer, source, isStrict, false, null, null, null, null, null, null);
   13.74 +        this(context, env, installer, source, errors, isStrict, false, null, null, null, null, null, null);
   13.75      }
   13.76  
   13.77      /**
   13.78 @@ -329,6 +344,7 @@
   13.79       * @param env                      script environment
   13.80       * @param installer                code installer
   13.81       * @param source                   source to compile
   13.82 +     * @param errors                   error manager
   13.83       * @param isStrict                 is this a strict compilation
   13.84       * @param isOnDemand               is this an on demand compilation
   13.85       * @param compiledFunction         compiled function, if any
   13.86 @@ -343,6 +359,7 @@
   13.87              final ScriptEnvironment env,
   13.88              final CodeInstaller<ScriptEnvironment> installer,
   13.89              final Source source,
   13.90 +            final ErrorManager errors,
   13.91              final boolean isStrict,
   13.92              final boolean isOnDemand,
   13.93              final RecompilableScriptFunctionData compiledFunction,
   13.94 @@ -359,6 +376,7 @@
   13.95          this.bytecode                 = new LinkedHashMap<>();
   13.96          this.log                      = initLogger(context);
   13.97          this.source                   = source;
   13.98 +        this.errors                   = errors;
   13.99          this.sourceName               = FunctionNode.getSourceName(source);
  13.100          this.onDemand                 = isOnDemand;
  13.101          this.compiledFunction         = compiledFunction;
  13.102 @@ -464,6 +482,19 @@
  13.103          return typeEvaluator.getOptimisticType(node);
  13.104      }
  13.105  
  13.106 +    /**
  13.107 +     * Returns true if the expression can be safely evaluated, and its value is an object known to always use
  13.108 +     * String as the type of its property names retrieved through
  13.109 +     * {@link ScriptRuntime#toPropertyIterator(Object)}. It is used to avoid optimistic assumptions about its
  13.110 +     * property name types.
  13.111 +     * @param expr the expression to test
  13.112 +     * @return true if the expression can be safely evaluated, and its value is an object known to always use
  13.113 +     * String as the type of its property iterators.
  13.114 +     */
  13.115 +    boolean hasStringPropertyIterator(final Expression expr) {
  13.116 +        return typeEvaluator.hasStringPropertyIterator(expr);
  13.117 +    }
  13.118 +
  13.119      void addInvalidatedProgramPoint(final int programPoint, final Type type) {
  13.120          invalidatedProgramPoints.put(programPoint, type);
  13.121      }
  13.122 @@ -524,7 +555,17 @@
  13.123  
  13.124          for (final CompilationPhase phase : phases) {
  13.125              log.fine(phase, " starting for ", quote(name));
  13.126 -            newFunctionNode = phase.apply(this, phases, newFunctionNode);
  13.127 +
  13.128 +            try {
  13.129 +                newFunctionNode = phase.apply(this, phases, newFunctionNode);
  13.130 +            } catch (final ParserException error) {
  13.131 +                errors.error(error);
  13.132 +                if (env._dump_on_error) {
  13.133 +                    error.printStackTrace(env.getErr());
  13.134 +                }
  13.135 +                return null;
  13.136 +            }
  13.137 +
  13.138              log.fine(phase, " done for function ", quote(name));
  13.139  
  13.140              if (env._print_mem_usage) {
  13.141 @@ -656,16 +697,8 @@
  13.142      CompileUnit createCompileUnit(final String unitClassName, final long initialWeight) {
  13.143          final ClassEmitter classEmitter = new ClassEmitter(context, sourceName, unitClassName, isStrict());
  13.144          final CompileUnit  compileUnit  = new CompileUnit(unitClassName, classEmitter, initialWeight);
  13.145 -
  13.146          classEmitter.begin();
  13.147  
  13.148 -        final MethodEmitter initMethod = classEmitter.init(EnumSet.of(Flag.PRIVATE));
  13.149 -        initMethod.begin();
  13.150 -        initMethod.load(Type.OBJECT, 0);
  13.151 -        initMethod.newInstance(jdk.nashorn.internal.scripts.JS.class);
  13.152 -        initMethod.returnVoid();
  13.153 -        initMethod.end();
  13.154 -
  13.155          return compileUnit;
  13.156      }
  13.157  
  13.158 @@ -703,13 +736,6 @@
  13.159          return name.replace('/', '.');
  13.160      }
  13.161  
  13.162 -    RecompilableScriptFunctionData getProgram() {
  13.163 -        if (compiledFunction == null) {
  13.164 -            return null;
  13.165 -        }
  13.166 -        return compiledFunction.getProgram();
  13.167 -    }
  13.168 -
  13.169      RecompilableScriptFunctionData getScriptFunctionData(final int functionId) {
  13.170          return compiledFunction == null ? null : compiledFunction.getScriptFunctionData(functionId);
  13.171      }
    14.1 --- a/src/jdk/nashorn/internal/codegen/DumpBytecode.java	Thu Sep 11 15:34:13 2014 -0700
    14.2 +++ b/src/jdk/nashorn/internal/codegen/DumpBytecode.java	Tue Sep 16 13:59:37 2014 -0700
    14.3 @@ -89,7 +89,7 @@
    14.4  
    14.5  
    14.6              // should code be dumped to disk - only valid in compile_only mode?
    14.7 -            if (env._dest_dir != null && env._compile_only) {
    14.8 +            if (env._dest_dir != null) {
    14.9                  final String fileName = className.replace('.', File.separatorChar) + ".class";
   14.10                  final int    index    = fileName.lastIndexOf(File.separatorChar);
   14.11  
    15.1 --- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Thu Sep 11 15:34:13 2014 -0700
    15.2 +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Tue Sep 16 13:59:37 2014 -0700
    15.3 @@ -69,9 +69,7 @@
    15.4       * Constructor
    15.5       *
    15.6       * @param codegen  code generator
    15.7 -     * @param keys     keys for fields in object
    15.8 -     * @param symbols  symbols for fields in object
    15.9 -     * @param values   list of values corresponding to keys
   15.10 +     * @param tuples   tuples for fields in object
   15.11       */
   15.12      FieldObjectCreator(final CodeGenerator codegen, final List<MapTuple<T>> tuples) {
   15.13          this(codegen, tuples, false, false);
   15.14 @@ -81,9 +79,7 @@
   15.15       * Constructor
   15.16       *
   15.17       * @param codegen      code generator
   15.18 -     * @param keys         keys for fields in object
   15.19 -     * @param symbols      symbols for fields in object
   15.20 -     * @param values       values (or null where no value) to be written to the fields
   15.21 +     * @param tuples       tuples for fields in object
   15.22       * @param isScope      is this a scope object
   15.23       * @param hasArguments does the created object have an "arguments" property
   15.24       */
   15.25 @@ -165,7 +161,7 @@
   15.26       * @param method      Script method.
   15.27       * @param key         Property key.
   15.28       * @param fieldIndex  Field number.
   15.29 -     * @param value       Value to store.
   15.30 +     * @param tuple       Tuple to store.
   15.31       */
   15.32      private void putField(final MethodEmitter method, final String key, final int fieldIndex, final MapTuple<T> tuple) {
   15.33          method.dup();
   15.34 @@ -188,7 +184,7 @@
   15.35       *
   15.36       * @param method Script method.
   15.37       * @param index  Slot index.
   15.38 -     * @param value  Value to store.
   15.39 +     * @param tuple  Tuple to store.
   15.40       */
   15.41      private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) {
   15.42          method.dup();
    16.1 --- a/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Thu Sep 11 15:34:13 2014 -0700
    16.2 +++ b/src/jdk/nashorn/internal/codegen/FindScopeDepths.java	Tue Sep 16 13:59:37 2014 -0700
    16.3 @@ -25,8 +25,6 @@
    16.4  
    16.5  package jdk.nashorn.internal.codegen;
    16.6  
    16.7 -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getClassName;
    16.8 -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
    16.9  import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
   16.10  
   16.11  import java.util.HashMap;
   16.12 @@ -34,6 +32,7 @@
   16.13  import java.util.Iterator;
   16.14  import java.util.Map;
   16.15  import java.util.Set;
   16.16 +import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
   16.17  import jdk.nashorn.internal.ir.Block;
   16.18  import jdk.nashorn.internal.ir.FunctionNode;
   16.19  import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
   16.20 @@ -44,7 +43,6 @@
   16.21  import jdk.nashorn.internal.ir.WithNode;
   16.22  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   16.23  import jdk.nashorn.internal.runtime.Context;
   16.24 -import jdk.nashorn.internal.runtime.PropertyMap;
   16.25  import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   16.26  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   16.27  import jdk.nashorn.internal.runtime.logging.Loggable;
   16.28 @@ -208,14 +206,10 @@
   16.29  
   16.30          assert nestedFunctions != null;
   16.31          // Generate the object class and property map in case this function is ever used as constructor
   16.32 -        final int         fieldCount         = getPaddedFieldCount(newFunctionNode.getThisProperties());
   16.33 -        final String      allocatorClassName = Compiler.binaryName(getClassName(fieldCount));
   16.34 -        final PropertyMap allocatorMap       = PropertyMap.newMap(null, allocatorClassName, 0, fieldCount, 0);
   16.35          final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData(
   16.36                  newFunctionNode,
   16.37                  compiler.getCodeInstaller(),
   16.38 -                allocatorClassName,
   16.39 -                allocatorMap,
   16.40 +                new AllocatorDescriptor(newFunctionNode.getThisProperties()),
   16.41                  nestedFunctions,
   16.42                  externalSymbolDepths.get(fnId),
   16.43                  internalSymbols.get(fnId)
    17.1 --- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Thu Sep 11 15:34:13 2014 -0700
    17.2 +++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java	Tue Sep 16 13:59:37 2014 -0700
    17.3 @@ -551,13 +551,19 @@
    17.4  
    17.5          final Expression init = forNode.getInit();
    17.6          if(forNode.isForIn()) {
    17.7 -            forNode.getModify().accept(this);
    17.8 -            enterTestFirstLoop(forNode, null, init);
    17.9 +            final JoinPredecessorExpression iterable = forNode.getModify();
   17.10 +            iterable.accept(this);
   17.11 +            enterTestFirstLoop(forNode, null, init,
   17.12 +                    // If we're iterating over property names, and we can discern from the runtime environment
   17.13 +                    // of the compilation that the object being iterated over must use strings for property
   17.14 +                    // names (e.g., it is a native JS object or array), then we'll not bother trying to treat
   17.15 +                    // the property names optimistically.
   17.16 +                    !forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()));
   17.17          } else {
   17.18              if(init != null) {
   17.19                  init.accept(this);
   17.20              }
   17.21 -            enterTestFirstLoop(forNode, forNode.getModify(), null);
   17.22 +            enterTestFirstLoop(forNode, forNode.getModify(), null, false);
   17.23          }
   17.24          return false;
   17.25      }
   17.26 @@ -792,7 +798,8 @@
   17.27          return false;
   17.28      }
   17.29  
   17.30 -    private void enterTestFirstLoop(final LoopNode loopNode, final JoinPredecessorExpression modify, final Expression iteratorValues) {
   17.31 +    private void enterTestFirstLoop(final LoopNode loopNode, final JoinPredecessorExpression modify,
   17.32 +            final Expression iteratorValues, final boolean iteratorValuesAreObject) {
   17.33          final JoinPredecessorExpression test = loopNode.getTest();
   17.34          if(isAlwaysFalse(test)) {
   17.35              test.accept(this);
   17.36 @@ -814,8 +821,12 @@
   17.37                  jumpToLabel(test, breakLabel);
   17.38              }
   17.39              if(iteratorValues instanceof IdentNode) {
   17.40 -                // Receives iterator values; they're currently all objects (JDK-8034954).
   17.41 -                onAssignment((IdentNode)iteratorValues, LvarType.OBJECT);
   17.42 +                final IdentNode ident = (IdentNode)iteratorValues;
   17.43 +                // Receives iterator values; the optimistic type of the iterator values is tracked on the
   17.44 +                // identifier, but we override optimism if it's known that the object being iterated over will
   17.45 +                // never have primitive property names.
   17.46 +                onAssignment(ident, iteratorValuesAreObject ? LvarType.OBJECT :
   17.47 +                    toLvarType(compiler.getOptimisticType(ident)));
   17.48              }
   17.49              final Block body = loopNode.getBody();
   17.50              body.accept(this);
   17.51 @@ -955,7 +966,7 @@
   17.52          if(whileNode.isDoWhile()) {
   17.53              enterDoWhileLoop(whileNode);
   17.54          } else {
   17.55 -            enterTestFirstLoop(whileNode, null, null);
   17.56 +            enterTestFirstLoop(whileNode, null, null, false);
   17.57          }
   17.58          return false;
   17.59      }
    18.1 --- a/src/jdk/nashorn/internal/codegen/Lower.java	Thu Sep 11 15:34:13 2014 -0700
    18.2 +++ b/src/jdk/nashorn/internal/codegen/Lower.java	Tue Sep 16 13:59:37 2014 -0700
    18.3 @@ -71,7 +71,6 @@
    18.4  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    18.5  import jdk.nashorn.internal.parser.Token;
    18.6  import jdk.nashorn.internal.parser.TokenType;
    18.7 -import jdk.nashorn.internal.runtime.CodeInstaller;
    18.8  import jdk.nashorn.internal.runtime.Context;
    18.9  import jdk.nashorn.internal.runtime.JSType;
   18.10  import jdk.nashorn.internal.runtime.Source;
   18.11 @@ -93,9 +92,6 @@
   18.12  
   18.13      private final DebugLogger log;
   18.14  
   18.15 -    // needed only to get unique eval id
   18.16 -    private final CodeInstaller<?> installer;
   18.17 -
   18.18      /**
   18.19       * Constructor.
   18.20       */
   18.21 @@ -143,7 +139,6 @@
   18.22              }
   18.23          });
   18.24  
   18.25 -        this.installer = compiler.getCodeInstaller();
   18.26          this.log       = initLogger(compiler.getContext());
   18.27      }
   18.28  
   18.29 @@ -566,16 +561,13 @@
   18.30      private String evalLocation(final IdentNode node) {
   18.31          final Source source = lc.getCurrentFunction().getSource();
   18.32          final int pos = node.position();
   18.33 -        // Code installer is null when running with --compile-only, use 0 as id in that case
   18.34 -        final long id = installer == null ? 0 : installer.getUniqueEvalId();
   18.35          return new StringBuilder().
   18.36              append(source.getName()).
   18.37              append('#').
   18.38              append(source.getLine(pos)).
   18.39              append(':').
   18.40              append(source.getColumn(pos)).
   18.41 -            append("<eval>@").
   18.42 -            append(id).
   18.43 +            append("<eval>").
   18.44              toString();
   18.45      }
   18.46  
    19.1 --- a/src/jdk/nashorn/internal/codegen/MapCreator.java	Thu Sep 11 15:34:13 2014 -0700
    19.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java	Tue Sep 16 13:59:37 2014 -0700
    19.3 @@ -52,8 +52,7 @@
    19.4       * Constructor
    19.5       *
    19.6       * @param structure structure to generate map for (a JO subclass)
    19.7 -     * @param keys      list of keys for map
    19.8 -     * @param symbols   list of symbols for map
    19.9 +     * @param tuples    list of tuples for map
   19.10       */
   19.11      MapCreator(final Class<? extends ScriptObject> structure, final List<MapTuple<T>> tuples) {
   19.12          this.structure = structure;
   19.13 @@ -149,6 +148,15 @@
   19.14              flags |= Property.IS_FUNCTION_DECLARATION;
   19.15          }
   19.16  
   19.17 +        if (symbol.isConst()) {
   19.18 +            flags |= Property.NOT_WRITABLE;
   19.19 +        }
   19.20 +
   19.21 +        // Mark symbol as needing declaration. Access before declaration will throw a ReferenceError.
   19.22 +        if (symbol.isBlockScoped() && symbol.isScope()) {
   19.23 +            flags |= Property.NEEDS_DECLARATION;
   19.24 +        }
   19.25 +
   19.26          return flags;
   19.27      }
   19.28  }
    20.1 --- a/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Thu Sep 11 15:34:13 2014 -0700
    20.2 +++ b/src/jdk/nashorn/internal/codegen/MethodEmitter.java	Tue Sep 16 13:59:37 2014 -0700
    20.3 @@ -2233,9 +2233,8 @@
    20.4      /**
    20.5       * Generate dynamic setter. Pop receiver and property from stack.
    20.6       *
    20.7 -     * @param valueType the type of the value to set
    20.8 -     * @param name      name of property
    20.9 -     * @param flags     call site flags
   20.10 +     * @param name  name of property
   20.11 +     * @param flags call site flags
   20.12       */
   20.13       void dynamicSet(final String name, final int flags) {
   20.14           assert !isOptimistic(flags);
   20.15 @@ -2462,7 +2461,6 @@
   20.16       * Register line number at a label
   20.17       *
   20.18       * @param line  line number
   20.19 -     * @param label label
   20.20       */
   20.21      void lineNumber(final int line) {
   20.22          if (context.getEnv()._debug_lines) {
    21.1 --- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Thu Sep 11 15:34:13 2014 -0700
    21.2 +++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java	Tue Sep 16 13:59:37 2014 -0700
    21.3 @@ -308,7 +308,7 @@
    21.4          newEmptyInit(className, classEmitter);
    21.5          newAllocate(className, classEmitter);
    21.6  
    21.7 -        return toByteArray(classEmitter);
    21.8 +        return toByteArray(className, classEmitter);
    21.9      }
   21.10  
   21.11      /**
   21.12 @@ -341,7 +341,7 @@
   21.13          initWithArguments.returnVoid();
   21.14          initWithArguments.end();
   21.15  
   21.16 -        return toByteArray(classEmitter);
   21.17 +        return toByteArray(className, classEmitter);
   21.18      }
   21.19  
   21.20      /**
   21.21 @@ -484,15 +484,13 @@
   21.22       * @param classEmitter Open class emitter.
   21.23       * @return Byte codes for the class.
   21.24       */
   21.25 -    private byte[] toByteArray(final ClassEmitter classEmitter) {
   21.26 +    private byte[] toByteArray(final String className, final ClassEmitter classEmitter) {
   21.27          classEmitter.end();
   21.28  
   21.29          final byte[] code = classEmitter.toByteArray();
   21.30          final ScriptEnvironment env = context.getEnv();
   21.31  
   21.32 -        if (env._print_code && env._print_code_dir == null) {
   21.33 -            env.getErr().println(ClassEmitter.disassemble(code));
   21.34 -        }
   21.35 +        DumpBytecode.dumpBytecode(env, log, code, className);
   21.36  
   21.37          if (env._verify_code) {
   21.38              context.verify(code);
   21.39 @@ -827,5 +825,45 @@
   21.40          return MH.findStatic(MethodHandles.lookup(), ObjectClassGenerator.class, name, MH.type(rtype, types));
   21.41      }
   21.42  
   21.43 +    /**
   21.44 +     * Describes the allocator class name and property map for a constructor function with the specified
   21.45 +     * number of "this" properties that it initializes.
   21.46 +     *
   21.47 +     */
   21.48 +    public static class AllocatorDescriptor {
   21.49 +        private final String allocatorClassName;
   21.50 +        private final PropertyMap allocatorMap;
   21.51  
   21.52 +        /**
   21.53 +         * Creates a new allocator descriptor
   21.54 +         * @param thisProperties the number of "this" properties that the function initializes
   21.55 +         */
   21.56 +        public AllocatorDescriptor(final int thisProperties) {
   21.57 +            final int paddedFieldCount = getPaddedFieldCount(thisProperties);
   21.58 +            this.allocatorClassName = Compiler.binaryName(getClassName(paddedFieldCount));
   21.59 +            this.allocatorMap = PropertyMap.newMap(null, allocatorClassName, 0, paddedFieldCount, 0);
   21.60 +        }
   21.61 +
   21.62 +        /**
   21.63 +         * Returns the name of the class that the function allocates
   21.64 +         * @return the name of the class that the function allocates
   21.65 +         */
   21.66 +        public String getAllocatorClassName() {
   21.67 +            return allocatorClassName;
   21.68 +        }
   21.69 +
   21.70 +        /**
   21.71 +         * Returns the allocator map for the function.
   21.72 +         * @return the allocator map for the function.
   21.73 +         */
   21.74 +        public PropertyMap getAllocatorMap() {
   21.75 +            return allocatorMap;
   21.76 +        }
   21.77 +
   21.78 +        @Override
   21.79 +        public String toString() {
   21.80 +            return "AllocatorDescriptor[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
   21.81 +                    allocatorMap.size() + "]";
   21.82 +        }
   21.83 +    }
   21.84  }
    22.1 --- a/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Thu Sep 11 15:34:13 2014 -0700
    22.2 +++ b/src/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Tue Sep 16 13:59:37 2014 -0700
    22.3 @@ -31,9 +31,11 @@
    22.4  import java.io.File;
    22.5  import java.io.FileInputStream;
    22.6  import java.io.FileOutputStream;
    22.7 +import java.io.IOException;
    22.8  import java.io.InputStream;
    22.9  import java.net.URL;
   22.10  import java.nio.file.Files;
   22.11 +import java.nio.file.Path;
   22.12  import java.security.AccessController;
   22.13  import java.security.MessageDigest;
   22.14  import java.security.PrivilegedAction;
   22.15 @@ -41,6 +43,14 @@
   22.16  import java.util.Base64;
   22.17  import java.util.Date;
   22.18  import java.util.Map;
   22.19 +import java.util.Timer;
   22.20 +import java.util.TimerTask;
   22.21 +import java.util.concurrent.TimeUnit;
   22.22 +import java.util.concurrent.atomic.AtomicBoolean;
   22.23 +import java.util.function.Function;
   22.24 +import java.util.function.IntFunction;
   22.25 +import java.util.function.Predicate;
   22.26 +import java.util.stream.Stream;
   22.27  import jdk.nashorn.internal.codegen.types.Type;
   22.28  import jdk.nashorn.internal.runtime.Context;
   22.29  import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   22.30 @@ -49,30 +59,66 @@
   22.31  import jdk.nashorn.internal.runtime.options.Options;
   22.32  
   22.33  /**
   22.34 - * Static utility that encapsulates persistence of decompilation information for functions. Normally, the type info
   22.35 - * persistence feature is enabled and operates in an operating-system specific per-user cache directory. You can
   22.36 - * override the directory by specifying it in the {@code nashorn.typeInfo.cacheDir} directory. Also, you can disable the
   22.37 - * type info persistence altogether by specifying the {@code nashorn.typeInfo.disabled} system property.
   22.38 + * Static utility that encapsulates persistence of type information for functions compiled with optimistic
   22.39 + * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized,
   22.40 + * the type information for deoptimization is stored in a cache file. If the same function is compiled in a
   22.41 + * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system
   22.42 + * to skip a lot of intermediate recompilations and immediately emit a version of the code that has its
   22.43 + * optimistic types at (or near) the steady state.
   22.44 + * </p><p>
   22.45 + * Normally, the type info persistence feature is disabled. When the {@code nashorn.typeInfo.maxFiles} system
   22.46 + * property is specified with a value greater than 0, it is enabled and operates in an operating-system
   22.47 + * specific per-user cache directory. You can override the directory by specifying it in the
   22.48 + * {@code nashorn.typeInfo.cacheDir} directory. The maximum number of files is softly enforced by a task that
   22.49 + * cleans up the directory periodically on a separate thread. It is run after some delay after a new file is
   22.50 + * added to the cache. The default delay is 20 seconds, and can be set using the
   22.51 + * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word
   22.52 + * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is
   22.53 + * allowed to grow without limits.
   22.54   */
   22.55  public final class OptimisticTypesPersistence {
   22.56 +    // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is
   22.57 +    // dependent on the application; setting it to e.g. 20000 is probably good enough for most uses and will
   22.58 +    // usually cap the cache directory to about 80MB presuming a 4kB filesystem allocation unit. There is one
   22.59 +    // file per JavaScript function.
   22.60 +    private static final int DEFAULT_MAX_FILES = 0;
   22.61 +    // Constants for signifying that the cache should not be limited
   22.62 +    private static final int UNLIMITED_FILES = -1;
   22.63 +    // Maximum number of files that should be cached on disk. The maximum will be softly enforced.
   22.64 +    private static final int MAX_FILES = getMaxFiles();
   22.65 +    // Number of seconds to wait between adding a new file to the cache and running a cleanup process
   22.66 +    private static final int DEFAULT_CLEANUP_DELAY = 20;
   22.67 +    private static final int CLEANUP_DELAY = Math.max(0, Options.getIntProperty(
   22.68 +            "nashorn.typeInfo.cleanupDelaySeconds", DEFAULT_CLEANUP_DELAY));
   22.69      // The name of the default subdirectory within the system cache directory where we store type info.
   22.70      private static final String DEFAULT_CACHE_SUBDIR_NAME = "com.oracle.java.NashornTypeInfo";
   22.71      // The directory where we cache type info
   22.72 -    private static final File cacheDir = createCacheDir();
   22.73 +    private static final File baseCacheDir = createBaseCacheDir();
   22.74 +    private static final File cacheDir = createCacheDir(baseCacheDir);
   22.75      // In-process locks to make sure we don't have a cross-thread race condition manipulating any file.
   22.76      private static final Object[] locks = cacheDir == null ? null : createLockArray();
   22.77 -
   22.78      // Only report one read/write error every minute
   22.79      private static final long ERROR_REPORT_THRESHOLD = 60000L;
   22.80  
   22.81      private static volatile long lastReportedError;
   22.82 -
   22.83 +    private static final AtomicBoolean scheduledCleanup;
   22.84 +    private static final Timer cleanupTimer;
   22.85 +    static {
   22.86 +        if (baseCacheDir == null || MAX_FILES == UNLIMITED_FILES) {
   22.87 +            scheduledCleanup = null;
   22.88 +            cleanupTimer = null;
   22.89 +        } else {
   22.90 +            scheduledCleanup = new AtomicBoolean();
   22.91 +            cleanupTimer = new Timer(true);
   22.92 +        }
   22.93 +    }
   22.94      /**
   22.95 -     * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed to
   22.96 -     * {@link #load(Object)} and {@link #store(Object, Map)} methods.
   22.97 +     * Retrieves an opaque descriptor for the persistence location for a given function. It should be passed
   22.98 +     * to {@link #load(Object)} and {@link #store(Object, Map)} methods.
   22.99       * @param source the source where the function comes from
  22.100       * @param functionId the unique ID number of the function within the source
  22.101 -     * @param paramTypes the types of the function parameters (as persistence is per parameter type specialization).
  22.102 +     * @param paramTypes the types of the function parameters (as persistence is per parameter type
  22.103 +     * specialization).
  22.104       * @return an opaque descriptor for the persistence location. Can be null if persistence is disabled.
  22.105       */
  22.106      public static Object getLocationDescriptor(final Source source, final int functionId, final Type[] paramTypes) {
  22.107 @@ -82,7 +128,8 @@
  22.108          final StringBuilder b = new StringBuilder(48);
  22.109          // Base64-encode the digest of the source, and append the function id.
  22.110          b.append(source.getDigest()).append('-').append(functionId);
  22.111 -        // Finally, if this is a parameter-type specialized version of the function, add the parameter types to the file name.
  22.112 +        // Finally, if this is a parameter-type specialized version of the function, add the parameter types
  22.113 +        // to the file name.
  22.114          if(paramTypes != null && paramTypes.length > 0) {
  22.115              b.append('-');
  22.116              for(final Type t: paramTypes) {
  22.117 @@ -118,6 +165,11 @@
  22.118              @Override
  22.119              public Void run() {
  22.120                  synchronized(getFileLock(file)) {
  22.121 +                    if (!file.exists()) {
  22.122 +                        // If the file already exists, we aren't increasing the number of cached files, so
  22.123 +                        // don't schedule cleanup.
  22.124 +                        scheduleCleanup();
  22.125 +                    }
  22.126                      try (final FileOutputStream out = new FileOutputStream(file)) {
  22.127                          out.getChannel().lock(); // lock exclusive
  22.128                          final DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(out));
  22.129 @@ -174,19 +226,19 @@
  22.130          }
  22.131      }
  22.132  
  22.133 -    private static File createCacheDir() {
  22.134 -        if(Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
  22.135 +    private static File createBaseCacheDir() {
  22.136 +        if(MAX_FILES == 0 || Options.getBooleanProperty("nashorn.typeInfo.disabled")) {
  22.137              return null;
  22.138          }
  22.139          try {
  22.140 -            return createCacheDirPrivileged();
  22.141 +            return createBaseCacheDirPrivileged();
  22.142          } catch(final Exception e) {
  22.143              getLogger().warning("Failed to create cache dir", e);
  22.144              return null;
  22.145          }
  22.146      }
  22.147  
  22.148 -    private static File createCacheDirPrivileged() {
  22.149 +    private static File createBaseCacheDirPrivileged() {
  22.150          return AccessController.doPrivileged(new PrivilegedAction<File>() {
  22.151              @Override
  22.152              public File run() {
  22.153 @@ -195,14 +247,35 @@
  22.154                  if(explicitDir != null) {
  22.155                      dir = new File(explicitDir);
  22.156                  } else {
  22.157 -                    // When no directory is explicitly specified, get an operating system specific cache directory,
  22.158 -                    // and create "com.oracle.java.NashornTypeInfo" in it.
  22.159 +                    // When no directory is explicitly specified, get an operating system specific cache
  22.160 +                    // directory, and create "com.oracle.java.NashornTypeInfo" in it.
  22.161                      final File systemCacheDir = getSystemCacheDir();
  22.162                      dir = new File(systemCacheDir, DEFAULT_CACHE_SUBDIR_NAME);
  22.163                      if (isSymbolicLink(dir)) {
  22.164                          return null;
  22.165                      }
  22.166                  }
  22.167 +                return dir;
  22.168 +            }
  22.169 +        });
  22.170 +    }
  22.171 +
  22.172 +    private static File createCacheDir(final File baseDir) {
  22.173 +        if (baseDir == null) {
  22.174 +            return null;
  22.175 +        }
  22.176 +        try {
  22.177 +            return createCacheDirPrivileged(baseDir);
  22.178 +        } catch(final Exception e) {
  22.179 +            getLogger().warning("Failed to create cache dir", e);
  22.180 +            return null;
  22.181 +        }
  22.182 +    }
  22.183 +
  22.184 +    private static File createCacheDirPrivileged(final File baseDir) {
  22.185 +        return AccessController.doPrivileged(new PrivilegedAction<File>() {
  22.186 +            @Override
  22.187 +            public File run() {
  22.188                  final String versionDirName;
  22.189                  try {
  22.190                      versionDirName = getVersionDirName();
  22.191 @@ -210,12 +283,12 @@
  22.192                      getLogger().warning("Failed to calculate version dir name", e);
  22.193                      return null;
  22.194                  }
  22.195 -                final File versionDir = new File(dir, versionDirName);
  22.196 +                final File versionDir = new File(baseDir, versionDirName);
  22.197                  if (isSymbolicLink(versionDir)) {
  22.198                      return null;
  22.199                  }
  22.200                  versionDir.mkdirs();
  22.201 -                if(versionDir.isDirectory()) {
  22.202 +                if (versionDir.isDirectory()) {
  22.203                      getLogger().info("Optimistic type persistence directory is " + versionDir);
  22.204                      return versionDir;
  22.205                  }
  22.206 @@ -235,12 +308,12 @@
  22.207              // Mac OS X stores caches in ~/Library/Caches
  22.208              return new File(new File(System.getProperty("user.home"), "Library"), "Caches");
  22.209          } else if(os.startsWith("Windows")) {
  22.210 -            // On Windows, temp directory is the best approximation of a cache directory, as its contents persist across
  22.211 -            // reboots and various cleanup utilities know about it. java.io.tmpdir normally points to a user-specific
  22.212 -            // temp directory, %HOME%\LocalSettings\Temp.
  22.213 +            // On Windows, temp directory is the best approximation of a cache directory, as its contents
  22.214 +            // persist across reboots and various cleanup utilities know about it. java.io.tmpdir normally
  22.215 +            // points to a user-specific temp directory, %HOME%\LocalSettings\Temp.
  22.216              return new File(System.getProperty("java.io.tmpdir"));
  22.217          } else {
  22.218 -            // In all other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache"
  22.219 +            // In other cases we're presumably dealing with a UNIX flavor (Linux, Solaris, etc.); "~/.cache"
  22.220              return new File(System.getProperty("user.home"), ".cache");
  22.221          }
  22.222      }
  22.223 @@ -278,7 +351,8 @@
  22.224              final int packageNameLen = className.lastIndexOf('.');
  22.225              final String dirStr = fileStr.substring(0, fileStr.length() - packageNameLen - 1);
  22.226              final File dir = new File(dirStr);
  22.227 -            return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(dir, 0L)));
  22.228 +            return "dev-" + new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(getLastModifiedClassFile(
  22.229 +                    dir, 0L)));
  22.230          } else {
  22.231              throw new AssertionError();
  22.232          }
  22.233 @@ -335,4 +409,108 @@
  22.234              return DebugLogger.DISABLED_LOGGER;
  22.235          }
  22.236      }
  22.237 +
  22.238 +    private static void scheduleCleanup() {
  22.239 +        if (MAX_FILES != UNLIMITED_FILES && scheduledCleanup.compareAndSet(false, true)) {
  22.240 +            cleanupTimer.schedule(new TimerTask() {
  22.241 +                @Override
  22.242 +                public void run() {
  22.243 +                    scheduledCleanup.set(false);
  22.244 +                    try {
  22.245 +                        doCleanup();
  22.246 +                    } catch (final IOException e) {
  22.247 +                        // Ignore it. While this is unfortunate, we don't have good facility for reporting
  22.248 +                        // this, as we're running in a thread that has no access to Context, so we can't grab
  22.249 +                        // a DebugLogger.
  22.250 +                    }
  22.251 +                }
  22.252 +            }, TimeUnit.SECONDS.toMillis(CLEANUP_DELAY));
  22.253 +        }
  22.254 +    }
  22.255 +
  22.256 +    private static void doCleanup() throws IOException {
  22.257 +        final long start = System.nanoTime();
  22.258 +        final Path[] files = getAllRegularFilesInLastModifiedOrder();
  22.259 +        final int nFiles = files.length;
  22.260 +        final int filesToDelete = Math.max(0, nFiles - MAX_FILES);
  22.261 +        int filesDeleted = 0;
  22.262 +        for (int i = 0; i < nFiles && filesDeleted < filesToDelete; ++i) {
  22.263 +            try {
  22.264 +                Files.deleteIfExists(files[i]);
  22.265 +                // Even if it didn't exist, we increment filesDeleted; it existed a moment earlier; something
  22.266 +                // else deleted it for us; that's okay with us.
  22.267 +                filesDeleted++;
  22.268 +            } catch (final Exception e) {
  22.269 +                // does not increase filesDeleted
  22.270 +            }
  22.271 +            files[i] = null; // gc eligible
  22.272 +        };
  22.273 +        final long duration = System.nanoTime() - start;
  22.274 +    }
  22.275 +
  22.276 +    private static Path[] getAllRegularFilesInLastModifiedOrder() throws IOException {
  22.277 +        try (final Stream<Path> filesStream = Files.walk(baseCacheDir.toPath())) {
  22.278 +            // TODO: rewrite below once we can use JDK8 syntactic constructs
  22.279 +            return filesStream
  22.280 +            .filter(new Predicate<Path>() {
  22.281 +                @Override
  22.282 +                public boolean test(final Path path) {
  22.283 +                    return !Files.isDirectory(path);
  22.284 +                };
  22.285 +            })
  22.286 +            .map(new Function<Path, PathAndTime>() {
  22.287 +                @Override
  22.288 +                public PathAndTime apply(final Path path) {
  22.289 +                    return new PathAndTime(path);
  22.290 +                }
  22.291 +            })
  22.292 +            .sorted()
  22.293 +            .map(new Function<PathAndTime, Path>() {
  22.294 +                @Override
  22.295 +                public Path apply(final PathAndTime pathAndTime) {
  22.296 +                    return pathAndTime.path;
  22.297 +                }
  22.298 +            })
  22.299 +            .toArray(new IntFunction<Path[]>() { // Replace with Path::new
  22.300 +                @Override
  22.301 +                public Path[] apply(final int length) {
  22.302 +                    return new Path[length];
  22.303 +                }
  22.304 +            });
  22.305 +        }
  22.306 +    }
  22.307 +
  22.308 +    private static class PathAndTime implements Comparable<PathAndTime> {
  22.309 +        private final Path path;
  22.310 +        private final long time;
  22.311 +
  22.312 +        PathAndTime(final Path path) {
  22.313 +            this.path = path;
  22.314 +            this.time = getTime(path);
  22.315 +        }
  22.316 +
  22.317 +        @Override
  22.318 +        public int compareTo(final PathAndTime other) {
  22.319 +            return Long.compare(time, other.time);
  22.320 +        }
  22.321 +
  22.322 +        private static long getTime(final Path path) {
  22.323 +            try {
  22.324 +                return Files.getLastModifiedTime(path).toMillis();
  22.325 +            } catch (IOException e) {
  22.326 +                // All files for which we can't retrieve the last modified date will be considered oldest.
  22.327 +                return -1L;
  22.328 +            }
  22.329 +        }
  22.330 +    }
  22.331 +
  22.332 +    private static int getMaxFiles() {
  22.333 +        final String str = Options.getStringProperty("nashorn.typeInfo.maxFiles", null);
  22.334 +        if (str == null) {
  22.335 +            return DEFAULT_MAX_FILES;
  22.336 +        } else if ("unlimited".equals(str)) {
  22.337 +            return UNLIMITED_FILES;
  22.338 +        }
  22.339 +        return Math.max(0, Integer.parseInt(str));
  22.340 +    }
  22.341  }
    23.1 --- a/src/jdk/nashorn/internal/codegen/TypeEvaluator.java	Thu Sep 11 15:34:13 2014 -0700
    23.2 +++ b/src/jdk/nashorn/internal/codegen/TypeEvaluator.java	Tue Sep 16 13:59:37 2014 -0700
    23.3 @@ -55,6 +55,19 @@
    23.4          this.runtimeScope = runtimeScope;
    23.5      }
    23.6  
    23.7 +    /**
    23.8 +     * Returns true if the expression can be safely evaluated, and its value is an object known to always use
    23.9 +     * String as the type of its property names retrieved through
   23.10 +     * {@link ScriptRuntime#toPropertyIterator(Object)}. It is used to avoid optimistic assumptions about its
   23.11 +     * property name types.
   23.12 +     * @param expr the expression to test
   23.13 +     * @return true if the expression can be safely evaluated, and its value is an object known to always use
   23.14 +     * String as the type of its property iterators.
   23.15 +     */
   23.16 +    boolean hasStringPropertyIterator(final Expression expr) {
   23.17 +        return evaluateSafely(expr) instanceof ScriptObject;
   23.18 +    }
   23.19 +
   23.20      Type getOptimisticType(final Optimistic node) {
   23.21          assert compiler.useOptimisticTypes();
   23.22  
   23.23 @@ -108,7 +121,7 @@
   23.24  
   23.25          // Safely evaluate the property, and return the narrowest type for the actual value (e.g. Type.INT for a boxed
   23.26          // integer).
   23.27 -        final Object value = property.getObjectValue(owner, owner);
   23.28 +        final Object value = property.needsDeclaration() ? ScriptRuntime.UNDEFINED : property.getObjectValue(owner, owner);
   23.29          if (value == ScriptRuntime.UNDEFINED) {
   23.30              return null;
   23.31          }
    24.1 --- a/src/jdk/nashorn/internal/codegen/types/Type.java	Thu Sep 11 15:34:13 2014 -0700
    24.2 +++ b/src/jdk/nashorn/internal/codegen/types/Type.java	Tue Sep 16 13:59:37 2014 -0700
    24.3 @@ -333,7 +333,7 @@
    24.4       */
    24.5      public static Map<Integer, Type> readTypeMap(final DataInput input) throws IOException {
    24.6          final int size = input.readInt();
    24.7 -        if (size == 0) {
    24.8 +        if (size <= 0) {
    24.9              return null;
   24.10          }
   24.11          final Map<Integer, Type> map = new TreeMap<>();
   24.12 @@ -345,7 +345,7 @@
   24.13                  case 'L': type = Type.OBJECT; break;
   24.14                  case 'D': type = Type.NUMBER; break;
   24.15                  case 'J': type = Type.LONG; break;
   24.16 -                default: throw new AssertionError();
   24.17 +                default: continue;
   24.18              }
   24.19              map.put(pp, type);
   24.20          }
    25.1 --- a/src/jdk/nashorn/internal/ir/Block.java	Thu Sep 11 15:34:13 2014 -0700
    25.2 +++ b/src/jdk/nashorn/internal/ir/Block.java	Tue Sep 16 13:59:37 2014 -0700
    25.3 @@ -277,6 +277,14 @@
    25.4      }
    25.5  
    25.6      /**
    25.7 +     * Returns the number of statements in the block.
    25.8 +     * @return the number of statements in the block.
    25.9 +     */
   25.10 +    public int getStatementCount() {
   25.11 +        return statements.size();
   25.12 +    }
   25.13 +
   25.14 +    /**
   25.15       * Returns the line number of the first statement in the block.
   25.16       * @return the line number of the first statement in the block, or -1 if the block has no statements.
   25.17       */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/src/jdk/nashorn/internal/ir/CompileUnitHolder.java	Tue Sep 16 13:59:37 2014 -0700
    26.3 @@ -0,0 +1,40 @@
    26.4 +/*
    26.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.7 + *
    26.8 + * This code is free software; you can redistribute it and/or modify it
    26.9 + * under the terms of the GNU General Public License version 2 only, as
   26.10 + * published by the Free Software Foundation.  Oracle designates this
   26.11 + * particular file as subject to the "Classpath" exception as provided
   26.12 + * by Oracle in the LICENSE file that accompanied this code.
   26.13 + *
   26.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.17 + * version 2 for more details (a copy is included in the LICENSE file that
   26.18 + * accompanied this code).
   26.19 + *
   26.20 + * You should have received a copy of the GNU General Public License version
   26.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.23 + *
   26.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.25 + * or visit www.oracle.com if you need additional information or have any
   26.26 + * questions.
   26.27 + */
   26.28 +
   26.29 +package jdk.nashorn.internal.ir;
   26.30 +
   26.31 +import jdk.nashorn.internal.codegen.CompileUnit;
   26.32 +
   26.33 +/**
   26.34 + * Marker interface for things in the IR that can hold compile units.
   26.35 + * {@link CompileUnit}
   26.36 + */
   26.37 +public interface CompileUnitHolder {
   26.38 +    /**
   26.39 +     * Return the compile unit held by this instance
   26.40 +     * @return compile unit
   26.41 +     */
   26.42 +    public CompileUnit getCompileUnit();
   26.43 +}
    27.1 --- a/src/jdk/nashorn/internal/ir/FunctionNode.java	Thu Sep 11 15:34:13 2014 -0700
    27.2 +++ b/src/jdk/nashorn/internal/ir/FunctionNode.java	Tue Sep 16 13:59:37 2014 -0700
    27.3 @@ -34,10 +34,8 @@
    27.4  
    27.5  import java.util.Collections;
    27.6  import java.util.EnumSet;
    27.7 -import java.util.HashSet;
    27.8  import java.util.Iterator;
    27.9  import java.util.List;
   27.10 -import java.util.Set;
   27.11  import java.util.function.Function;
   27.12  import jdk.nashorn.internal.AssertsEnabled;
   27.13  import jdk.nashorn.internal.codegen.CompileUnit;
   27.14 @@ -48,6 +46,7 @@
   27.15  import jdk.nashorn.internal.ir.annotations.Ignore;
   27.16  import jdk.nashorn.internal.ir.annotations.Immutable;
   27.17  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
   27.18 +import jdk.nashorn.internal.runtime.RecompilableScriptFunctionData;
   27.19  import jdk.nashorn.internal.runtime.ScriptFunction;
   27.20  import jdk.nashorn.internal.runtime.Source;
   27.21  import jdk.nashorn.internal.runtime.UserAccessorProperty;
   27.22 @@ -57,7 +56,7 @@
   27.23   * IR representation for function (or script.)
   27.24   */
   27.25  @Immutable
   27.26 -public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode> {
   27.27 +public final class FunctionNode extends LexicalContextExpression implements Flags<FunctionNode>, CompileUnitHolder {
   27.28      /** Type used for all FunctionNodes */
   27.29      public static final Type FUNCTION_TYPE = Type.typeFor(ScriptFunction.class);
   27.30  
   27.31 @@ -110,8 +109,11 @@
   27.32      /** Source of entity. */
   27.33      private final Source source;
   27.34  
   27.35 -    /** Unique ID used for recompilation among other things */
   27.36 -    private final int id;
   27.37 +    /**
   27.38 +     * Opaque object representing parser state at the end of the function. Used when reparsing outer functions
   27.39 +     * to skip parsing inner functions.
   27.40 +     */
   27.41 +    private final Object endParserState;
   27.42  
   27.43      /** External function identifier. */
   27.44      @Ignore
   27.45 @@ -138,10 +140,6 @@
   27.46      /** Last token of function. **/
   27.47      private final long lastToken;
   27.48  
   27.49 -    /** Declared symbols in this function node */
   27.50 -    @Ignore
   27.51 -    private final Set<Symbol> declaredSymbols;
   27.52 -
   27.53      /** Method's namespace. */
   27.54      private final Namespace namespace;
   27.55  
   27.56 @@ -260,6 +258,14 @@
   27.57      /** trace callsite values in this function? */
   27.58      public static final int IS_TRACE_VALUES    = 1 << 26;
   27.59  
   27.60 +    /**
   27.61 +     * Whether this function needs the callee {@link ScriptFunction} instance passed to its code as a
   27.62 +     * parameter on invocation. Note that we aren't, in fact using this flag in function nodes.
   27.63 +     * Rather, it is always calculated (see {@link #needsCallee()}). {@link RecompilableScriptFunctionData}
   27.64 +     * will, however, cache the value of this flag.
   27.65 +     */
   27.66 +    public static final int NEEDS_CALLEE       = 1 << 27;
   27.67 +
   27.68      /** extension callsite flags mask */
   27.69      public static final int EXTENSION_CALLSITE_FLAGS = IS_PRINT_PARSE |
   27.70          IS_PRINT_LOWER_PARSE | IS_PRINT_AST | IS_PRINT_LOWER_AST |
   27.71 @@ -275,16 +281,9 @@
   27.72      /** Does this function potentially need "arguments"? Note that this is not a full test, as further negative check of REDEFINES_ARGS is needed. */
   27.73      private static final int MAYBE_NEEDS_ARGUMENTS = USES_ARGUMENTS | HAS_EVAL;
   27.74  
   27.75 -    /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval.
   27.76 -     *  We also pessimistically need a parent scope if we have lazy children that have not yet been compiled */
   27.77 +    /** Does this function need the parent scope? It needs it if either it or its descendants use variables from it, or have a deep eval. */
   27.78      private static final int NEEDS_PARENT_SCOPE = USES_ANCESTOR_SCOPE | HAS_DEEP_EVAL;
   27.79  
   27.80 -    /** Used to signify "null", e.g. if someone asks for the parent of the program node */
   27.81 -    public static final int NO_FUNCTION_ID = 0;
   27.82 -
   27.83 -    /** Where to start assigning global and unique function node ids */
   27.84 -    public static final int FIRST_FUNCTION_ID = NO_FUNCTION_ID + 1;
   27.85 -
   27.86      /** What is the return type of this function? */
   27.87      private Type returnType = Type.UNKNOWN;
   27.88  
   27.89 @@ -292,11 +291,10 @@
   27.90       * Constructor
   27.91       *
   27.92       * @param source     the source
   27.93 -     * @param id         unique id
   27.94       * @param lineNumber line number
   27.95       * @param token      token
   27.96       * @param finish     finish
   27.97 -     * @param firstToken first token of the funtion node (including the function declaration)
   27.98 +     * @param firstToken first token of the function node (including the function declaration)
   27.99       * @param namespace  the namespace
  27.100       * @param ident      the identifier
  27.101       * @param name       the name of the function
  27.102 @@ -306,7 +304,6 @@
  27.103       */
  27.104      public FunctionNode(
  27.105          final Source source,
  27.106 -        final int id,
  27.107          final int lineNumber,
  27.108          final long token,
  27.109          final int finish,
  27.110 @@ -320,7 +317,6 @@
  27.111          super(token, finish);
  27.112  
  27.113          this.source           = source;
  27.114 -        this.id               = id;
  27.115          this.lineNumber       = lineNumber;
  27.116          this.ident            = ident;
  27.117          this.name             = name;
  27.118 @@ -330,17 +326,18 @@
  27.119          this.lastToken        = token;
  27.120          this.namespace        = namespace;
  27.121          this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
  27.122 -        this.declaredSymbols  = new HashSet<>();
  27.123          this.flags            = flags;
  27.124          this.compileUnit      = null;
  27.125          this.body             = null;
  27.126          this.thisProperties   = 0;
  27.127          this.rootClass        = null;
  27.128 +        this.endParserState    = null;
  27.129      }
  27.130  
  27.131      private FunctionNode(
  27.132          final FunctionNode functionNode,
  27.133          final long lastToken,
  27.134 +        Object endParserState,
  27.135          final int flags,
  27.136          final String name,
  27.137          final Type returnType,
  27.138 @@ -352,6 +349,7 @@
  27.139          final Class<?> rootClass) {
  27.140          super(functionNode);
  27.141  
  27.142 +        this.endParserState    = endParserState;
  27.143          this.lineNumber       = functionNode.lineNumber;
  27.144          this.flags            = flags;
  27.145          this.name             = name;
  27.146 @@ -366,10 +364,8 @@
  27.147  
  27.148          // the fields below never change - they are final and assigned in constructor
  27.149          this.source          = functionNode.source;
  27.150 -        this.id              = functionNode.id;
  27.151          this.ident           = functionNode.ident;
  27.152          this.namespace       = functionNode.namespace;
  27.153 -        this.declaredSymbols = functionNode.declaredSymbols;
  27.154          this.kind            = functionNode.kind;
  27.155          this.firstToken      = functionNode.firstToken;
  27.156      }
  27.157 @@ -435,11 +431,11 @@
  27.158      }
  27.159  
  27.160      /**
  27.161 -     * Get the unique ID for this function
  27.162 +     * Get the unique ID for this function within the script file.
  27.163       * @return the id
  27.164       */
  27.165      public int getId() {
  27.166 -        return id;
  27.167 +        return position();
  27.168      }
  27.169  
  27.170      /**
  27.171 @@ -541,6 +537,7 @@
  27.172                  new FunctionNode(
  27.173                          this,
  27.174                          lastToken,
  27.175 +                        endParserState,
  27.176                          flags,
  27.177                          name,
  27.178                          returnType,
  27.179 @@ -612,6 +609,7 @@
  27.180                  new FunctionNode(
  27.181                          this,
  27.182                          lastToken,
  27.183 +                        endParserState,
  27.184                          flags,
  27.185                          name,
  27.186                          returnType,
  27.187 @@ -650,15 +648,24 @@
  27.188      }
  27.189  
  27.190      /**
  27.191 -     * Check if the {@code eval} keyword is used in this function
  27.192 +     * Check if this function has a call expression for the identifier "eval" (that is, {@code eval(...)}).
  27.193       *
  27.194 -     * @return true if {@code eval} is used
  27.195 +     * @return true if {@code eval} is called.
  27.196       */
  27.197      public boolean hasEval() {
  27.198          return getFlag(HAS_EVAL);
  27.199      }
  27.200  
  27.201      /**
  27.202 +     * Returns true if a function nested (directly or transitively) within this function {@link #hasEval()}.
  27.203 +     *
  27.204 +     * @return true if a nested function calls {@code eval}.
  27.205 +     */
  27.206 +    public boolean hasNestedEval() {
  27.207 +        return getFlag(HAS_NESTED_EVAL);
  27.208 +    }
  27.209 +
  27.210 +    /**
  27.211       * Get the first token for this function
  27.212       * @return the first token
  27.213       */
  27.214 @@ -724,24 +731,6 @@
  27.215      }
  27.216  
  27.217      /**
  27.218 -     * Return a set of symbols declared in this function node. This
  27.219 -     * is only relevant after Attr, otherwise it will be an empty
  27.220 -     * set as no symbols have been introduced
  27.221 -     * @return set of declared symbols in function
  27.222 -     */
  27.223 -    public Set<Symbol> getDeclaredSymbols() {
  27.224 -        return Collections.unmodifiableSet(declaredSymbols);
  27.225 -    }
  27.226 -
  27.227 -    /**
  27.228 -     * Add a declared symbol to this function node
  27.229 -     * @param symbol symbol that is declared
  27.230 -     */
  27.231 -    public void addDeclaredSymbol(final Symbol symbol) {
  27.232 -        declaredSymbols.add(symbol);
  27.233 -    }
  27.234 -
  27.235 -    /**
  27.236       * Get the function body
  27.237       * @return the function body
  27.238       */
  27.239 @@ -765,6 +754,7 @@
  27.240                  new FunctionNode(
  27.241                          this,
  27.242                          lastToken,
  27.243 +                        endParserState,
  27.244                          flags |
  27.245                              (body.needsScope() ?
  27.246                                      FunctionNode.HAS_SCOPE_BLOCK :
  27.247 @@ -863,6 +853,7 @@
  27.248                  new FunctionNode(
  27.249                          this,
  27.250                          lastToken,
  27.251 +                        endParserState,
  27.252                          flags,
  27.253                          name,
  27.254                          returnType,
  27.255 @@ -923,6 +914,7 @@
  27.256                  new FunctionNode(
  27.257                          this,
  27.258                          lastToken,
  27.259 +                        endParserState,
  27.260                          flags,
  27.261                          name,
  27.262                          returnType,
  27.263 @@ -935,6 +927,41 @@
  27.264      }
  27.265  
  27.266      /**
  27.267 +     * Returns the end parser state for this function.
  27.268 +     * @return the end parser state for this function.
  27.269 +     */
  27.270 +    public Object getEndParserState() {
  27.271 +        return endParserState;
  27.272 +    }
  27.273 +
  27.274 +    /**
  27.275 +     * Set the end parser state for this function.
  27.276 +     * @param lc lexical context
  27.277 +     * @param endParserState the parser state to set
  27.278 +     * @return function node or a new one if state was changed
  27.279 +     */
  27.280 +    public FunctionNode setEndParserState(final LexicalContext lc, final Object endParserState) {
  27.281 +        if (this.endParserState == endParserState) {
  27.282 +            return this;
  27.283 +        }
  27.284 +        return Node.replaceInLexicalContext(
  27.285 +                lc,
  27.286 +                this,
  27.287 +                new FunctionNode(
  27.288 +                        this,
  27.289 +                        lastToken,
  27.290 +                        endParserState,
  27.291 +                        flags,
  27.292 +                        name,
  27.293 +                        returnType,
  27.294 +                        compileUnit,
  27.295 +                        compilationState,
  27.296 +                        body,
  27.297 +                        parameters,
  27.298 +                        thisProperties, rootClass));
  27.299 +    }
  27.300 +
  27.301 +    /**
  27.302       * Get the name of this function
  27.303       * @return the name
  27.304       */
  27.305 @@ -958,6 +985,7 @@
  27.306                  new FunctionNode(
  27.307                          this,
  27.308                          lastToken,
  27.309 +                        endParserState,
  27.310                          flags,
  27.311                          name,
  27.312                          returnType,
  27.313 @@ -970,13 +998,13 @@
  27.314      }
  27.315  
  27.316      /**
  27.317 -     * Check if this function should have all its variables in its own scope. Scripts, split sub-functions, and
  27.318 +     * Check if this function should have all its variables in its own scope. Split sub-functions, and
  27.319       * functions having with and/or eval blocks are such.
  27.320       *
  27.321       * @return true if all variables should be in scope
  27.322       */
  27.323      public boolean allVarsInScope() {
  27.324 -        return isProgram() || getFlag(HAS_ALL_VARS_IN_SCOPE);
  27.325 +        return getFlag(HAS_ALL_VARS_IN_SCOPE);
  27.326      }
  27.327  
  27.328      /**
  27.329 @@ -1023,6 +1051,7 @@
  27.330                  new FunctionNode(
  27.331                          this,
  27.332                          lastToken,
  27.333 +                        endParserState,
  27.334                          flags,
  27.335                          name,
  27.336                          returnType,
  27.337 @@ -1101,6 +1130,7 @@
  27.338              new FunctionNode(
  27.339                  this,
  27.340                  lastToken,
  27.341 +                endParserState,
  27.342                  flags,
  27.343                  name,
  27.344                  type,
  27.345 @@ -1126,6 +1156,7 @@
  27.346       * @see Compiler
  27.347       * @return the compile unit
  27.348       */
  27.349 +    @Override
  27.350      public CompileUnit getCompileUnit() {
  27.351          return compileUnit;
  27.352      }
  27.353 @@ -1147,6 +1178,7 @@
  27.354                  new FunctionNode(
  27.355                          this,
  27.356                          lastToken,
  27.357 +                        endParserState,
  27.358                          flags,
  27.359                          name,
  27.360                          returnType,
  27.361 @@ -1202,6 +1234,7 @@
  27.362                  new FunctionNode(
  27.363                          this,
  27.364                          lastToken,
  27.365 +                        endParserState,
  27.366                          flags,
  27.367                          name,
  27.368                          returnType,
    28.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java	Thu Sep 11 15:34:13 2014 -0700
    28.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java	Tue Sep 16 13:59:37 2014 -0700
    28.3 @@ -46,6 +46,8 @@
    28.4      private static final int INITIALIZED_HERE  = 1 << 1;
    28.5      private static final int FUNCTION          = 1 << 2;
    28.6      private static final int FUTURESTRICT_NAME = 1 << 3;
    28.7 +    private static final int IS_DECLARED_HERE  = 1 << 4;
    28.8 +    private static final int IS_DEAD           = 1 << 5;
    28.9  
   28.10      /** Identifier. */
   28.11      private final String name;
   28.12 @@ -247,6 +249,45 @@
   28.13      }
   28.14  
   28.15      /**
   28.16 +     * Is this a LET or CONST identifier used before its declaration?
   28.17 +     *
   28.18 +     * @return true if identifier is dead
   28.19 +     */
   28.20 +    public boolean isDead() {
   28.21 +        return (flags & IS_DEAD) != 0;
   28.22 +    }
   28.23 +
   28.24 +    /**
   28.25 +     * Flag this IdentNode as a LET or CONST identifier used before its declaration.
   28.26 +     *
   28.27 +     * @return a new IdentNode equivalent to this but marked as dead.
   28.28 +     */
   28.29 +    public IdentNode markDead() {
   28.30 +        return new IdentNode(this, name, type, flags | IS_DEAD, programPoint, conversion);
   28.31 +    }
   28.32 +
   28.33 +    /**
   28.34 +     * Is this IdentNode declared here?
   28.35 +     *
   28.36 +     * @return true if identifier is declared here
   28.37 +     */
   28.38 +    public boolean isDeclaredHere() {
   28.39 +        return (flags & IS_DECLARED_HERE) != 0;
   28.40 +    }
   28.41 +
   28.42 +    /**
   28.43 +     * Flag this IdentNode as being declared here.
   28.44 +     *
   28.45 +     * @return a new IdentNode equivalent to this but marked as declared here.
   28.46 +     */
   28.47 +    public IdentNode setIsDeclaredHere() {
   28.48 +        if (isDeclaredHere()) {
   28.49 +            return this;
   28.50 +        }
   28.51 +        return new IdentNode(this, name, type, flags | IS_DECLARED_HERE, programPoint, conversion);
   28.52 +    }
   28.53 +
   28.54 +    /**
   28.55       * Check if the name of this IdentNode is same as that of a compile-time property (currently __DIR__, __FILE__, and
   28.56       * __LINE__).
   28.57       *
    29.1 --- a/src/jdk/nashorn/internal/ir/LexicalContext.java	Thu Sep 11 15:34:13 2014 -0700
    29.2 +++ b/src/jdk/nashorn/internal/ir/LexicalContext.java	Tue Sep 16 13:59:37 2014 -0700
    29.3 @@ -351,8 +351,7 @@
    29.4      }
    29.5  
    29.6      /**
    29.7 -     * Get the function for this block. If the block is itself a function
    29.8 -     * this returns identity
    29.9 +     * Get the function for this block.
   29.10       * @param block block for which to get function
   29.11       * @return function for block
   29.12       */
    30.1 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java	Thu Sep 11 15:34:13 2014 -0700
    30.2 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java	Tue Sep 16 13:59:37 2014 -0700
    30.3 @@ -603,7 +603,7 @@
    30.4           * An ArrayUnit is a range in an ArrayLiteral. ArrayLiterals can
    30.5           * be split if they are too large, for bytecode generation reasons
    30.6           */
    30.7 -        public static final class ArrayUnit {
    30.8 +        public static final class ArrayUnit implements CompileUnitHolder {
    30.9              /** Compile unit associated with the postsets range. */
   30.10              private final CompileUnit compileUnit;
   30.11  
   30.12 @@ -642,6 +642,7 @@
   30.13               * The array compile unit
   30.14               * @return array compile unit
   30.15               */
   30.16 +            @Override
   30.17              public CompileUnit getCompileUnit() {
   30.18                  return compileUnit;
   30.19              }
    31.1 --- a/src/jdk/nashorn/internal/ir/SplitNode.java	Thu Sep 11 15:34:13 2014 -0700
    31.2 +++ b/src/jdk/nashorn/internal/ir/SplitNode.java	Tue Sep 16 13:59:37 2014 -0700
    31.3 @@ -39,7 +39,7 @@
    31.4   * Node indicating code is split across classes.
    31.5   */
    31.6  @Immutable
    31.7 -public class SplitNode extends LexicalContextStatement implements Labels {
    31.8 +public class SplitNode extends LexicalContextStatement implements Labels, CompileUnitHolder {
    31.9      /** Split node method name. */
   31.10      private final String name;
   31.11  
   31.12 @@ -116,6 +116,7 @@
   31.13       * Get the compile unit for this split node
   31.14       * @return compile unit
   31.15       */
   31.16 +    @Override
   31.17      public CompileUnit getCompileUnit() {
   31.18          return compileUnit;
   31.19      }
    32.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java	Thu Sep 11 15:34:13 2014 -0700
    32.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java	Tue Sep 16 13:59:37 2014 -0700
    32.3 @@ -54,17 +54,17 @@
    32.4      public static final int IS_VAR      = 2;
    32.5      /** Is this a parameter */
    32.6      public static final int IS_PARAM    = 3;
    32.7 -    /** Is this a constant */
    32.8 -    public static final int IS_CONSTANT = 4;
    32.9      /** Mask for kind flags */
   32.10 -    public static final int KINDMASK = (1 << 3) - 1; // Kinds are represented by lower three bits
   32.11 +    public static final int KINDMASK = (1 << 2) - 1; // Kinds are represented by lower two bits
   32.12  
   32.13      /** Is this symbol in scope */
   32.14 -    public static final int IS_SCOPE                = 1 <<  3;
   32.15 +    public static final int IS_SCOPE                = 1 <<  2;
   32.16      /** Is this a this symbol */
   32.17 -    public static final int IS_THIS                 = 1 <<  4;
   32.18 +    public static final int IS_THIS                 = 1 <<  3;
   32.19      /** Is this a let */
   32.20 -    public static final int IS_LET                  = 1 <<  5;
   32.21 +    public static final int IS_LET                  = 1 <<  4;
   32.22 +    /** Is this a const */
   32.23 +    public static final int IS_CONST                = 1 <<  5;
   32.24      /** Is this an internal symbol, never represented explicitly in source code */
   32.25      public static final int IS_INTERNAL             = 1 <<  6;
   32.26      /** Is this a function self-reference symbol */
   32.27 @@ -83,6 +83,8 @@
   32.28      public static final int HAS_DOUBLE_VALUE        = 1 << 13;
   32.29      /** Is this symbol known to store an object value ? */
   32.30      public static final int HAS_OBJECT_VALUE        = 1 << 14;
   32.31 +    /** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
   32.32 +    public static final int HAS_BEEN_DECLARED       = 1 << 15;
   32.33  
   32.34      /** Null or name identifying symbol. */
   32.35      private final String name;
   32.36 @@ -184,14 +186,17 @@
   32.37              sb.append(" global");
   32.38              break;
   32.39          case IS_VAR:
   32.40 -            sb.append(" var");
   32.41 +            if (isConst()) {
   32.42 +                sb.append(" const");
   32.43 +            } else if (isLet()) {
   32.44 +                sb.append(" let");
   32.45 +            } else {
   32.46 +                sb.append(" var");
   32.47 +            }
   32.48              break;
   32.49          case IS_PARAM:
   32.50              sb.append(" param");
   32.51              break;
   32.52 -        case IS_CONSTANT:
   32.53 -            sb.append(" const");
   32.54 -            break;
   32.55          default:
   32.56              break;
   32.57          }
   32.58 @@ -204,10 +209,6 @@
   32.59              sb.append(" internal");
   32.60          }
   32.61  
   32.62 -        if (isLet()) {
   32.63 -            sb.append(" let");
   32.64 -        }
   32.65 -
   32.66          if (isThis()) {
   32.67              sb.append(" this");
   32.68          }
   32.69 @@ -410,8 +411,8 @@
   32.70       * Check if this symbol is a constant
   32.71       * @return true if a constant
   32.72       */
   32.73 -    public boolean isConstant() {
   32.74 -        return (flags & KINDMASK) == IS_CONSTANT;
   32.75 +    public boolean isConst() {
   32.76 +        return (flags & IS_CONST) != 0;
   32.77      }
   32.78  
   32.79      /**
   32.80 @@ -440,15 +441,6 @@
   32.81      }
   32.82  
   32.83      /**
   32.84 -     * Flag this symbol as a let
   32.85 -     */
   32.86 -    public void setIsLet() {
   32.87 -        if (!isLet()) {
   32.88 -            flags |= IS_LET;
   32.89 -        }
   32.90 -    }
   32.91 -
   32.92 -    /**
   32.93       * Flag this symbol as a function's self-referencing symbol.
   32.94       * @return true if this symbol as a function's self-referencing symbol.
   32.95       */
   32.96 @@ -456,6 +448,20 @@
   32.97          return (flags & IS_FUNCTION_SELF) != 0;
   32.98      }
   32.99  
  32.100 +    public boolean isBlockScoped() {
  32.101 +        return isLet() || isConst();
  32.102 +    }
  32.103 +
  32.104 +    public boolean hasBeenDeclared() {
  32.105 +        return (flags & HAS_BEEN_DECLARED) != 0;
  32.106 +    }
  32.107 +
  32.108 +    public void setHasBeenDeclared() {
  32.109 +        if (!hasBeenDeclared()) {
  32.110 +            flags |= HAS_BEEN_DECLARED;
  32.111 +        }
  32.112 +    }
  32.113 +
  32.114      /**
  32.115       * Get the index of the field used to store this symbol, should it be an AccessorProperty
  32.116       * and get allocated in a JO-prefixed ScriptObject subclass.
    33.1 --- a/src/jdk/nashorn/internal/ir/VarNode.java	Thu Sep 11 15:34:13 2014 -0700
    33.2 +++ b/src/jdk/nashorn/internal/ir/VarNode.java	Tue Sep 16 13:59:37 2014 -0700
    33.3 @@ -27,6 +27,7 @@
    33.4  
    33.5  import jdk.nashorn.internal.ir.annotations.Immutable;
    33.6  import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    33.7 +import jdk.nashorn.internal.parser.Token;
    33.8  
    33.9  /**
   33.10   * Node represents a var/let declaration.
   33.11 @@ -43,12 +44,18 @@
   33.12      private final int flags;
   33.13  
   33.14      /** Flag that determines if this function node is a statement */
   33.15 -    public static final int IS_STATEMENT = 1 << 0;
   33.16 +    public static final int IS_STATEMENT                 = 1 << 0;
   33.17 +
   33.18 +    /** Flag for ES6 LET declaration */
   33.19 +    public static final int IS_LET                       = 1 << 1;
   33.20 +
   33.21 +    /** Flag for ES6 CONST declaration */
   33.22 +    public static final int IS_CONST                     = 1 << 2;
   33.23  
   33.24      /** Flag that determines if this is the last function declaration in a function
   33.25       *  This is used to micro optimize the placement of return value assignments for
   33.26       *  a program node */
   33.27 -    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 1;
   33.28 +    public static final int IS_LAST_FUNCTION_DECLARATION = 1 << 3;
   33.29  
   33.30      /**
   33.31       * Constructor
   33.32 @@ -109,6 +116,43 @@
   33.33      }
   33.34  
   33.35      /**
   33.36 +     * Is this a VAR node block scoped? This returns true for ECMAScript 6 LET and CONST nodes.
   33.37 +     * @return true if an ES6 LET or CONST node
   33.38 +     */
   33.39 +    public boolean isBlockScoped() {
   33.40 +        return getFlag(IS_LET) || getFlag(IS_CONST);
   33.41 +    }
   33.42 +
   33.43 +    /**
   33.44 +     * Is this an ECMAScript 6 LET node?
   33.45 +     * @return true if LET node
   33.46 +     */
   33.47 +    public boolean isLet() {
   33.48 +        return getFlag(IS_LET);
   33.49 +    }
   33.50 +
   33.51 +    /**
   33.52 +     * Is this an ECMAScript 6 CONST node?
   33.53 +     * @return true if CONST node
   33.54 +     */
   33.55 +    public boolean isConst() {
   33.56 +        return getFlag(IS_CONST);
   33.57 +    }
   33.58 +
   33.59 +    /**
   33.60 +     * Return the flags to use for symbols for this declaration.
   33.61 +     * @return the symbol flags
   33.62 +     */
   33.63 +    public int getSymbolFlags() {
   33.64 +        if (isLet()) {
   33.65 +            return Symbol.IS_VAR | Symbol.IS_LET;
   33.66 +        } else if (isConst()) {
   33.67 +            return Symbol.IS_VAR | Symbol.IS_CONST;
   33.68 +        }
   33.69 +        return Symbol.IS_VAR;
   33.70 +    }
   33.71 +
   33.72 +    /**
   33.73       * Does this variable declaration have an init value
   33.74       * @return true if an init exists, false otherwise
   33.75       */
   33.76 @@ -139,7 +183,7 @@
   33.77  
   33.78      @Override
   33.79      public void toString(final StringBuilder sb, final boolean printType) {
   33.80 -        sb.append("var ");
   33.81 +        sb.append(Token.descType(getToken()).getName()).append(' ');
   33.82          name.toString(sb, printType);
   33.83  
   33.84          if (init != null) {
    34.1 --- a/src/jdk/nashorn/internal/objects/Global.java	Thu Sep 11 15:34:13 2014 -0700
    34.2 +++ b/src/jdk/nashorn/internal/objects/Global.java	Tue Sep 16 13:59:37 2014 -0700
    34.3 @@ -631,6 +631,24 @@
    34.4      }
    34.5  
    34.6      /**
    34.7 +     * Returns a method handle that creates a wrapper object for a JS primitive value.
    34.8 +     *
    34.9 +     * @param self receiver object
   34.10 +     * @return method handle to create wrapper objects for primitive receiver
   34.11 +     */
   34.12 +    public static MethodHandle getPrimitiveWrapFilter(final Object self) {
   34.13 +        if (self instanceof String || self instanceof ConsString) {
   34.14 +            return NativeString.WRAPFILTER;
   34.15 +        } else if (self instanceof Number) {
   34.16 +            return NativeNumber.WRAPFILTER;
   34.17 +        } else if (self instanceof Boolean) {
   34.18 +            return NativeBoolean.WRAPFILTER;
   34.19 +        }
   34.20 +        throw new IllegalArgumentException("Unsupported primitive: " + self);
   34.21 +    }
   34.22 +
   34.23 +
   34.24 +    /**
   34.25       * Create a new empty script object
   34.26       *
   34.27       * @return the new ScriptObject
    35.1 --- a/src/jdk/nashorn/internal/objects/NativeBoolean.java	Thu Sep 11 15:34:13 2014 -0700
    35.2 +++ b/src/jdk/nashorn/internal/objects/NativeBoolean.java	Tue Sep 16 13:59:37 2014 -0700
    35.3 @@ -51,9 +51,9 @@
    35.4  public final class NativeBoolean extends ScriptObject {
    35.5      private final boolean value;
    35.6  
    35.7 -    // Method handle to create an object wrapper for a primitive boolean
    35.8 -    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
    35.9 -    // Method handle to retrieve the Boolean prototype object
   35.10 +    /** Method handle to create an object wrapper for a primitive boolean. */
   35.11 +    static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
   35.12 +    /** Method handle to retrieve the Boolean prototype object. */
   35.13      private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
   35.14  
   35.15      // initialized by nasgen
    36.1 --- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Sep 11 15:34:13 2014 -0700
    36.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java	Tue Sep 16 13:59:37 2014 -0700
    36.3 @@ -28,6 +28,7 @@
    36.4  import static jdk.nashorn.internal.lookup.Lookup.MH;
    36.5  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    36.6  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    36.7 +import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
    36.8  
    36.9  import java.lang.invoke.MethodHandle;
   36.10  import java.lang.invoke.MethodHandles;
   36.11 @@ -697,7 +698,7 @@
   36.12                  if (methodHandle != null) {
   36.13                      return new GuardedInvocation(
   36.14                              methodHandle,
   36.15 -                            testJSAdaptor(adaptee, findData.getGetter(Object.class, UnwarrantedOptimismException.INVALID_PROGRAM_POINT), findData.getOwner(), func),
   36.16 +                            testJSAdaptor(adaptee, findData.getGetter(Object.class, INVALID_PROGRAM_POINT, null), findData.getOwner(), func),
   36.17                              adaptee.getProtoSwitchPoint(hook, findData.getOwner()));
   36.18                  }
   36.19               }
    37.1 --- a/src/jdk/nashorn/internal/objects/NativeNumber.java	Thu Sep 11 15:34:13 2014 -0700
    37.2 +++ b/src/jdk/nashorn/internal/objects/NativeNumber.java	Tue Sep 16 13:59:37 2014 -0700
    37.3 @@ -57,9 +57,9 @@
    37.4  @ScriptClass("Number")
    37.5  public final class NativeNumber extends ScriptObject {
    37.6  
    37.7 -    // Method handle to create an object wrapper for a primitive number
    37.8 -    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
    37.9 -    // Method handle to retrieve the Number prototype object
   37.10 +    /** Method handle to create an object wrapper for a primitive number. */
   37.11 +    static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
   37.12 +    /** Method handle to retrieve the Number prototype object. */
   37.13      private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
   37.14  
   37.15      /** ECMA 15.7.3.2 largest positive finite value */
    38.1 --- a/src/jdk/nashorn/internal/objects/NativeString.java	Thu Sep 11 15:34:13 2014 -0700
    38.2 +++ b/src/jdk/nashorn/internal/objects/NativeString.java	Tue Sep 16 13:59:37 2014 -0700
    38.3 @@ -71,9 +71,9 @@
    38.4  
    38.5      private final CharSequence value;
    38.6  
    38.7 -    // Method handle to create an object wrapper for a primitive string
    38.8 -    private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
    38.9 -    // Method handle to retrieve the String prototype object
   38.10 +    /** Method handle to create an object wrapper for a primitive string */
   38.11 +    static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeString.class, Object.class));
   38.12 +    /** Method handle to retrieve the String prototype object */
   38.13      private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
   38.14  
   38.15      // initialized by nasgen
    39.1 --- a/src/jdk/nashorn/internal/parser/AbstractParser.java	Thu Sep 11 15:34:13 2014 -0700
    39.2 +++ b/src/jdk/nashorn/internal/parser/AbstractParser.java	Tue Sep 16 13:59:37 2014 -0700
    39.3 @@ -326,18 +326,28 @@
    39.4      }
    39.5  
    39.6      /**
    39.7 -     * Check next token and advance.
    39.8 +     * Check current token and advance to the next token.
    39.9       *
   39.10       * @param expected Expected tokenType.
   39.11       *
   39.12       * @throws ParserException on unexpected token type
   39.13       */
   39.14      protected final void expect(final TokenType expected) throws ParserException {
   39.15 +        expectDontAdvance(expected);
   39.16 +        next();
   39.17 +    }
   39.18 +
   39.19 +    /**
   39.20 +     * Check current token, but don't advance to the next token.
   39.21 +     *
   39.22 +     * @param expected Expected tokenType.
   39.23 +     *
   39.24 +     * @throws ParserException on unexpected token type
   39.25 +     */
   39.26 +    protected final void expectDontAdvance(final TokenType expected) throws ParserException {
   39.27          if (type != expected) {
   39.28              throw error(expectMessage(expected));
   39.29          }
   39.30 -
   39.31 -        next();
   39.32      }
   39.33  
   39.34      /**
    40.1 --- a/src/jdk/nashorn/internal/parser/Lexer.java	Thu Sep 11 15:34:13 2014 -0700
    40.2 +++ b/src/jdk/nashorn/internal/parser/Lexer.java	Tue Sep 16 13:59:37 2014 -0700
    40.3 @@ -35,6 +35,7 @@
    40.4  import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
    40.5  import static jdk.nashorn.internal.parser.TokenType.EXECSTRING;
    40.6  import static jdk.nashorn.internal.parser.TokenType.FLOATING;
    40.7 +import static jdk.nashorn.internal.parser.TokenType.FUNCTION;
    40.8  import static jdk.nashorn.internal.parser.TokenType.HEXADECIMAL;
    40.9  import static jdk.nashorn.internal.parser.TokenType.LBRACE;
   40.10  import static jdk.nashorn.internal.parser.TokenType.LPAREN;
   40.11 @@ -85,6 +86,9 @@
   40.12      /** Type of last token added. */
   40.13      private TokenType last;
   40.14  
   40.15 +    private final boolean pauseOnFunctionBody;
   40.16 +    private boolean pauseOnNextLeftBrace;
   40.17 +
   40.18      private static final String SPACETAB = " \t";  // ASCII space and tab
   40.19      private static final String LFCR     = "\n\r"; // line feed and carriage return (ctrl-m)
   40.20  
   40.21 @@ -182,20 +186,23 @@
   40.22       * @param scripting are we in scripting mode
   40.23       */
   40.24      public Lexer(final Source source, final TokenStream stream, final boolean scripting) {
   40.25 -        this(source, 0, source.getLength(), stream, scripting);
   40.26 +        this(source, 0, source.getLength(), stream, scripting, false);
   40.27      }
   40.28  
   40.29      /**
   40.30 -     * Contructor
   40.31 +     * Constructor
   40.32       *
   40.33       * @param source    the source
   40.34       * @param start     start position in source from which to start lexing
   40.35       * @param len       length of source segment to lex
   40.36       * @param stream    token stream to lex
   40.37       * @param scripting are we in scripting mode
   40.38 +     * @param pauseOnFunctionBody if true, lexer will return from {@link #lexify()} when it encounters a
   40.39 +     * function body. This is used with the feature where the parser is skipping nested function bodies to
   40.40 +     * avoid reading ahead unnecessarily when we skip the function bodies.
   40.41       */
   40.42  
   40.43 -    public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting) {
   40.44 +    public Lexer(final Source source, final int start, final int len, final TokenStream stream, final boolean scripting, final boolean pauseOnFunctionBody) {
   40.45          super(source.getContent(), 1, start, len);
   40.46          this.source      = source;
   40.47          this.stream      = stream;
   40.48 @@ -203,6 +210,8 @@
   40.49          this.nested      = false;
   40.50          this.pendingLine = 1;
   40.51          this.last        = EOL;
   40.52 +
   40.53 +        this.pauseOnFunctionBody = pauseOnFunctionBody;
   40.54      }
   40.55  
   40.56      private Lexer(final Lexer lexer, final State state) {
   40.57 @@ -216,6 +225,7 @@
   40.58          pendingLine = state.pendingLine;
   40.59          linePosition = state.linePosition;
   40.60          last = EOL;
   40.61 +        pauseOnFunctionBody = false;
   40.62      }
   40.63  
   40.64      static class State extends Scanner.State {
   40.65 @@ -810,6 +820,9 @@
   40.66          final int length = scanIdentifier();
   40.67          // Check to see if it is a keyword.
   40.68          final TokenType type = TokenLookup.lookupKeyword(content, start, length);
   40.69 +        if (type == FUNCTION && pauseOnFunctionBody) {
   40.70 +            pauseOnNextLeftBrace = true;
   40.71 +        }
   40.72          // Add keyword or identifier token.
   40.73          add(type, start);
   40.74      }
   40.75 @@ -1597,6 +1610,9 @@
   40.76                  // We break to let the parser decide what it is.
   40.77                  if (canStartLiteral(type)) {
   40.78                      break;
   40.79 +                } else if (type == LBRACE && pauseOnNextLeftBrace) {
   40.80 +                    pauseOnNextLeftBrace = false;
   40.81 +                    break;
   40.82                  }
   40.83              } else if (Character.isJavaIdentifierStart(ch0) || ch0 == '\\' && ch1 == 'u') {
   40.84                  // Scan and add identifier or keyword.
    41.1 --- a/src/jdk/nashorn/internal/parser/Parser.java	Thu Sep 11 15:34:13 2014 -0700
    41.2 +++ b/src/jdk/nashorn/internal/parser/Parser.java	Tue Sep 16 13:59:37 2014 -0700
    41.3 @@ -45,6 +45,7 @@
    41.4  import static jdk.nashorn.internal.parser.TokenType.IF;
    41.5  import static jdk.nashorn.internal.parser.TokenType.INCPOSTFIX;
    41.6  import static jdk.nashorn.internal.parser.TokenType.LBRACE;
    41.7 +import static jdk.nashorn.internal.parser.TokenType.LET;
    41.8  import static jdk.nashorn.internal.parser.TokenType.LPAREN;
    41.9  import static jdk.nashorn.internal.parser.TokenType.RBRACE;
   41.10  import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
   41.11 @@ -147,7 +148,7 @@
   41.12      /** to receive line information from Lexer when scanning multine literals. */
   41.13      protected final Lexer.LineInfoReceiver lineInfoReceiver;
   41.14  
   41.15 -    private int nextFunctionId;
   41.16 +    private RecompilableScriptFunctionData reparsedFunction;
   41.17  
   41.18      /**
   41.19       * Constructor
   41.20 @@ -170,7 +171,7 @@
   41.21       * @param log debug logger if one is needed
   41.22       */
   41.23      public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final DebugLogger log) {
   41.24 -        this(env, source, errors, strict, FunctionNode.FIRST_FUNCTION_ID, 0, log);
   41.25 +        this(env, source, errors, strict, 0, log);
   41.26      }
   41.27  
   41.28      /**
   41.29 @@ -180,15 +181,13 @@
   41.30       * @param source  source to parse
   41.31       * @param errors  error manager
   41.32       * @param strict  parser created with strict mode enabled.
   41.33 -     * @param nextFunctionId  starting value for assigning new unique ids to function nodes
   41.34       * @param lineOffset line offset to start counting lines from
   41.35       * @param log debug logger if one is needed
   41.36       */
   41.37 -    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int nextFunctionId, final int lineOffset, final DebugLogger log) {
   41.38 +    public Parser(final ScriptEnvironment env, final Source source, final ErrorManager errors, final boolean strict, final int lineOffset, final DebugLogger log) {
   41.39          super(source, errors, strict, lineOffset);
   41.40          this.env = env;
   41.41          this.namespace = new Namespace(env.getNamespace());
   41.42 -        this.nextFunctionId    = nextFunctionId;
   41.43          this.scripting = env._scripting;
   41.44          if (this.scripting) {
   41.45              this.lineInfoReceiver = new Lexer.LineInfoReceiver() {
   41.46 @@ -227,6 +226,16 @@
   41.47      }
   41.48  
   41.49      /**
   41.50 +     * Sets the {@link RecompilableScriptFunctionData} representing the function being reparsed (when this
   41.51 +     * parser instance is used to reparse a previously parsed function, as part of its on-demand compilation).
   41.52 +     * This will trigger various special behaviors, such as skipping nested function bodies.
   41.53 +     * @param reparsedFunction the function being reparsed.
   41.54 +     */
   41.55 +    public void setReparsedFunction(final RecompilableScriptFunctionData reparsedFunction) {
   41.56 +        this.reparsedFunction = reparsedFunction;
   41.57 +    }
   41.58 +
   41.59 +    /**
   41.60       * Execute parse and return the resulting function node.
   41.61       * Errors will be thrown and the error manager will contain information
   41.62       * if parsing should fail
   41.63 @@ -263,7 +272,7 @@
   41.64  
   41.65          try {
   41.66              stream = new TokenStream();
   41.67 -            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions);
   41.68 +            lexer  = new Lexer(source, startPos, len, stream, scripting && !env._no_syntax_extensions, reparsedFunction != null);
   41.69              lexer.line = lexer.pendingLine = lineOffset + 1;
   41.70              line = lineOffset;
   41.71  
   41.72 @@ -471,7 +480,6 @@
   41.73          final FunctionNode functionNode =
   41.74              new FunctionNode(
   41.75                  source,
   41.76 -                nextFunctionId++,
   41.77                  functionLine,
   41.78                  token,
   41.79                  Token.descPosition(token),
   41.80 @@ -579,6 +587,10 @@
   41.81          }
   41.82      }
   41.83  
   41.84 +    private boolean useBlockScope() {
   41.85 +        return env._es6;
   41.86 +    }
   41.87 +
   41.88      private static boolean isArguments(final String name) {
   41.89          return ARGUMENTS_NAME.equals(name);
   41.90      }
   41.91 @@ -694,9 +706,20 @@
   41.92              FunctionNode.Kind.SCRIPT,
   41.93              functionLine);
   41.94  
   41.95 +        // If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations.
   41.96 +        final int startLine = start;
   41.97 +        Block outer = useBlockScope() ? newBlock() : null;
   41.98          functionDeclarations = new ArrayList<>();
   41.99 -        sourceElements(allowPropertyFunction);
  41.100 -        addFunctionDeclarations(script);
  41.101 +
  41.102 +        try {
  41.103 +            sourceElements(allowPropertyFunction);
  41.104 +            addFunctionDeclarations(script);
  41.105 +        } finally {
  41.106 +            if (outer != null) {
  41.107 +                outer = restoreBlock(outer);
  41.108 +                appendStatement(new BlockStatement(startLine, outer));
  41.109 +            }
  41.110 +        }
  41.111          functionDeclarations = null;
  41.112  
  41.113          expect(EOF);
  41.114 @@ -868,7 +891,7 @@
  41.115              block();
  41.116              break;
  41.117          case VAR:
  41.118 -            variableStatement(true);
  41.119 +            variableStatement(type, true);
  41.120              break;
  41.121          case SEMICOLON:
  41.122              emptyStatement();
  41.123 @@ -918,8 +941,12 @@
  41.124              expect(SEMICOLON);
  41.125              break;
  41.126          default:
  41.127 +            if (useBlockScope() && (type == LET || type == CONST)) {
  41.128 +                variableStatement(type, true);
  41.129 +                break;
  41.130 +            }
  41.131              if (env._const_as_var && type == CONST) {
  41.132 -                variableStatement(true);
  41.133 +                variableStatement(TokenType.VAR, true);
  41.134                  break;
  41.135              }
  41.136  
  41.137 @@ -1035,11 +1062,17 @@
  41.138       * Parse a VAR statement.
  41.139       * @param isStatement True if a statement (not used in a FOR.)
  41.140       */
  41.141 -    private List<VarNode> variableStatement(final boolean isStatement) {
  41.142 +    private List<VarNode> variableStatement(final TokenType varType, final boolean isStatement) {
  41.143          // VAR tested in caller.
  41.144          next();
  41.145  
  41.146          final List<VarNode> vars = new ArrayList<>();
  41.147 +        int varFlags = VarNode.IS_STATEMENT;
  41.148 +        if (varType == LET) {
  41.149 +            varFlags |= VarNode.IS_LET;
  41.150 +        } else if (varType == CONST) {
  41.151 +            varFlags |= VarNode.IS_CONST;
  41.152 +        }
  41.153  
  41.154          while (true) {
  41.155              // Get starting token.
  41.156 @@ -1063,10 +1096,12 @@
  41.157                  } finally {
  41.158                      defaultNames.pop();
  41.159                  }
  41.160 +            } else if (varType == CONST) {
  41.161 +                throw error(AbstractParser.message("missing.const.assignment", name.getName()));
  41.162              }
  41.163  
  41.164              // Allocate var node.
  41.165 -            final VarNode var = new VarNode(varLine, varToken, finish, name, init);
  41.166 +            final VarNode var = new VarNode(varLine, varToken, finish, name.setIsDeclaredHere(), init, varFlags);
  41.167              vars.add(var);
  41.168              appendStatement(var);
  41.169  
  41.170 @@ -1180,9 +1215,12 @@
  41.171       * Parse a FOR statement.
  41.172       */
  41.173      private void forStatement() {
  41.174 +        // When ES6 for-let is enabled we create a container block to capture the LET.
  41.175 +        final int startLine = start;
  41.176 +        Block outer = useBlockScope() ? newBlock() : null;
  41.177 +
  41.178          // Create FOR node, capturing FOR token.
  41.179          ForNode forNode = new ForNode(line, token, Token.descPosition(token), null, ForNode.IS_FOR);
  41.180 -
  41.181          lc.push(forNode);
  41.182  
  41.183          try {
  41.184 @@ -1203,14 +1241,19 @@
  41.185              switch (type) {
  41.186              case VAR:
  41.187                  // Var statements captured in for outer block.
  41.188 -                vars = variableStatement(false);
  41.189 +                vars = variableStatement(type, false);
  41.190                  break;
  41.191              case SEMICOLON:
  41.192                  break;
  41.193              default:
  41.194 +                if (useBlockScope() && (type == LET || type == CONST)) {
  41.195 +                    // LET/CONST captured in container block created above.
  41.196 +                    vars = variableStatement(type, false);
  41.197 +                    break;
  41.198 +                }
  41.199                  if (env._const_as_var && type == CONST) {
  41.200                      // Var statements captured in for outer block.
  41.201 -                    vars = variableStatement(false);
  41.202 +                    vars = variableStatement(TokenType.VAR, false);
  41.203                      break;
  41.204                  }
  41.205  
  41.206 @@ -1290,8 +1333,13 @@
  41.207              appendStatement(forNode);
  41.208          } finally {
  41.209              lc.pop(forNode);
  41.210 +            if (outer != null) {
  41.211 +                outer.setFinish(forNode.getFinish());
  41.212 +                outer = restoreBlock(outer);
  41.213 +                appendStatement(new BlockStatement(startLine, outer));
  41.214 +            }
  41.215          }
  41.216 -     }
  41.217 +    }
  41.218  
  41.219      /**
  41.220       * ... IterationStatement :
  41.221 @@ -1722,7 +1770,7 @@
  41.222          }
  41.223      }
  41.224  
  41.225 -   /**
  41.226 +    /**
  41.227       * ThrowStatement :
  41.228       *      throw Expression ; // [no LineTerminator here]
  41.229       *
  41.230 @@ -2609,7 +2657,7 @@
  41.231          FunctionNode functionNode = functionBody(functionToken, name, parameters, FunctionNode.Kind.NORMAL, functionLine);
  41.232  
  41.233          if (isStatement) {
  41.234 -            if (topLevel) {
  41.235 +            if (topLevel || useBlockScope()) {
  41.236                  functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
  41.237              } else if (isStrictMode) {
  41.238                  throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
  41.239 @@ -2661,9 +2709,16 @@
  41.240          }
  41.241  
  41.242          if (isStatement) {
  41.243 -            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, VarNode.IS_STATEMENT);
  41.244 +            int varFlags = VarNode.IS_STATEMENT;
  41.245 +            if (!topLevel && useBlockScope()) {
  41.246 +                // mark ES6 block functions as lexically scoped
  41.247 +                varFlags |= VarNode.IS_LET;
  41.248 +            }
  41.249 +            final VarNode varNode = new VarNode(functionLine, functionToken, finish, name, functionNode, varFlags);
  41.250              if (topLevel) {
  41.251                  functionDeclarations.add(varNode);
  41.252 +            } else if (useBlockScope()) {
  41.253 +                prependStatement(varNode); // Hoist to beginning of current block
  41.254              } else {
  41.255                  appendStatement(varNode);
  41.256              }
  41.257 @@ -2780,10 +2835,14 @@
  41.258          FunctionNode functionNode = null;
  41.259          long lastToken = 0L;
  41.260  
  41.261 +        final boolean parseBody;
  41.262 +        Object endParserState = null;
  41.263          try {
  41.264              // Create a new function block.
  41.265              functionNode = newFunctionNode(firstToken, ident, parameters, kind, functionLine);
  41.266 -
  41.267 +            assert functionNode != null;
  41.268 +            final int functionId = functionNode.getId();
  41.269 +            parseBody = reparsedFunction == null || functionId <= reparsedFunction.getFunctionNodeId();
  41.270              // Nashorn extension: expression closures
  41.271              if (!env._no_syntax_extensions && type != LBRACE) {
  41.272                  /*
  41.273 @@ -2799,34 +2858,143 @@
  41.274                  assert lc.getCurrentBlock() == lc.getFunctionBody(functionNode);
  41.275                  // EOL uses length field to store the line number
  41.276                  final int lastFinish = Token.descPosition(lastToken) + (Token.descType(lastToken) == EOL ? 0 : Token.descLength(lastToken));
  41.277 -                final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
  41.278 -                appendStatement(returnNode);
  41.279 +                // Only create the return node if we aren't skipping nested functions. Note that we aren't
  41.280 +                // skipping parsing of these extended functions; they're considered to be small anyway. Also,
  41.281 +                // they don't end with a single well known token, so it'd be very hard to get correctly (see
  41.282 +                // the note below for reasoning on skipping happening before instead of after RBRACE for
  41.283 +                // details).
  41.284 +                if (parseBody) {
  41.285 +                    final ReturnNode returnNode = new ReturnNode(functionNode.getLineNumber(), expr.getToken(), lastFinish, expr);
  41.286 +                    appendStatement(returnNode);
  41.287 +                }
  41.288                  functionNode.setFinish(lastFinish);
  41.289 -
  41.290              } else {
  41.291 -                expect(LBRACE);
  41.292 -
  41.293 -                // Gather the function elements.
  41.294 -                final List<Statement> prevFunctionDecls = functionDeclarations;
  41.295 -                functionDeclarations = new ArrayList<>();
  41.296 -                try {
  41.297 -                    sourceElements(false);
  41.298 -                    addFunctionDeclarations(functionNode);
  41.299 -                } finally {
  41.300 -                    functionDeclarations = prevFunctionDecls;
  41.301 +                expectDontAdvance(LBRACE);
  41.302 +                if (parseBody || !skipFunctionBody(functionNode)) {
  41.303 +                    next();
  41.304 +                    // Gather the function elements.
  41.305 +                    final List<Statement> prevFunctionDecls = functionDeclarations;
  41.306 +                    functionDeclarations = new ArrayList<>();
  41.307 +                    try {
  41.308 +                        sourceElements(false);
  41.309 +                        addFunctionDeclarations(functionNode);
  41.310 +                    } finally {
  41.311 +                        functionDeclarations = prevFunctionDecls;
  41.312 +                    }
  41.313 +
  41.314 +                    lastToken = token;
  41.315 +                    if (parseBody) {
  41.316 +                        // Since the lexer can read ahead and lexify some number of tokens in advance and have
  41.317 +                        // them buffered in the TokenStream, we need to produce a lexer state as it was just
  41.318 +                        // before it lexified RBRACE, and not whatever is its current (quite possibly well read
  41.319 +                        // ahead) state.
  41.320 +                        endParserState = new ParserState(Token.descPosition(token), line, linePosition);
  41.321 +
  41.322 +                        // NOTE: you might wonder why do we capture/restore parser state before RBRACE instead of
  41.323 +                        // after RBRACE; after all, we could skip the below "expect(RBRACE);" if we captured the
  41.324 +                        // state after it. The reason is that RBRACE is a well-known token that we can expect and
  41.325 +                        // will never involve us getting into a weird lexer state, and as such is a great reparse
  41.326 +                        // point. Typical example of a weird lexer state after RBRACE would be:
  41.327 +                        //     function this_is_skipped() { ... } "use strict";
  41.328 +                        // because lexer is doing weird off-by-one maneuvers around string literal quotes. Instead
  41.329 +                        // of compensating for the possibility of a string literal (or similar) after RBRACE,
  41.330 +                        // we'll rather just restart parsing from this well-known, friendly token instead.
  41.331 +                    }
  41.332                  }
  41.333 -
  41.334 -                lastToken = token;
  41.335                  expect(RBRACE);
  41.336                  functionNode.setFinish(finish);
  41.337              }
  41.338          } finally {
  41.339              functionNode = restoreFunctionNode(functionNode, lastToken);
  41.340          }
  41.341 +
  41.342 +        // NOTE: we can only do alterations to the function node after restoreFunctionNode.
  41.343 +
  41.344 +        if (parseBody) {
  41.345 +            functionNode = functionNode.setEndParserState(lc, endParserState);
  41.346 +        } else if (functionNode.getBody().getStatementCount() > 0){
  41.347 +            // This is to ensure the body is empty when !parseBody but we couldn't skip parsing it (see
  41.348 +            // skipFunctionBody() for possible reasons). While it is not strictly necessary for correctness to
  41.349 +            // enforce empty bodies in nested functions that were supposed to be skipped, we do assert it as
  41.350 +            // an invariant in few places in the compiler pipeline, so for consistency's sake we'll throw away
  41.351 +            // nested bodies early if we were supposed to skip 'em.
  41.352 +            functionNode = functionNode.setBody(null, functionNode.getBody().setStatements(null,
  41.353 +                    Collections.<Statement>emptyList()));
  41.354 +        }
  41.355 +
  41.356 +        if (reparsedFunction != null) {
  41.357 +            // We restore the flags stored in the function's ScriptFunctionData that we got when we first
  41.358 +            // eagerly parsed the code. We're doing it because some flags would be set based on the
  41.359 +            // content of the function, or even content of its nested functions, most of which are normally
  41.360 +            // skipped during an on-demand compilation.
  41.361 +            final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
  41.362 +            if (data != null) {
  41.363 +                // Data can be null if when we originally parsed the file, we removed the function declaration
  41.364 +                // as it was dead code.
  41.365 +                functionNode = functionNode.setFlags(lc, data.getFunctionFlags());
  41.366 +                // This compensates for missing markEval() in case the function contains an inner function
  41.367 +                // that contains eval(), that now we didn't discover since we skipped the inner function.
  41.368 +                if (functionNode.hasNestedEval()) {
  41.369 +                    assert functionNode.hasScopeBlock();
  41.370 +                    functionNode = functionNode.setBody(lc, functionNode.getBody().setNeedsScope(null));
  41.371 +                }
  41.372 +            }
  41.373 +        }
  41.374          printAST(functionNode);
  41.375          return functionNode;
  41.376      }
  41.377  
  41.378 +    private boolean skipFunctionBody(final FunctionNode functionNode) {
  41.379 +        if (reparsedFunction == null) {
  41.380 +            // Not reparsing, so don't skip any function body.
  41.381 +            return false;
  41.382 +        }
  41.383 +        // Skip to the RBRACE of this function, and continue parsing from there.
  41.384 +        final RecompilableScriptFunctionData data = reparsedFunction.getScriptFunctionData(functionNode.getId());
  41.385 +        if (data == null) {
  41.386 +            // Nested function is not known to the reparsed function. This can happen if the FunctionNode was
  41.387 +            // in dead code that was removed. Both FoldConstants and Lower prune dead code. In that case, the
  41.388 +            // FunctionNode was dropped before a RecompilableScriptFunctionData could've been created for it.
  41.389 +            return false;
  41.390 +        }
  41.391 +        final ParserState parserState = (ParserState)data.getEndParserState();
  41.392 +        assert parserState != null;
  41.393 +
  41.394 +        stream.reset();
  41.395 +        lexer = parserState.createLexer(source, lexer, stream, scripting && !env._no_syntax_extensions);
  41.396 +        line = parserState.line;
  41.397 +        linePosition = parserState.linePosition;
  41.398 +        // Doesn't really matter, but it's safe to treat it as if there were a semicolon before
  41.399 +        // the RBRACE.
  41.400 +        type = SEMICOLON;
  41.401 +        k = -1;
  41.402 +        next();
  41.403 +
  41.404 +        return true;
  41.405 +    }
  41.406 +
  41.407 +    /**
  41.408 +     * Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer
  41.409 +     * for resuming parsing after skipping a function body.
  41.410 +     */
  41.411 +    private static class ParserState {
  41.412 +        private final int position;
  41.413 +        private final int line;
  41.414 +        private final int linePosition;
  41.415 +
  41.416 +        ParserState(final int position, final int line, final int linePosition) {
  41.417 +            this.position = position;
  41.418 +            this.line = line;
  41.419 +            this.linePosition = linePosition;
  41.420 +        }
  41.421 +
  41.422 +        Lexer createLexer(final Source source, final Lexer lexer, final TokenStream stream, final boolean scripting) {
  41.423 +            final Lexer newLexer = new Lexer(source, position, lexer.limit - position, stream, scripting, true);
  41.424 +            newLexer.restoreState(new Lexer.State(position, Integer.MAX_VALUE, line, -1, linePosition, SEMICOLON));
  41.425 +            return newLexer;
  41.426 +        }
  41.427 +    }
  41.428 +
  41.429      private void printAST(final FunctionNode functionNode) {
  41.430          if (functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
  41.431              env.getErr().println(new ASTWriter(functionNode));
  41.432 @@ -2838,7 +3006,6 @@
  41.433      }
  41.434  
  41.435      private void addFunctionDeclarations(final FunctionNode functionNode) {
  41.436 -        assert lc.peek() == lc.getFunctionBody(functionNode);
  41.437          VarNode lastDecl = null;
  41.438          for (int i = functionDeclarations.size() - 1; i >= 0; i--) {
  41.439              Statement decl = functionDeclarations.get(i);
  41.440 @@ -3200,6 +3367,9 @@
  41.441              } else {
  41.442                  lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL);
  41.443              }
  41.444 +            // NOTE: it is crucial to mark the body of the outer function as needing scope even when we skip
  41.445 +            // parsing a nested function. functionBody() contains code to compensate for the lack of invoking
  41.446 +            // this method when the parser skips a nested function.
  41.447              lc.setBlockNeedsScope(lc.getFunctionBody(fn));
  41.448          }
  41.449      }
    42.1 --- a/src/jdk/nashorn/internal/parser/TokenStream.java	Thu Sep 11 15:34:13 2014 -0700
    42.2 +++ b/src/jdk/nashorn/internal/parser/TokenStream.java	Tue Sep 16 13:59:37 2014 -0700
    42.3 @@ -209,4 +209,8 @@
    42.4          in = count;
    42.5          buffer = newBuffer;
    42.6      }
    42.7 +
    42.8 +    void reset() {
    42.9 +        in = out = count = base = 0;
   42.10 +    }
   42.11  }
    43.1 --- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Thu Sep 11 15:34:13 2014 -0700
    43.2 +++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java	Tue Sep 16 13:59:37 2014 -0700
    43.3 @@ -549,6 +549,8 @@
    43.4                  type == Object.class :
    43.5                  "invalid getter type " + type + " for " + getKey();
    43.6  
    43.7 +        checkUndeclared();
    43.8 +
    43.9          //all this does is add a return value filter for object fields only
   43.10          final MethodHandle[] getterCache = GETTER_CACHE;
   43.11          final MethodHandle cachedGetter = getterCache[i];
   43.12 @@ -579,6 +581,8 @@
   43.13              return getOptimisticPrimitiveGetter(type, programPoint);
   43.14          }
   43.15  
   43.16 +        checkUndeclared();
   43.17 +
   43.18          return debug(
   43.19              createGetter(
   43.20                  getCurrentType(),
   43.21 @@ -608,6 +612,13 @@
   43.22          return newMap;
   43.23      }
   43.24  
   43.25 +    private void checkUndeclared() {
   43.26 +        if ((getFlags() & NEEDS_DECLARATION) != 0) {
   43.27 +            // a lexically defined variable that hasn't seen its declaration - throw ReferenceError
   43.28 +            throw ECMAErrors.referenceError("not.defined", getKey());
   43.29 +        }
   43.30 +    }
   43.31 +
   43.32      // the final three arguments are for debug printout purposes only
   43.33      @SuppressWarnings("unused")
   43.34      private static Object replaceMap(final Object sobj, final PropertyMap newMap) {
   43.35 @@ -635,13 +646,14 @@
   43.36  
   43.37      @Override
   43.38      public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
   43.39 -        final int      i       = getAccessorTypeIndex(type);
   43.40 -        final int      ci      = isUndefined() ? -1 : getAccessorTypeIndex(getCurrentType());
   43.41 -        final Class<?> forType = isUndefined() ? type : getCurrentType();
   43.42 +        checkUndeclared();
   43.43 +
   43.44 +        final int typeIndex        = getAccessorTypeIndex(type);
   43.45 +        final int currentTypeIndex = getAccessorTypeIndex(getCurrentType());
   43.46  
   43.47          //if we are asking for an object setter, but are still a primitive type, we might try to box it
   43.48          MethodHandle mh;
   43.49 -        if (needsInvalidator(i, ci)) {
   43.50 +        if (needsInvalidator(typeIndex, currentTypeIndex)) {
   43.51              final Property     newProperty = getWiderProperty(type);
   43.52              final PropertyMap  newMap      = getWiderMap(currentMap, newProperty);
   43.53  
   43.54 @@ -652,6 +664,7 @@
   43.55                   mh = ObjectClassGenerator.createGuardBoxedPrimitiveSetter(ct, generateSetter(ct, ct), mh);
   43.56              }
   43.57          } else {
   43.58 +            final Class<?> forType = isUndefined() ? type : getCurrentType();
   43.59              mh = generateSetter(!forType.isPrimitive() ? Object.class : forType, type);
   43.60          }
   43.61  
   43.62 @@ -692,11 +705,12 @@
   43.63          if (OBJECT_FIELDS_ONLY) {
   43.64              return false;
   43.65          }
   43.66 -        return getCurrentType() != Object.class && (isConfigurable() || isWritable());
   43.67 +        // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
   43.68 +        return getCurrentType() == null || (getCurrentType() != Object.class && (isConfigurable() || isWritable()));
   43.69      }
   43.70  
   43.71 -    private boolean needsInvalidator(final int ti, final int fti) {
   43.72 -        return canChangeType() && ti > fti;
   43.73 +    private boolean needsInvalidator(final int typeIndex, final int currentTypeIndex) {
   43.74 +        return canChangeType() && typeIndex > currentTypeIndex;
   43.75      }
   43.76  
   43.77      @Override
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/src/jdk/nashorn/internal/runtime/AllocationStrategy.java	Tue Sep 16 13:59:37 2014 -0700
    44.3 @@ -0,0 +1,104 @@
    44.4 +/*
    44.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    44.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    44.7 + *
    44.8 + * This code is free software; you can redistribute it and/or modify it
    44.9 + * under the terms of the GNU General Public License version 2 only, as
   44.10 + * published by the Free Software Foundation.  Oracle designates this
   44.11 + * particular file as subject to the "Classpath" exception as provided
   44.12 + * by Oracle in the LICENSE file that accompanied this code.
   44.13 + *
   44.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   44.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   44.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   44.17 + * version 2 for more details (a copy is included in the LICENSE file that
   44.18 + * accompanied this code).
   44.19 + *
   44.20 + * You should have received a copy of the GNU General Public License version
   44.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   44.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   44.23 + *
   44.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   44.25 + * or visit www.oracle.com if you need additional information or have any
   44.26 + * questions.
   44.27 + */
   44.28 +package jdk.nashorn.internal.runtime;
   44.29 +
   44.30 +import static jdk.nashorn.internal.lookup.Lookup.MH;
   44.31 +
   44.32 +import java.io.Serializable;
   44.33 +import java.lang.invoke.MethodHandle;
   44.34 +import java.lang.invoke.MethodHandles;
   44.35 +import jdk.nashorn.internal.codegen.CompilerConstants;
   44.36 +import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
   44.37 +
   44.38 +/**
   44.39 + * Encapsulates the allocation strategy for a function when used as a constructor. Basically the same as
   44.40 + * {@link AllocatorDescriptor}, but with an additionally cached resolved method handle. There is also a
   44.41 + * canonical default allocation strategy for functions that don't assign any "this" properties (vast majority
   44.42 + * of all functions), therefore saving some storage space in {@link RecompilableScriptFunctionData} that would
   44.43 + * otherwise be lost to identical tuples of (map, className, handle) fields.
   44.44 + */
   44.45 +final class AllocationStrategy implements Serializable {
   44.46 +    private static final long serialVersionUID = 1L;
   44.47 +
   44.48 +    private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
   44.49 +
   44.50 +    private static final AllocationStrategy DEFAULT_STRATEGY = new AllocationStrategy(new AllocatorDescriptor(0));
   44.51 +
   44.52 +    /** Allocator map from allocator descriptor */
   44.53 +    private final PropertyMap allocatorMap;
   44.54 +
   44.55 +    /** Name of class where allocator function resides */
   44.56 +    private final String allocatorClassName;
   44.57 +
   44.58 +    /** lazily generated allocator */
   44.59 +    private transient MethodHandle allocator;
   44.60 +
   44.61 +    private AllocationStrategy(final AllocatorDescriptor desc) {
   44.62 +        this.allocatorMap = desc.getAllocatorMap();
   44.63 +        // These classes get loaded, so an interned variant of their name is most likely around anyway.
   44.64 +        this.allocatorClassName = desc.getAllocatorClassName().intern();
   44.65 +    }
   44.66 +
   44.67 +    private boolean matches(final AllocatorDescriptor desc) {
   44.68 +        return desc.getAllocatorMap().size() == allocatorMap.size() &&
   44.69 +                desc.getAllocatorClassName().equals(allocatorClassName);
   44.70 +    }
   44.71 +
   44.72 +    static AllocationStrategy get(final AllocatorDescriptor desc) {
   44.73 +        return DEFAULT_STRATEGY.matches(desc) ? DEFAULT_STRATEGY : new AllocationStrategy(desc);
   44.74 +    }
   44.75 +
   44.76 +    PropertyMap getAllocatorMap() {
   44.77 +        return allocatorMap;
   44.78 +    }
   44.79 +
   44.80 +    ScriptObject allocate(final PropertyMap map) {
   44.81 +        try {
   44.82 +            if (allocator == null) {
   44.83 +                allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName),
   44.84 +                        CompilerConstants.ALLOCATE.symbolName(), MH.type(ScriptObject.class, PropertyMap.class));
   44.85 +            }
   44.86 +            return (ScriptObject)allocator.invokeExact(map);
   44.87 +        } catch (final RuntimeException | Error e) {
   44.88 +            throw e;
   44.89 +        } catch (final Throwable t) {
   44.90 +            throw new RuntimeException(t);
   44.91 +        }
   44.92 +    }
   44.93 +
   44.94 +    private Object readResolve() {
   44.95 +        if(allocatorMap.size() == DEFAULT_STRATEGY.allocatorMap.size() &&
   44.96 +                allocatorClassName.equals(DEFAULT_STRATEGY.allocatorClassName)) {
   44.97 +            return DEFAULT_STRATEGY;
   44.98 +        }
   44.99 +        return this;
  44.100 +    }
  44.101 +
  44.102 +    @Override
  44.103 +    public String toString() {
  44.104 +        return "AllocationStrategy[allocatorClassName=" + allocatorClassName + ", allocatorMap.size=" +
  44.105 +                allocatorMap.size() + "]";
  44.106 +    }
  44.107 +}
    45.1 --- a/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Thu Sep 11 15:34:13 2014 -0700
    45.2 +++ b/src/jdk/nashorn/internal/runtime/CodeInstaller.java	Tue Sep 16 13:59:37 2014 -0700
    45.3 @@ -80,12 +80,6 @@
    45.4      public long getUniqueScriptId();
    45.5  
    45.6      /**
    45.7 -     * Get next unique eval id
    45.8 -     * @return unique eval id
    45.9 -     */
   45.10 -    public long getUniqueEvalId();
   45.11 -
   45.12 -    /**
   45.13       * Store a compiled script for later reuse
   45.14       * @param source the script source
   45.15       * @param mainClassName the main class name
    46.1 --- a/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Thu Sep 11 15:34:13 2014 -0700
    46.2 +++ b/src/jdk/nashorn/internal/runtime/CompiledFunction.java	Tue Sep 16 13:59:37 2014 -0700
    46.3 @@ -27,7 +27,6 @@
    46.4  import static jdk.nashorn.internal.lookup.Lookup.MH;
    46.5  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
    46.6  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
    46.7 -
    46.8  import java.lang.invoke.CallSite;
    46.9  import java.lang.invoke.MethodHandle;
   46.10  import java.lang.invoke.MethodHandles;
   46.11 @@ -39,6 +38,7 @@
   46.12  import java.util.TreeMap;
   46.13  import java.util.function.Supplier;
   46.14  import java.util.logging.Level;
   46.15 +
   46.16  import jdk.internal.dynalink.linker.GuardedInvocation;
   46.17  import jdk.nashorn.internal.codegen.Compiler;
   46.18  import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
    47.1 --- a/src/jdk/nashorn/internal/runtime/Context.java	Thu Sep 11 15:34:13 2014 -0700
    47.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java	Tue Sep 16 13:59:37 2014 -0700
    47.3 @@ -196,16 +196,11 @@
    47.4          }
    47.5  
    47.6          @Override
    47.7 -        public long getUniqueEvalId() {
    47.8 -            return context.getUniqueEvalId();
    47.9 -        }
   47.10 -
   47.11 -        @Override
   47.12 -        public void storeScript(final String classInfoFile, final Source source, final String mainClassName,
   47.13 +        public void storeScript(final String cacheKey, final Source source, final String mainClassName,
   47.14                                  final Map<String,byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers,
   47.15                                  final Object[] constants, final int compilationId) {
   47.16              if (context.codeStore != null) {
   47.17 -                context.codeStore.storeScript(classInfoFile, source, mainClassName, classBytes, initializers, constants, compilationId);
   47.18 +                context.codeStore.storeScript(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId);
   47.19              }
   47.20          }
   47.21  
   47.22 @@ -334,9 +329,6 @@
   47.23      /** Unique id for script. Used only when --loader-per-compile=false */
   47.24      private final AtomicLong uniqueScriptId;
   47.25  
   47.26 -    /** Unique id for 'eval' */
   47.27 -    private final AtomicLong uniqueEvalId;
   47.28 -
   47.29      /** Optional class filter to use for Java classes. Can be null. */
   47.30      private final ClassFilter classFilter;
   47.31  
   47.32 @@ -450,7 +442,6 @@
   47.33              this.uniqueScriptId = new AtomicLong();
   47.34          }
   47.35          this.errors    = errors;
   47.36 -        this.uniqueEvalId = new AtomicLong();
   47.37  
   47.38          // if user passed -classpath option, make a class loader with that and set it as
   47.39          // thread context class loader so that script can access classes from that path.
   47.40 @@ -1132,7 +1123,7 @@
   47.41          if (storedScript == null) {
   47.42              functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
   47.43  
   47.44 -            if (errors.hasErrors()) {
   47.45 +            if (errMan.hasErrors()) {
   47.46                  return null;
   47.47              }
   47.48  
   47.49 @@ -1162,9 +1153,13 @@
   47.50                      env,
   47.51                      installer,
   47.52                      source,
   47.53 +                    errMan,
   47.54                      strict | functionNode.isStrict());
   47.55  
   47.56              final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
   47.57 +            if (errMan.hasErrors()) {
   47.58 +                return null;
   47.59 +            }
   47.60              script = compiledFunction.getRootClass();
   47.61              compiler.persistClassInfo(cacheKey, compiledFunction);
   47.62          } else {
   47.63 @@ -1186,10 +1181,6 @@
   47.64               }, CREATE_LOADER_ACC_CTXT);
   47.65      }
   47.66  
   47.67 -    private long getUniqueEvalId() {
   47.68 -        return uniqueEvalId.getAndIncrement();
   47.69 -    }
   47.70 -
   47.71      private long getUniqueScriptId() {
   47.72          return uniqueScriptId.getAndIncrement();
   47.73      }
    48.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java	Thu Sep 11 15:34:13 2014 -0700
    48.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java	Tue Sep 16 13:59:37 2014 -0700
    48.3 @@ -29,7 +29,9 @@
    48.4  import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
    48.5  
    48.6  import java.lang.invoke.MethodHandle;
    48.7 +import jdk.internal.dynalink.linker.LinkRequest;
    48.8  import jdk.nashorn.internal.codegen.ObjectClassGenerator;
    48.9 +import jdk.nashorn.internal.objects.Global;
   48.10  
   48.11  /**
   48.12   * This class represents the result from a find property search.
   48.13 @@ -58,6 +60,18 @@
   48.14      }
   48.15  
   48.16      /**
   48.17 +     * Return a copy of this FindProperty with a different property.
   48.18 +     *
   48.19 +     * @param newProperty the new property
   48.20 +     * @return the new FindProperty instance
   48.21 +     */
   48.22 +    public FindProperty replaceProperty(final Property newProperty) {
   48.23 +        assert this.property.getKey().equals(newProperty.getKey());
   48.24 +        assert this.property.getSlot() == newProperty.getSlot();
   48.25 +        return new FindProperty(self, prototype, newProperty);
   48.26 +    }
   48.27 +
   48.28 +    /**
   48.29       * Ask for a getter that returns the given type. The type has nothing to do with the
   48.30       * internal representation of the property. It may be an Object (boxing primitives) or
   48.31       * a primitive (primitive fields with -Dnashorn.fields.dual=true)
   48.32 @@ -67,25 +81,17 @@
   48.33       * @param programPoint program point, or INVALID_PROGRAM_POINT if pessimistic
   48.34       * @return method handle for the getter
   48.35       */
   48.36 -    public MethodHandle getGetter(final Class<?> type, final int programPoint) {
   48.37 +    public MethodHandle getGetter(final Class<?> type, final int programPoint, final LinkRequest request) {
   48.38          final MethodHandle getter;
   48.39          if (isValid(programPoint)) {
   48.40              getter = property.getOptimisticGetter(type, programPoint);
   48.41          } else {
   48.42              getter = property.getGetter(type);
   48.43          }
   48.44 -        return getGetterInner(getter);
   48.45 -    }
   48.46 -
   48.47 -    private MethodHandle getGetterInner(final MethodHandle getter) {
   48.48          if (property instanceof UserAccessorProperty) {
   48.49 -            final UserAccessorProperty uc        = (UserAccessorProperty)property;
   48.50 -            final ScriptObject         owner     = getOwner();
   48.51 -            final ScriptObject         container = (owner != null) ? owner : self;
   48.52 -            return MH.insertArguments(getter, 0, uc.getAccessors(container));
   48.53 +            return insertAccessorsGetter((UserAccessorProperty) property, request, getter);
   48.54          }
   48.55          return getter;
   48.56 -
   48.57      }
   48.58  
   48.59      /**
   48.60 @@ -99,18 +105,31 @@
   48.61       *
   48.62       * @return method handle for the getter
   48.63       */
   48.64 -    public MethodHandle getSetter(final Class<?> type, final boolean strict) {
   48.65 -        final MethodHandle setter = property.getSetter(type, getOwner().getMap());
   48.66 +    public MethodHandle getSetter(final Class<?> type, final boolean strict, final LinkRequest request) {
   48.67 +        MethodHandle setter = property.getSetter(type, getOwner().getMap());
   48.68          if (property instanceof UserAccessorProperty) {
   48.69 -            final UserAccessorProperty uc        = (UserAccessorProperty)property;
   48.70 -            final ScriptObject         owner     = getOwner();
   48.71 -            final ScriptObject         container = (owner != null) ? owner : self;
   48.72 -            return MH.insertArguments(setter, 0, uc.getAccessors(container), strict ? property.getKey() : null);
   48.73 +            setter =  MH.insertArguments(setter, 1, strict ? property.getKey() : null);
   48.74 +            return insertAccessorsGetter((UserAccessorProperty) property, request, setter);
   48.75          }
   48.76  
   48.77          return setter;
   48.78      }
   48.79  
   48.80 +    // Fold an accessor getter into the method handle of a user accessor property.
   48.81 +    private MethodHandle insertAccessorsGetter(final UserAccessorProperty uap, final LinkRequest request, final MethodHandle mh) {
   48.82 +        MethodHandle superGetter = uap.getAccessorsGetter();
   48.83 +        if (isInherited()) {
   48.84 +            superGetter = ScriptObject.addProtoFilter(superGetter, getProtoChainLength());
   48.85 +        }
   48.86 +        if (request != null && !(request.getReceiver() instanceof ScriptObject)) {
   48.87 +            final MethodHandle wrapFilter = Global.getPrimitiveWrapFilter(request.getReceiver());
   48.88 +            superGetter = MH.filterArguments(superGetter, 0, wrapFilter.asType(wrapFilter.type().changeReturnType(superGetter.type().parameterType(0))));
   48.89 +        }
   48.90 +        superGetter = MH.asType(superGetter, superGetter.type().changeParameterType(0, Object.class));
   48.91 +
   48.92 +        return MH.foldArguments(mh, superGetter);
   48.93 +    }
   48.94 +
   48.95      /**
   48.96       * Return the {@code ScriptObject} owning of the property:  this means the prototype.
   48.97       * @return owner of property
   48.98 @@ -124,7 +143,7 @@
   48.99       * @return appropriate receiver
  48.100       */
  48.101      public ScriptObject getGetterReceiver() {
  48.102 -        return property != null && property.hasGetterFunction(prototype) ? self : prototype;
  48.103 +        return property != null && property instanceof UserAccessorProperty ? self : prototype;
  48.104      }
  48.105  
  48.106      /**
    49.1 --- a/src/jdk/nashorn/internal/runtime/GlobalConstants.java	Thu Sep 11 15:34:13 2014 -0700
    49.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalConstants.java	Tue Sep 16 13:59:37 2014 -0700
    49.3 @@ -28,6 +28,8 @@
    49.4  import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
    49.5  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
    49.6  import static jdk.nashorn.internal.lookup.Lookup.MH;
    49.7 +import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
    49.8 +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.getProgramPoint;
    49.9  import static jdk.nashorn.internal.runtime.logging.DebugLogger.quote;
   49.10  
   49.11  import java.lang.invoke.MethodHandle;
   49.12 @@ -370,22 +372,19 @@
   49.13       * @param find      property lookup
   49.14       * @param receiver  receiver
   49.15       * @param desc      callsite descriptor
   49.16 -     * @param request   link request
   49.17 -     * @param operator  operator
   49.18       *
   49.19       * @return resulting getter, or null if failed to create constant
   49.20       */
   49.21 -    synchronized GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
   49.22 -        if (GLOBAL_ONLY && !find.getOwner().isGlobal()) {
   49.23 +    synchronized GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc) {
   49.24 +        // Also return null if property may have side effects
   49.25 +        if ((GLOBAL_ONLY && !find.getOwner().isGlobal()) || find.getProperty() instanceof UserAccessorProperty) {
   49.26              return null;
   49.27          }
   49.28  
   49.29 -        final int programPoint         = NashornCallSiteDescriptor.isOptimistic(desc) ?
   49.30 -            NashornCallSiteDescriptor.getProgramPoint(desc) :
   49.31 -            UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
   49.32 -        final boolean     isOptimistic = programPoint != UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
   49.33 -        final Class<?>    retType      = desc.getMethodType().returnType();
   49.34 -        final String      name         = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
   49.35 +        final boolean  isOptimistic = NashornCallSiteDescriptor.isOptimistic(desc);
   49.36 +        final int      programPoint = isOptimistic ? getProgramPoint(desc) : INVALID_PROGRAM_POINT;
   49.37 +        final Class<?> retType      = desc.getMethodType().returnType();
   49.38 +        final String   name         = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
   49.39  
   49.40          final Access acc = getOrCreateSwitchPoint(name);
   49.41  
    50.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java	Thu Sep 11 15:34:13 2014 -0700
    50.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java	Tue Sep 16 13:59:37 2014 -0700
    50.3 @@ -938,11 +938,8 @@
    50.4       * @return double
    50.5       */
    50.6      public static int toInt32Optimistic(final Object obj, final int programPoint) {
    50.7 -        if (obj != null) {
    50.8 -            final Class<?> clz = obj.getClass();
    50.9 -            if (clz == Integer.class) {
   50.10 -                return ((Integer)obj).intValue();
   50.11 -            }
   50.12 +        if (obj != null && obj.getClass() == Integer.class) {
   50.13 +            return ((Integer)obj).intValue();
   50.14          }
   50.15          throw new UnwarrantedOptimismException(obj, programPoint);
   50.16      }
    51.1 --- a/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Thu Sep 11 15:34:13 2014 -0700
    51.2 +++ b/src/jdk/nashorn/internal/runtime/OptimisticReturnFilters.java	Tue Sep 16 13:59:37 2014 -0700
    51.3 @@ -191,19 +191,20 @@
    51.4      }
    51.5  
    51.6      /**
    51.7 -     * Returns the argument value as an int. If the argument is not a Number object that can be exactly represented as
    51.8 -     * an int, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
    51.9 -     * can use it. See {code CodeGenerator.ENSURE_INT}.
   51.10 +     * Returns the argument value as an int. If the argument is not a wrapper for a primitive numeric type
   51.11 +     * with a value that can be exactly represented as an int, throw an {@link UnwarrantedOptimismException}.
   51.12 +     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_INT}.
   51.13       * @param arg the original argument.
   51.14       * @param programPoint the program point used in the exception
   51.15       * @return the value of the argument as an int.
   51.16 -     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as an int.
   51.17 +     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
   51.18 +     * a value that can be exactly represented as an int.
   51.19       */
   51.20      public static int ensureInt(final Object arg, final int programPoint) {
   51.21          // NOTE: this doesn't delegate to ensureInt(double, int) as in that case if arg were a Long, it would throw a
   51.22          // (potentially imprecise) Double in the UnwarrantedOptimismException. This way, it will put the correct valued
   51.23          // Long into the exception.
   51.24 -        if (arg instanceof Number) {
   51.25 +        if (isPrimitiveNumberWrapper(arg)) {
   51.26              final double d = ((Number)arg).doubleValue();
   51.27              if (JSType.isRepresentableAsInt(d) && !JSType.isNegativeZero(d)) {
   51.28                  return (int)d;
   51.29 @@ -212,6 +213,15 @@
   51.30          throw new UnwarrantedOptimismException(arg, programPoint);
   51.31      }
   51.32  
   51.33 +    private static boolean isPrimitiveNumberWrapper(final Object obj) {
   51.34 +        if (obj == null) {
   51.35 +            return false;
   51.36 +        }
   51.37 +        final Class<?> c = obj.getClass();
   51.38 +        return c == Integer.class || c == Double.class || c == Long.class ||
   51.39 +               c ==   Float.class || c ==  Short.class || c == Byte.class;
   51.40 +    }
   51.41 +
   51.42      @SuppressWarnings("unused")
   51.43      private static int ensureInt(final boolean arg, final int programPoint) {
   51.44          throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
   51.45 @@ -236,35 +246,40 @@
   51.46      }
   51.47  
   51.48      /**
   51.49 -     * Returns the argument value as a long. If the argument is not a Number object that can be exactly represented as
   51.50 -     * a long, throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
   51.51 -     * can use it. See {code CodeGenerator.ENSURE_LONG}.
   51.52 +     * Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type
   51.53 +     * with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}.
   51.54 +     * This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}.
   51.55       * @param arg the original argument.
   51.56       * @param programPoint the program point used in the exception
   51.57       * @return the value of the argument as a long.
   51.58 -     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long.
   51.59 +     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
   51.60 +     * a value that can be exactly represented as a long
   51.61       */
   51.62      public static long ensureLong(final Object arg, final int programPoint) {
   51.63 -        if (arg instanceof Long) {
   51.64 -            // Must check for Long separately, as Long.doubleValue() isn't precise.
   51.65 -            return ((Long)arg).longValue();
   51.66 -        } else if (arg instanceof Number) {
   51.67 -            return ensureLong(((Number)arg).doubleValue(), programPoint);
   51.68 +        if (arg != null) {
   51.69 +            final Class<?> c = arg.getClass();
   51.70 +            if (c == Long.class) {
   51.71 +                // Must check for Long separately, as Long.doubleValue() isn't precise.
   51.72 +                return ((Long)arg).longValue();
   51.73 +            } else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class ||
   51.74 +                    c == Byte.class) {
   51.75 +                return ensureLong(((Number)arg).doubleValue(), programPoint);
   51.76 +            }
   51.77          }
   51.78          throw new UnwarrantedOptimismException(arg, programPoint);
   51.79      }
   51.80  
   51.81      /**
   51.82 -     * Returns the argument value as a double. If the argument is not a Number object, throw an
   51.83 -     * {@link UnwarrantedOptimismException}.This method is only public so that generated script code can use it. See
   51.84 -     * {code CodeGenerator.ENSURE_NUMBER}.
   51.85 +     * Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type
   51.86 +     * throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
   51.87 +     * can use it. See {code CodeGenerator.ENSURE_NUMBER}.
   51.88       * @param arg the original argument.
   51.89       * @param programPoint the program point used in the exception
   51.90       * @return the value of the argument as a double.
   51.91 -     * @throws UnwarrantedOptimismException if the argument is not a Number that can be exactly represented as a long.
   51.92 +     * @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type.
   51.93       */
   51.94      public static double ensureNumber(final Object arg, final int programPoint) {
   51.95 -        if (arg instanceof Number) { // arg == null -> false
   51.96 +        if (isPrimitiveNumberWrapper(arg)) {
   51.97              return ((Number)arg).doubleValue();
   51.98          }
   51.99          throw new UnwarrantedOptimismException(arg, programPoint);
    52.1 --- a/src/jdk/nashorn/internal/runtime/Property.java	Thu Sep 11 15:34:13 2014 -0700
    52.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java	Tue Sep 16 13:59:37 2014 -0700
    52.3 @@ -82,11 +82,14 @@
    52.4       * is narrower than object, e.g. Math.PI which is declared
    52.5       * as a double
    52.6       */
    52.7 -    public static final int IS_NASGEN_PRIMITIVE = 1 << 6;
    52.8 +    public static final int IS_NASGEN_PRIMITIVE     = 1 << 6;
    52.9  
   52.10      /** Is this property bound to a receiver? This means get/set operations will be delegated to
   52.11       *  a statically defined object instead of the object passed as callsite parameter. */
   52.12 -    public static final int IS_BOUND = 1 << 8;
   52.13 +    public static final int IS_BOUND                = 1 << 7;
   52.14 +
   52.15 +    /** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */
   52.16 +    public static final int NEEDS_DECLARATION       = 1 << 8;
   52.17  
   52.18      /** Property key. */
   52.19      private final String key;
   52.20 @@ -287,6 +290,15 @@
   52.21      }
   52.22  
   52.23      /**
   52.24 +     * Is this a LET or CONST property that needs to see its declaration before being usable?
   52.25 +     *
   52.26 +     * @return true if this is a block-scoped variable
   52.27 +     */
   52.28 +    public boolean needsDeclaration() {
   52.29 +        return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION;
   52.30 +    }
   52.31 +
   52.32 +    /**
   52.33       * Add more property flags to the property. Properties are immutable here,
   52.34       * so any property change that results in a larger flag set results in the
   52.35       * property being cloned. Use only the return value
    53.1 --- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Thu Sep 11 15:34:13 2014 -0700
    53.2 +++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java	Tue Sep 16 13:59:37 2014 -0700
    53.3 @@ -42,6 +42,7 @@
    53.4  import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
    53.5  import jdk.nashorn.internal.codegen.CompilerConstants;
    53.6  import jdk.nashorn.internal.codegen.FunctionSignature;
    53.7 +import jdk.nashorn.internal.codegen.ObjectClassGenerator.AllocatorDescriptor;
    53.8  import jdk.nashorn.internal.codegen.OptimisticTypesPersistence;
    53.9  import jdk.nashorn.internal.codegen.TypeMap;
   53.10  import jdk.nashorn.internal.codegen.types.Type;
   53.11 @@ -55,7 +56,6 @@
   53.12  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   53.13  import jdk.nashorn.internal.runtime.logging.Loggable;
   53.14  import jdk.nashorn.internal.runtime.logging.Logger;
   53.15 -
   53.16  /**
   53.17   * This is a subclass that represents a script function that may be regenerated,
   53.18   * for example with specialization based on call site types, or lazily generated.
   53.19 @@ -81,26 +81,29 @@
   53.20      /** Token of this function within the source. */
   53.21      private final long token;
   53.22  
   53.23 -    /** Allocator map from makeMap() */
   53.24 -    private final PropertyMap allocatorMap;
   53.25 +    /**
   53.26 +     * Represents the allocation strategy (property map, script object class, and method handle) for when
   53.27 +     * this function is used as a constructor. Note that majority of functions (those not setting any this.*
   53.28 +     * properties) will share a single canonical "default strategy" instance.
   53.29 +     */
   53.30 +    private final AllocationStrategy allocationStrategy;
   53.31 +
   53.32 +    /**
   53.33 +     * Opaque object representing parser state at the end of the function. Used when reparsing outer function
   53.34 +     * to help with skipping parsing inner functions.
   53.35 +     */
   53.36 +    private final Object endParserState;
   53.37  
   53.38      /** Code installer used for all further recompilation/specialization of this ScriptFunction */
   53.39      private transient CodeInstaller<ScriptEnvironment> installer;
   53.40  
   53.41 -    /** Name of class where allocator function resides */
   53.42 -    private final String allocatorClassName;
   53.43 -
   53.44 -    /** lazily generated allocator */
   53.45 -    private transient MethodHandle allocator;
   53.46 -
   53.47      private final Map<Integer, RecompilableScriptFunctionData> nestedFunctions;
   53.48  
   53.49      /** Id to parent function if one exists */
   53.50      private RecompilableScriptFunctionData parent;
   53.51  
   53.52 -    private final boolean isDeclared;
   53.53 -    private final boolean isAnonymous;
   53.54 -    private final boolean needsCallee;
   53.55 +    /** Copy of the {@link FunctionNode} flags. */
   53.56 +    private final int functionFlags;
   53.57  
   53.58      private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
   53.59  
   53.60 @@ -119,8 +122,7 @@
   53.61       *
   53.62       * @param functionNode        functionNode that represents this function code
   53.63       * @param installer           installer for code regeneration versions of this function
   53.64 -     * @param allocatorClassName  name of our allocator class, will be looked up dynamically if used as a constructor
   53.65 -     * @param allocatorMap        allocator map to seed instances with, when constructing
   53.66 +     * @param allocationDescriptor descriptor for the allocation behavior when this function is used as a constructor
   53.67       * @param nestedFunctions     nested function map
   53.68       * @param externalScopeDepths external scope depths
   53.69       * @param internalSymbols     internal symbols to method, defined in its scope
   53.70 @@ -128,30 +130,27 @@
   53.71      public RecompilableScriptFunctionData(
   53.72          final FunctionNode functionNode,
   53.73          final CodeInstaller<ScriptEnvironment> installer,
   53.74 -        final String allocatorClassName,
   53.75 -        final PropertyMap allocatorMap,
   53.76 +        final AllocatorDescriptor allocationDescriptor,
   53.77          final Map<Integer, RecompilableScriptFunctionData> nestedFunctions,
   53.78          final Map<String, Integer> externalScopeDepths,
   53.79          final Set<String> internalSymbols) {
   53.80  
   53.81          super(functionName(functionNode),
   53.82                Math.min(functionNode.getParameters().size(), MAX_ARITY),
   53.83 -              getFlags(functionNode));
   53.84 +              getDataFlags(functionNode));
   53.85  
   53.86          this.functionName        = functionNode.getName();
   53.87          this.lineNumber          = functionNode.getLineNumber();
   53.88 -        this.isDeclared          = functionNode.isDeclared();
   53.89 -        this.needsCallee         = functionNode.needsCallee();
   53.90 -        this.isAnonymous         = functionNode.isAnonymous();
   53.91 +        this.functionFlags       = functionNode.getFlags() | (functionNode.needsCallee() ? FunctionNode.NEEDS_CALLEE : 0);
   53.92          this.functionNodeId      = functionNode.getId();
   53.93          this.source              = functionNode.getSource();
   53.94 +        this.endParserState      = functionNode.getEndParserState();
   53.95          this.token               = tokenFor(functionNode);
   53.96          this.installer           = installer;
   53.97 -        this.allocatorClassName  = allocatorClassName;
   53.98 -        this.allocatorMap        = allocatorMap;
   53.99 -        this.nestedFunctions     = nestedFunctions;
  53.100 -        this.externalScopeDepths = externalScopeDepths;
  53.101 -        this.internalSymbols     = new HashSet<>(internalSymbols);
  53.102 +        this.allocationStrategy  = AllocationStrategy.get(allocationDescriptor);
  53.103 +        this.nestedFunctions     = smallMap(nestedFunctions);
  53.104 +        this.externalScopeDepths = smallMap(externalScopeDepths);
  53.105 +        this.internalSymbols     = smallSet(new HashSet<>(internalSymbols));
  53.106  
  53.107          for (final RecompilableScriptFunctionData nfn : nestedFunctions.values()) {
  53.108              assert nfn.getParent() == null;
  53.109 @@ -161,6 +160,27 @@
  53.110          createLogger();
  53.111      }
  53.112  
  53.113 +    private static <K, V> Map<K, V> smallMap(final Map<K, V> map) {
  53.114 +        if (map == null || map.isEmpty()) {
  53.115 +            return Collections.emptyMap();
  53.116 +        } else if (map.size() == 1) {
  53.117 +            final Map.Entry<K, V> entry = map.entrySet().iterator().next();
  53.118 +            return Collections.singletonMap(entry.getKey(), entry.getValue());
  53.119 +        } else {
  53.120 +            return map;
  53.121 +        }
  53.122 +    }
  53.123 +
  53.124 +    private static <T> Set<T> smallSet(final Set<T> set) {
  53.125 +        if (set == null || set.isEmpty()) {
  53.126 +            return Collections.emptySet();
  53.127 +        } else if (set.size() == 1) {
  53.128 +            return Collections.singleton(set.iterator().next());
  53.129 +        } else {
  53.130 +            return set;
  53.131 +        }
  53.132 +    }
  53.133 +
  53.134      @Override
  53.135      public DebugLogger getLogger() {
  53.136          return log;
  53.137 @@ -190,11 +210,7 @@
  53.138       * @return the external symbol table with proto depths
  53.139       */
  53.140      public int getExternalSymbolDepth(final String symbolName) {
  53.141 -        final Map<String, Integer> map = externalScopeDepths;
  53.142 -        if (map == null) {
  53.143 -            return -1;
  53.144 -        }
  53.145 -        final Integer depth = map.get(symbolName);
  53.146 +        final Integer depth = externalScopeDepths.get(symbolName);
  53.147          if (depth == null) {
  53.148              return -1;
  53.149          }
  53.150 @@ -202,6 +218,23 @@
  53.151      }
  53.152  
  53.153      /**
  53.154 +     * Returns the names of all external symbols this function uses.
  53.155 +     * @return the names of all external symbols this function uses.
  53.156 +     */
  53.157 +    public Set<String> getExternalSymbolNames() {
  53.158 +        return Collections.unmodifiableSet(externalScopeDepths.keySet());
  53.159 +    }
  53.160 +
  53.161 +    /**
  53.162 +     * Returns the opaque object representing the parser state at the end of this function's body, used to
  53.163 +     * skip parsing this function when reparsing its containing outer function.
  53.164 +     * @return the object representing the end parser state
  53.165 +     */
  53.166 +    public Object getEndParserState() {
  53.167 +        return endParserState;
  53.168 +    }
  53.169 +
  53.170 +    /**
  53.171       * Get the parent of this RecompilableScriptFunctionData. If we are
  53.172       * a nested function, we have a parent. Note that "null" return value
  53.173       * can also mean that we have a parent but it is unknown, so this can
  53.174 @@ -269,7 +302,7 @@
  53.175  
  53.176      @Override
  53.177      public boolean inDynamicContext() {
  53.178 -        return (flags & IN_DYNAMIC_CONTEXT) != 0;
  53.179 +        return getFunctionFlag(FunctionNode.IN_DYNAMIC_CONTEXT);
  53.180      }
  53.181  
  53.182      private static String functionName(final FunctionNode fn) {
  53.183 @@ -293,7 +326,7 @@
  53.184          return Token.toDesc(TokenType.FUNCTION, position, length);
  53.185      }
  53.186  
  53.187 -    private static int getFlags(final FunctionNode functionNode) {
  53.188 +    private static int getDataFlags(final FunctionNode functionNode) {
  53.189          int flags = IS_CONSTRUCTOR;
  53.190          if (functionNode.isStrict()) {
  53.191              flags |= IS_STRICT;
  53.192 @@ -307,37 +340,20 @@
  53.193          if (functionNode.isVarArg()) {
  53.194              flags |= IS_VARIABLE_ARITY;
  53.195          }
  53.196 -        if (functionNode.inDynamicContext()) {
  53.197 -            flags |= IN_DYNAMIC_CONTEXT;
  53.198 -        }
  53.199          return flags;
  53.200      }
  53.201  
  53.202      @Override
  53.203      PropertyMap getAllocatorMap() {
  53.204 -        return allocatorMap;
  53.205 +        return allocationStrategy.getAllocatorMap();
  53.206      }
  53.207  
  53.208      @Override
  53.209      ScriptObject allocate(final PropertyMap map) {
  53.210 -        try {
  53.211 -            ensureHasAllocator(); //if allocatorClass name is set to null (e.g. for bound functions) we don't even try
  53.212 -            return allocator == null ? null : (ScriptObject)allocator.invokeExact(map);
  53.213 -        } catch (final RuntimeException | Error e) {
  53.214 -            throw e;
  53.215 -        } catch (final Throwable t) {
  53.216 -            throw new RuntimeException(t);
  53.217 -        }
  53.218 -    }
  53.219 -
  53.220 -    private void ensureHasAllocator() throws ClassNotFoundException {
  53.221 -        if (allocator == null && allocatorClassName != null) {
  53.222 -            this.allocator = MH.findStatic(LOOKUP, Context.forStructureClass(allocatorClassName), CompilerConstants.ALLOCATE.symbolName(), MH.type(ScriptObject.class, PropertyMap.class));
  53.223 -        }
  53.224 +        return allocationStrategy.allocate(map);
  53.225      }
  53.226  
  53.227      FunctionNode reparse() {
  53.228 -        final boolean isProgram = functionNodeId == FunctionNode.FIRST_FUNCTION_ID;
  53.229          // NOTE: If we aren't recompiling the top-level program, we decrease functionNodeId 'cause we'll have a synthetic program node
  53.230          final int descPosition = Token.descPosition(token);
  53.231          final Context context = Context.getContextTrusted();
  53.232 @@ -346,18 +362,27 @@
  53.233              source,
  53.234              new Context.ThrowErrorManager(),
  53.235              isStrict(),
  53.236 -            functionNodeId - (isProgram ? 0 : 1),
  53.237              lineNumber - 1,
  53.238              context.getLogger(Parser.class)); // source starts at line 0, so even though lineNumber is the correct declaration line, back off one to make it exclusive
  53.239  
  53.240 -        if (isAnonymous) {
  53.241 +        if (getFunctionFlag(FunctionNode.IS_ANONYMOUS)) {
  53.242              parser.setFunctionName(functionName);
  53.243          }
  53.244 +        parser.setReparsedFunction(this);
  53.245  
  53.246 -        final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition, Token.descLength(token), true);
  53.247 -        // Parser generates a program AST even if we're recompiling a single function, so when we are only recompiling a
  53.248 -        // single function, extract it from the program.
  53.249 -        return (isProgram ? program : extractFunctionFromScript(program)).setName(null, functionName);
  53.250 +        final FunctionNode program = parser.parse(CompilerConstants.PROGRAM.symbolName(), descPosition,
  53.251 +                Token.descLength(token), true);
  53.252 +        // Parser generates a program AST even if we're recompiling a single function, so when we are only
  53.253 +        // recompiling a single function, extract it from the program.
  53.254 +        return (isProgram() ? program : extractFunctionFromScript(program)).setName(null, functionName);
  53.255 +    }
  53.256 +
  53.257 +    private boolean getFunctionFlag(final int flag) {
  53.258 +        return (functionFlags & flag) != 0;
  53.259 +    }
  53.260 +
  53.261 +    private boolean isProgram() {
  53.262 +        return getFunctionFlag(FunctionNode.IS_PROGRAM);
  53.263      }
  53.264  
  53.265      TypeMap typeMap(final MethodType fnCallSiteType) {
  53.266 @@ -394,6 +419,7 @@
  53.267                  context.getEnv(),
  53.268                  installer,
  53.269                  functionNode.getSource(),  // source
  53.270 +                context.getErrorManager(),
  53.271                  isStrict() | functionNode.isStrict(), // is strict
  53.272                  true,       // is on demand
  53.273                  this,       // compiledFunction, i.e. this RecompilableScriptFunctionData
  53.274 @@ -545,7 +571,7 @@
  53.275          assert fns.size() == 1 : "got back more than one method in recompilation";
  53.276          final FunctionNode f = fns.iterator().next();
  53.277          assert f.getId() == functionNodeId;
  53.278 -        if (!isDeclared && f.isDeclared()) {
  53.279 +        if (!getFunctionFlag(FunctionNode.IS_DECLARED) && f.isDeclared()) {
  53.280              return f.clearFlag(null, FunctionNode.IS_DECLARED);
  53.281          }
  53.282          return f;
  53.283 @@ -668,7 +694,15 @@
  53.284  
  53.285      @Override
  53.286      public boolean needsCallee() {
  53.287 -        return needsCallee;
  53.288 +        return getFunctionFlag(FunctionNode.NEEDS_CALLEE);
  53.289 +    }
  53.290 +
  53.291 +    /**
  53.292 +     * Returns the {@link FunctionNode} flags associated with this function data.
  53.293 +     * @return the {@link FunctionNode} flags associated with this function data.
  53.294 +     */
  53.295 +    public int getFunctionFlags() {
  53.296 +        return functionFlags;
  53.297      }
  53.298  
  53.299      @Override
  53.300 @@ -720,21 +754,6 @@
  53.301      }
  53.302  
  53.303      /**
  53.304 -     * Get the uppermost parent, the program, for this data
  53.305 -     * @return program
  53.306 -     */
  53.307 -    public RecompilableScriptFunctionData getProgram() {
  53.308 -        RecompilableScriptFunctionData program = this;
  53.309 -        while (true) {
  53.310 -            final RecompilableScriptFunctionData p = program.getParent();
  53.311 -            if (p == null) {
  53.312 -                return program;
  53.313 -            }
  53.314 -            program = p;
  53.315 -        }
  53.316 -    }
  53.317 -
  53.318 -    /**
  53.319       * Check whether a certain name is a global symbol, i.e. only exists as defined
  53.320       * in outermost scope and not shadowed by being parameter or assignment in inner
  53.321       * scopes
    54.1 --- a/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Thu Sep 11 15:34:13 2014 -0700
    54.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java	Tue Sep 16 13:59:37 2014 -0700
    54.3 @@ -94,6 +94,9 @@
    54.4      /** Use single Global instance per jsr223 engine instance. */
    54.5      public final boolean _global_per_engine;
    54.6  
    54.7 +    /** Enable experimental ECMAScript 6 features. */
    54.8 +    public final boolean _es6;
    54.9 +
   54.10      /** Argument passed to compile only if optimistic compilation should take place */
   54.11      public static final String COMPILE_ONLY_OPTIMISTIC_ARG = "optimistic";
   54.12  
   54.13 @@ -258,6 +261,15 @@
   54.14          _version              = options.getBoolean("version");
   54.15          _verify_code          = options.getBoolean("verify.code");
   54.16  
   54.17 +        final String language = options.getString("language");
   54.18 +        if (language == null || language.equals("es5")) {
   54.19 +            _es6 = false;
   54.20 +        } else if (language.equals("es6")) {
   54.21 +            _es6 = true;
   54.22 +        } else {
   54.23 +            throw new RuntimeException("Unsupported language: " + language);
   54.24 +        }
   54.25 +
   54.26          String dir = null;
   54.27          String func = null;
   54.28          final String pc = options.getString("print.code");
    55.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Thu Sep 11 15:34:13 2014 -0700
    55.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Tue Sep 16 13:59:37 2014 -0700
    55.3 @@ -36,6 +36,7 @@
    55.4  import java.lang.invoke.MethodType;
    55.5  import java.lang.invoke.SwitchPoint;
    55.6  import java.util.Collections;
    55.7 +
    55.8  import jdk.internal.dynalink.CallSiteDescriptor;
    55.9  import jdk.internal.dynalink.linker.GuardedInvocation;
   55.10  import jdk.internal.dynalink.linker.LinkRequest;
   55.11 @@ -44,6 +45,9 @@
   55.12  import jdk.nashorn.internal.codegen.CompilerConstants.Call;
   55.13  import jdk.nashorn.internal.objects.Global;
   55.14  import jdk.nashorn.internal.objects.NativeFunction;
   55.15 +import jdk.nashorn.internal.runtime.ScriptFunctionData;
   55.16 +import jdk.nashorn.internal.runtime.ScriptObject;
   55.17 +import jdk.nashorn.internal.runtime.ScriptRuntime;
   55.18  import jdk.nashorn.internal.runtime.linker.Bootstrap;
   55.19  import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
   55.20  
   55.21 @@ -621,6 +625,23 @@
   55.22              appliedType = appliedType.changeParameterType(1, Object.class);
   55.23          }
   55.24  
   55.25 +        /*
   55.26 +         * dropArgs is a synthetic method handle that contains any args that we need to
   55.27 +         * get rid of that come after the arguments array in the apply case. We adapt
   55.28 +         * the callsite to ask for 3 args only and then dropArguments on the method handle
   55.29 +         * to make it fit the extraneous args.
   55.30 +         */
   55.31 +        MethodType dropArgs = MH.type(void.class);
   55.32 +        if (isApply && !isFailedApplyToCall) {
   55.33 +            final int pc = appliedType.parameterCount();
   55.34 +            for (int i = 3; i < pc; i++) {
   55.35 +                dropArgs = dropArgs.appendParameterTypes(appliedType.parameterType(i));
   55.36 +            }
   55.37 +            if (pc > 3) {
   55.38 +                appliedType = appliedType.dropParameterTypes(3, pc);
   55.39 +            }
   55.40 +        }
   55.41 +
   55.42          if (isApply || isFailedApplyToCall) {
   55.43              if (passesArgs) {
   55.44                  // R(this, args) => R(this, Object[])
   55.45 @@ -702,6 +723,15 @@
   55.46          }
   55.47          inv = MH.dropArguments(inv, 0, applyFnType);
   55.48  
   55.49 +        /*
   55.50 +         * Dropargs can only be non-()V in the case of isApply && !isFailedApplyToCall, which
   55.51 +         * is when we need to add arguments to the callsite to catch and ignore the synthetic
   55.52 +         * extra args that someone has added to the command line.
   55.53 +         */
   55.54 +        for (int i = 0; i < dropArgs.parameterCount(); i++) {
   55.55 +            inv = MH.dropArguments(inv, 4 + i, dropArgs.parameterType(i));
   55.56 +        }
   55.57 +
   55.58          MethodHandle guard = appliedInvocation.getGuard();
   55.59          // If the guard checks the value of "this" but we aren't passing thisArg, insert the default one
   55.60          if (!passesThis && guard.type().parameterCount() > 1) {
    56.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Thu Sep 11 15:34:13 2014 -0700
    56.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java	Tue Sep 16 13:59:37 2014 -0700
    56.3 @@ -90,8 +90,6 @@
    56.4      public static final int USES_THIS      = 1 << 4;
    56.5      /** Is this a variable arity function? */
    56.6      public static final int IS_VARIABLE_ARITY = 1 << 5;
    56.7 -    /** Is this declared in a dynamic context */
    56.8 -    public static final int IN_DYNAMIC_CONTEXT = 1 << 6;
    56.9  
   56.10      /** Flag for strict or built-in functions */
   56.11      public static final int IS_STRICT_OR_BUILTIN = IS_STRICT | IS_BUILTIN;
    57.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java	Thu Sep 11 15:34:13 2014 -0700
    57.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java	Tue Sep 16 13:59:37 2014 -0700
    57.3 @@ -158,6 +158,7 @@
    57.4  
    57.5      static final MethodHandle MEGAMORPHIC_GET    = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
    57.6      static final MethodHandle GLOBALFILTER       = findOwnMH_S("globalFilter", Object.class, Object.class);
    57.7 +    static final MethodHandle DECLARE_AND_SET    = findOwnMH_V("declareAndSet", void.class, String.class, Object.class);
    57.8  
    57.9      private static final MethodHandle TRUNCATINGFILTER   = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
   57.10      private static final MethodHandle KNOWNFUNCPROPGUARDSELF = findOwnMH_S("knownFunctionPropertyGuardSelf", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, ScriptFunction.class);
   57.11 @@ -1049,7 +1050,7 @@
   57.12      }
   57.13  
   57.14      private static int getIntValue(final FindProperty find, final int programPoint) {
   57.15 -        final MethodHandle getter = find.getGetter(int.class, programPoint);
   57.16 +        final MethodHandle getter = find.getGetter(int.class, programPoint, null);
   57.17          if (getter != null) {
   57.18              try {
   57.19                  return (int)getter.invokeExact((Object)find.getGetterReceiver());
   57.20 @@ -1064,7 +1065,7 @@
   57.21      }
   57.22  
   57.23      private static long getLongValue(final FindProperty find, final int programPoint) {
   57.24 -        final MethodHandle getter = find.getGetter(long.class, programPoint);
   57.25 +        final MethodHandle getter = find.getGetter(long.class, programPoint, null);
   57.26          if (getter != null) {
   57.27              try {
   57.28                  return (long)getter.invokeExact((Object)find.getGetterReceiver());
   57.29 @@ -1079,7 +1080,7 @@
   57.30      }
   57.31  
   57.32      private static double getDoubleValue(final FindProperty find, final int programPoint) {
   57.33 -        final MethodHandle getter = find.getGetter(double.class, programPoint);
   57.34 +        final MethodHandle getter = find.getGetter(double.class, programPoint, null);
   57.35          if (getter != null) {
   57.36              try {
   57.37                  return (double)getter.invokeExact((Object)find.getGetterReceiver());
   57.38 @@ -1970,7 +1971,7 @@
   57.39              }
   57.40          }
   57.41  
   57.42 -        final GuardedInvocation cinv = Global.getConstants().findGetMethod(find, this, desc, request, operator);
   57.43 +        final GuardedInvocation cinv = Global.getConstants().findGetMethod(find, this, desc);
   57.44          if (cinv != null) {
   57.45              return cinv;
   57.46          }
   57.47 @@ -1982,7 +1983,7 @@
   57.48                  NashornCallSiteDescriptor.getProgramPoint(desc) :
   57.49                  UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
   57.50  
   57.51 -        mh = find.getGetter(returnType, programPoint);
   57.52 +        mh = find.getGetter(returnType, programPoint, request);
   57.53          // Get the appropriate guard for this callsite and property.
   57.54          final MethodHandle guard = NashornGuards.getGuard(this, property, desc, explicitInstanceOfCheck);
   57.55          final ScriptObject owner = find.getOwner();
   57.56 @@ -1994,8 +1995,9 @@
   57.57              mh = Lookup.emptyGetter(returnType);
   57.58              protoSwitchPoint = getProtoSwitchPoint(name, owner);
   57.59          } else if (!find.isSelf()) {
   57.60 -            assert mh.type().returnType().equals(returnType) : "returntype mismatch for getter " + mh.type().returnType() + " != " + returnType;
   57.61 -            if (!property.hasGetterFunction(owner)) {
   57.62 +            assert mh.type().returnType().equals(returnType) :
   57.63 +                    "return type mismatch for getter " + mh.type().returnType() + " != " + returnType;
   57.64 +            if (!(property instanceof UserAccessorProperty)) {
   57.65                  // Add a filter that replaces the self object with the prototype owning the property.
   57.66                  mh = addProtoFilter(mh, find.getProtoChainLength());
   57.67              }
   57.68 @@ -2027,6 +2029,22 @@
   57.69          return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
   57.70      }
   57.71  
   57.72 +    // Marks a property as declared and sets its value. Used as slow path for block-scoped LET and CONST
   57.73 +    @SuppressWarnings("unused")
   57.74 +    private void declareAndSet(final String key, final Object value) {
   57.75 +        final PropertyMap map = getMap();
   57.76 +        final FindProperty find = findProperty(key, false);
   57.77 +        assert find != null;
   57.78 +
   57.79 +        final Property property = find.getProperty();
   57.80 +        assert property != null;
   57.81 +        assert property.needsDeclaration();
   57.82 +
   57.83 +        final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
   57.84 +        setMap(newMap);
   57.85 +        set(key, value, true);
   57.86 +    }
   57.87 +
   57.88      /**
   57.89       * Find the appropriate GETINDEX method for an invoke dynamic call.
   57.90       *
   57.91 @@ -2140,7 +2158,7 @@
   57.92          }
   57.93  
   57.94          if (find != null) {
   57.95 -            if (!find.getProperty().isWritable()) {
   57.96 +            if (!find.getProperty().isWritable() && !NashornCallSiteDescriptor.isDeclaration(desc)) {
   57.97                  // Existing, non-writable property
   57.98                  return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
   57.99              }
  57.100 @@ -2150,7 +2168,7 @@
  57.101              }
  57.102          }
  57.103  
  57.104 -        final GuardedInvocation inv = new SetMethodCreator(this, find, desc, explicitInstanceOfCheck).createGuardedInvocation();
  57.105 +        final GuardedInvocation inv = new SetMethodCreator(this, find, desc, request).createGuardedInvocation();
  57.106  
  57.107          final GuardedInvocation cinv = Global.getConstants().findSetMethod(find, this, inv, desc, request);
  57.108          if (cinv != null) {
  57.109 @@ -2303,13 +2321,13 @@
  57.110                          find.isSelf()?
  57.111                              getKnownFunctionPropertyGuardSelf(
  57.112                                  getMap(),
  57.113 -                                find.getGetter(Object.class, INVALID_PROGRAM_POINT),
  57.114 +                                find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
  57.115                                  func)
  57.116                              :
  57.117                              //TODO this always does a scriptobject check
  57.118                              getKnownFunctionPropertyGuardProto(
  57.119                                  getMap(),
  57.120 -                                find.getGetter(Object.class, INVALID_PROGRAM_POINT),
  57.121 +                                find.getGetter(Object.class, INVALID_PROGRAM_POINT, request),
  57.122                                  find.getProtoChainLength(),
  57.123                                  func),
  57.124                          getProtoSwitchPoint(NO_SUCH_PROPERTY_NAME, find.getOwner()),
    58.1 --- a/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Thu Sep 11 15:34:13 2014 -0700
    58.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptRuntime.java	Tue Sep 16 13:59:37 2014 -0700
    58.3 @@ -108,6 +108,11 @@
    58.4      public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
    58.5  
    58.6      /**
    58.7 +     * Throws a reference error for an undefined variable.
    58.8 +     */
    58.9 +    public static final Call THROW_REFERENCE_ERROR = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "throwReferenceError", void.class, String.class);
   58.10 +
   58.11 +    /**
   58.12       * Converts a switch tag value to a simple integer. deflt value if it can't.
   58.13       *
   58.14       * @param tag   Switch statement tag value.
   58.15 @@ -382,6 +387,15 @@
   58.16      }
   58.17  
   58.18      /**
   58.19 +     * Throws a reference error for an undefined variable.
   58.20 +     *
   58.21 +     * @param name the variable name
   58.22 +     */
   58.23 +    public static void throwReferenceError(final String name) {
   58.24 +        throw referenceError("not.defined", name);
   58.25 +    }
   58.26 +
   58.27 +    /**
   58.28       * Call a script function as a constructor with given args.
   58.29       *
   58.30       * @param target ScriptFunction object.
    59.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Thu Sep 11 15:34:13 2014 -0700
    59.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java	Tue Sep 16 13:59:37 2014 -0700
    59.3 @@ -33,6 +33,7 @@
    59.4  import java.lang.invoke.SwitchPoint;
    59.5  import jdk.internal.dynalink.CallSiteDescriptor;
    59.6  import jdk.internal.dynalink.linker.GuardedInvocation;
    59.7 +import jdk.internal.dynalink.linker.LinkRequest;
    59.8  import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
    59.9  import jdk.nashorn.internal.runtime.linker.NashornGuards;
   59.10  
   59.11 @@ -48,7 +49,7 @@
   59.12      private final FindProperty       find;
   59.13      private final CallSiteDescriptor desc;
   59.14      private final Class<?>           type;
   59.15 -    private final boolean            explicitInstanceOfCheck;
   59.16 +    private final LinkRequest        request;
   59.17  
   59.18      /**
   59.19       * Creates a new property setter method creator.
   59.20 @@ -56,14 +57,15 @@
   59.21       * @param find a result of a {@link ScriptObject#findProperty(String, boolean)} on the object for the property we
   59.22       * want to create a setter for. Can be null if the property does not yet exist on the object.
   59.23       * @param desc the descriptor of the call site that triggered the property setter lookup
   59.24 +     * @param request the link request
   59.25       */
   59.26 -    SetMethodCreator(final ScriptObject sobj, final FindProperty find, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck) {
   59.27 -        this.sobj = sobj;
   59.28 -        this.map  = sobj.getMap();
   59.29 -        this.find = find;
   59.30 -        this.desc = desc;
   59.31 -        this.type = desc.getMethodType().parameterType(1);
   59.32 -        this.explicitInstanceOfCheck = explicitInstanceOfCheck;
   59.33 +    SetMethodCreator(final ScriptObject sobj, final FindProperty find, final CallSiteDescriptor desc, final LinkRequest request) {
   59.34 +        this.sobj    = sobj;
   59.35 +        this.map     = sobj.getMap();
   59.36 +        this.find    = find;
   59.37 +        this.desc    = desc;
   59.38 +        this.type    = desc.getMethodType().parameterType(1);
   59.39 +        this.request = request;
   59.40  
   59.41      }
   59.42  
   59.43 @@ -111,6 +113,7 @@
   59.44              // getGuard() and getException() either both return null, or neither does. The reason for that is that now
   59.45              // getGuard returns a map guard that casts its argument to ScriptObject, and if that fails, we need to
   59.46              // relink on ClassCastException.
   59.47 +            final boolean explicitInstanceOfCheck = NashornGuards.explicitInstanceOfCheck(desc, request);
   59.48              return new GuardedInvocation(methodHandle, NashornGuards.getGuard(sobj, property, desc, explicitInstanceOfCheck),
   59.49                      (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
   59.50          }
   59.51 @@ -140,13 +143,36 @@
   59.52  
   59.53      private SetMethod createExistingPropertySetter() {
   59.54          final Property property = find.getProperty();
   59.55 -        final MethodHandle methodHandle = find.getSetter(type, NashornCallSiteDescriptor.isStrict(desc));
   59.56 +        final boolean isStrict  = NashornCallSiteDescriptor.isStrict(desc);
   59.57 +        final MethodHandle methodHandle;
   59.58 +
   59.59 +        if (NashornCallSiteDescriptor.isDeclaration(desc)) {
   59.60 +            assert property.needsDeclaration();
   59.61 +            // This is a LET or CONST being declared. The property is already there but flagged as needing declaration.
   59.62 +            // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set
   59.63 +            // method if the pre-callsite map is stable (which should be the case for function scopes except for
   59.64 +            // non-strict functions containing eval() with var). Otherwise we have to use a slow setter that creates
   59.65 +            // a new PropertyMap on the fly.
   59.66 +            final PropertyMap oldMap = getMap();
   59.67 +            final Property newProperty = property.removeFlags(Property.NEEDS_DECLARATION);
   59.68 +            final PropertyMap newMap = oldMap.replaceProperty(property, newProperty);
   59.69 +            final MethodHandle fastSetter = find.replaceProperty(newProperty).getSetter(type, isStrict, request);
   59.70 +            final MethodHandle slowSetter = MH.insertArguments(ScriptObject.DECLARE_AND_SET, 1, getName()).asType(fastSetter.type());
   59.71 +
   59.72 +            // cas map used as guard, if true that means we can do the set fast
   59.73 +            MethodHandle casMap = MH.insertArguments(ScriptObject.CAS_MAP, 1, oldMap, newMap);
   59.74 +            casMap = MH.dropArguments(casMap, 1, type);
   59.75 +            casMap = MH.asType(casMap, casMap.type().changeParameterType(0, Object.class));
   59.76 +            methodHandle = MH.guardWithTest(casMap, fastSetter, slowSetter);
   59.77 +        } else {
   59.78 +            methodHandle = find.getSetter(type, isStrict, request);
   59.79 +        }
   59.80  
   59.81          assert methodHandle != null;
   59.82          assert property     != null;
   59.83  
   59.84          final MethodHandle boundHandle;
   59.85 -        if (!property.hasSetterFunction(find.getOwner()) && find.isInherited()) {
   59.86 +        if (!(property instanceof UserAccessorProperty) && find.isInherited()) {
   59.87              boundHandle = ScriptObject.addProtoFilter(methodHandle, find.getProtoChainLength());
   59.88          } else {
   59.89              boundHandle = methodHandle;
    60.1 --- a/src/jdk/nashorn/internal/runtime/Timing.java	Thu Sep 11 15:34:13 2014 -0700
    60.2 +++ b/src/jdk/nashorn/internal/runtime/Timing.java	Tue Sep 16 13:59:37 2014 -0700
    60.3 @@ -33,6 +33,8 @@
    60.4  import java.util.Map;
    60.5  import java.util.concurrent.TimeUnit;
    60.6  import java.util.function.Supplier;
    60.7 +
    60.8 +import jdk.nashorn.internal.codegen.CompileUnit;
    60.9  import jdk.nashorn.internal.runtime.logging.DebugLogger;
   60.10  import jdk.nashorn.internal.runtime.logging.Loggable;
   60.11  import jdk.nashorn.internal.runtime.logging.Logger;
   60.12 @@ -189,7 +191,7 @@
   60.13              maxKeyLength++;
   60.14  
   60.15              final StringBuilder sb = new StringBuilder();
   60.16 -            sb.append("Accumulated complation phase Timings:\n\n");
   60.17 +            sb.append("Accumulated compilation phase timings:\n\n");
   60.18              for (final Map.Entry<String, Long> entry : timings.entrySet()) {
   60.19                  int len;
   60.20  
   60.21 @@ -224,6 +226,9 @@
   60.22                  append((int)(knownTime * 100.0 / total)).
   60.23                  append("%])");
   60.24  
   60.25 +            sb.append("\n\nEmitted compile units: ").
   60.26 +                append(CompileUnit.getEmittedUnitCount());
   60.27 +
   60.28              return sb.toString();
   60.29          }
   60.30  
    61.1 --- a/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Thu Sep 11 15:34:13 2014 -0700
    61.2 +++ b/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java	Tue Sep 16 13:59:37 2014 -0700
    61.3 @@ -34,8 +34,8 @@
    61.4  
    61.5  import java.lang.invoke.MethodHandle;
    61.6  import java.lang.invoke.MethodHandles;
    61.7 +import java.lang.invoke.MethodType;
    61.8  import java.util.concurrent.Callable;
    61.9 -import jdk.nashorn.internal.codegen.CompilerConstants;
   61.10  import jdk.nashorn.internal.lookup.Lookup;
   61.11  import jdk.nashorn.internal.runtime.linker.Bootstrap;
   61.12  
   61.13 @@ -48,7 +48,7 @@
   61.14  
   61.15      private static final long serialVersionUID = -5928687246526840321L;
   61.16  
   61.17 -    static class Accessors {
   61.18 +    static final class Accessors {
   61.19          Object getter;
   61.20          Object setter;
   61.21  
   61.22 @@ -67,20 +67,20 @@
   61.23          }
   61.24      }
   61.25  
   61.26 +    private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
   61.27 +
   61.28      /** Getter method handle */
   61.29 -    private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
   61.30 -            "userAccessorGetter", Object.class, Accessors.class, Object.class);
   61.31 +    private final static MethodHandle INVOKE_GETTER_ACCESSOR = findOwnMH_S("invokeGetterAccessor", Object.class, Accessors.class, Object.class);
   61.32  
   61.33      /** Setter method handle */
   61.34 -    private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
   61.35 -            "userAccessorSetter", void.class, Accessors.class, String.class, Object.class, Object.class);
   61.36 +    private final static MethodHandle INVOKE_SETTER_ACCESSOR = findOwnMH_S("invokeSetterAccessor", void.class, Accessors.class, String.class, Object.class, Object.class);
   61.37  
   61.38      /** Dynamic invoker for getter */
   61.39 -    private static final Object INVOKE_UA_GETTER = new Object();
   61.40 +    private static final Object GETTER_INVOKER_KEY = new Object();
   61.41  
   61.42      private static MethodHandle getINVOKE_UA_GETTER() {
   61.43  
   61.44 -        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_GETTER,
   61.45 +        return Context.getGlobal().getDynamicInvoker(GETTER_INVOKER_KEY,
   61.46                  new Callable<MethodHandle>() {
   61.47                      @Override
   61.48                      public MethodHandle call() {
   61.49 @@ -91,10 +91,10 @@
   61.50      }
   61.51  
   61.52      /** Dynamic invoker for setter */
   61.53 -    private static Object INVOKE_UA_SETTER = new Object();
   61.54 +    private static Object SETTER_INVOKER_KEY = new Object();
   61.55  
   61.56      private static MethodHandle getINVOKE_UA_SETTER() {
   61.57 -        return Context.getGlobal().getDynamicInvoker(INVOKE_UA_SETTER,
   61.58 +        return Context.getGlobal().getDynamicInvoker(SETTER_INVOKER_KEY,
   61.59                  new Callable<MethodHandle>() {
   61.60                      @Override
   61.61                      public MethodHandle call() {
   61.62 @@ -190,7 +190,7 @@
   61.63  
   61.64      @Override
   61.65      public Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
   61.66 -        return userAccessorGetter(getAccessors((owner != null) ? owner : self), self);
   61.67 +        return invokeGetterAccessor(getAccessors((owner != null) ? owner : self), self);
   61.68      }
   61.69  
   61.70      @Override
   61.71 @@ -210,13 +210,13 @@
   61.72  
   61.73      @Override
   61.74      public void setValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
   61.75 -        userAccessorSetter(getAccessors((owner != null) ? owner : self), strict ? getKey() : null, self, value);
   61.76 +        invokeSetterAccessor(getAccessors((owner != null) ? owner : self), strict ? getKey() : null, self, value);
   61.77      }
   61.78  
   61.79      @Override
   61.80      public MethodHandle getGetter(final Class<?> type) {
   61.81          //this returns a getter on the format (Accessors, Object receiver)
   61.82 -        return Lookup.filterReturnType(USER_ACCESSOR_GETTER.methodHandle(), type);
   61.83 +        return Lookup.filterReturnType(INVOKE_GETTER_ACCESSOR, type);
   61.84      }
   61.85  
   61.86      @Override
   61.87 @@ -260,7 +260,7 @@
   61.88  
   61.89      @Override
   61.90      public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
   61.91 -        return USER_ACCESSOR_SETTER.methodHandle();
   61.92 +        return INVOKE_SETTER_ACCESSOR;
   61.93      }
   61.94  
   61.95      @Override
   61.96 @@ -269,11 +269,21 @@
   61.97          return (value instanceof ScriptFunction) ? (ScriptFunction)value : null;
   61.98      }
   61.99  
  61.100 +    /**
  61.101 +     * Get the getter for the {@code Accessors} object.
  61.102 +     * This is the the super {@code Object} type getter with {@code Accessors} return type.
  61.103 +     *
  61.104 +     * @return The getter handle for the Accessors
  61.105 +     */
  61.106 +    MethodHandle getAccessorsGetter() {
  61.107 +        return super.getGetter(Object.class).asType(MethodType.methodType(Accessors.class, Object.class));
  61.108 +    }
  61.109 +
  61.110      // User defined getter and setter are always called by "dyn:call". Note that the user
  61.111      // getter/setter may be inherited. If so, proto is bound during lookup. In either
  61.112      // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
  61.113      // to be called is retrieved everytime and applied.
  61.114 -    static Object userAccessorGetter(final Accessors gs, final Object self) {
  61.115 +    private static Object invokeGetterAccessor(final Accessors gs, final Object self) {
  61.116          final Object func = gs.getter;
  61.117          if (func instanceof ScriptFunction) {
  61.118              try {
  61.119 @@ -288,7 +298,7 @@
  61.120          return UNDEFINED;
  61.121      }
  61.122  
  61.123 -    static void userAccessorSetter(final Accessors gs, final String name, final Object self, final Object value) {
  61.124 +    private static void invokeSetterAccessor(final Accessors gs, final String name, final Object self, final Object value) {
  61.125          final Object func = gs.setter;
  61.126          if (func instanceof ScriptFunction) {
  61.127              try {
  61.128 @@ -303,4 +313,8 @@
  61.129          }
  61.130      }
  61.131  
  61.132 +    private static MethodHandle findOwnMH_S(final String name, final Class<?> rtype, final Class<?>... types) {
  61.133 +        return MH.findStatic(LOOKUP, UserAccessorProperty.class, name, MH.type(rtype, types));
  61.134 +    }
  61.135 +
  61.136  }
    62.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Thu Sep 11 15:34:13 2014 -0700
    62.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java	Tue Sep 16 13:59:37 2014 -0700
    62.3 @@ -628,18 +628,20 @@
    62.4          Class<?> widest = Integer.class;
    62.5  
    62.6          for (final Object item : items) {
    62.7 -            final Class<?> itemClass = item == null ? null : item.getClass();
    62.8 +            if (item == null) {
    62.9 +                return Object.class;
   62.10 +            }
   62.11 +            final Class<?> itemClass = item.getClass();
   62.12              if (itemClass == Long.class) {
   62.13                  if (widest == Integer.class) {
   62.14                      widest = Long.class;
   62.15                  }
   62.16 -            } else if (itemClass == Double.class) {
   62.17 +            } else if (itemClass == Double.class || itemClass == Float.class) {
   62.18                  if (widest == Integer.class || widest == Long.class) {
   62.19                      widest = Double.class;
   62.20                  }
   62.21 -            } else if (!(item instanceof Number)) {
   62.22 -                widest = Object.class;
   62.23 -                break;
   62.24 +            } else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) {
   62.25 +                return Object.class;
   62.26              }
   62.27          }
   62.28  
    63.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Thu Sep 11 15:34:13 2014 -0700
    63.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Tue Sep 16 13:59:37 2014 -0700
    63.3 @@ -54,23 +54,25 @@
    63.4      public static final int CALLSITE_OPTIMISTIC    = 1 << 3;
    63.5      /** Is this really an apply that we try to call as a call? */
    63.6      public static final int CALLSITE_APPLY_TO_CALL = 1 << 4;
    63.7 +    /** Does this a callsite for a variable declaration? */
    63.8 +    public static final int CALLSITE_DECLARE       = 1 << 5;
    63.9  
   63.10      /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
   63.11       * code where call sites have this flag set. */
   63.12 -    public static final int CALLSITE_PROFILE        = 1 << 5;
   63.13 +    public static final int CALLSITE_PROFILE         = 1 << 6;
   63.14      /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
   63.15       * call sites have this flag set. */
   63.16 -    public static final int CALLSITE_TRACE          = 1 << 6;
   63.17 +    public static final int CALLSITE_TRACE           = 1 << 7;
   63.18      /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
   63.19       * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   63.20 -    public static final int CALLSITE_TRACE_MISSES   = 1 << 7;
   63.21 +    public static final int CALLSITE_TRACE_MISSES    = 1 << 8;
   63.22      /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
   63.23       * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   63.24 -    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 8;
   63.25 +    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 9;
   63.26      /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
   63.27       * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
   63.28       * have this flag set. */
   63.29 -    public static final int CALLSITE_TRACE_VALUES   = 1 << 9;
   63.30 +    public static final int CALLSITE_TRACE_VALUES    = 1 << 10;
   63.31  
   63.32      //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
   63.33      //right now given the program points
   63.34 @@ -82,10 +84,10 @@
   63.35       * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
   63.36       * trace/profile settings.
   63.37       */
   63.38 -    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 10;
   63.39 +    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 11;
   63.40  
   63.41      /**
   63.42 -     * Maximum program point value. 22 bits should be enough for anyone
   63.43 +     * Maximum program point value. 21 bits should be enough for anyone
   63.44       */
   63.45      public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1;
   63.46  
   63.47 @@ -123,6 +125,9 @@
   63.48                  assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
   63.49                  sb.append("scope ");
   63.50              }
   63.51 +            if ((flags & CALLSITE_DECLARE) != 0) {
   63.52 +                sb.append("declare ");
   63.53 +            }
   63.54          }
   63.55          if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
   63.56              sb.append("apply2call ");
   63.57 @@ -329,6 +334,15 @@
   63.58      }
   63.59  
   63.60      /**
   63.61 +     * Does this callsite contain a declaration for its target?
   63.62 +     * @param desc descriptor
   63.63 +     * @return true if contains declaration
   63.64 +     */
   63.65 +    public static boolean isDeclaration(final CallSiteDescriptor desc) {
   63.66 +        return isFlag(desc, CALLSITE_DECLARE);
   63.67 +    }
   63.68 +
   63.69 +    /**
   63.70       * Get a program point from a descriptor (must be optimistic)
   63.71       * @param desc descriptor
   63.72       * @return program point
    64.1 --- a/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Thu Sep 11 15:34:13 2014 -0700
    64.2 +++ b/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java	Tue Sep 16 13:59:37 2014 -0700
    64.3 @@ -32,11 +32,10 @@
    64.4  import jdk.internal.dynalink.CallSiteDescriptor;
    64.5  import jdk.internal.dynalink.linker.GuardedInvocation;
    64.6  import jdk.internal.dynalink.linker.LinkRequest;
    64.7 -import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
    64.8  import jdk.internal.dynalink.support.Guards;
    64.9 -import jdk.nashorn.internal.lookup.Lookup;
   64.10  import jdk.nashorn.internal.runtime.FindProperty;
   64.11  import jdk.nashorn.internal.runtime.ScriptObject;
   64.12 +import jdk.nashorn.internal.runtime.UserAccessorProperty;
   64.13  
   64.14  /**
   64.15   * Implements lookup of methods to link for dynamic operations on JavaScript primitive values (booleans, strings, and
   64.16 @@ -86,15 +85,6 @@
   64.17                                                      final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
   64.18                                                      final MethodHandle protoFilter) {
   64.19          final CallSiteDescriptor desc = request.getCallSiteDescriptor();
   64.20 -        final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
   64.21 -        if ("setProp".equals(operator) || "setElem".equals(operator)) {
   64.22 -            final MethodType type = desc.getMethodType();
   64.23 -            MethodHandle method = MH.asType(Lookup.EMPTY_SETTER, MH.type(void.class, Object.class, type.parameterType(1)));
   64.24 -            if (type.parameterCount() == 3) {
   64.25 -                method = MH.dropArguments(method, 2, type.parameterType(2));
   64.26 -            }
   64.27 -            return new GuardedInvocation(method, guard);
   64.28 -        }
   64.29  
   64.30          if(desc.getNameTokenCount() > 2) {
   64.31              final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
   64.32 @@ -102,7 +92,7 @@
   64.33              if(find == null) {
   64.34                  // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
   64.35                  return null;
   64.36 -            } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
   64.37 +            } else if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
   64.38                  // If property is found in the prototype object bind the method handle directly to
   64.39                  // the proto filter instead of going through wrapper instantiation below.
   64.40                  final ScriptObject proto = wrappedReceiver.getProto();
    65.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Thu Sep 11 15:34:13 2014 -0700
    65.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Tue Sep 16 13:59:37 2014 -0700
    65.3 @@ -58,6 +58,7 @@
    65.4  parser.error.regex.repeated.flag=Repeated RegExp flag: {0}
    65.5  parser.error.regex.syntax={0}
    65.6  parser.error.trailing.comma.in.json=Trailing comma is not allowed in JSON
    65.7 +parser.error.missing.const.assignment=Missing assignment to constant "{0}"
    65.8  
    65.9  # strict mode error messages
   65.10  parser.error.strict.no.with="with" statement cannot be used in strict mode
   65.11 @@ -162,6 +163,8 @@
   65.12  
   65.13  syntax.error.invalid.json=Invalid JSON: {0}
   65.14  syntax.error.strict.cant.delete=cannot delete "{0}" in strict mode
   65.15 +syntax.error.redeclare.variable=Variable "{0}" has already been declared
   65.16 +syntax.error.assign.constant=Assignment to constant "{0}"
   65.17  
   65.18  io.error.cant.write=cannot write "{0}"
   65.19  config.error.no.dest=no destination directory supplied
    66.1 --- a/src/jdk/nashorn/internal/runtime/resources/Options.properties	Thu Sep 11 15:34:13 2014 -0700
    66.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Options.properties	Tue Sep 16 13:59:37 2014 -0700
    66.3 @@ -329,6 +329,14 @@
    66.4      desc="Enable scripting features."   \
    66.5  }
    66.6  
    66.7 +nashorn.option.language = {                      \
    66.8 +    name="--language",                           \
    66.9 +    type=String,                                 \
   66.10 +    params=[es5|es6],                            \
   66.11 +    default=es5,                                 \
   66.12 +    desc="Specify ECMAScript language version."  \
   66.13 +}
   66.14 +
   66.15  nashorn.option.stdout = {                                                \
   66.16      name="--stdout",                                                     \
   66.17      is_undocumented=true,                                                \
    67.1 --- a/src/jdk/nashorn/tools/Shell.java	Thu Sep 11 15:34:13 2014 -0700
    67.2 +++ b/src/jdk/nashorn/tools/Shell.java	Tue Sep 16 13:59:37 2014 -0700
    67.3 @@ -246,12 +246,21 @@
    67.4  
    67.5              // For each file on the command line.
    67.6              for (final String fileName : files) {
    67.7 -                final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors, env._strict, FunctionNode.FIRST_FUNCTION_ID, 0, context.getLogger(Parser.class)).parse();
    67.8 +                final FunctionNode functionNode = new Parser(env, sourceFor(fileName, new File(fileName)), errors, env._strict, 0, context.getLogger(Parser.class)).parse();
    67.9  
   67.10                  if (errors.getNumberOfErrors() != 0) {
   67.11                      return COMPILATION_ERROR;
   67.12                  }
   67.13  
   67.14 +                new Compiler(
   67.15 +                       context,
   67.16 +                       env,
   67.17 +                       null, //null - pass no code installer - this is compile only
   67.18 +                       functionNode.getSource(),
   67.19 +                       context.getErrorManager(),
   67.20 +                       env._strict | functionNode.isStrict()).
   67.21 +                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
   67.22 +
   67.23                  if (env._print_ast) {
   67.24                      context.getErr().println(new ASTWriter(functionNode));
   67.25                  }
   67.26 @@ -260,14 +269,9 @@
   67.27                      context.getErr().println(new PrintVisitor(functionNode));
   67.28                  }
   67.29  
   67.30 -                //null - pass no code installer - this is compile only
   67.31 -                new Compiler(
   67.32 -                       context,
   67.33 -                       env,
   67.34 -                       null,
   67.35 -                       functionNode.getSource(),
   67.36 -                       env._strict | functionNode.isStrict()).
   67.37 -                       compile(functionNode, CompilationPhases.COMPILE_ALL_NO_INSTALL);
   67.38 +                if (errors.getNumberOfErrors() != 0) {
   67.39 +                    return COMPILATION_ERROR;
   67.40 +                }
   67.41              }
   67.42          } finally {
   67.43              env.getOut().flush();
    68.1 --- a/test/script/basic/JDK-8030182_2.js	Thu Sep 11 15:34:13 2014 -0700
    68.2 +++ b/test/script/basic/JDK-8030182_2.js	Tue Sep 16 13:59:37 2014 -0700
    68.3 @@ -41,6 +41,6 @@
    68.4  try {
    68.5      eval(str);
    68.6  } catch (e) {
    68.7 -    print(e.stack.replace(/\\/g, '/').replace(/<eval>@[0-9]+/, '<eval>@<id>'));
    68.8 +    print(e.stack.replace(/\\/g, '/'));
    68.9  }
   68.10  
    69.1 --- a/test/script/basic/JDK-8030182_2.js.EXPECTED	Thu Sep 11 15:34:13 2014 -0700
    69.2 +++ b/test/script/basic/JDK-8030182_2.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    69.3 @@ -1,3 +1,3 @@
    69.4  ReferenceError: "g" is not defined
    69.5 -	at <program> (test/script/basic/JDK-8030182_2.js#42:4<eval>@<id>:-1)
    69.6 +	at <program> (test/script/basic/JDK-8030182_2.js#42:4<eval>:-1)
    69.7  	at <program> (test/script/basic/JDK-8030182_2.js:42)
    70.1 --- a/test/script/basic/JDK-8048079_1.js	Thu Sep 11 15:34:13 2014 -0700
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,35 +0,0 @@
    70.4 -/*
    70.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    70.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    70.7 - *
    70.8 - * This code is free software; you can redistribute it and/or modify it
    70.9 - * under the terms of the GNU General Public License version 2 only, as
   70.10 - * published by the Free Software Foundation.
   70.11 - *
   70.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   70.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   70.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   70.15 - * version 2 for more details (a copy is included in the LICENSE file that
   70.16 - * accompanied this code).
   70.17 - *
   70.18 - * You should have received a copy of the GNU General Public License version
   70.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   70.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   70.21 - *
   70.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   70.23 - * or visit www.oracle.com if you need additional information or have any
   70.24 - * questions.
   70.25 - */
   70.26 -
   70.27 -/**
   70.28 - * JDK-8048079: Persistent code store is broken after optimistic types merge
   70.29 - *
   70.30 - * @test
   70.31 - * @run
   70.32 - * @option -pcc
   70.33 - * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   70.34 - * @fork
   70.35 - */
   70.36 -
   70.37 -load(__DIR__ + 'prototype.js');
   70.38 -load(__DIR__ + 'yui.js');
    71.1 --- a/test/script/basic/JDK-8048079_1.js.EXPECTED	Thu Sep 11 15:34:13 2014 -0700
    71.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.3 @@ -1,3 +0,0 @@
    71.4 -parsed and compiled ok prototype.js
    71.5 -parsed and compiled ok yui-min.js
    71.6 -parsed and compiled ok yui.js
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/test/script/basic/JDK-8048079_1a.js	Tue Sep 16 13:59:37 2014 -0700
    72.3 @@ -0,0 +1,34 @@
    72.4 +/*
    72.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    72.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    72.7 + *
    72.8 + * This code is free software; you can redistribute it and/or modify it
    72.9 + * under the terms of the GNU General Public License version 2 only, as
   72.10 + * published by the Free Software Foundation.
   72.11 + *
   72.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   72.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   72.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   72.15 + * version 2 for more details (a copy is included in the LICENSE file that
   72.16 + * accompanied this code).
   72.17 + *
   72.18 + * You should have received a copy of the GNU General Public License version
   72.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   72.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   72.21 + *
   72.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   72.23 + * or visit www.oracle.com if you need additional information or have any
   72.24 + * questions.
   72.25 + */
   72.26 +
   72.27 +/**
   72.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge
   72.29 + *
   72.30 + * @test
   72.31 + * @runif external.prototype
   72.32 + * @option -pcc
   72.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   72.34 + * @fork
   72.35 + */
   72.36 +
   72.37 +load(__DIR__ + 'prototype.js');
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/test/script/basic/JDK-8048079_1a.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    73.3 @@ -0,0 +1,1 @@
    73.4 +parsed and compiled ok prototype.js
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/test/script/basic/JDK-8048079_1b.js	Tue Sep 16 13:59:37 2014 -0700
    74.3 @@ -0,0 +1,34 @@
    74.4 +/*
    74.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    74.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    74.7 + *
    74.8 + * This code is free software; you can redistribute it and/or modify it
    74.9 + * under the terms of the GNU General Public License version 2 only, as
   74.10 + * published by the Free Software Foundation.
   74.11 + *
   74.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   74.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   74.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   74.15 + * version 2 for more details (a copy is included in the LICENSE file that
   74.16 + * accompanied this code).
   74.17 + *
   74.18 + * You should have received a copy of the GNU General Public License version
   74.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   74.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   74.21 + *
   74.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   74.23 + * or visit www.oracle.com if you need additional information or have any
   74.24 + * questions.
   74.25 + */
   74.26 +
   74.27 +/**
   74.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge
   74.29 + *
   74.30 + * @test
   74.31 + * @runif external.yui
   74.32 + * @option -pcc
   74.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   74.34 + * @fork
   74.35 + */
   74.36 +
   74.37 +load(__DIR__ + 'yui.js');
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/test/script/basic/JDK-8048079_1b.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    75.3 @@ -0,0 +1,2 @@
    75.4 +parsed and compiled ok yui-min.js
    75.5 +parsed and compiled ok yui.js
    76.1 --- a/test/script/basic/JDK-8048079_2.js	Thu Sep 11 15:34:13 2014 -0700
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,35 +0,0 @@
    76.4 -/*
    76.5 - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    76.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    76.7 - *
    76.8 - * This code is free software; you can redistribute it and/or modify it
    76.9 - * under the terms of the GNU General Public License version 2 only, as
   76.10 - * published by the Free Software Foundation.
   76.11 - *
   76.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
   76.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   76.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   76.15 - * version 2 for more details (a copy is included in the LICENSE file that
   76.16 - * accompanied this code).
   76.17 - *
   76.18 - * You should have received a copy of the GNU General Public License version
   76.19 - * 2 along with this work; if not, write to the Free Software Foundation,
   76.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   76.21 - *
   76.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   76.23 - * or visit www.oracle.com if you need additional information or have any
   76.24 - * questions.
   76.25 - */
   76.26 -
   76.27 -/**
   76.28 - * JDK-8048079: Persistent code store is broken after optimistic types merge
   76.29 - *
   76.30 - * @test
   76.31 - * @run
   76.32 - * @option -pcc
   76.33 - * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   76.34 - * @fork
   76.35 - */
   76.36 -
   76.37 -load(__DIR__ + 'prototype.js');
   76.38 -load(__DIR__ + 'yui.js');
    77.1 --- a/test/script/basic/JDK-8048079_2.js.EXPECTED	Thu Sep 11 15:34:13 2014 -0700
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,3 +0,0 @@
    77.4 -parsed and compiled ok prototype.js
    77.5 -parsed and compiled ok yui-min.js
    77.6 -parsed and compiled ok yui.js
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/test/script/basic/JDK-8048079_2a.js	Tue Sep 16 13:59:37 2014 -0700
    78.3 @@ -0,0 +1,34 @@
    78.4 +/*
    78.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    78.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    78.7 + *
    78.8 + * This code is free software; you can redistribute it and/or modify it
    78.9 + * under the terms of the GNU General Public License version 2 only, as
   78.10 + * published by the Free Software Foundation.
   78.11 + *
   78.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   78.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   78.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   78.15 + * version 2 for more details (a copy is included in the LICENSE file that
   78.16 + * accompanied this code).
   78.17 + *
   78.18 + * You should have received a copy of the GNU General Public License version
   78.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   78.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   78.21 + *
   78.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   78.23 + * or visit www.oracle.com if you need additional information or have any
   78.24 + * questions.
   78.25 + */
   78.26 +
   78.27 +/**
   78.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge.
   78.29 + * Same script as JDK-8048079_1a.js to exercise code cache.
   78.30 + * @test
   78.31 + * @runif external.prototype
   78.32 + * @option -pcc
   78.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   78.34 + * @fork
   78.35 + */
   78.36 +
   78.37 +load(__DIR__ + 'prototype.js');
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/test/script/basic/JDK-8048079_2a.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    79.3 @@ -0,0 +1,1 @@
    79.4 +parsed and compiled ok prototype.js
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/test/script/basic/JDK-8048079_2b.js	Tue Sep 16 13:59:37 2014 -0700
    80.3 @@ -0,0 +1,34 @@
    80.4 +/*
    80.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    80.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    80.7 + *
    80.8 + * This code is free software; you can redistribute it and/or modify it
    80.9 + * under the terms of the GNU General Public License version 2 only, as
   80.10 + * published by the Free Software Foundation.
   80.11 + *
   80.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   80.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   80.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   80.15 + * version 2 for more details (a copy is included in the LICENSE file that
   80.16 + * accompanied this code).
   80.17 + *
   80.18 + * You should have received a copy of the GNU General Public License version
   80.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   80.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   80.21 + *
   80.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   80.23 + * or visit www.oracle.com if you need additional information or have any
   80.24 + * questions.
   80.25 + */
   80.26 +
   80.27 +/**
   80.28 + * JDK-8048079: Persistent code store is broken after optimistic types merge
   80.29 + * Same script as JDK-8048079_1b.js to exercise code cache again.
   80.30 + * @test
   80.31 + * @runif external.yui
   80.32 + * @option -pcc
   80.33 + * @option -Dnashorn.persistent.code.cache=build/nashorn_code_cache
   80.34 + * @fork
   80.35 + */
   80.36 +
   80.37 +load(__DIR__ + 'yui.js');
    81.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.2 +++ b/test/script/basic/JDK-8048079_2b.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    81.3 @@ -0,0 +1,2 @@
    81.4 +parsed and compiled ok yui-min.js
    81.5 +parsed and compiled ok yui.js
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/test/script/basic/JDK-8056129.js	Tue Sep 16 13:59:37 2014 -0700
    82.3 @@ -0,0 +1,42 @@
    82.4 +/*
    82.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    82.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    82.7 + * 
    82.8 + * This code is free software; you can redistribute it and/or modify it
    82.9 + * under the terms of the GNU General Public License version 2 only, as
   82.10 + * published by the Free Software Foundation.
   82.11 + * 
   82.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   82.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   82.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   82.15 + * version 2 for more details (a copy is included in the LICENSE file that
   82.16 + * accompanied this code).
   82.17 + * 
   82.18 + * You should have received a copy of the GNU General Public License version
   82.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   82.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   82.21 + * 
   82.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   82.23 + * or visit www.oracle.com if you need additional information or have any
   82.24 + * questions.
   82.25 + */
   82.26 +
   82.27 +/**
   82.28 + * JDK-8056129: AtomicInteger is treated as primitive number with optimistic compilation
   82.29 + *
   82.30 + * @test
   82.31 + * @run
   82.32 + */
   82.33 +
   82.34 +var AtomicInteger = java.util.concurrent.atomic.AtomicInteger;
   82.35 +
   82.36 +function getAtomic() { 
   82.37 +   return new AtomicInteger() 
   82.38 +} 
   82.39 +var x = getAtomic() 
   82.40 +print(x instanceof AtomicInteger)
   82.41 +
   82.42 +var a = []
   82.43 +a.push(x)
   82.44 +var y = a[0]
   82.45 +print(y instanceof AtomicInteger)
    83.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.2 +++ b/test/script/basic/JDK-8056129.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    83.3 @@ -0,0 +1,2 @@
    83.4 +true
    83.5 +true
    84.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.2 +++ b/test/script/basic/JDK-8057019-2.js	Tue Sep 16 13:59:37 2014 -0700
    84.3 @@ -0,0 +1,33 @@
    84.4 +/*
    84.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    84.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    84.7 + *
    84.8 + * This code is free software; you can redistribute it and/or modify it
    84.9 + * under the terms of the GNU General Public License version 2 only, as
   84.10 + * published by the Free Software Foundation.
   84.11 + *
   84.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   84.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   84.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   84.15 + * version 2 for more details (a copy is included in the LICENSE file that
   84.16 + * accompanied this code).
   84.17 + *
   84.18 + * You should have received a copy of the GNU General Public License version
   84.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   84.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   84.21 + *
   84.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   84.23 + * or visit www.oracle.com if you need additional information or have any
   84.24 + * questions.
   84.25 + */
   84.26 +
   84.27 +/**
   84.28 + * this apply with extra arguments
   84.29 + * (with apply to call enabled)
   84.30 + *
   84.31 + * @test
   84.32 + * @run
   84.33 + */
   84.34 +
   84.35 +load(__DIR__ + 'JDK-8057019-payload.js');
   84.36 +
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/test/script/basic/JDK-8057019-2.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    85.3 @@ -0,0 +1,24 @@
    85.4 +1 2 undefined
    85.5 +1 2 3
    85.6 +1 2 3
    85.7 +1 2 undefined
    85.8 +1 2 3
    85.9 +1 2 3
   85.10 +1 2 undefined
   85.11 +1 2 3
   85.12 +1 2 3
   85.13 +1 2 undefined
   85.14 +1 2 3
   85.15 +1 2 3
   85.16 +1 2 undefined
   85.17 +1 2 3
   85.18 +1 2 3
   85.19 +23 apa gorilla
   85.20 +23 apa gorilla
   85.21 +23 apa gorilla
   85.22 +23 apa gorilla
   85.23 +23 apa gorilla
   85.24 +23 apa gorilla
   85.25 +TypeError: Function.prototype.apply expects an Array for second argument
   85.26 +TypeError: Function.prototype.apply expects an Array for second argument
   85.27 +TypeError: Function.prototype.apply expects an Array for second argument
    86.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.2 +++ b/test/script/basic/JDK-8057019-payload.js	Tue Sep 16 13:59:37 2014 -0700
    86.3 @@ -0,0 +1,102 @@
    86.4 +/*
    86.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    86.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    86.7 + *
    86.8 + * This code is free software; you can redistribute it and/or modify it
    86.9 + * under the terms of the GNU General Public License version 2 only, as
   86.10 + * published by the Free Software Foundation.
   86.11 + *
   86.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   86.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   86.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   86.15 + * version 2 for more details (a copy is included in the LICENSE file that
   86.16 + * accompanied this code).
   86.17 + *
   86.18 + * You should have received a copy of the GNU General Public License version
   86.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   86.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   86.21 + *
   86.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   86.23 + * or visit www.oracle.com if you need additional information or have any
   86.24 + * questions.
   86.25 + */
   86.26 +
   86.27 +/**
   86.28 + * this apply with extra arguments
   86.29 + *
   86.30 + * @subtest
   86.31 + */
   86.32 +
   86.33 +function func(x, y, z) {
   86.34 +    print(x, y, z);
   86.35 +}
   86.36 +
   86.37 +function g() {
   86.38 +    func.apply(this, arguments);
   86.39 +}
   86.40 +function h() {
   86.41 +    func.apply(this, arguments, 23);
   86.42 +}
   86.43 +function i() {
   86.44 +    func.apply(this, arguments, 23, 4711);
   86.45 +}
   86.46 +function j() {
   86.47 +    func.apply(this, arguments, 23, 4711, "apa", "dingo", "gorilla");
   86.48 +}
   86.49 +function k() {
   86.50 +    func.apply(this, arguments, 23);
   86.51 +}
   86.52 +function l() {
   86.53 +    func.apply(this, [23, "apa", "gorilla", "dingo"], 17);
   86.54 +}
   86.55 +function m() {
   86.56 +    func.apply(this, [23, "apa", "gorilla", "dingo"]);
   86.57 +}
   86.58 +function n() {
   86.59 +    func.apply(this, "significant");
   86.60 +}
   86.61 +
   86.62 +g(1,2);
   86.63 +g(1,2,3);
   86.64 +g(1,2,3,4);
   86.65 +
   86.66 +h(1,2);
   86.67 +h(1,2,3);
   86.68 +h(1,2,3,4);
   86.69 +
   86.70 +i(1,2);
   86.71 +i(1,2,3);
   86.72 +i(1,2,3,4);
   86.73 +
   86.74 +j(1,2);
   86.75 +j(1,2,3);
   86.76 +j(1,2,3,4);
   86.77 +
   86.78 +k(1,2);
   86.79 +k(1,2,3);
   86.80 +k(1,2,3,4);
   86.81 +
   86.82 +l(1,2);
   86.83 +l(1,2,3);
   86.84 +l(1,2,3,4);
   86.85 +
   86.86 +m(1,2);
   86.87 +m(1,2,3);
   86.88 +m(1,2,3,4);
   86.89 +
   86.90 +try {
   86.91 +    n(1,2);
   86.92 +} catch (e) {
   86.93 +    print(e);
   86.94 +}
   86.95 +try {
   86.96 +    n(1,2,3);
   86.97 +} catch (e) {
   86.98 +    print(e);    
   86.99 +}
  86.100 +
  86.101 +try {
  86.102 +    n(1,2,3,4);
  86.103 +} catch (e) {
  86.104 +    print(e);   
  86.105 +}
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/test/script/basic/JDK-8057019.js	Tue Sep 16 13:59:37 2014 -0700
    87.3 @@ -0,0 +1,35 @@
    87.4 +/*
    87.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    87.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    87.7 + *
    87.8 + * This code is free software; you can redistribute it and/or modify it
    87.9 + * under the terms of the GNU General Public License version 2 only, as
   87.10 + * published by the Free Software Foundation.
   87.11 + *
   87.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   87.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   87.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   87.15 + * version 2 for more details (a copy is included in the LICENSE file that
   87.16 + * accompanied this code).
   87.17 + *
   87.18 + * You should have received a copy of the GNU General Public License version
   87.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   87.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   87.21 + *
   87.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   87.23 + * or visit www.oracle.com if you need additional information or have any
   87.24 + * questions.
   87.25 + */
   87.26 +
   87.27 +/**
   87.28 + * this apply with extra arguments
   87.29 + * (turning off apply to call)
   87.30 + *
   87.31 + * @fork
   87.32 + * @option -Dnashorn.apply2call=false
   87.33 + * @test
   87.34 + * @run
   87.35 + */
   87.36 +
   87.37 +load(__DIR__ + 'JDK-8057019-payload.js');
   87.38 +
    88.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    88.2 +++ b/test/script/basic/JDK-8057019.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    88.3 @@ -0,0 +1,24 @@
    88.4 +1 2 undefined
    88.5 +1 2 3
    88.6 +1 2 3
    88.7 +1 2 undefined
    88.8 +1 2 3
    88.9 +1 2 3
   88.10 +1 2 undefined
   88.11 +1 2 3
   88.12 +1 2 3
   88.13 +1 2 undefined
   88.14 +1 2 3
   88.15 +1 2 3
   88.16 +1 2 undefined
   88.17 +1 2 3
   88.18 +1 2 3
   88.19 +23 apa gorilla
   88.20 +23 apa gorilla
   88.21 +23 apa gorilla
   88.22 +23 apa gorilla
   88.23 +23 apa gorilla
   88.24 +23 apa gorilla
   88.25 +TypeError: Function.prototype.apply expects an Array for second argument
   88.26 +TypeError: Function.prototype.apply expects an Array for second argument
   88.27 +TypeError: Function.prototype.apply expects an Array for second argument
    89.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    89.2 +++ b/test/script/basic/JDK-8058179.js	Tue Sep 16 13:59:37 2014 -0700
    89.3 @@ -0,0 +1,48 @@
    89.4 +/*
    89.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
    89.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    89.7 + * 
    89.8 + * This code is free software; you can redistribute it and/or modify it
    89.9 + * under the terms of the GNU General Public License version 2 only, as
   89.10 + * published by the Free Software Foundation.
   89.11 + * 
   89.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   89.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   89.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   89.15 + * version 2 for more details (a copy is included in the LICENSE file that
   89.16 + * accompanied this code).
   89.17 + * 
   89.18 + * You should have received a copy of the GNU General Public License version
   89.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   89.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   89.21 + * 
   89.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   89.23 + * or visit www.oracle.com if you need additional information or have any
   89.24 + * questions.
   89.25 + */
   89.26 +
   89.27 +/**
   89.28 + * JDK-8058179: Global constants get in the way of self-modifying properties
   89.29 + *
   89.30 + * @test
   89.31 + * @run
   89.32 + */
   89.33 +
   89.34 +var global = this;
   89.35 +
   89.36 +Object.defineProperty(global, "value", {
   89.37 +    get: function() {
   89.38 +        print("getting value");
   89.39 +        global["value"] = "value 2";
   89.40 +        return "value 1";
   89.41 +    },
   89.42 +    set: function(value) {
   89.43 +        print("setting value: " + value);
   89.44 +        delete global["value"];
   89.45 +        global["value"] = value;
   89.46 +    },
   89.47 +    configurable: true
   89.48 +});
   89.49 +
   89.50 +print(value);
   89.51 +print(value);
    90.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    90.2 +++ b/test/script/basic/JDK-8058179.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    90.3 @@ -0,0 +1,4 @@
    90.4 +getting value
    90.5 +setting value: value 2
    90.6 +value 1
    90.7 +value 2
    91.1 --- a/test/script/basic/apply_to_call/apply_to_call4.js.EXPECTED	Thu Sep 11 15:34:13 2014 -0700
    91.2 +++ b/test/script/basic/apply_to_call/apply_to_call4.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    91.3 @@ -15,8 +15,8 @@
    91.4  2.3
    91.5  3.4
    91.6  test 5 done
    91.7 -a=object
    91.8 -17
    91.9 +a=number
   91.10 +22
   91.11  undefined
   91.12  Now it's time for transforms
   91.13  19
    92.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    92.2 +++ b/test/script/basic/es6/block-function-decl.js	Tue Sep 16 13:59:37 2014 -0700
    92.3 @@ -0,0 +1,51 @@
    92.4 +/*
    92.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    92.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    92.7 + *
    92.8 + * This code is free software; you can redistribute it and/or modify it
    92.9 + * under the terms of the GNU General Public License version 2 only, as
   92.10 + * published by the Free Software Foundation.
   92.11 + *
   92.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   92.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   92.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   92.15 + * version 2 for more details (a copy is included in the LICENSE file that
   92.16 + * accompanied this code).
   92.17 + *
   92.18 + * You should have received a copy of the GNU General Public License version
   92.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   92.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   92.21 + *
   92.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   92.23 + * or visit www.oracle.com if you need additional information or have any
   92.24 + * questions.
   92.25 + */
   92.26 +
   92.27 +/**
   92.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   92.29 + *
   92.30 + * @test
   92.31 + * @run
   92.32 + * @option --language=es6
   92.33 + */
   92.34 +
   92.35 +"use strict";
   92.36 +
   92.37 +{
   92.38 +    // f is defined on block level
   92.39 +    print(f);
   92.40 +    f();
   92.41 +    function f() {
   92.42 +        print("in f");
   92.43 +    }
   92.44 +    print(f);
   92.45 +    f();
   92.46 +}
   92.47 +
   92.48 +try {
   92.49 +    print(typeof f);
   92.50 +    f();
   92.51 +} catch (e) {
   92.52 +    print(e);
   92.53 +}
   92.54 +
    93.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    93.2 +++ b/test/script/basic/es6/block-function-decl.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    93.3 @@ -0,0 +1,10 @@
    93.4 +function f() {
    93.5 +        print("in f");
    93.6 +    }
    93.7 +in f
    93.8 +function f() {
    93.9 +        print("in f");
   93.10 +    }
   93.11 +in f
   93.12 +undefined
   93.13 +ReferenceError: "f" is not defined
    94.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    94.2 +++ b/test/script/basic/es6/const-empty.js	Tue Sep 16 13:59:37 2014 -0700
    94.3 @@ -0,0 +1,37 @@
    94.4 +/*
    94.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    94.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    94.7 + * 
    94.8 + * This code is free software; you can redistribute it and/or modify it
    94.9 + * under the terms of the GNU General Public License version 2 only, as
   94.10 + * published by the Free Software Foundation.
   94.11 + * 
   94.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   94.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   94.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   94.15 + * version 2 for more details (a copy is included in the LICENSE file that
   94.16 + * accompanied this code).
   94.17 + * 
   94.18 + * You should have received a copy of the GNU General Public License version
   94.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   94.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   94.21 + * 
   94.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   94.23 + * or visit www.oracle.com if you need additional information or have any
   94.24 + * questions.
   94.25 + */
   94.26 +
   94.27 +/**
   94.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   94.29 + *
   94.30 + * @test
   94.31 + * @run
   94.32 + * @option --language=es6
   94.33 + */
   94.34 +
   94.35 +try {
   94.36 +    eval('"use strict";\n' +
   94.37 +        'const x;\n');
   94.38 +} catch (e) {
   94.39 +    print(e);
   94.40 +}
    95.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    95.2 +++ b/test/script/basic/es6/const-empty.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    95.3 @@ -0,0 +1,3 @@
    95.4 +SyntaxError: test/script/basic/es6/const-empty.js#33:4<eval>:2:7 Missing assignment to constant "x"
    95.5 +const x;
    95.6 +       ^
    96.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    96.2 +++ b/test/script/basic/es6/const-reassign.js	Tue Sep 16 13:59:37 2014 -0700
    96.3 @@ -0,0 +1,174 @@
    96.4 +/*
    96.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    96.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    96.7 + *
    96.8 + * This code is free software; you can redistribute it and/or modify it
    96.9 + * under the terms of the GNU General Public License version 2 only, as
   96.10 + * published by the Free Software Foundation.
   96.11 + *
   96.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   96.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   96.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   96.15 + * version 2 for more details (a copy is included in the LICENSE file that
   96.16 + * accompanied this code).
   96.17 + *
   96.18 + * You should have received a copy of the GNU General Public License version
   96.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   96.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   96.21 + *
   96.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   96.23 + * or visit www.oracle.com if you need additional information or have any
   96.24 + * questions.
   96.25 + */
   96.26 +
   96.27 +/**
   96.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
   96.29 + *
   96.30 + * @test
   96.31 + * @run
   96.32 + * @option --language=es6 */
   96.33 +
   96.34 +"use strict";
   96.35 +
   96.36 +try {
   96.37 +    eval('"use strict";\n' +
   96.38 +        'const x = 2;\n' +
   96.39 +        'x = 1;\n');
   96.40 +} catch (e) {
   96.41 +    print(e.name);
   96.42 +}
   96.43 +
   96.44 +try {
   96.45 +    eval('"use strict";\n' +
   96.46 +        'const x = 2;\n' +
   96.47 +        'x++;\n');
   96.48 +    fail("const assignment didn't throw");
   96.49 +} catch (e) {
   96.50 +    print(e.name);
   96.51 +}
   96.52 +
   96.53 +try {
   96.54 +    eval('"use strict";\n' +
   96.55 +        'const x = 2;\n' +
   96.56 +        'x--;\n');
   96.57 +    fail("const assignment didn't throw");
   96.58 +} catch (e) {
   96.59 +    print(e.name);
   96.60 +}
   96.61 +
   96.62 +try {
   96.63 +    eval('"use strict";\n' +
   96.64 +        'const x = 2;\n' +
   96.65 +        '++x;\n');
   96.66 +    fail("const assignment didn't throw");
   96.67 +} catch (e) {
   96.68 +    print(e.name);
   96.69 +}
   96.70 +
   96.71 +try {
   96.72 +    eval('"use strict";\n' +
   96.73 +        'const x = 2;\n' +
   96.74 +        '--x;\n');
   96.75 +    fail("const assignment didn't throw");
   96.76 +} catch (e) {
   96.77 +    print(e.name);
   96.78 +}
   96.79 +
   96.80 +try {
   96.81 +    eval('"use strict";\n' +
   96.82 +        'const x = 2;\n' +
   96.83 +        'x += 1;\n');
   96.84 +    fail("const assignment didn't throw");
   96.85 +} catch (e) {
   96.86 +    print(e.name);
   96.87 +}
   96.88 +
   96.89 +try {
   96.90 +    eval('"use strict";\n' +
   96.91 +        'const x = 2;\n' +
   96.92 +        'x *= 1;\n');
   96.93 +    fail("const assignment didn't throw");
   96.94 +} catch (e) {
   96.95 +    print(e.name);
   96.96 +}
   96.97 +
   96.98 +try {
   96.99 +    eval('"use strict";\n' +
  96.100 +        'const x = 2;\n' +
  96.101 +        'x /= 1;\n');
  96.102 +    fail("const assignment didn't throw");
  96.103 +} catch (e) {
  96.104 +    print(e.name);
  96.105 +}
  96.106 +
  96.107 +try {
  96.108 +    eval('"use strict";\n' +
  96.109 +        'const x = 2;\n' +
  96.110 +        'x %= 1;\n');
  96.111 +    fail("const assignment didn't throw");
  96.112 +} catch (e) {
  96.113 +    print(e.name);
  96.114 +}
  96.115 +
  96.116 +try {
  96.117 +    eval('"use strict";\n' +
  96.118 +        'const x = 2;\n' +
  96.119 +        'x |= 1;\n');
  96.120 +    fail("const assignment didn't throw");
  96.121 +} catch (e) {
  96.122 +    print(e.name);
  96.123 +}
  96.124 +
  96.125 +try {
  96.126 +    eval('"use strict";\n' +
  96.127 +        'const x = 2;\n' +
  96.128 +        'x &= 1;\n');
  96.129 +    fail("const assignment didn't throw");
  96.130 +} catch (e) {
  96.131 +    print(e.name);
  96.132 +}
  96.133 +
  96.134 +try {
  96.135 +    eval('"use strict";\n' +
  96.136 +        'const x = 2;\n' +
  96.137 +        'x ^= 1;\n');
  96.138 +    fail("const assignment didn't throw");
  96.139 +} catch (e) {
  96.140 +    print(e.name);
  96.141 +}
  96.142 +
  96.143 +try {
  96.144 +    eval('"use strict";\n' +
  96.145 +        'const x = 2;\n' +
  96.146 +        'x <<= 1;\n');
  96.147 +    fail("const assignment didn't throw");
  96.148 +} catch (e) {
  96.149 +    print(e.name);
  96.150 +}
  96.151 +
  96.152 +try {
  96.153 +    eval('"use strict";\n' +
  96.154 +        'const x = 2;\n' +
  96.155 +        'x >>= 1;\n');
  96.156 +    fail("const assignment didn't throw");
  96.157 +} catch (e) {
  96.158 +    print(e.name);
  96.159 +}
  96.160 +
  96.161 +try {
  96.162 +    eval('"use strict";\n' +
  96.163 +        'const x = 2;\n' +
  96.164 +        'x >>>= 1;\n');
  96.165 +    fail("const assignment didn't throw");
  96.166 +} catch (e) {
  96.167 +    print(e.name);
  96.168 +}
  96.169 +
  96.170 +try {
  96.171 +    eval('"use strict";\n' +
  96.172 +        'const x = 2;\n' +
  96.173 +        'delete x;\n');
  96.174 +    fail("const assignment didn't throw");
  96.175 +} catch (e) {
  96.176 +    print(e.name);
  96.177 +}
    97.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    97.2 +++ b/test/script/basic/es6/const-reassign.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    97.3 @@ -0,0 +1,16 @@
    97.4 +SyntaxError
    97.5 +SyntaxError
    97.6 +SyntaxError
    97.7 +SyntaxError
    97.8 +SyntaxError
    97.9 +SyntaxError
   97.10 +SyntaxError
   97.11 +SyntaxError
   97.12 +SyntaxError
   97.13 +SyntaxError
   97.14 +SyntaxError
   97.15 +SyntaxError
   97.16 +SyntaxError
   97.17 +SyntaxError
   97.18 +SyntaxError
   97.19 +SyntaxError
    98.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    98.2 +++ b/test/script/basic/es6/const-redeclare-extra.js	Tue Sep 16 13:59:37 2014 -0700
    98.3 @@ -0,0 +1,59 @@
    98.4 +/*
    98.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
    98.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    98.7 + * 
    98.8 + * This code is free software; you can redistribute it and/or modify it
    98.9 + * under the terms of the GNU General Public License version 2 only, as
   98.10 + * published by the Free Software Foundation.
   98.11 + * 
   98.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   98.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   98.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   98.15 + * version 2 for more details (a copy is included in the LICENSE file that
   98.16 + * accompanied this code).
   98.17 + * 
   98.18 + * You should have received a copy of the GNU General Public License version
   98.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   98.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   98.21 + * 
   98.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   98.23 + * or visit www.oracle.com if you need additional information or have any
   98.24 + * questions.
   98.25 + */
   98.26 +
   98.27 +/**
   98.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
   98.29 + *
   98.30 + * @test
   98.31 + * @run
   98.32 + * @option --language=es6
   98.33 + * @option -scripting
   98.34 + */
   98.35 +
   98.36 +
   98.37 +function tryIt (code) {
   98.38 +    try {
   98.39 +        eval(code)
   98.40 +    } catch (e) {
   98.41 +        print(e)
   98.42 +    }
   98.43 +}
   98.44 +
   98.45 +tryIt(<<CODE
   98.46 +    "use strict";
   98.47 +    const x = 2;
   98.48 +    var x = {};
   98.49 +CODE)
   98.50 +
   98.51 +tryIt(<<CODE
   98.52 +    "use strict";
   98.53 +    var x = 2;
   98.54 +    const x = {};
   98.55 +CODE)
   98.56 +
   98.57 +tryIt(<<CODE
   98.58 +    "use strict";
   98.59 +    function x () {}
   98.60 +    const x = 5;
   98.61 +CODE)
   98.62 +
    99.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    99.2 +++ b/test/script/basic/es6/const-redeclare-extra.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
    99.3 @@ -0,0 +1,9 @@
    99.4 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:8 Variable "x" has already been declared
    99.5 +    var x = {};
    99.6 +        ^
    99.7 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:2:8 Variable "x" has already been declared
    99.8 +    var x = 2;
    99.9 +        ^
   99.10 +SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:2:13 Variable "x" has already been declared
   99.11 +    function x () {}
   99.12 +             ^
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/test/script/basic/es6/const-redeclare.js	Tue Sep 16 13:59:37 2014 -0700
   100.3 @@ -0,0 +1,38 @@
   100.4 +/*
   100.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   100.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   100.7 + * 
   100.8 + * This code is free software; you can redistribute it and/or modify it
   100.9 + * under the terms of the GNU General Public License version 2 only, as
  100.10 + * published by the Free Software Foundation.
  100.11 + * 
  100.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  100.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  100.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  100.15 + * version 2 for more details (a copy is included in the LICENSE file that
  100.16 + * accompanied this code).
  100.17 + * 
  100.18 + * You should have received a copy of the GNU General Public License version
  100.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  100.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  100.21 + * 
  100.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  100.23 + * or visit www.oracle.com if you need additional information or have any
  100.24 + * questions.
  100.25 + */
  100.26 +
  100.27 +/**
  100.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  100.29 + *
  100.30 + * @test
  100.31 + * @run
  100.32 + * @option --language=es6
  100.33 + */
  100.34 +
  100.35 +try {
  100.36 +    eval('"use strict";\n' +
  100.37 +         'const x = 2;\n' +
  100.38 +         'const x = 2;\n');
  100.39 +} catch (e) {
  100.40 +    print(e);
  100.41 +}
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/test/script/basic/es6/const-redeclare.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   101.3 @@ -0,0 +1,3 @@
   101.4 +SyntaxError: test/script/basic/es6/const-redeclare.js#33:4<eval>:2:6 Variable "x" has already been declared
   101.5 +const x = 2;
   101.6 +      ^
   102.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   102.2 +++ b/test/script/basic/es6/const-self.js	Tue Sep 16 13:59:37 2014 -0700
   102.3 @@ -0,0 +1,42 @@
   102.4 +/*
   102.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   102.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   102.7 + *
   102.8 + * This code is free software; you can redistribute it and/or modify it
   102.9 + * under the terms of the GNU General Public License version 2 only, as
  102.10 + * published by the Free Software Foundation.
  102.11 + *
  102.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  102.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  102.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  102.15 + * version 2 for more details (a copy is included in the LICENSE file that
  102.16 + * accompanied this code).
  102.17 + *
  102.18 + * You should have received a copy of the GNU General Public License version
  102.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  102.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  102.21 + *
  102.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  102.23 + * or visit www.oracle.com if you need additional information or have any
  102.24 + * questions.
  102.25 + */
  102.26 +
  102.27 +/**
  102.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  102.29 + *
  102.30 + * @test
  102.31 + * @run
  102.32 + * @option --language=es6 */
  102.33 +
  102.34 +"use strict";
  102.35 +
  102.36 +const a = 1, b = a;
  102.37 +
  102.38 +print(a, b);
  102.39 +
  102.40 +try {
  102.41 +    eval('"use strict";\n' +
  102.42 +         'const a = a;\n');
  102.43 +} catch (e) {
  102.44 +    print(e);
  102.45 +}
   103.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   103.2 +++ b/test/script/basic/es6/const-self.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   103.3 @@ -0,0 +1,2 @@
   103.4 +1 1
   103.5 +ReferenceError: "a" is not defined
   104.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   104.2 +++ b/test/script/basic/es6/const-tdz.js	Tue Sep 16 13:59:37 2014 -0700
   104.3 @@ -0,0 +1,81 @@
   104.4 +/*
   104.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   104.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   104.7 + *
   104.8 + * This code is free software; you can redistribute it and/or modify it
   104.9 + * under the terms of the GNU General Public License version 2 only, as
  104.10 + * published by the Free Software Foundation.
  104.11 + *
  104.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  104.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  104.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  104.15 + * version 2 for more details (a copy is included in the LICENSE file that
  104.16 + * accompanied this code).
  104.17 + *
  104.18 + * You should have received a copy of the GNU General Public License version
  104.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  104.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  104.21 + *
  104.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  104.23 + * or visit www.oracle.com if you need additional information or have any
  104.24 + * questions.
  104.25 + */
  104.26 +
  104.27 +/**
  104.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  104.29 + *
  104.30 + * @test
  104.31 + * @run
  104.32 + * @option --language=es6 */
  104.33 +
  104.34 +"use strict";
  104.35 +
  104.36 +{
  104.37 +    print("test 1");
  104.38 +
  104.39 +    function f() {
  104.40 +        try {
  104.41 +            print(a);
  104.42 +        } catch (a) {
  104.43 +            print(a);
  104.44 +        }
  104.45 +    }
  104.46 +
  104.47 +    f();
  104.48 +    const a = 1;
  104.49 +    f();
  104.50 +}
  104.51 +
  104.52 +{
  104.53 +    print("test 2");
  104.54 +
  104.55 +    function f() {
  104.56 +        try {
  104.57 +            print(a);
  104.58 +        } catch (a) {
  104.59 +            print(a);
  104.60 +        }
  104.61 +    }
  104.62 +
  104.63 +    f();
  104.64 +    const a = 2;
  104.65 +    f();
  104.66 +}
  104.67 +
  104.68 +{
  104.69 +    print("test 3");
  104.70 +    {
  104.71 +        try {
  104.72 +            print(a);
  104.73 +        } catch (a) {
  104.74 +            print(a);
  104.75 +        }
  104.76 +    }
  104.77 +
  104.78 +    const a = 3;
  104.79 +
  104.80 +    {
  104.81 +        print(a);
  104.82 +    }
  104.83 +}
  104.84 +
   105.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   105.2 +++ b/test/script/basic/es6/const-tdz.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   105.3 @@ -0,0 +1,9 @@
   105.4 +test 1
   105.5 +ReferenceError: "a" is not defined
   105.6 +1
   105.7 +test 2
   105.8 +ReferenceError: "a" is not defined
   105.9 +2
  105.10 +test 3
  105.11 +ReferenceError: "a" is not defined
  105.12 +3
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/test/script/basic/es6/const.js	Tue Sep 16 13:59:37 2014 -0700
   106.3 @@ -0,0 +1,69 @@
   106.4 +/*
   106.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   106.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   106.7 + * 
   106.8 + * This code is free software; you can redistribute it and/or modify it
   106.9 + * under the terms of the GNU General Public License version 2 only, as
  106.10 + * published by the Free Software Foundation.
  106.11 + * 
  106.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  106.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  106.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  106.15 + * version 2 for more details (a copy is included in the LICENSE file that
  106.16 + * accompanied this code).
  106.17 + * 
  106.18 + * You should have received a copy of the GNU General Public License version
  106.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  106.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  106.21 + * 
  106.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  106.23 + * or visit www.oracle.com if you need additional information or have any
  106.24 + * questions.
  106.25 + */
  106.26 +
  106.27 +/**
  106.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  106.29 + *
  106.30 + * @test
  106.31 + * @run
  106.32 + * @option --language=es6
  106.33 + */
  106.34 +
  106.35 +"use strict";
  106.36 +
  106.37 +const a = 2;
  106.38 +const c = 2;
  106.39 +print(a, c);
  106.40 +
  106.41 +function f(x) {
  106.42 +    const a = 5;
  106.43 +    const c = 10;
  106.44 +    print(a, c);
  106.45 +    if (x) {
  106.46 +        const a = 42;
  106.47 +        const c = 43;
  106.48 +        print(a, c);
  106.49 +    }
  106.50 +    print(a, c);
  106.51 +
  106.52 +    function inner() {
  106.53 +        (function() {
  106.54 +            print(a, c);
  106.55 +        })();
  106.56 +    }
  106.57 +    inner();
  106.58 +}
  106.59 +
  106.60 +f(true);
  106.61 +f(false);
  106.62 +
  106.63 +(function() {
  106.64 +    (function() {
  106.65 +        print(a, c);
  106.66 +    })();
  106.67 +})();
  106.68 +
  106.69 +function outer() {
  106.70 +    print(a, c);
  106.71 +}
  106.72 +outer();
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/test/script/basic/es6/const.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   107.3 @@ -0,0 +1,10 @@
   107.4 +2 2
   107.5 +5 10
   107.6 +42 43
   107.7 +5 10
   107.8 +5 10
   107.9 +5 10
  107.10 +5 10
  107.11 +5 10
  107.12 +2 2
  107.13 +2 2
   108.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   108.2 +++ b/test/script/basic/es6/for-let.js	Tue Sep 16 13:59:37 2014 -0700
   108.3 @@ -0,0 +1,41 @@
   108.4 +/*
   108.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   108.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   108.7 + * 
   108.8 + * This code is free software; you can redistribute it and/or modify it
   108.9 + * under the terms of the GNU General Public License version 2 only, as
  108.10 + * published by the Free Software Foundation.
  108.11 + * 
  108.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  108.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  108.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  108.15 + * version 2 for more details (a copy is included in the LICENSE file that
  108.16 + * accompanied this code).
  108.17 + * 
  108.18 + * You should have received a copy of the GNU General Public License version
  108.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  108.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  108.21 + * 
  108.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  108.23 + * or visit www.oracle.com if you need additional information or have any
  108.24 + * questions.
  108.25 + */
  108.26 +
  108.27 +/**
  108.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  108.29 + *
  108.30 + * @test
  108.31 + * @run
  108.32 + * @option --language=es6 */
  108.33 +
  108.34 +"use strict";
  108.35 +
  108.36 +for (let i = 0; i < 10; i++) {
  108.37 +    print(i);
  108.38 +}
  108.39 +
  108.40 +try {
  108.41 +    print(i);
  108.42 +} catch (e) {
  108.43 +    print(e);
  108.44 +}
   109.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   109.2 +++ b/test/script/basic/es6/for-let.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   109.3 @@ -0,0 +1,11 @@
   109.4 +0
   109.5 +1
   109.6 +2
   109.7 +3
   109.8 +4
   109.9 +5
  109.10 +6
  109.11 +7
  109.12 +8
  109.13 +9
  109.14 +ReferenceError: "i" is not defined
   110.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   110.2 +++ b/test/script/basic/es6/let-eval.js	Tue Sep 16 13:59:37 2014 -0700
   110.3 @@ -0,0 +1,98 @@
   110.4 +/*
   110.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   110.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   110.7 + *
   110.8 + * This code is free software; you can redistribute it and/or modify it
   110.9 + * under the terms of the GNU General Public License version 2 only, as
  110.10 + * published by the Free Software Foundation.
  110.11 + *
  110.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  110.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  110.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  110.15 + * version 2 for more details (a copy is included in the LICENSE file that
  110.16 + * accompanied this code).
  110.17 + *
  110.18 + * You should have received a copy of the GNU General Public License version
  110.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  110.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  110.21 + *
  110.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  110.23 + * or visit www.oracle.com if you need additional information or have any
  110.24 + * questions.
  110.25 + */
  110.26 +
  110.27 +/**
  110.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  110.29 + *
  110.30 + * @test
  110.31 + * @run
  110.32 + * @option --language=es6 */
  110.33 +
  110.34 +"use strict";
  110.35 +
  110.36 +function f() {
  110.37 +    var a;
  110.38 +    let b;
  110.39 +    const c = 0;
  110.40 +
  110.41 +    print(a, b, c);
  110.42 +
  110.43 +    try {
  110.44 +        eval("x = 1; print('x: ' + x);");
  110.45 +        print("assignment to x succeeded");
  110.46 +    } catch (e) {
  110.47 +        print(e);
  110.48 +    }
  110.49 +    try {
  110.50 +        eval("'use strict'; let z = 1; print('z: ' + z);");
  110.51 +        print("assignment to z succeeded");
  110.52 +        eval("print('z: ' + z);");
  110.53 +    } catch (e) {
  110.54 +        print(e);
  110.55 +    }
  110.56 +
  110.57 +    try {
  110.58 +        eval("a = 1; print(a);");
  110.59 +        print("assignment to a succeeded");
  110.60 +    } catch (e) {
  110.61 +        print(e);
  110.62 +    }
  110.63 +    print("a: " + a);
  110.64 +
  110.65 +    try {
  110.66 +        eval("b = 1; print('b: ' + b);");
  110.67 +        print("assignment to b succeeded");
  110.68 +    } catch (e) {
  110.69 +        print(e);
  110.70 +    }
  110.71 +    print("b: " + b);
  110.72 +
  110.73 +    try {
  110.74 +        eval("c = 1; print('c: ' + c);");
  110.75 +        print("assignment to c succeeded");
  110.76 +    } catch (e) {
  110.77 +        print(e);
  110.78 +    }
  110.79 +    print("c: " + c);
  110.80 +
  110.81 +    eval("a = 2; let b = 3;");
  110.82 +
  110.83 +    try {
  110.84 +        print(a, b, c);
  110.85 +    } catch (e) {
  110.86 +        print(e);
  110.87 +    }
  110.88 +
  110.89 +    let x;
  110.90 +
  110.91 +    try {
  110.92 +        print(a, b, c, x);
  110.93 +    } catch (e) {
  110.94 +        print(e);
  110.95 +    }
  110.96 +
  110.97 +}
  110.98 +
  110.99 +f();
 110.100 +
 110.101 +print(typeof a, typeof b, typeof c, typeof x, typeof z);
   111.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   111.2 +++ b/test/script/basic/es6/let-eval.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   111.3 @@ -0,0 +1,16 @@
   111.4 +undefined undefined 0
   111.5 +ReferenceError: "x" is not defined
   111.6 +z: 1
   111.7 +assignment to z succeeded
   111.8 +ReferenceError: "z" is not defined
   111.9 +1
  111.10 +assignment to a succeeded
  111.11 +a: 1
  111.12 +b: 1
  111.13 +assignment to b succeeded
  111.14 +b: 1
  111.15 +TypeError: "c" is not a writable property of [object Object]
  111.16 +c: 0
  111.17 +2 1 0
  111.18 +2 1 0 undefined
  111.19 +undefined undefined undefined undefined undefined
   112.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   112.2 +++ b/test/script/basic/es6/let-load-lib.js	Tue Sep 16 13:59:37 2014 -0700
   112.3 @@ -0,0 +1,48 @@
   112.4 +/*
   112.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   112.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   112.7 + *
   112.8 + * This code is free software; you can redistribute it and/or modify it
   112.9 + * under the terms of the GNU General Public License version 2 only, as
  112.10 + * published by the Free Software Foundation.
  112.11 + *
  112.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  112.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  112.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  112.15 + * version 2 for more details (a copy is included in the LICENSE file that
  112.16 + * accompanied this code).
  112.17 + *
  112.18 + * You should have received a copy of the GNU General Public License version
  112.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  112.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  112.21 + *
  112.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  112.23 + * or visit www.oracle.com if you need additional information or have any
  112.24 + * questions.
  112.25 + */
  112.26 +
  112.27 +/**
  112.28 + * @subtest
  112.29 + */
  112.30 +
  112.31 +"use strict";
  112.32 +
  112.33 +// var should be visible in other script, let and const not
  112.34 +var a = 1;
  112.35 +let b = 2;
  112.36 +const c = 3;
  112.37 +
  112.38 +// top level function should be visible
  112.39 +function top() {
  112.40 +    print("top level function");
  112.41 +}
  112.42 +
  112.43 +// block level function not visible outside script
  112.44 +{
  112.45 +    function block() {
  112.46 +        print("block function");
  112.47 +    }
  112.48 +
  112.49 +    top();
  112.50 +    block();
  112.51 +}
   113.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   113.2 +++ b/test/script/basic/es6/let-load.js	Tue Sep 16 13:59:37 2014 -0700
   113.3 @@ -0,0 +1,62 @@
   113.4 +/*
   113.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   113.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   113.7 + *
   113.8 + * This code is free software; you can redistribute it and/or modify it
   113.9 + * under the terms of the GNU General Public License version 2 only, as
  113.10 + * published by the Free Software Foundation.
  113.11 + *
  113.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  113.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  113.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  113.15 + * version 2 for more details (a copy is included in the LICENSE file that
  113.16 + * accompanied this code).
  113.17 + *
  113.18 + * You should have received a copy of the GNU General Public License version
  113.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  113.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  113.21 + *
  113.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  113.23 + * or visit www.oracle.com if you need additional information or have any
  113.24 + * questions.
  113.25 + */
  113.26 +
  113.27 +/**
  113.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  113.29 + *
  113.30 + * @test
  113.31 + * @run
  113.32 + * @option --language=es6 */
  113.33 +
  113.34 +"use strict";
  113.35 +
  113.36 +load(__DIR__ + "let-load-lib.js");
  113.37 +
  113.38 +{
  113.39 +    let a = 20;
  113.40 +    const c = 30;
  113.41 +    print("print local defs: " + a, c);
  113.42 +}
  113.43 +
  113.44 +print("imported var: " + a);
  113.45 +try {
  113.46 +    print("imported let: " + b);
  113.47 +} catch (e) {
  113.48 +    print(e);
  113.49 +}
  113.50 +
  113.51 +try {
  113.52 +    print("imported const: " + c);
  113.53 +} catch (e) {
  113.54 +    print(e);
  113.55 +}
  113.56 +
  113.57 +top();
  113.58 +
  113.59 +try {
  113.60 +    block();
  113.61 +} catch (e) {
  113.62 +    print(e);
  113.63 +}
  113.64 +
  113.65 +
   114.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   114.2 +++ b/test/script/basic/es6/let-load.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   114.3 @@ -0,0 +1,8 @@
   114.4 +top level function
   114.5 +block function
   114.6 +print local defs: 20 30
   114.7 +imported var: 1
   114.8 +ReferenceError: "b" is not defined
   114.9 +ReferenceError: "c" is not defined
  114.10 +top level function
  114.11 +ReferenceError: "block" is not defined
   115.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   115.2 +++ b/test/script/basic/es6/let-nodeclare.js	Tue Sep 16 13:59:37 2014 -0700
   115.3 @@ -0,0 +1,52 @@
   115.4 +/*
   115.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   115.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   115.7 + *
   115.8 + * This code is free software; you can redistribute it and/or modify it
   115.9 + * under the terms of the GNU General Public License version 2 only, as
  115.10 + * published by the Free Software Foundation.
  115.11 + *
  115.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  115.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  115.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  115.15 + * version 2 for more details (a copy is included in the LICENSE file that
  115.16 + * accompanied this code).
  115.17 + *
  115.18 + * You should have received a copy of the GNU General Public License version
  115.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  115.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  115.21 + *
  115.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  115.23 + * or visit www.oracle.com if you need additional information or have any
  115.24 + * questions.
  115.25 + */
  115.26 +
  115.27 +/**
  115.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  115.29 + *
  115.30 + * @test
  115.31 + * @run
  115.32 + * @option --language=es6 */
  115.33 +
  115.34 +"use strict";
  115.35 +
  115.36 +try {
  115.37 +    if (true) {
  115.38 +        let x = 2;
  115.39 +        print(x);
  115.40 +    }
  115.41 +    print(x);
  115.42 +} catch (e) {
  115.43 +    print(e);
  115.44 +}
  115.45 +
  115.46 +
  115.47 +try {
  115.48 +    if (true) {
  115.49 +        const x = 2;
  115.50 +        print(x);
  115.51 +    }
  115.52 +    print(x);
  115.53 +} catch (e) {
  115.54 +    print(e);
  115.55 +}
   116.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   116.2 +++ b/test/script/basic/es6/let-nodeclare.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   116.3 @@ -0,0 +1,4 @@
   116.4 +2
   116.5 +ReferenceError: "x" is not defined
   116.6 +2
   116.7 +ReferenceError: "x" is not defined
   117.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   117.2 +++ b/test/script/basic/es6/let-redeclare-extra.js	Tue Sep 16 13:59:37 2014 -0700
   117.3 @@ -0,0 +1,70 @@
   117.4 +/*
   117.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   117.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   117.7 + * 
   117.8 + * This code is free software; you can redistribute it and/or modify it
   117.9 + * under the terms of the GNU General Public License version 2 only, as
  117.10 + * published by the Free Software Foundation.
  117.11 + * 
  117.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  117.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  117.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  117.15 + * version 2 for more details (a copy is included in the LICENSE file that
  117.16 + * accompanied this code).
  117.17 + * 
  117.18 + * You should have received a copy of the GNU General Public License version
  117.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  117.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  117.21 + * 
  117.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  117.23 + * or visit www.oracle.com if you need additional information or have any
  117.24 + * questions.
  117.25 + */
  117.26 +
  117.27 +/**
  117.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
  117.29 + *
  117.30 + * @test
  117.31 + * @run
  117.32 + * @option --language=es6
  117.33 + * @option -scripting
  117.34 + */
  117.35 +
  117.36 +function tryIt (code) {
  117.37 +    try {
  117.38 +        eval(code)
  117.39 +    } catch (e) {
  117.40 +        print(e)
  117.41 +    }
  117.42 +}
  117.43 +
  117.44 +tryIt(<<CODE
  117.45 +    "use strict";
  117.46 +    let x = 2;
  117.47 +    const x = function (a,b,c) {};
  117.48 +CODE)
  117.49 +
  117.50 +tryIt(<<CODE
  117.51 +    "use strict";
  117.52 +    let x = {};
  117.53 +    var x = 2;
  117.54 +CODE)
  117.55 +
  117.56 +tryIt(<<CODE
  117.57 +    "use strict";
  117.58 +    var x = 2;
  117.59 +    let x = undefined;
  117.60 +CODE)
  117.61 +
  117.62 +tryIt(<<CODE
  117.63 +    "use strict";
  117.64 +    const x = function (){};
  117.65 +    let x = {};
  117.66 +CODE)
  117.67 +
  117.68 +
  117.69 +tryIt(<<CODE
  117.70 +    "use strict";
  117.71 +    let a = 2;
  117.72 +    function a () {};
  117.73 +CODE)
  117.74 \ No newline at end of file
   118.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   118.2 +++ b/test/script/basic/es6/let-redeclare-extra.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   118.3 @@ -0,0 +1,15 @@
   118.4 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "x" has already been declared
   118.5 +    let x = 2;
   118.6 +        ^
   118.7 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:8 Variable "x" has already been declared
   118.8 +    var x = 2;
   118.9 +        ^
  118.10 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "x" has already been declared
  118.11 +    var x = 2;
  118.12 +        ^
  118.13 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:10 Variable "x" has already been declared
  118.14 +    const x = function (){};
  118.15 +          ^
  118.16 +SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:13 Variable "a" has already been declared
  118.17 +    function a () {};
  118.18 +             ^
   119.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   119.2 +++ b/test/script/basic/es6/let-redeclare.js	Tue Sep 16 13:59:37 2014 -0700
   119.3 @@ -0,0 +1,38 @@
   119.4 +/*
   119.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   119.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   119.7 + * 
   119.8 + * This code is free software; you can redistribute it and/or modify it
   119.9 + * under the terms of the GNU General Public License version 2 only, as
  119.10 + * published by the Free Software Foundation.
  119.11 + * 
  119.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  119.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  119.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  119.15 + * version 2 for more details (a copy is included in the LICENSE file that
  119.16 + * accompanied this code).
  119.17 + * 
  119.18 + * You should have received a copy of the GNU General Public License version
  119.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  119.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  119.21 + * 
  119.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  119.23 + * or visit www.oracle.com if you need additional information or have any
  119.24 + * questions.
  119.25 + */
  119.26 +
  119.27 +/**
  119.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  119.29 + *
  119.30 + * @test
  119.31 + * @run
  119.32 + * @option --language=es6
  119.33 + */
  119.34 +
  119.35 +try {
  119.36 +    eval('"use strict";\n' +
  119.37 +         'let x = 2;\n' +
  119.38 +         'let x = 2;\n');
  119.39 +} catch (e) {
  119.40 +    print(e);
  119.41 +}
   120.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   120.2 +++ b/test/script/basic/es6/let-redeclare.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   120.3 @@ -0,0 +1,3 @@
   120.4 +SyntaxError: test/script/basic/es6/let-redeclare.js#33:4<eval>:2:4 Variable "x" has already been declared
   120.5 +let x = 2;
   120.6 +    ^
   121.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   121.2 +++ b/test/script/basic/es6/let-self.js	Tue Sep 16 13:59:37 2014 -0700
   121.3 @@ -0,0 +1,42 @@
   121.4 +/*
   121.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   121.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   121.7 + *
   121.8 + * This code is free software; you can redistribute it and/or modify it
   121.9 + * under the terms of the GNU General Public License version 2 only, as
  121.10 + * published by the Free Software Foundation.
  121.11 + *
  121.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  121.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  121.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  121.15 + * version 2 for more details (a copy is included in the LICENSE file that
  121.16 + * accompanied this code).
  121.17 + *
  121.18 + * You should have received a copy of the GNU General Public License version
  121.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  121.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  121.21 + *
  121.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  121.23 + * or visit www.oracle.com if you need additional information or have any
  121.24 + * questions.
  121.25 + */
  121.26 +
  121.27 +/**
  121.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  121.29 + *
  121.30 + * @test
  121.31 + * @run
  121.32 + * @option --language=es6 */
  121.33 +
  121.34 +"use strict";
  121.35 +
  121.36 +let a, b = a;
  121.37 +
  121.38 +print(a, b);
  121.39 +
  121.40 +try {
  121.41 +    eval('"use strict";\n' +
  121.42 +         'let a = a;\n');
  121.43 +} catch (e) {
  121.44 +    print(e);
  121.45 +}
   122.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   122.2 +++ b/test/script/basic/es6/let-self.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   122.3 @@ -0,0 +1,2 @@
   122.4 +undefined undefined
   122.5 +ReferenceError: "a" is not defined
   123.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   123.2 +++ b/test/script/basic/es6/let-tdz.js	Tue Sep 16 13:59:37 2014 -0700
   123.3 @@ -0,0 +1,97 @@
   123.4 +/*
   123.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   123.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   123.7 + *
   123.8 + * This code is free software; you can redistribute it and/or modify it
   123.9 + * under the terms of the GNU General Public License version 2 only, as
  123.10 + * published by the Free Software Foundation.
  123.11 + *
  123.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  123.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  123.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  123.15 + * version 2 for more details (a copy is included in the LICENSE file that
  123.16 + * accompanied this code).
  123.17 + *
  123.18 + * You should have received a copy of the GNU General Public License version
  123.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  123.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  123.21 + *
  123.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  123.23 + * or visit www.oracle.com if you need additional information or have any
  123.24 + * questions.
  123.25 + */
  123.26 +
  123.27 +/**
  123.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  123.29 + *
  123.30 + * @test
  123.31 + * @run
  123.32 + * @option --language=es6 */
  123.33 +
  123.34 +"use strict";
  123.35 +
  123.36 +{
  123.37 +    print("test 1");
  123.38 +
  123.39 +    function f() {
  123.40 +        try {
  123.41 +            print(a);
  123.42 +        } catch (a) {
  123.43 +            print(a);
  123.44 +        }
  123.45 +    }
  123.46 +
  123.47 +    f();
  123.48 +    let a = 1;
  123.49 +    f();
  123.50 +}
  123.51 +
  123.52 +{
  123.53 +    print("test 2");
  123.54 +
  123.55 +    function f() {
  123.56 +        try {
  123.57 +            print(a);
  123.58 +        } catch (a) {
  123.59 +            print(a);
  123.60 +        }
  123.61 +    }
  123.62 +
  123.63 +    f();
  123.64 +    let a = 2;
  123.65 +    f();
  123.66 +}
  123.67 +
  123.68 +{
  123.69 +    print("test 3");
  123.70 +
  123.71 +    {
  123.72 +        try {
  123.73 +            print(a);
  123.74 +        } catch (a) {
  123.75 +            print(a);
  123.76 +        }
  123.77 +    }
  123.78 +
  123.79 +    let a = 3;
  123.80 +
  123.81 +    {
  123.82 +        print(a);
  123.83 +    }
  123.84 +}
  123.85 +
  123.86 +{
  123.87 +    print("test 4");
  123.88 +    let a;
  123.89 +
  123.90 +    {
  123.91 +        print(a);
  123.92 +    }
  123.93 +
  123.94 +    a = 4;
  123.95 +
  123.96 +    {
  123.97 +        print(a);
  123.98 +    }
  123.99 +}
 123.100 +
   124.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   124.2 +++ b/test/script/basic/es6/let-tdz.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   124.3 @@ -0,0 +1,12 @@
   124.4 +test 1
   124.5 +ReferenceError: "a" is not defined
   124.6 +1
   124.7 +test 2
   124.8 +ReferenceError: "a" is not defined
   124.9 +2
  124.10 +test 3
  124.11 +ReferenceError: "a" is not defined
  124.12 +3
  124.13 +test 4
  124.14 +undefined
  124.15 +4
   125.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   125.2 +++ b/test/script/basic/es6/let.js	Tue Sep 16 13:59:37 2014 -0700
   125.3 @@ -0,0 +1,69 @@
   125.4 +/*
   125.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   125.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   125.7 + * 
   125.8 + * This code is free software; you can redistribute it and/or modify it
   125.9 + * under the terms of the GNU General Public License version 2 only, as
  125.10 + * published by the Free Software Foundation.
  125.11 + * 
  125.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  125.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  125.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  125.15 + * version 2 for more details (a copy is included in the LICENSE file that
  125.16 + * accompanied this code).
  125.17 + * 
  125.18 + * You should have received a copy of the GNU General Public License version
  125.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  125.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  125.21 + * 
  125.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  125.23 + * or visit www.oracle.com if you need additional information or have any
  125.24 + * questions.
  125.25 + */
  125.26 +
  125.27 +/**
  125.28 + * JDK-8051889: Implement block scoping in symbol assignment and scope computation
  125.29 + *
  125.30 + * @test
  125.31 + * @run
  125.32 + * @option --language=es6 */
  125.33 +
  125.34 +"use strict";
  125.35 +
  125.36 +let a = 2;
  125.37 +let c = 2;
  125.38 +print(a, c);
  125.39 +
  125.40 +function f(x) {
  125.41 +    let a = 5;
  125.42 +    const c = 10;
  125.43 +    print(a, c);
  125.44 +    if (x) {
  125.45 +        let a = 42;
  125.46 +        const c = 43;
  125.47 +        print(a, c);
  125.48 +    }
  125.49 +    print(a, c);
  125.50 +
  125.51 +    function inner() {
  125.52 +        (function() {
  125.53 +            print(a, c);
  125.54 +        })();
  125.55 +    }
  125.56 +    inner();
  125.57 +}
  125.58 +
  125.59 +f(true);
  125.60 +f(false);
  125.61 +
  125.62 +(function() {
  125.63 +    (function() {
  125.64 +        print(a, c);
  125.65 +    })();
  125.66 +})();
  125.67 +
  125.68 +function outer() {
  125.69 +    print(a, c);
  125.70 +}
  125.71 +outer();
  125.72 +
   126.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   126.2 +++ b/test/script/basic/es6/let.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   126.3 @@ -0,0 +1,10 @@
   126.4 +2 2
   126.5 +5 10
   126.6 +42 43
   126.7 +5 10
   126.8 +5 10
   126.9 +5 10
  126.10 +5 10
  126.11 +5 10
  126.12 +2 2
  126.13 +2 2
   127.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   127.2 +++ b/test/script/basic/es6/let_const_closure.js	Tue Sep 16 13:59:37 2014 -0700
   127.3 @@ -0,0 +1,123 @@
   127.4 +/*
   127.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   127.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   127.7 + *
   127.8 + * This code is free software; you can redistribute it and/or modify it
   127.9 + * under the terms of the GNU General Public License version 2 only, as
  127.10 + * published by the Free Software Foundation.
  127.11 + *
  127.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  127.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  127.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  127.15 + * version 2 for more details (a copy is included in the LICENSE file that
  127.16 + * accompanied this code).
  127.17 + *
  127.18 + * You should have received a copy of the GNU General Public License version
  127.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  127.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  127.21 + *
  127.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  127.23 + * or visit www.oracle.com if you need additional information or have any
  127.24 + * questions.
  127.25 + */
  127.26 +
  127.27 +/**
  127.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
  127.29 + *
  127.30 + * @test
  127.31 + * @run
  127.32 + * @option --language=es6
  127.33 + * @option -scripting
  127.34 + */
  127.35 +
  127.36 +function tryIt(code) {
  127.37 +    try {
  127.38 +        eval(code)
  127.39 +    } catch (e) {
  127.40 +        print(e)
  127.41 +    }
  127.42 +}
  127.43 +
  127.44 +
  127.45 +tryIt(<<CODE
  127.46 +    function a () {
  127.47 +        this.val = 41
  127.48 +        let self = this
  127.49 +        this.b = function () {
  127.50 +            return self.val;
  127.51 +        }
  127.52 +    }
  127.53 +    c = new a()
  127.54 +    print(c.b.call(null))
  127.55 +CODE)
  127.56 +
  127.57 +
  127.58 +tryIt(<<CODE
  127.59 +        function a () {
  127.60 +            this.val = 42
  127.61 +            let self = this
  127.62 +            this.b = function () {
  127.63 +                return this.val;
  127.64 +            }.bind(self)
  127.65 +        }
  127.66 +        c = new a()
  127.67 +        print(c.b.call(null))
  127.68 +CODE)
  127.69 +
  127.70 +tryIt(<<CODE
  127.71 +    function a () {
  127.72 +        this.val = 43
  127.73 +        const self = this
  127.74 +        this.b = function () {
  127.75 +            return self.val;
  127.76 +        }
  127.77 +    }
  127.78 +    c = new a()
  127.79 +    print(c.b.call(null))
  127.80 +CODE)
  127.81 +
  127.82 +tryIt(<<CODE
  127.83 +        function a () {
  127.84 +            this.val = 44
  127.85 +            const self = this
  127.86 +            this.b = function () {
  127.87 +                return this.val;
  127.88 +            }.bind(self)
  127.89 +        }
  127.90 +        c = new a()
  127.91 +        print(c.b.call(null))
  127.92 +CODE)
  127.93 +
  127.94 +tryIt(<<CODE
  127.95 +       let a = {name : 'test'}
  127.96 +       let f = function () {
  127.97 +            print(this.name)
  127.98 +       }
  127.99 +       let nf = f.bind(a)
 127.100 +       nf()
 127.101 +       if (true) {
 127.102 +            let a = null
 127.103 +            nf()
 127.104 +       }
 127.105 +       nf()
 127.106 +CODE)
 127.107 +
 127.108 +
 127.109 +tryIt(<<CODE
 127.110 +       let arr = []
 127.111 +       for (let i = 0; i < 3; i++) {
 127.112 +           arr[i] = function(){return i;}
 127.113 +       }
 127.114 +       for (let i in arr) {
 127.115 +            print(arr[i]())
 127.116 +       }
 127.117 +       arr = []
 127.118 +       for (var i = 0; i < 3; i++) {
 127.119 +            (function(i){
 127.120 +                arr[i] = function(){return i;}
 127.121 +            })(i)
 127.122 +       }
 127.123 +       for (let i in arr) {
 127.124 +           print(arr[i]())
 127.125 +       }
 127.126 +CODE)
 127.127 \ No newline at end of file
   128.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   128.2 +++ b/test/script/basic/es6/let_const_closure.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   128.3 @@ -0,0 +1,13 @@
   128.4 +41
   128.5 +42
   128.6 +43
   128.7 +44
   128.8 +test
   128.9 +test
  128.10 +test
  128.11 +3
  128.12 +3
  128.13 +3
  128.14 +0
  128.15 +1
  128.16 +2
   129.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   129.2 +++ b/test/script/basic/es6/let_const_reuse.js	Tue Sep 16 13:59:37 2014 -0700
   129.3 @@ -0,0 +1,71 @@
   129.4 +/*
   129.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   129.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   129.7 + *
   129.8 + * This code is free software; you can redistribute it and/or modify it
   129.9 + * under the terms of the GNU General Public License version 2 only, as
  129.10 + * published by the Free Software Foundation.
  129.11 + *
  129.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  129.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  129.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  129.15 + * version 2 for more details (a copy is included in the LICENSE file that
  129.16 + * accompanied this code).
  129.17 + *
  129.18 + * You should have received a copy of the GNU General Public License version
  129.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  129.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  129.21 + *
  129.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  129.23 + * or visit www.oracle.com if you need additional information or have any
  129.24 + * questions.
  129.25 + */
  129.26 +
  129.27 +/**
  129.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
  129.29 + *
  129.30 + * @test
  129.31 + * @run
  129.32 + * @option --language=es6
  129.33 + * @option -scripting
  129.34 + */
  129.35 +
  129.36 +function tryIt (code) {
  129.37 +     try {
  129.38 +         eval(code)
  129.39 +     } catch (e) {
  129.40 +         print(e)
  129.41 +     }
  129.42 +}
  129.43 +
  129.44 +tryIt(<<CODE
  129.45 +    let a = 23
  129.46 +    if (true) {
  129.47 +        a--
  129.48 +        let a = 43;
  129.49 +    }
  129.50 +CODE)
  129.51 +
  129.52 +tryIt(<<CODE
  129.53 +    const a = 23
  129.54 +    if (true) {
  129.55 +        a--
  129.56 +        const a = 43;
  129.57 +    }
  129.58 +CODE)
  129.59 +
  129.60 +tryIt(<<CODE
  129.61 +    let a = 23
  129.62 +    if (true) {
  129.63 +        a--
  129.64 +        const a = 43;
  129.65 +    }
  129.66 +CODE)
  129.67 +
  129.68 +tryIt(<<CODE
  129.69 +    const a = 23
  129.70 +    if (true) {
  129.71 +        a--
  129.72 +        let a = 43;
  129.73 +    }
  129.74 +CODE)
   130.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   130.2 +++ b/test/script/basic/es6/let_const_reuse.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   130.3 @@ -0,0 +1,8 @@
   130.4 +ReferenceError: "a" is not defined
   130.5 +SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>:3:8 Assignment to constant "a"
   130.6 +        a--
   130.7 +        ^
   130.8 +SyntaxError: test/script/basic/es6/let_const_reuse.js#35:9<eval>:3:8 Assignment to constant "a"
   130.9 +        a--
  130.10 +        ^
  130.11 +ReferenceError: "a" is not defined
   131.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   131.2 +++ b/test/script/basic/es6/let_different_types.js	Tue Sep 16 13:59:37 2014 -0700
   131.3 @@ -0,0 +1,73 @@
   131.4 +/*
   131.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   131.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   131.7 + * 
   131.8 + * This code is free software; you can redistribute it and/or modify it
   131.9 + * under the terms of the GNU General Public License version 2 only, as
  131.10 + * published by the Free Software Foundation.
  131.11 + * 
  131.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  131.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  131.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  131.15 + * version 2 for more details (a copy is included in the LICENSE file that
  131.16 + * accompanied this code).
  131.17 + * 
  131.18 + * You should have received a copy of the GNU General Public License version
  131.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  131.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  131.21 + * 
  131.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  131.23 + * or visit www.oracle.com if you need additional information or have any
  131.24 + * questions.
  131.25 + */
  131.26 +
  131.27 +/**
  131.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
  131.29 + *
  131.30 + * @test
  131.31 + * @run
  131.32 + * @option --language=es6
  131.33 + * @option -scripting
  131.34 + */
  131.35 +
  131.36 +function tryIt (code) {
  131.37 +    try {
  131.38 +        eval(code)
  131.39 +    } catch (e) {
  131.40 +        print(e)
  131.41 +    }
  131.42 +}
  131.43 +
  131.44 +tryIt(<<CODE
  131.45 +    let a = function () {  var a = "Hello World!"; return a; }
  131.46 +    print(typeof a)
  131.47 +    {
  131.48 +        let a = 34;
  131.49 +        print(typeof a)
  131.50 +        if (true) {
  131.51 +            let c = 54.7
  131.52 +            var d = c
  131.53 +            print(typeof c)
  131.54 +            print(typeof d)
  131.55 +        }
  131.56 +    }
  131.57 +    print(typeof a)
  131.58 +    print(typeof a())
  131.59 +    print(typeof c)
  131.60 +    print(typeof d)
  131.61 +    print(d)
  131.62 +CODE)
  131.63 +
  131.64 +tryIt(<<CODE
  131.65 +    let a = {}
  131.66 +    if (true) {
  131.67 +        function a () {
  131.68 +            print (typeof a)
  131.69 +            return 'Hello World!'
  131.70 +        }
  131.71 +        print(typeof a)
  131.72 +        print(a())
  131.73 +    }
  131.74 +    print(typeof a)
  131.75 +CODE)
  131.76 +
   132.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   132.2 +++ b/test/script/basic/es6/let_different_types.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   132.3 @@ -0,0 +1,13 @@
   132.4 +function
   132.5 +number
   132.6 +number
   132.7 +number
   132.8 +function
   132.9 +string
  132.10 +undefined
  132.11 +number
  132.12 +54.7
  132.13 +function
  132.14 +function
  132.15 +Hello World!
  132.16 +object
   133.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   133.2 +++ b/test/script/basic/es6/let_loops.js	Tue Sep 16 13:59:37 2014 -0700
   133.3 @@ -0,0 +1,80 @@
   133.4 +/*
   133.5 + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   133.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   133.7 + *
   133.8 + * This code is free software; you can redistribute it and/or modify it
   133.9 + * under the terms of the GNU General Public License version 2 only, as
  133.10 + * published by the Free Software Foundation.
  133.11 + *
  133.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  133.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  133.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  133.15 + * version 2 for more details (a copy is included in the LICENSE file that
  133.16 + * accompanied this code).
  133.17 + *
  133.18 + * You should have received a copy of the GNU General Public License version
  133.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  133.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  133.21 + *
  133.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  133.23 + * or visit www.oracle.com if you need additional information or have any
  133.24 + * questions.
  133.25 + */
  133.26 +
  133.27 +/**
  133.28 + * JDK-8057678: Tests for let&const keywords in Nashorn
  133.29 + *
  133.30 + * @test
  133.31 + * @run
  133.32 + * @option --language=es6
  133.33 + * @option -scripting
  133.34 + */
  133.35 +
  133.36 +
  133.37 +function tryIt (code) {
  133.38 +    try {
  133.39 +        eval(code)
  133.40 +    } catch (e) {
  133.41 +        print(e)
  133.42 +    }
  133.43 +}
  133.44 +
  133.45 +tryIt(<<CODE
  133.46 +      let a = 2;
  133.47 +      do {
  133.48 +        a--;
  133.49 +        let b = a;
  133.50 +      } while (a > 0);
  133.51 +      print(a)
  133.52 +      print(b)
  133.53 +CODE)
  133.54 +
  133.55 +tryIt(<<CODE
  133.56 +       let a = 2
  133.57 +       while(a > 0) {
  133.58 +            a--
  133.59 +            let b = a
  133.60 +       }
  133.61 +       print(a)
  133.62 +       print(b)
  133.63 +CODE)
  133.64 +
  133.65 +tryIt(<<CODE
  133.66 +       let a = 2
  133.67 +       while(a > 0) {
  133.68 +            a--
  133.69 +            const b = a
  133.70 +       }
  133.71 +       print(a)
  133.72 +       print(b)
  133.73 +CODE)
  133.74 +
  133.75 +tryIt(<<CODE
  133.76 +       let a = 2;
  133.77 +       do {
  133.78 +         a--;
  133.79 +         const b = a;
  133.80 +       } while (a > 0);
  133.81 +       print(a)
  133.82 +       print(b)
  133.83 +CODE)
   134.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   134.2 +++ b/test/script/basic/es6/let_loops.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   134.3 @@ -0,0 +1,8 @@
   134.4 +0
   134.5 +ReferenceError: "b" is not defined
   134.6 +0
   134.7 +ReferenceError: "b" is not defined
   134.8 +0
   134.9 +ReferenceError: "b" is not defined
  134.10 +0
  134.11 +ReferenceError: "b" is not defined
   135.1 --- a/test/script/basic/optimistic_check_type.js	Thu Sep 11 15:34:13 2014 -0700
   135.2 +++ b/test/script/basic/optimistic_check_type.js	Tue Sep 16 13:59:37 2014 -0700
   135.3 @@ -36,13 +36,18 @@
   135.4  
   135.5  // Testing conditional operator
   135.6  print(inspect("" ? b : x.a, "ternary operator"))
   135.7 -print(inspect(x.b ? b : x.a, "ternary operator"))
   135.8 -print(inspect(c ? b : a, "ternary operator"))
   135.9 -print(inspect(!c ? b : a, "ternary operator"))
  135.10 -print(inspect(d ? b : x.c, "ternary operator"))
  135.11 +var b1 = b;
  135.12 +print(inspect(x.b ? b1 : x.a, "ternary operator"))
  135.13 +var b2 = b;
  135.14 +print(inspect(c ? b2 : a, "ternary operator"))
  135.15 +var b3 = b;
  135.16 +print(inspect(!c ? b3 : a, "ternary operator"))
  135.17 +var b4 = b;
  135.18 +print(inspect(d ? b4 : x.c, "ternary operator"))
  135.19  print(inspect(x.c ? a : c, "ternary operator"))
  135.20  print(inspect(c ? d : a, "ternary operator"))
  135.21 -print(inspect(c ? +a : b, "ternary operator"))
  135.22 +var b5 = b;
  135.23 +print(inspect(c ? +a : b5, "ternary operator"))
  135.24  
  135.25  // Testing format methods
  135.26  print(inspect(b.toFixed(2), "global double toFixed()"))
  135.27 @@ -53,11 +58,14 @@
  135.28  print(inspect(trees[1], "member object"))
  135.29  trees[1] = undefined;
  135.30  print(inspect(trees[1], "member undefined"))
  135.31 -print(inspect(1 in trees ? b : a, "conditional on array member"))
  135.32 +var b6=b;
  135.33 +print(inspect(1 in trees ? b6 : a, "conditional on array member"))
  135.34  delete trees[2]
  135.35 -print(inspect(2 in trees ? b : a, "conditional on array member"))
  135.36 +var b7=b;
  135.37 +print(inspect(2 in trees ? b7 : a, "conditional on array member"))
  135.38  print(inspect(3 in trees ? trees[2]="bay" : a, "conditional on array member"))
  135.39 -print(inspect("oak" in trees ? b : a, "conditional on array member"))
  135.40 +var b8=b;
  135.41 +print(inspect("oak" in trees ? b8 : a, "conditional on array member"))
  135.42  
  135.43  // Testing nested functions and return value
  135.44  function f1() {
   136.1 --- a/test/script/basic/splitter.js	Thu Sep 11 15:34:13 2014 -0700
   136.2 +++ b/test/script/basic/splitter.js	Tue Sep 16 13:59:37 2014 -0700
   136.3 @@ -30,7 +30,5 @@
   136.4   * @fork
   136.5   */
   136.6  
   136.7 -load(__DIR__ + 'prototype.js');
   136.8 -load(__DIR__ + 'yui.js');
   136.9  load(__DIR__ + 'NASHORN-689.js');
  136.10  load(__DIR__ + 'NASHORN-58.js');
   137.1 --- a/test/script/basic/splitter.js.EXPECTED	Thu Sep 11 15:34:13 2014 -0700
   137.2 +++ b/test/script/basic/splitter.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   137.3 @@ -1,6 +1,3 @@
   137.4 -parsed and compiled ok prototype.js
   137.5 -parsed and compiled ok yui-min.js
   137.6 -parsed and compiled ok yui.js
   137.7  a=10
   137.8  a=9
   137.9  a=8
   138.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   138.2 +++ b/test/script/basic/splitter_prototype.js	Tue Sep 16 13:59:37 2014 -0700
   138.3 @@ -0,0 +1,33 @@
   138.4 +/*
   138.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   138.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   138.7 + *
   138.8 + * This code is free software; you can redistribute it and/or modify it
   138.9 + * under the terms of the GNU General Public License version 2 only, as
  138.10 + * published by the Free Software Foundation.
  138.11 + *
  138.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  138.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  138.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  138.15 + * version 2 for more details (a copy is included in the LICENSE file that
  138.16 + * accompanied this code).
  138.17 + *
  138.18 + * You should have received a copy of the GNU General Public License version
  138.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  138.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  138.21 + *
  138.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  138.23 + * or visit www.oracle.com if you need additional information or have any
  138.24 + * questions.
  138.25 + */
  138.26 +
  138.27 +/**
  138.28 + * Test various scripts with low splitter threshold
  138.29 + *
  138.30 + * @test
  138.31 + * @option -Dnashorn.compiler.splitter.threshold=200
  138.32 + * @runif external.prototype
  138.33 + * @fork
  138.34 + */
  138.35 +
  138.36 +load(__DIR__ + 'prototype.js');
   139.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   139.2 +++ b/test/script/basic/splitter_prototype.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   139.3 @@ -0,0 +1,1 @@
   139.4 +parsed and compiled ok prototype.js
   140.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   140.2 +++ b/test/script/basic/splitter_yui.js	Tue Sep 16 13:59:37 2014 -0700
   140.3 @@ -0,0 +1,33 @@
   140.4 +/*
   140.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   140.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   140.7 + *
   140.8 + * This code is free software; you can redistribute it and/or modify it
   140.9 + * under the terms of the GNU General Public License version 2 only, as
  140.10 + * published by the Free Software Foundation.
  140.11 + *
  140.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
  140.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  140.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  140.15 + * version 2 for more details (a copy is included in the LICENSE file that
  140.16 + * accompanied this code).
  140.17 + *
  140.18 + * You should have received a copy of the GNU General Public License version
  140.19 + * 2 along with this work; if not, write to the Free Software Foundation,
  140.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  140.21 + *
  140.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  140.23 + * or visit www.oracle.com if you need additional information or have any
  140.24 + * questions.
  140.25 + */
  140.26 +
  140.27 +/**
  140.28 + * Test various scripts with low splitter threshold
  140.29 + *
  140.30 + * @test
  140.31 + * @option -Dnashorn.compiler.splitter.threshold=200
  140.32 + * @runif external.yui
  140.33 + * @fork
  140.34 + */
  140.35 +
  140.36 +load(__DIR__ + 'yui.js');
   141.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   141.2 +++ b/test/script/basic/splitter_yui.js.EXPECTED	Tue Sep 16 13:59:37 2014 -0700
   141.3 @@ -0,0 +1,2 @@
   141.4 +parsed and compiled ok yui-min.js
   141.5 +parsed and compiled ok yui.js
   142.1 --- a/test/script/trusted/JDK-8006529.js	Thu Sep 11 15:34:13 2014 -0700
   142.2 +++ b/test/script/trusted/JDK-8006529.js	Tue Sep 16 13:59:37 2014 -0700
   142.3 @@ -120,7 +120,7 @@
   142.4  
   142.5  var sourceForMethod = Source.class.getMethod("sourceFor", java.lang.String.class, java.lang.String.class)
   142.6  var ParserConstructor = Parser.class.getConstructor(ScriptEnvironment.class, Source.class, ErrorManager.class)
   142.7 -var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, boolean.class);
   142.8 +var CompilerConstructor = Compiler.class.getConstructor(Context.class, ScriptEnvironment.class, CodeInstaller.class, Source.class, ErrorManager.class, boolean.class);
   142.9  
  142.10  // compile(script) -- compiles a script specified as a string with its
  142.11  // source code, returns a jdk.nashorn.internal.ir.FunctionNode object
  142.12 @@ -134,7 +134,7 @@
  142.13      var parser   = ParserConstructor.newInstance(env, source, ThrowErrorManager.class.newInstance());
  142.14      var func     = parseMethod.invoke(parser);
  142.15  
  142.16 -    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, false);
  142.17 +    var compiler = CompilerConstructor.newInstance(ctxt, env, null, source, null, false);
  142.18  
  142.19      return compileMethod.invoke(compiler, func, phases);
  142.20  };
   143.1 --- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Thu Sep 11 15:34:13 2014 -0700
   143.2 +++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java	Tue Sep 16 13:59:37 2014 -0700
   143.3 @@ -407,6 +407,75 @@
   143.4          Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
   143.5      }
   143.6  
   143.7 +
   143.8 +    /**
   143.9 +     * Test multi-threaded access to prototype user accessor properties for shared script classes with multiple globals.
  143.10 +     */
  143.11 +    @Test
  143.12 +    public static void multiThreadedAccessorTest() throws ScriptException, InterruptedException {
  143.13 +        final ScriptEngineManager m = new ScriptEngineManager();
  143.14 +        final ScriptEngine e = m.getEngineByName("nashorn");
  143.15 +        final Bindings b = e.createBindings();
  143.16 +        final ScriptContext origContext = e.getContext();
  143.17 +        final ScriptContext newCtxt = new SimpleScriptContext();
  143.18 +        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
  143.19 +
  143.20 +        e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'original context' })", origContext);
  143.21 +        e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'new context', configurable: true })", newCtxt);
  143.22 +        final String sharedScript = "({}).foo";
  143.23 +
  143.24 +        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
  143.25 +        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
  143.26 +        t1.start();
  143.27 +        t2.start();
  143.28 +        t1.join();
  143.29 +        t2.join();
  143.30 +
  143.31 +        final Object obj3 = e.eval("delete Object.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
  143.32 +        assertEquals(obj3, "newer context");
  143.33 +        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
  143.34 +        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
  143.35 +
  143.36 +        t3.start();
  143.37 +        t4.start();
  143.38 +        t3.join();
  143.39 +        t4.join();
  143.40 +    }
  143.41 +
  143.42 +    /**
  143.43 +     * Test multi-threaded access to primitive prototype user accessor properties for shared script classes with multiple globals.
  143.44 +     */
  143.45 +    @Test
  143.46 +    public static void multiThreadedPrimitiveAccessorTest() throws ScriptException, InterruptedException {
  143.47 +        final ScriptEngineManager m = new ScriptEngineManager();
  143.48 +        final ScriptEngine e = m.getEngineByName("nashorn");
  143.49 +        final Bindings b = e.createBindings();
  143.50 +        final ScriptContext origContext = e.getContext();
  143.51 +        final ScriptContext newCtxt = new SimpleScriptContext();
  143.52 +        newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
  143.53 +
  143.54 +        e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'original context' })", origContext);
  143.55 +        e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'new context' })", newCtxt);
  143.56 +        final String sharedScript = "''.foo";
  143.57 +
  143.58 +        final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
  143.59 +        final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
  143.60 +        t1.start();
  143.61 +        t2.start();
  143.62 +        t1.join();
  143.63 +        t2.join();
  143.64 +
  143.65 +        final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
  143.66 +        assertEquals(obj3, "newer context");
  143.67 +        final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
  143.68 +        final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
  143.69 +
  143.70 +        t3.start();
  143.71 +        t4.start();
  143.72 +        t3.join();
  143.73 +        t4.join();
  143.74 +    }
  143.75 +
  143.76      /**
  143.77       * Test multi-threaded scope function invocation for shared script classes with multiple globals.
  143.78       */
   144.1 --- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Thu Sep 11 15:34:13 2014 -0700
   144.2 +++ b/test/src/jdk/nashorn/internal/codegen/CompilerTest.java	Tue Sep 16 13:59:37 2014 -0700
   144.3 @@ -98,11 +98,16 @@
   144.4              compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() {
   144.5                  @Override
   144.6                  public boolean exclude(final File file, final String content) {
   144.7 -                    return content.indexOf("@negative") != -1;
   144.8 +                    return content != null && content.contains("@negative");
   144.9                  }
  144.10              });
  144.11          }
  144.12 -        compileTestSet(new File(TEST_BASIC_DIR), null);
  144.13 +        compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() {
  144.14 +            @Override
  144.15 +            public boolean exclude(final File file, final String content) {
  144.16 +                return file.getName().equals("es6");
  144.17 +            }
  144.18 +        });
  144.19          compileTestSet(new File(TEST_NODE_DIR, "node"), null);
  144.20          compileTestSet(new File(TEST_NODE_DIR, "src"), null);
  144.21      }
  144.22 @@ -136,6 +141,9 @@
  144.23      private int skipped;
  144.24  
  144.25      private void compileJSDirectory(final File dir, final TestFilter filter) {
  144.26 +        if (filter != null && filter.exclude(dir, null)) {
  144.27 +            return;
  144.28 +        }
  144.29          for (final File f : dir.listFiles()) {
  144.30              if (f.isDirectory()) {
  144.31                  compileJSDirectory(f, filter);
   145.1 --- a/test/src/jdk/nashorn/internal/parser/ParserTest.java	Thu Sep 11 15:34:13 2014 -0700
   145.2 +++ b/test/src/jdk/nashorn/internal/parser/ParserTest.java	Tue Sep 16 13:59:37 2014 -0700
   145.3 @@ -82,11 +82,16 @@
   145.4              parseTestSet(TEST262_SUITE_DIR, new TestFilter() {
   145.5                  @Override
   145.6                  public boolean exclude(final File file, final String content) {
   145.7 -                    return content.indexOf("@negative") != -1;
   145.8 +                    return content != null && content.contains("@negative");
   145.9                  }
  145.10              });
  145.11          }
  145.12 -        parseTestSet(TEST_BASIC_DIR, null);
  145.13 +        parseTestSet(TEST_BASIC_DIR,  new TestFilter() {
  145.14 +            @Override
  145.15 +            public boolean exclude(final File file, final String content) {
  145.16 +                return file.getName().equals("es6");
  145.17 +            }
  145.18 +        });
  145.19      }
  145.20  
  145.21      private void parseTestSet(final String testSet, final TestFilter filter) {
  145.22 @@ -120,6 +125,9 @@
  145.23      private int skipped;
  145.24  
  145.25      private void parseJSDirectory(final File dir, final TestFilter filter) {
  145.26 +        if (filter != null && filter.exclude(dir, null)) {
  145.27 +            return;
  145.28 +        }
  145.29          for (final File f : dir.listFiles()) {
  145.30              if (f.isDirectory()) {
  145.31                  parseJSDirectory(f, filter);
   146.1 --- a/test/src/jdk/nashorn/internal/test/framework/TestFinder.java	Thu Sep 11 15:34:13 2014 -0700
   146.2 +++ b/test/src/jdk/nashorn/internal/test/framework/TestFinder.java	Tue Sep 16 13:59:37 2014 -0700
   146.3 @@ -261,14 +261,17 @@
   146.4                      isTest = false;
   146.5                      isNotTest = true;
   146.6                      break;
   146.7 -                case "@runif":
   146.8 -                    if (System.getProperty(scanner.next()) != null) {
   146.9 +                case "@runif": {
  146.10 +                    final String prop = scanner.next();
  146.11 +                    if (System.getProperty(prop) != null) {
  146.12                          shouldRun = true;
  146.13                      } else {
  146.14 +                        factory.log("WARNING: (" + prop + ") skipping " + testFile);
  146.15                          isTest = false;
  146.16                          isNotTest = true;
  146.17                      }
  146.18                      break;
  146.19 +                }
  146.20                  case "@run":
  146.21                      shouldRun = true;
  146.22                      break;

mercurial