changeset 1982:b082c0d76be4 icedtea-3.3.0pre01

Merge jdk8u112-b16
author andrew
date Thu, 12 Jan 2017 06:59:38 +0000
parents 40834ff46bfc (current diff) d1f2cab06d35 (diff)
children 08947f14df4e
files .hgtags
diffstat 46 files changed, 1510 insertions(+), 140 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Nov 08 05:26:18 2016 +0000
+++ b/.hgtags	Thu Jan 12 06:59:38 2017 +0000
@@ -646,3 +646,19 @@
 76bf7299d622029f1a579667611deeccc405e81a jdk8u111-b12
 7ed1a5c5e45a1d576cc76dc96b3f0699bfe0a642 jdk8u111-b13
 0fb33c8b64d1d97095c668b81ad7a11e4c06e89f icedtea-3.2.0
+97770cfdb942dce0a7c461175bce4fddac5ad339 jdk8u111-b14
+1bf96637e4bbbc31f7c560c16d62ce2ed9020e03 jdk8u112-b00
+be4ef6af7d3d67380d9df3348f75324ff6d8c971 jdk8u112-b01
+29f97057e4e10194263902a6406f65d789944c5e jdk8u112-b02
+16bc4cb8f50b251aa648c6aae5ca063c0893b44b jdk8u112-b03
+bc02dfd3deccefbcfcb71969ff56ae58ef80c686 jdk8u112-b04
+2432a2e9de108e12c3be6e52f37d7702a9a87d49 jdk8u112-b06
+d591fb5e1d37d1186290521cd31d5795d74cfa5b jdk8u112-b07
+910a02770fc92745517e63018345be36dc8d7d0c jdk8u112-b08
+51e59a0544a0be24ed72b43fc9483ffded8cdad2 jdk8u112-b09
+319eba518b6ec84fe3ff4811e66319cdb7e6f33e jdk8u112-b10
+081aa69ac6faaa8ebb9a21d9a0c617d34e03b447 jdk8u112-b11
+21b35ff81519584f5af010e852c14b6db88c1ebd jdk8u112-b12
+001041e75430b132f0e0ba96b98f3891435c4440 jdk8u112-b13
+b0aa9a71f5fbcb0d58fa009fd9bd3ea0897b315e jdk8u112-b14
+adc75eca17418a42357776339b390533a94541d6 jdk8u112-b15
--- a/LICENSE	Tue Nov 08 05:26:18 2016 +0000
+++ b/LICENSE	Thu Jan 12 06:59:38 2017 +0000
@@ -3,7 +3,7 @@
 Version 2, June 1991
 
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
 Everyone is permitted to copy and distribute verbatim copies of this license
 document, but changing it is not allowed.
@@ -287,8 +287,8 @@
     more details.
 
     You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc., 59
-    Temple Place, Suite 330, Boston, MA 02111-1307 USA
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
 Also add information on how to contact you by electronic and paper mail.
 
--- a/make/build.xml	Tue Nov 08 05:26:18 2016 +0000
+++ b/make/build.xml	Thu Jan 12 06:59:38 2017 +0000
@@ -83,6 +83,12 @@
     <condition property="jfr.options" value="${run.test.jvmargs.jfr}" else="">
       <istrue value="${jfr}"/>
     </condition>
+
+    <condition property="test-sys-prop-no-security.os.not.windows">
+      <not>
+        <os family="windows"/>
+      </not>
+    </condition>
   </target>
 
   <!-- check minimum ant version required to be 1.8.4 -->
@@ -419,6 +425,10 @@
     permission java.io.FilePermission "${basedir}/test/script/external/showdown/-", "read";
 };
 
+grant codeBase "file:/${basedir}/test/script/basic/JDK-8158467.js" {
+    permission java.lang.RuntimePermission "nashorn.setConfig";
+};
+
     </echo>
 
     <replace file="${build.dir}/nashorn.policy"><replacetoken>\</replacetoken><replacevalue>/</replacevalue></replace>    <!--hack for Windows - to make URLs with normal path separators -->
--- a/samples/exec.js	Tue Nov 08 05:26:18 2016 +0000
+++ b/samples/exec.js	Thu Jan 12 06:59:38 2017 +0000
@@ -39,9 +39,10 @@
 $EXEC("cat", "Hello, world!")
 
 // Additional arguments can be passed after the stdin argument, as an array of
-// strings, or a sequence of varargs:
-$EXEC("ls", "" /* no stdin */, "-l", "-a")
-$EXEC("ls", "" /* no stdin */, ["-l", "-a"])
+// strings, or a sequence of varargs (if there is no stdin, null or undefined
+// can be passed):
+$EXEC("ls", undefined, "-l", "-a")
+$EXEC("ls", undefined, ["-l", "-a"])
 
 // Output of running external commands is returned from $EXEC:
 print($EXEC("ls"))
--- a/src/jdk/nashorn/api/scripting/NashornException.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/api/scripting/NashornException.java	Thu Jan 12 06:59:38 2017 +0000
@@ -175,10 +175,8 @@
                 String methodName = st.getMethodName();
                 if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) {
                     methodName = "<program>";
-                }
-
-                if (methodName.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName())) {
-                    methodName = "<anonymous>";
+                } else {
+                    methodName = stripMethodName(methodName);
                 }
 
                 filtered.add(new StackTraceElement(className, methodName,
@@ -188,6 +186,22 @@
         return filtered.toArray(new StackTraceElement[filtered.size()]);
     }
 
+    private static String stripMethodName(final String methodName) {
+        String name = methodName;
+
+        final int nestedSeparator = name.lastIndexOf(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName());
+        if (nestedSeparator >= 0) {
+            name = name.substring(nestedSeparator + 1);
+        }
+
+        final int idSeparator = name.indexOf(CompilerConstants.ID_FUNCTION_SEPARATOR.symbolName());
+        if (idSeparator >= 0) {
+            name = name.substring(0, idSeparator);
+        }
+
+        return name.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName()) ? "<anonymous>" : name;
+    }
+
     /**
      * Return a formatted script stack trace string with frames information separated by '\n'
      *
--- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Thu Jan 12 06:59:38 2017 +0000
@@ -319,6 +319,9 @@
         // Create new global instance mirror and associate with the Bindings.
         final ScriptObjectMirror mirror = createGlobalMirror();
         bindings.put(NASHORN_GLOBAL, mirror);
+        // Since we created this global explicitly for the non-default script context we set the
+        // current script context in global permanently so that invokes work as expected. See JDK-8150219
+        mirror.getHomeGlobal().setInitScriptContext(ctxt);
         return mirror.getHomeGlobal();
     }
 
--- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java	Thu Jan 12 06:59:38 2017 +0000
@@ -78,6 +78,12 @@
     /** function prefix for anonymous functions */
     ANON_FUNCTION_PREFIX("L:"),
 
+    /** separator for method names of nested functions */
+    NESTED_FUNCTION_SEPARATOR("#"),
+
+    /** separator for making method names unique by appending numeric ids */
+    ID_FUNCTION_SEPARATOR("-"),
+
     /** method name for Java method that is the program entry point */
     PROGRAM(":program"),
 
--- a/src/jdk/nashorn/internal/codegen/Namespace.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/codegen/Namespace.java	Thu Jan 12 06:59:38 2017 +0000
@@ -68,7 +68,7 @@
     }
 
     /**
-     * Create a uniqueName name in the namespace in the form base$n where n varies.
+     * Create a uniqueName name in the namespace in the form base-n where n varies.
      * Also truncates very long names that would otherwise break ASM.
      *
      * @param base Base of name.  Base will be returned if uniqueName.
@@ -83,7 +83,7 @@
             if (counter != null) {
                 final int count = counter + 1;
                 namespaceDirectory.put(truncatedBase, count);
-                return truncatedBase + '-' + count;
+                return truncatedBase + CompilerConstants.ID_FUNCTION_SEPARATOR.symbolName() + count;
             }
         }
 
--- a/src/jdk/nashorn/internal/objects/Global.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/objects/Global.java	Thu Jan 12 06:59:38 2017 +0000
@@ -928,6 +928,8 @@
     private ThreadLocal<ScriptContext> scontext;
     // current ScriptEngine associated - can be null.
     private ScriptEngine engine;
+    // initial ScriptContext - usually null and only used for special case
+    private volatile ScriptContext initscontext;
 
     // ES6 global lexical scope.
     private final LexicalScope lexicalScope;
@@ -953,9 +955,22 @@
         return scontext.get();
     }
 
+    /**
+     * Set the initial script context
+     * @param ctxt initial script context
+     */
+    public void setInitScriptContext(final ScriptContext ctxt) {
+        this.initscontext = ctxt;
+    }
+
     private ScriptContext currentContext() {
         final ScriptContext sc = scontext != null? scontext.get() : null;
-        return (sc != null)? sc : (engine != null? engine.getContext() : null);
+        if (sc != null) {
+            return sc;
+        } else if (initscontext != null) {
+            return initscontext;
+        }
+        return engine != null? engine.getContext() : null;
     }
 
     @Override
--- a/src/jdk/nashorn/internal/objects/NativeArray.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java	Thu Jan 12 06:59:38 2017 +0000
@@ -247,7 +247,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicInvoker("dyn:call", double.class,
-                            ScriptFunction.class, Object.class, Object.class, Object.class);
+                            Object.class, Object.class, Object.class, Object.class);
                     }
                 });
     }
@@ -1219,23 +1219,23 @@
         return copy;
     }
 
-    private static ScriptFunction compareFunction(final Object comparefn) {
+    private static Object compareFunction(final Object comparefn) {
         if (comparefn == ScriptRuntime.UNDEFINED) {
             return null;
         }
 
-        if (! (comparefn instanceof ScriptFunction)) {
+        if (!Bootstrap.isCallable(comparefn)) {
             throw typeError("not.a.function", ScriptRuntime.safeToString(comparefn));
         }
 
-        return (ScriptFunction)comparefn;
+        return comparefn;
     }
 
     private static Object[] sort(final Object[] array, final Object comparefn) {
-        final ScriptFunction cmp = compareFunction(comparefn);
+        final Object cmp = compareFunction(comparefn);
 
         final List<Object> list = Arrays.asList(array);
-        final Object cmpThis = cmp == null || cmp.isStrict() ? ScriptRuntime.UNDEFINED : Global.instance();
+        final Object cmpThis = cmp == null || Bootstrap.isStrictCallable(cmp) ? ScriptRuntime.UNDEFINED : Global.instance();
 
         try {
             Collections.sort(list, new Comparator<Object>() {
--- a/src/jdk/nashorn/internal/objects/NativeJSON.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/objects/NativeJSON.java	Thu Jan 12 06:59:38 2017 +0000
@@ -35,7 +35,10 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.Callable;
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.internal.objects.annotations.Attribute;
 import jdk.nashorn.internal.objects.annotations.Function;
 import jdk.nashorn.internal.objects.annotations.ScriptClass;
@@ -44,7 +47,6 @@
 import jdk.nashorn.internal.runtime.JSONFunctions;
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -68,6 +70,18 @@
                 });
     }
 
+    private static final Object JSOBJECT_INVOKER = new Object();
+
+    private static MethodHandle getJSOBJECT_INVOKER() {
+        return Global.instance().getDynamicInvoker(JSOBJECT_INVOKER,
+                new Callable<MethodHandle>() {
+                    @Override
+                    public MethodHandle call() {
+                        return Bootstrap.createDynamicInvoker("dyn:call",
+                            Object.class, Object.class, Object.class);
+                    }
+                });
+    }
 
     private static final Object REPLACER_INVOKER = new Object();
 
@@ -77,7 +91,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
-                            ScriptFunction.class, ScriptObject.class, Object.class, Object.class);
+                            Object.class, Object.class, Object.class, Object.class);
                     }
                 });
     }
@@ -127,9 +141,10 @@
         final StringifyState state = new StringifyState();
 
         // If there is a replacer, it must be a function or an array.
-        if (replacer instanceof ScriptFunction) {
-            state.replacerFunction = (ScriptFunction) replacer;
+        if (Bootstrap.isCallable(replacer)) {
+            state.replacerFunction = replacer;
         } else if (isArray(replacer) ||
+                isJSObjectArray(replacer) ||
                 replacer instanceof Iterable ||
                 (replacer != null && replacer.getClass().isArray())) {
 
@@ -201,18 +216,19 @@
     // stringify helpers.
 
     private static class StringifyState {
-        final Map<ScriptObject, ScriptObject> stack = new IdentityHashMap<>();
+        final Map<Object, Object> stack = new IdentityHashMap<>();
 
         StringBuilder  indent = new StringBuilder();
         String         gap = "";
         List<String>   propertyList = null;
-        ScriptFunction replacerFunction = null;
+        Object         replacerFunction = null;
     }
 
     // Spec: The abstract operation Str(key, holder).
-    private static Object str(final Object key, final ScriptObject holder, final StringifyState state) {
-        Object value = holder.get(key);
+    private static Object str(final Object key, final Object holder, final StringifyState state) {
+        assert holder instanceof ScriptObject || holder instanceof JSObject;
 
+        Object value = getProperty(holder, key);
         try {
             if (value instanceof ScriptObject) {
                 final InvokeByName toJSONInvoker = getTO_JSON();
@@ -221,6 +237,12 @@
                 if (Bootstrap.isCallable(toJSON)) {
                     value = toJSONInvoker.getInvoker().invokeExact(toJSON, svalue, key);
                 }
+            } else if (value instanceof JSObject) {
+                final JSObject jsObj = (JSObject)value;
+                final Object toJSON = jsObj.getMember("toJSON");
+                if (Bootstrap.isCallable(toJSON)) {
+                    value = getJSOBJECT_INVOKER().invokeExact(toJSON, value);
+                }
             }
 
             if (state.replacerFunction != null) {
@@ -262,10 +284,10 @@
 
         final JSType type = JSType.of(value);
         if (type == JSType.OBJECT) {
-            if (isArray(value)) {
-                return JA((ScriptObject)value, state);
-            } else if (value instanceof ScriptObject) {
-                return JO((ScriptObject)value, state);
+            if (isArray(value) || isJSObjectArray(value)) {
+                return JA(value, state);
+            } else if (value instanceof ScriptObject || value instanceof JSObject) {
+                return JO(value, state);
             }
         }
 
@@ -273,7 +295,9 @@
     }
 
     // Spec: The abstract operation JO(value) serializes an object.
-    private static String JO(final ScriptObject value, final StringifyState state) {
+    private static String JO(final Object value, final StringifyState state) {
+        assert value instanceof ScriptObject || value instanceof JSObject;
+
         if (state.stack.containsKey(value)) {
             throw typeError("JSON.stringify.cyclic");
         }
@@ -284,7 +308,8 @@
 
         final StringBuilder finalStr = new StringBuilder();
         final List<Object>  partial  = new ArrayList<>();
-        final List<String>  k        = state.propertyList == null ? Arrays.asList(value.getOwnKeys(false)) : state.propertyList;
+        final List<String>  k        = state.propertyList == null ?
+                Arrays.asList(getOwnKeys(value)) : state.propertyList;
 
         for (final Object p : k) {
             final Object strP = str(p, value, state);
@@ -349,7 +374,9 @@
     }
 
     // Spec: The abstract operation JA(value) serializes an array.
-    private static Object JA(final ScriptObject value, final StringifyState state) {
+    private static Object JA(final Object value, final StringifyState state) {
+        assert value instanceof ScriptObject || value instanceof JSObject;
+
         if (state.stack.containsKey(value)) {
             throw typeError("JSON.stringify.cyclic");
         }
@@ -359,7 +386,7 @@
         state.indent.append(state.gap);
         final List<Object> partial = new ArrayList<>();
 
-        final int length = JSType.toInteger(value.getLength());
+        final int length = JSType.toInteger(getLength(value));
         int index = 0;
 
         while (index < length) {
@@ -413,4 +440,48 @@
 
         return finalStr.toString();
     }
+
+    private static String[] getOwnKeys(final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).getOwnKeys(false);
+        } else if (obj instanceof ScriptObjectMirror) {
+            return ((ScriptObjectMirror)obj).getOwnKeys(false);
+        } else if (obj instanceof JSObject) {
+            // No notion of "own keys" or "proto" for general JSObject! We just
+            // return all keys of the object. This will be useful for POJOs
+            // implementing JSObject interface.
+            return ((JSObject)obj).keySet().toArray(new String[0]);
+        } else {
+            throw new AssertionError("should not reach here");
+        }
+    }
+
+    private static Object getLength(final Object obj) {
+        if (obj instanceof ScriptObject) {
+            return ((ScriptObject)obj).getLength();
+        } else if (obj instanceof JSObject) {
+            return ((JSObject)obj).getMember("length");
+        } else {
+            throw new AssertionError("should not reach here");
+        }
+    }
+
+    private static boolean isJSObjectArray(final Object obj) {
+        return (obj instanceof JSObject) && ((JSObject)obj).isArray();
+    }
+
+    private static Object getProperty(final Object holder, final Object key) {
+        if (holder instanceof ScriptObject) {
+            return ((ScriptObject)holder).get(key);
+        } else if (holder instanceof JSObject) {
+            JSObject jsObj = (JSObject)holder;
+            if (key instanceof Integer) {
+                return jsObj.getSlot((Integer)key);
+            } else {
+                return jsObj.getMember(Objects.toString(key));
+            }
+        } else {
+            return new AssertionError("should not reach here");
+        }
+    }
 }
--- a/src/jdk/nashorn/internal/objects/NativeRegExp.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java	Thu Jan 12 06:59:38 2017 +0000
@@ -46,7 +46,6 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.ParserException;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
@@ -656,7 +655,7 @@
      * @param replacement Replacement string.
      * @return String with substitutions.
      */
-    String replace(final String string, final String replacement, final ScriptFunction function) throws Throwable {
+    String replace(final String string, final String replacement, final Object function) throws Throwable {
         final RegExpMatcher matcher = regexp.match(string);
 
         if (matcher == null) {
@@ -672,7 +671,7 @@
             sb.append(string, 0, matcher.start());
 
             if (function != null) {
-                final Object self = function.isStrict() ? UNDEFINED : Global.instance();
+                final Object self = Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
                 sb.append(callReplaceValue(getReplaceValueInvoker(), function, self, matcher, string));
             } else {
                 appendReplacement(matcher, string, replacement, sb);
@@ -692,7 +691,7 @@
         final StringBuilder sb = new StringBuilder();
 
         final MethodHandle invoker = function == null ? null : getReplaceValueInvoker();
-        final Object self = function == null || function.isStrict() ? UNDEFINED : Global.instance();
+        final Object self = function == null || Bootstrap.isStrictCallable(function) ? UNDEFINED : Global.instance();
 
         do {
             sb.append(string, thisIndex, matcher.start());
@@ -808,12 +807,13 @@
                 new Callable<MethodHandle>() {
                     @Override
                     public MethodHandle call() {
-                        return Bootstrap.createDynamicInvoker("dyn:call", String.class, ScriptFunction.class, Object.class, Object[].class);
+                        return Bootstrap.createDynamicInvoker("dyn:call",
+                            String.class, Object.class, Object.class, Object[].class);
                     }
                 });
     }
 
-    private String callReplaceValue(final MethodHandle invoker, final ScriptFunction function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
+    private String callReplaceValue(final MethodHandle invoker, final Object function, final Object self, final RegExpMatcher matcher, final String string) throws Throwable {
         final Object[] groups = groups(matcher);
         final Object[] args   = Arrays.copyOf(groups, groups.length + 2);
 
--- a/src/jdk/nashorn/internal/objects/NativeString.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/objects/NativeString.java	Thu Jan 12 06:59:38 2017 +0000
@@ -56,14 +56,13 @@
 import jdk.nashorn.internal.runtime.JSType;
 import jdk.nashorn.internal.runtime.OptimisticBuiltins;
 import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptObject;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
 import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
 import jdk.nashorn.internal.runtime.linker.NashornGuards;
 import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
 
-
 /**
  * ECMA 15.5 String Objects.
  */
@@ -749,8 +748,8 @@
             nativeRegExp = NativeRegExp.flatRegExp(JSType.toString(string));
         }
 
-        if (replacement instanceof ScriptFunction) {
-            return nativeRegExp.replace(str, "", (ScriptFunction)replacement);
+        if (Bootstrap.isCallable(replacement)) {
+            return nativeRegExp.replace(str, "", replacement);
         }
 
         return nativeRegExp.replace(str, JSType.toString(replacement), null);
--- a/src/jdk/nashorn/internal/parser/AbstractParser.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/parser/AbstractParser.java	Thu Jan 12 06:59:38 2017 +0000
@@ -200,8 +200,10 @@
      * @return tokenType of next token.
      */
     private TokenType nextToken() {
-        // Capture last token tokenType.
-        last = type;
+        // Capture last token type, but ignore comments (which are irrelevant for the purpose of newline detection).
+        if (type != COMMENT) {
+            last = type;
+        }
         if (type != EOF) {
 
             // Set up next token.
--- a/src/jdk/nashorn/internal/parser/Parser.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/parser/Parser.java	Thu Jan 12 06:59:38 2017 +0000
@@ -459,7 +459,7 @@
 
         final FunctionNode parentFunction = lc.getCurrentFunction();
         if (parentFunction != null && !parentFunction.isProgram()) {
-            sb.append(parentFunction.getName()).append('$');
+            sb.append(parentFunction.getName()).append(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName());
         }
 
         assert ident.getName() != null;
@@ -1135,7 +1135,7 @@
 
     /**
      * ExpressionStatement :
-     *      Expression ; // [lookahead ~( or  function )]
+     *      Expression ; // [lookahead ~({ or  function )]
      *
      * See 12.4
      *
--- a/src/jdk/nashorn/internal/runtime/Context.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/Context.java	Thu Jan 12 06:59:38 2017 +0000
@@ -377,10 +377,12 @@
     final boolean _strict;
 
     /** class loader to resolve classes from script. */
-    private final ClassLoader  appLoader;
+    private final ClassLoader appLoader;
 
-    /** Class loader to load classes from -classpath option, if set. */
-    private final ClassLoader  classPathLoader;
+    /*package-private*/
+    ClassLoader getAppLoader() {
+        return appLoader;
+    }
 
     /** Class loader to load classes compiled from scripts. */
     private final ScriptLoader scriptLoader;
@@ -395,11 +397,12 @@
     private final ClassFilter classFilter;
 
     private static final ClassLoader myLoader = Context.class.getClassLoader();
-    private static final StructureLoader sharedLoader;
+    /** Process-wide singleton structure loader */
+    private static final StructureLoader theStructLoader;
 
     /*package-private*/ @SuppressWarnings("static-method")
-    ClassLoader getSharedLoader() {
-        return sharedLoader;
+    ClassLoader getStructLoader() {
+        return theStructLoader;
     }
 
     private static AccessControlContext createNoPermAccCtxt() {
@@ -417,7 +420,7 @@
     private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT  = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
 
     static {
-        sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
+        theStructLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
             @Override
             public StructureLoader run() {
                 return new StructureLoader(myLoader);
@@ -495,7 +498,6 @@
         this.classFilter = classFilter;
         this.env       = new ScriptEnvironment(options, out, err);
         this._strict   = env._strict;
-        this.appLoader = appLoader;
         if (env._loader_per_compile) {
             this.scriptLoader = null;
             this.uniqueScriptId = null;
@@ -505,17 +507,17 @@
         }
         this.errors    = errors;
 
-        // if user passed -classpath option, make a class loader with that and set it as
-        // thread context class loader so that script can access classes from that path.
+        // if user passed -classpath option, make a URLClassLoader with that and
+        // the app loader as the parent.
         final String classPath = options.getString("classpath");
         if (!env._compile_only && classPath != null && !classPath.isEmpty()) {
             // make sure that caller can create a class loader.
             if (sm != null) {
-                sm.checkPermission(new RuntimePermission("createClassLoader"));
+                sm.checkCreateClassLoader();
             }
-            this.classPathLoader = NashornLoader.createClassLoader(classPath);
+            this.appLoader = NashornLoader.createClassLoader(classPath, appLoader);
         } else {
-            this.classPathLoader = null;
+            this.appLoader = appLoader;
         }
 
         final int cacheSize = env._class_cache_size;
@@ -927,7 +929,7 @@
         if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) {
             throw new ClassNotFoundException(fullName);
         }
-        return (Class<? extends ScriptObject>)Class.forName(fullName, true, sharedLoader);
+        return (Class<? extends ScriptObject>)Class.forName(fullName, true, theStructLoader);
     }
 
     /**
@@ -1044,17 +1046,18 @@
             checkPackageAccess(sm, fullName);
         }
 
-        // try the script -classpath loader, if that is set
-        if (classPathLoader != null) {
-            try {
-                return Class.forName(fullName, true, classPathLoader);
-            } catch (final ClassNotFoundException ignored) {
-                // ignore, continue search
+        // Try finding using the "app" loader.
+        if (appLoader != null) {
+            return Class.forName(fullName, true, appLoader);
+        } else {
+            final Class<?> cl = Class.forName(fullName);
+            // return the Class only if it was loaded by boot loader
+            if (cl.getClassLoader() == null) {
+                return cl;
+            } else {
+                throw new ClassNotFoundException(fullName);
             }
         }
-
-        // Try finding using the "app" loader.
-        return Class.forName(fullName, true, appLoader);
     }
 
     /**
@@ -1085,7 +1088,7 @@
             // No verification when security manager is around as verifier
             // may load further classes - which should be avoided.
             if (System.getSecurityManager() == null) {
-                CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true));
+                CheckClassAdapter.verify(new ClassReader(bytecode), theStructLoader, false, new PrintWriter(System.err, true));
             }
         }
     }
@@ -1201,15 +1204,10 @@
     }
 
     private URL getResourceURL(final String resName) {
-        // try the classPathLoader if we have and then
-        // try the appLoader if non-null.
-        if (classPathLoader != null) {
-            return classPathLoader.getResource(resName);
-        } else if (appLoader != null) {
+        if (appLoader != null) {
             return appLoader.getResource(resName);
         }
-
-        return null;
+        return ClassLoader.getSystemResource(resName);
     }
 
     private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
@@ -1336,7 +1334,7 @@
              new PrivilegedAction<ScriptLoader>() {
                 @Override
                 public ScriptLoader run() {
-                    return new ScriptLoader(appLoader, Context.this);
+                    return new ScriptLoader(Context.this);
                 }
              }, CREATE_LOADER_ACC_CTXT);
     }
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java	Thu Jan 12 06:59:38 2017 +0000
@@ -46,7 +46,7 @@
                     @Override
                     public MethodHandle call() {
                         return Bootstrap.createDynamicInvoker("dyn:call", Object.class,
-                            ScriptFunction.class, ScriptObject.class, String.class, Object.class);
+                             Object.class, Object.class, String.class, Object.class);
                     }
                 });
     }
@@ -90,16 +90,16 @@
 
     // apply 'reviver' function if available
     private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
-        if (reviver instanceof ScriptFunction) {
+        if (Bootstrap.isCallable(reviver)) {
             final ScriptObject root = global.newObject();
             root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
-            return walk(root, "", (ScriptFunction)reviver);
+            return walk(root, "", reviver);
         }
         return unfiltered;
     }
 
     // This is the abstract "Walk" operation from the spec.
-    private static Object walk(final ScriptObject holder, final Object name, final ScriptFunction reviver) {
+    private static Object walk(final ScriptObject holder, final Object name, final Object reviver) {
         final Object val = holder.get(name);
         if (val instanceof ScriptObject) {
             final ScriptObject     valueObj = (ScriptObject)val;
@@ -131,7 +131,7 @@
 
         try {
              // Object.class, ScriptFunction.class, ScriptObject.class, String.class, Object.class);
-             return getREVIVER_INVOKER().invokeExact(reviver, holder, JSType.toString(name), val);
+             return getREVIVER_INVOKER().invokeExact(reviver, (Object)holder, JSType.toString(name), val);
         } catch(Error|RuntimeException t) {
             throw t;
         } catch(final Throwable t) {
--- a/src/jdk/nashorn/internal/runtime/NashornLoader.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/NashornLoader.java	Thu Jan 12 06:59:38 2017 +0000
@@ -35,7 +35,6 @@
 import java.security.PermissionCollection;
 import java.security.Permissions;
 import java.security.SecureClassLoader;
-import jdk.nashorn.tools.Shell;
 
 /**
  * Superclass for Nashorn class loader classes.
@@ -103,10 +102,10 @@
     /**
      * Create a secure URL class loader for the given classpath
      * @param classPath classpath for the loader to search from
+     * @param parent the parent class loader for the new class loader
      * @return the class loader
      */
-    static ClassLoader createClassLoader(final String classPath) {
-        final ClassLoader parent = Shell.class.getClassLoader();
+    static ClassLoader createClassLoader(final String classPath, final ClassLoader parent) {
         final URL[] urls = pathToURLs(classPath);
         return URLClassLoader.newInstance(urls, parent);
     }
--- a/src/jdk/nashorn/internal/runtime/ScriptLoader.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/ScriptLoader.java	Thu Jan 12 06:59:38 2017 +0000
@@ -44,20 +44,45 @@
     /**
      * Constructor.
      */
-    ScriptLoader(final ClassLoader parent, final Context context) {
-        super(parent);
+    ScriptLoader(final Context context) {
+        super(context.getStructLoader());
         this.context = context;
     }
 
     @Override
     protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
         checkPackageAccess(name);
-        if (name.startsWith(NASHORN_PKG_PREFIX)) {
-            return context.getSharedLoader().loadClass(name);
-        }
         return super.loadClass(name, resolve);
     }
 
+
+     @Override
+     protected Class<?> findClass(String name) throws ClassNotFoundException {
+         final ClassLoader appLoader = context.getAppLoader();
+
+         /*
+          * If the appLoader is null, don't bother side-delegating to it!
+          * Bootloader has been already attempted via parent loader
+          * delegation from the "loadClass" method.
+          *
+          * Also, make sure that we don't delegate to the app loader
+          * for nashorn's own classes or nashorn generated classes!
+          */
+         if (appLoader == null || name.startsWith(NASHORN_PKG_PREFIX)) {
+             throw new ClassNotFoundException(name);
+         }
+
+         /*
+          * This split-delegation is used so that caller loader
+          * based resolutions of classes would work. For example,
+          * java.sql.DriverManager uses caller's class loader to
+          * get Driver instances. Without this split-delegation
+          * a script class evaluating DriverManager.getDrivers()
+          * will not get back any JDBC driver!
+          */
+         return appLoader.loadClass(name);
+     }
+
     // package-private and private stuff below this point
 
     /**
--- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java	Thu Jan 12 06:59:38 2017 +0000
@@ -132,9 +132,9 @@
      * Nashorn extension: exec a string in a separate process.
      *
      * @param self   self reference
-     * @param args   string to execute, input and additional arguments, to be appended to {@code string}. Additional arguments can be passed as
-     *               either one JavaScript array, whose elements will be converted to strings; or as a sequence of
-     *               varargs, each of which will be converted to a string.
+     * @param args   string to execute, input and additional arguments, to be appended to {@code string}. Additional
+     *               arguments can be passed as either one JavaScript array, whose elements will be converted to
+     *               strings; or as a sequence of varargs, each of which will be converted to a string.
      *
      * @return output string from the request
      *
@@ -167,7 +167,10 @@
             // If a working directory is present, use it.
             final Object pwd = envProperties.get(PWD_NAME);
             if (pwd != UNDEFINED) {
-                processBuilder.directory(new File(JSType.toString(pwd)));
+                final File pwdFile = new File(JSType.toString(pwd));
+                if (pwdFile.exists()) {
+                    processBuilder.directory(pwdFile);
+                }
             }
 
             // Set up ENV variables.
@@ -219,13 +222,13 @@
         errThread.start();
 
         // If input is present, pass on to process.
-        try (OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream())) {
-            if (input != UNDEFINED) {
+        if (!JSType.nullOrUndefined(input)) {
+            try (OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream())) {
                 final String in = JSType.toString(input);
                 outputStream.write(in, 0, in.length());
+            } catch (final IOException ex) {
+                // Process was not expecting input.  May be normal state of affairs.
             }
-        } catch (final IOException ex) {
-            // Process was not expecting input.  May be normal state of affairs.
         }
 
         // Wait for the process to complete.
@@ -275,9 +278,8 @@
      * @param str a {@link String} to tokenize.
      * @return a {@link List} of {@link String}s representing the tokens that
      * constitute the string.
-     * @throws IOException in case {@link StreamTokenizer#nextToken()} raises it.
      */
-    public static List<String> tokenizeString(final String str) throws IOException {
+    public static List<String> tokenizeString(final String str) {
         final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(str));
         tokenizer.resetSyntax();
         tokenizer.wordChars(0, 255);
@@ -287,7 +289,7 @@
         tokenizer.quoteChar('\'');
         final List<String> tokenList = new ArrayList<>();
         final StringBuilder toAppend = new StringBuilder();
-        while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
+        while (nextToken(tokenizer) != StreamTokenizer.TT_EOF) {
             final String s = tokenizer.sval;
             // The tokenizer understands about honoring quoted strings and recognizes
             // them as one token that possibly contains multiple space-separated words.
@@ -306,4 +308,12 @@
         }
         return tokenList;
     }
+
+    private static int nextToken(final StreamTokenizer tokenizer) {
+        try {
+            return tokenizer.nextToken();
+        } catch (final IOException ioe) {
+            return StreamTokenizer.TT_EOF;
+        }
+    }
 }
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Thu Jan 12 06:59:38 2017 +0000
@@ -159,7 +159,9 @@
             return ((JSObject)callable).isStrictFunction();
         } else if (callable instanceof BoundCallable) {
             return isStrictCallable(((BoundCallable)callable).getCallable());
-        } else if (BeansLinker.isDynamicMethod(callable) || callable instanceof StaticClass) {
+        } else if (BeansLinker.isDynamicMethod(callable) ||
+                callable instanceof StaticClass ||
+                isFunctionalInterfaceObject(callable)) {
             return false;
         }
         throw notFunction(callable);
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
 import java.util.Map;
 import javax.script.Bindings;
 import jdk.internal.dynalink.CallSiteDescriptor;
@@ -140,12 +141,15 @@
     }
 
     private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) {
-        // TODO: if call site is already a vararg, don't do asCollector
         MethodHandle mh = JSOBJECT_CALL;
         if (NashornCallSiteDescriptor.isApplyToCall(desc)) {
             mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, JSOBJECT_CALL);
         }
-        return new GuardedInvocation(MH.asCollector(mh, Object[].class, desc.getMethodType().parameterCount() - 2), IS_JSOBJECT_GUARD);
+        final MethodType type = desc.getMethodType();
+        mh = type.parameterType(type.parameterCount() - 1) == Object[].class ?
+                mh :
+                MH.asCollector(mh, Object[].class, type.parameterCount() - 2);
+        return new GuardedInvocation(mh, IS_JSOBJECT_GUARD);
     }
 
     private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) {
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Thu Jan 12 06:59:38 2017 +0000
@@ -177,7 +177,7 @@
             if (iface.isAnnotationPresent(FunctionalInterface.class)) {
                 // return the first abstract method
                 for (final Method m : iface.getMethods()) {
-                    if (Modifier.isAbstract(m.getModifiers())) {
+                    if (Modifier.isAbstract(m.getModifiers()) && !isOverridableObjectMethod(m)) {
                         return m.getName();
                     }
                 }
@@ -188,6 +188,23 @@
         return findFunctionalInterfaceMethodName(clazz.getSuperclass());
     }
 
+    // is this an overridable java.lang.Object method?
+    private static boolean isOverridableObjectMethod(final Method m) {
+        switch (m.getName()) {
+            case "equals":
+                if (m.getReturnType() == boolean.class) {
+                    final Class<?>[] params = m.getParameterTypes();
+                    return params.length == 1 && params[0] == Object.class;
+                }
+                return false;
+            case "hashCode":
+                return m.getReturnType() == int.class && m.getParameterCount() == 0;
+            case "toString":
+                return m.getReturnType() == String.class && m.getParameterCount() == 0;
+        }
+        return false;
+    }
+
     // Returns @FunctionalInterface annotated interface's single abstract
     // method name. If not found, returns null.
     static String getFunctionalInterfaceMethodName(final Class<?> clazz) {
--- a/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java	Thu Jan 12 06:59:38 2017 +0000
@@ -80,8 +80,17 @@
             this.negLookaheadLevel = negLookaheadLevel;
         }
 
-        boolean isContained(final int group, final int level) {
-            return group == this.negLookaheadGroup && level >= this.negLookaheadLevel;
+        /**
+         * Returns true if this Capture can be referenced from the position specified by the
+         * group and level parameters. This is the case if either the group is not within
+         * a negative lookahead, or the position of the referrer is in the same negative lookahead.
+         *
+         * @param group current negative lookahead group
+         * @param level current negative lokahead level
+         * @return true if this capture group can be referenced from the given position
+         */
+        boolean canBeReferencedFrom(final int group, final int level) {
+            return this.negLookaheadLevel == 0 || (group == this.negLookaheadGroup && level >= this.negLookaheadLevel);
         }
 
     }
@@ -671,8 +680,9 @@
 
                 } else if (decimalValue <= caps.size()) {
                     //  Captures inside a negative lookahead are undefined when referenced from the outside.
-                    if (!caps.get(decimalValue - 1).isContained(negLookaheadGroup, negLookaheadLevel)) {
-                        // Reference to capture in negative lookahead, omit from output buffer.
+                    final Capture capture = caps.get(decimalValue - 1);
+                    if (!capture.canBeReferencedFrom(negLookaheadGroup, negLookaheadLevel)) {
+                        // Outside reference to capture in negative lookahead, omit from output buffer.
                         sb.setLength(sb.length() - 1);
                     } else {
                         // Append backreference to output buffer.
--- a/src/jdk/nashorn/tools/Shell.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/src/jdk/nashorn/tools/Shell.java	Thu Jan 12 06:59:38 2017 +0000
@@ -25,20 +25,6 @@
 
 package jdk.nashorn.tools;
 
-import static jdk.nashorn.internal.runtime.Source.sourceFor;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.List;
-import java.util.Locale;
-import java.util.ResourceBundle;
 import jdk.nashorn.api.scripting.NashornException;
 import jdk.nashorn.internal.codegen.Compiler;
 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
@@ -54,8 +40,30 @@
 import jdk.nashorn.internal.runtime.ScriptEnvironment;
 import jdk.nashorn.internal.runtime.ScriptFunction;
 import jdk.nashorn.internal.runtime.ScriptRuntime;
+import jdk.nashorn.internal.runtime.ScriptingFunctions;
 import jdk.nashorn.internal.runtime.options.Options;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import static jdk.nashorn.internal.runtime.Source.sourceFor;
+
 /**
  * Command line Shell for processing JavaScript files.
  */
@@ -195,7 +203,8 @@
         // parse options
         if (args != null) {
             try {
-                options.process(args);
+                final String[] prepArgs = preprocessArgs(args);
+                options.process(prepArgs);
             } catch (final IllegalArgumentException e) {
                 werr.println(bundle.getString("shell.usage"));
                 options.displayHelp(e);
@@ -226,6 +235,75 @@
     }
 
     /**
+     * Preprocess the command line arguments passed in by the shell. This method checks, for the first non-option
+     * argument, whether the file denoted by it begins with a shebang line. If so, it is assumed that execution in
+     * shebang mode is intended. The consequence of this is that the identified script file will be treated as the
+     * <em>only</em> script file, and all subsequent arguments will be regarded as arguments to the script.
+     * <p>
+     * This method canonicalizes the command line arguments to the form {@code <options> <script> -- <arguments>} if a
+     * shebang script is identified. On platforms that pass shebang arguments as single strings, the shebang arguments
+     * will be broken down into single arguments; whitespace is used as separator.
+     * <p>
+     * Shebang mode is entered regardless of whether the script is actually run directly from the shell, or indirectly
+     * via the {@code jjs} executable. It is the user's / script author's responsibility to ensure that the arguments
+     * given on the shebang line do not lead to a malformed argument sequence. In particular, the shebang arguments
+     * should not contain any whitespace for purposes other than separating arguments, as the different platforms deal
+     * with whitespace in different and incompatible ways.
+     * <p>
+     * @implNote Example:<ul>
+     * <li>Shebang line in {@code script.js}: {@code #!/path/to/jjs --language=es6}</li>
+     * <li>Command line: {@code ./script.js arg2}</li>
+     * <li>{@code args} array passed to Nashorn: {@code --language=es6,./script.js,arg}</li>
+     * <li>Required canonicalized arguments array: {@code --language=es6,./script.js,--,arg2}</li>
+     * </ul>
+     *
+     * @param args the command line arguments as passed into Nashorn.
+     * @return the passed and possibly canonicalized argument list
+     */
+    private static String[] preprocessArgs(final String[] args) {
+        if (args.length == 0) {
+            return args;
+        }
+
+        final List<String> processedArgs = new ArrayList<>();
+        processedArgs.addAll(Arrays.asList(args));
+
+        // Nashorn supports passing multiple shebang arguments. On platforms that pass anything following the
+        // shebang interpreter notice as one argument, the first element of the argument array needs to be special-cased
+        // as it might actually contain several arguments. Mac OS X splits shebang arguments, other platforms don't.
+        // This special handling is also only necessary if the first argument actually starts with an option.
+        if (args[0].startsWith("-") && !System.getProperty("os.name", "generic").startsWith("Mac OS X")) {
+            processedArgs.addAll(0, ScriptingFunctions.tokenizeString(processedArgs.remove(0)));
+        }
+
+        int shebangFilePos = -1; // -1 signifies "none found"
+        // identify a shebang file and its position in the arguments array (if any)
+        for (int i = 0; i < processedArgs.size(); ++i) {
+            final String a = processedArgs.get(i);
+            if (!a.startsWith("-")) {
+                final Path p = Paths.get(a);
+                String l = "";
+                try (final BufferedReader r = Files.newBufferedReader(p)) {
+                    l = r.readLine();
+                } catch (IOException ioe) {
+                    // ignore
+                }
+                if (l.startsWith("#!")) {
+                    shebangFilePos = i;
+                }
+                // We're only checking the first non-option argument. If it's not a shebang file, we're in normal
+                // execution mode.
+                break;
+            }
+        }
+        if (shebangFilePos != -1) {
+            // Insert the argument separator after the shebang script file.
+            processedArgs.add(shebangFilePos + 1, "--");
+        }
+        return processedArgs.toArray(new String[0]);
+    }
+
+    /**
      * Compiles the given script files in the command line
      * This is called only when using the --compile-only flag
      *
--- a/test/script/basic/JDK-8025515.js	Tue Nov 08 05:26:18 2016 +0000
+++ b/test/script/basic/JDK-8025515.js	Thu Jan 12 06:59:38 2017 +0000
@@ -61,8 +61,8 @@
 var f = (function() {
     return function() { a.b.c; };
 })();
-testMethodName(f, "f$L:62");
+testMethodName(f, "f#L:62");
 
 testMethodName((function() {
     return function() { return a.b.c; };
-})(), "L:66$L:67");
+})(), "L:66#L:67");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8137240.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8137240: Negative lookahead in RegEx breaks backreference
+ *
+ * @test
+ * @run
+ */
+
+
+Assert.assertEquals('aa'.replace(/(a)(?!b)\1/gm, 'c'), 'c');
+
+var result = 'aa'.match(/(a)(?!b)\1/);
+Assert.assertTrue(result.length === 2);
+Assert.assertTrue(result[0] === 'aa');
+Assert.assertTrue(result[1] === 'a');
+
+result = 'aa'.match(/(a)(?!(b))\2(a)/);
+Assert.assertTrue(result.length === 4);
+Assert.assertTrue(result[0] === 'aa');
+Assert.assertTrue(result[1] === 'a');
+Assert.assertTrue(result[2] === undefined);
+Assert.assertTrue(result[3] === 'a');
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8156714.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8156714: Parsing issue with automatic semicolon insertion
+ *
+ * @test
+ * @run
+ */
+
+a = function() {
+}
+
+/* */ function b() {
+}
+
+c = function() {
+} /*
+
+*/ function d() {
+}
+
+try {
+    eval("x = function() {} /* */ function y() {}");
+    throw new Error("Error expected");
+} catch (e) {
+    if (!(e instanceof SyntaxError)) {
+        throw new Error("Unexpected error: " + e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8156896.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8156896: Script stack trace should display function names
+ *
+ * @test
+ * @run
+ */
+
+function checkNamedFunction(stack) {
+    Assert.assertTrue(stack.indexOf("Error\n\tat bar (") === 0);
+}
+
+function checkAnonymousFunction(stack) {
+    Assert.assertTrue(stack.indexOf("Error\n\tat <anonymous> (") === 0);
+}
+
+// Named functions
+function bar() { try { throw new Error(); } catch(e) { return e.stack; } }
+checkNamedFunction(bar());
+
+bar = function() { try { throw new Error(); } catch(e) { return e.stack; } };
+checkNamedFunction(bar());
+
+f = (function() {return function bar() { try { throw new Error(); } catch(e) { return e.stack; } } })();
+checkNamedFunction(f());
+
+f = new Function("return function bar() { try { throw new Error(); } catch(e) { return e.stack; } }")();
+checkNamedFunction(f());
+
+// Anonymous functions
+checkAnonymousFunction((function() { try { throw new Error(); } catch(e) { return e.stack; } })());
+
+f = (function() {return function() { try { throw new Error(); } catch(e) { return e.stack; } } })();
+checkAnonymousFunction(f());
+
+f = new Function("return function() { try { throw new Error(); } catch(e) { return e.stack; } }")();
+checkAnonymousFunction(f());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8157160.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8157160: JSON.stringify does not work on ScriptObjectMirror objects
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+var SM = Java.type("javax.script.ScriptEngineManager");
+var AJSO = Java.type("jdk.nashorn.api.scripting.AbstractJSObject");
+var Supplier = Java.type("java.util.function.Supplier");
+
+var engine = new SM().getEngineByName("nashorn");
+
+// JSON stringify ScriptObjectMirror instances
+print(JSON.stringify(engine.eval("({ foo : 42 })")));
+print(JSON.stringify(engine.eval("([5, 6, 76, 7])")));
+print(JSON.stringify(engine.eval(<<EOF
+ ({
+     toJSON: function() "hello"
+ })
+EOF
+)));
+
+print(JSON.stringify(engine.eval(<<EOF
+obj = {
+    name: 'nashorn',
+    versions: [ 'es5.1', 'es6' ]
+}
+EOF
+)));
+
+var dm = engine.eval("new Date()");
+print('"' + dm.toJSON() + '"' == JSON.stringify(dm));
+
+// JSON stringifying an arbitrary JSObject impl.
+var jsObj = new AJSO() {
+    keySet: function() {
+        var keys = new java.util.HashSet();
+        keys.add("x");
+        keys.add("y");
+        return keys;
+    },
+
+    getMember: function(name) {
+        if (name == "x") {
+            return 42;
+        } else if (name == "y") {
+            return "hello";
+        }
+    }
+};
+print(JSON.stringify(jsObj));
+
+// try toJSON implementation on JSObject
+var jsObj2 = new AJSO() {
+    getMember: function(name) {
+        if (name == 'toJSON') {
+            return function() {
+                return "my json representation";
+            }
+        }
+    }
+};
+print(JSON.stringify(jsObj2));
+
+var jsObj3 = new AJSO() {
+    getMember: function(name) {
+        if (name == 'toJSON') {
+            return new Supplier() {
+                "get": function() {
+                    return "value from toJSON function";
+                }
+            };
+        }
+    }
+};
+print(JSON.stringify(jsObj3));
+
+// replacer function from another script world
+print(JSON.stringify({
+   foo: "hello"
+}, engine.eval(<<EOF
+    function (key, value) {
+       if (key == "foo") {
+           return value.toUpperCase()
+       }
+       return value;
+    }
+EOF)));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8157160.js.EXPECTED	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,9 @@
+{"foo":42}
+[5,6,76,7]
+"hello"
+{"name":"nashorn","versions":["es5.1","es6"]}
+true
+{"x":42,"y":"hello"}
+"my json representation"
+"value from toJSON function"
+{"foo":"HELLO"}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8157680.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8157680: Callback parameter of any JS builtin implementation should accept any Callable
+ *
+ * @option -scripting
+ * @test
+ * @run
+ */
+
+var SM = Java.type("javax.script.ScriptEngineManager")
+var engine = new SM().getEngineByName("nashorn")
+
+engine.put("output", print);
+var reviver = engine.eval(<<EOF
+function(name, value) {
+   if (name == "") return value
+   output(name + " = " + value)
+   return value
+}
+EOF)
+
+// reviver function from mirror world!
+JSON.parse('{ "foo" : 44, "bar" : "hello" }', reviver)
+
+var AJO = Java.type("jdk.nashorn.api.scripting.AbstractJSObject")
+// reviver function as a JSObject function
+JSON.parse('{ "nashorn" : "hello" }', new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var name = args[0], value = args[1]
+        if (name == "") return value
+        print(name + " -> " + value)
+        return value
+    } 
+})
+
+// compare function from the mirror world
+var arr = [34,567,-3, 53].sort(engine.eval(<<EOF
+    function(x, y) x < y? -1 : ((x > y)? 1 : 0)
+EOF))
+print(arr)
+
+// compare function as a JSObject function
+arr = [34,57,-3, 53, 670, 33].sort(new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var x = args[0], y = args[1]
+        return x < y? -1 : ((x > y)? 1 : 0)
+    }
+})
+print(arr)
+
+// replacer function from mirror world
+var str = "hello".replace(/l/g, engine.eval(<<EOF
+    function() "_"
+EOF))
+print(str)
+
+// replacer function as a JSObject function
+str = "hello".replace(/[el]/g, new AJO() {
+    isFunction: function() true,
+    call: function(thiz, args) {
+        var match = args[0]
+        return match.toUpperCase()
+    }
+})
+print(str)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8157680.js.EXPECTED	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,7 @@
+foo = 44
+bar = hello
+nashorn -> hello
+-3,34,53,567
+-3,33,34,53,57,670
+he__o
+hELLo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8157819.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8157819: TypeError when a java.util.Comparator object is invoked as a function
+ *
+ * @test
+ * @run
+ */
+
+var compare = java.util.Comparator.naturalOrder()
+Assert.assertTrue(compare("nashorn", "ecmascript") > 0)
+Assert.assertTrue(compare("abc", "xyz") < 0)
+Assert.assertTrue(compare("hello", "hello") == 0)
+
+var rcompare = java.util.Comparator.reverseOrder()
+Assert.assertTrue(rcompare("nashorn", "ecmascript") < 0)
+Assert.assertTrue(rcompare("abc", "xyz") > 0)
+Assert.assertTrue(rcompare("hello", "hello") == 0)
+
+var arr = [ "nashorn", "JavaScript", "ECMAScript", "ecmascript", "js" ]
+Assert.assertEquals(arr.sort(compare).join(),
+    "ECMAScript,JavaScript,ecmascript,js,nashorn")
+Assert.assertEquals(arr.sort(rcompare).join(),
+    "nashorn,js,ecmascript,JavaScript,ECMAScript")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8158467.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8158467: AccessControlException is thrown on public Java class access if "script app loader" is set to null
+ *
+ * @option -scripting
+ * @test
+ * @run
+ */
+
+var Factory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
+var fac = new Factory();
+
+// This script has to be given RuntimePermission("nashorn.setConfig")
+var e = fac["getScriptEngine(java.lang.ClassLoader)"](null);
+
+print(e.eval("java.lang.System"));
+print(e.eval("({ foo: 42})").foo);
+print((e.eval("function(x) x*x"))(31));
+
+e.put("output", print);
+var runnable = e.eval(<<EOF
+    new java.lang.Runnable() {
+        run: function() {
+            output("hello Runnable");
+        }
+    }
+EOF);
+
+runnable.run();
+
+var obj = e.eval(<<EOF
+new (Java.extend(Java.type("java.lang.Object"))) {
+    hashCode: function() 33,
+    toString: function() "I'm object"
+}
+EOF);
+
+print(obj.hashCode());
+print(obj.toString());
+
+// should throw SecurityException!
+try {
+    e.eval("Packages.jdk.internal");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw SecurityException!
+try {
+    e.eval("Java.type('jdk.internal.misc.Unsafe')");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw SecurityException!
+try {
+    e.eval("Java.type('jdk.nashorn.internal.Context')");
+} catch (ex) {
+    print(ex);
+}
+
+// should throw ClassNotFoundException as null is script
+// "app loader" [and not platform loader which loads nashorn]
+e.eval(<<EOF
+try {
+    Java.type('jdk.nashorn.api.scripting.JSObject');
+} catch (ex) {
+    output(ex);
+}
+EOF);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8158467.js.EXPECTED	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,10 @@
+[JavaClass java.lang.System]
+42
+961
+hello Runnable
+33
+I'm object
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.internal")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.internal.misc")
+java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.jdk.nashorn.internal")
+java.lang.ClassNotFoundException: jdk.nashorn.api.scripting.JSObject
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/currently-failing/JDK-8144221.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test that shebang handling works properly.
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+// The test generates three different JavaScript source files. The first two
+// are generated at the beginning of the test and do not change.
+// * a.js
+//   print("A: " + arguments)
+// * b.js
+//   #!<path_to_jjs> -lalelu -- ignore
+//   print("B: " + arguments)
+//
+// The third file, shebang.js, is generated differently for each particular
+// test case, containing different shebang lines and one statement:
+// * shebang.js
+//   #!<path_to_jjs> <shebang_line>
+//   print("S: " + arguments)
+//
+// The path_to_jjs is extracted from the environment based on JAVA_HOME, so the
+// latter must be set properly.
+//
+// Each shebang.js is run four times, in all possible combinations of values
+// from the following two axes:
+// * without passing any arguments, and passing the arguments 'a.js' and
+//   '"hello world"' (the latter being a quoted string);
+// * run via jjs, and via direct shell execution (using shebang).
+
+var pseudosheb  = "#!${jjs} -lalelu -- ignore",
+    System      = Java.type('java.lang.System'),
+    Paths       = Java.type('java.nio.file.Paths'),
+    Files       = Java.type('java.nio.file.Files'),
+    Opt         = Java.type('java.nio.file.StandardOpenOption'),
+    Arrays      = Java.type('java.util.Arrays')
+
+var sep      = Java.type('java.io.File').separator,
+    win      = System.getProperty("os.name").startsWith("Windows"),
+    jjsName  = "jjs" + (win ? ".exe" : ""),
+    javaHome = System.getProperty("java.home")
+
+var jjs = javaHome + "/../bin/".replace(/\//g, sep) + jjsName
+if (!Files.exists(Paths.get(jjs))) {
+    jjs = javaHome + "/bin/".replace(/\//g, sep) + jjsName
+}
+
+// Create and cwd to a temporary directory.
+
+var tmpdir = Files.createTempDirectory(null),
+    tmp    = tmpdir.toAbsolutePath().toString(),
+    curpwd = $ENV.PWD
+
+$ENV.PWD = tmp
+
+// Test cases. Each case is documented with the expected output for the four
+// different executions.
+
+var shebs = [
+        // No arguments on the shebang line.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "",
+        // One interpreter argument.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "--language=es6",
+        // Two interpreter arguments.
+        // noargs jjs/shebang -> no output but "S" prefix
+        // args jjs/shebang   -> output the arguments with "S" prefix
+        "--language=es6 -scripting",
+        // One interpreter argument and a JavaScript file without shebang.
+        // (For shebang execution, this is a pathological example, as the
+        // JavaScript file passed as a shebang argument will be analyzed and
+        // shebang mode will not be entered.)
+        // noargs jjs     -> no output but "S" prefix
+        // args jjs       -> output the arguments with "S" prefix
+        // noargs shebang -> no output but "A" and "S" prefixes
+        // args shebang   -> output "A", "S", and "A" prefixes, then the error
+        //                   message:
+        //                   "java.io.IOException: hello world is not a file"
+        "-scripting a.js",
+        // One interpreter argument and a JavaScript file with shebang. (This
+        // is another pathological example, as it will force shebang mode,
+        // leading to all subsequent arguments, including shebang.js, being
+        // treated as arguments to the script b.js.)
+        // noargs jjs     -> no output but the "S" prefix
+        // args jjs       -> output the arguments with "S" prefix
+        // noargs shebang -> output shebang.js with "B" prefix
+        // args shebang   -> output shebang.js and the arguments with "B"
+        //                   prefix
+        "-scripting b.js"
+    ]
+
+function write(file, lines) {
+    Files.write(Paths.get(tmp, file), Arrays.asList(lines), Opt.CREATE, Opt.WRITE)
+}
+
+function insn(name) {
+    return "print('${name}:' + arguments)"
+}
+
+function run(viajjs, name, arg1, arg2) {
+    var prefix = viajjs ? "${jjs} -scripting " : win ? 'sh -c "' : '',
+        suffix = viajjs ? '' : win ? '"' : ''
+    $EXEC("${prefix}./shebang.js ${arg1} ${arg2}${suffix}")
+    print("* ${name} via ${viajjs ? 'jjs' : 'shebang'}")
+    print($OUT.trim())
+    print($ERR.trim())
+}
+
+write('a.js', insn('A'))
+write('b.js', [pseudosheb, insn('B')])
+
+shebs.forEach(function(sheb) {
+    var shebang = "#!${jjs} ${sheb}"
+    print("<<< ${sheb} >>>")
+    write('shebang.js', [shebang, insn('S')])
+    $EXEC('chmod +x shebang.js')
+    run(false, 'noargs', '', '')
+    run(true, 'noargs', '', '')
+    run(false, 'withargs', 'a.js', "'hello world'")
+    run(true, 'withargs', 'a.js', "'hello world'")
+    $EXEC('rm shebang.js')
+})
+
+// Cleanup.
+
+$EXEC('rm a.js b.js')
+$ENV.PWD = curpwd
+Files.delete(tmpdir)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/currently-failing/JDK-8144221.js.EXPECTED	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,68 @@
+<<<  >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< --language=es6 >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< --language=es6 -scripting >>>
+* noargs via shebang
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+S:a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
+<<< -scripting a.js >>>
+* noargs via shebang
+A:
+S:
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+A:
+S:
+A:
+java.io.IOException: hello world is not a file
+* withargs via jjs
+S:a.js,hello world
+
+<<< -scripting b.js >>>
+* noargs via shebang
+B:./shebang.js
+
+* noargs via jjs
+S:
+
+* withargs via shebang
+B:./shebang.js,a.js,hello world
+
+* withargs via jjs
+S:a.js,hello world
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/nosecurity/JDK-8130127.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8130127: streamline input parameter of Nashorn scripting $EXEC function
+ *
+ * Test different variants of stdin passing to $EXEC.
+ *
+ * @test
+ * @option -scripting
+ * @run
+ */
+
+var File = java.io.File,
+    sep = File.separator,
+    System = java.lang.System,
+    os = System.getProperty("os.name"),
+    win = os.startsWith("Windows"),
+    jjsName = "jjs" + (win ? ".exe" : ""),
+    javaHome = System.getProperty("java.home")
+
+var jjs = javaHome + "/../bin/".replace(/\//g, sep) + jjsName
+if (!new File(jjs).isFile()) {
+    jjs = javaHome + "/bin/".replace(/\//g, sep) + jjsName
+}
+
+var jjsCmd = jjs + " readprint.js"
+
+print($EXEC(jjsCmd))
+print($EXEC(jjsCmd, null))
+print($EXEC(jjsCmd, undefined))
+print($EXEC(jjsCmd, ""))
+
+print($EXEC(jjs, "print('hello')"))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/nosecurity/JDK-8130127.js.EXPECTED	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,6 @@
+
+
+
+
+hello
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/nosecurity/os-not-windows.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Test that we're not running on Windows. The test actually checks if the os.not.windows property is set and processed
+ * by runif correctly.
+ *
+ * @test
+ * @runif os.not.windows
+ * @run
+ */
+
+var os = java.lang.System.getProperty("os.name")
+
+if (os.startsWith("Windows")) {
+    throw "This test should not be run on Windows."
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/nosecurity/readprint.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This is a dummy script accompanying JDK-8130127.js.
+ *
+ * @subtest
+ * @run ignore supplemental
+ */
+
+var l = readLine()
+print(l)
+
--- a/test/script/trusted/JDK-8087292.js	Tue Nov 08 05:26:18 2016 +0000
+++ b/test/script/trusted/JDK-8087292.js	Thu Jan 12 06:59:38 2017 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,26 +29,58 @@
  * @run
  */
 
+load(__DIR__ + "JDK-util.js")
+
+var jHomePath = System.getenv("JAVA_HOME")
+var jLauncher = "${jHomePath}/bin/java"
+var altjLauncher = which('java')
+
+if (windows) {
+    if(winCyg) {
+        jLauncher = "${jHomePath}" + "/bin/java.exe"
+        jLauncher = cygpath(jLauncher,outPath.windows) 
+    }
+    else {
+        jLauncher = "${jHomePath}" + "\\bin\\java.exe"
+        altjLauncher = which('java.exe')
+        altjLauncher = cygpath(altjLauncher,outPath.windows)
+    }
+}
+
+function exists(f) {
+    return Files.exists(Paths.get(f))
+}
+
+var javaLauncher = exists(jLauncher) ? jLauncher : altjLauncher
+
+
+if (!exists(javaLauncher)) {
+    throw "no java launcher found; tried ${jLauncher} and ${altjLauncher}"
+}
+
 function tryExec() {
     try {
-        `java`
+	$EXEC("${javaLauncher}")
     } catch (e) {
-        print(e);
+      print(e)
     }
 
     // make sure we got non-zero ("failure") exit code!
     if ($EXIT == 0) {
-        print("Error: expected $EXIT code to be non-zero");
+        print("Error: expected $EXIT code to be non-zero")
     }
 }
+//convert windows paths to cygwin
+if (windows)
+    javaLauncher = (winCyg) ? cygpath(javaLauncher,outPath.mixed).trim() : cygpath(javaLauncher,outPath.windows).trim()
 
 // no exception now!
-tryExec();
+tryExec()
 
 // turn on error with non-zero exit code
-$EXEC.throwOnError = true;
-tryExec();
+$EXEC.throwOnError = true
+tryExec()
 
 // no exception after this
-$EXEC.throwOnError = false;
-tryExec();
+$EXEC.throwOnError = false
+tryExec()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/trusted/JDK-util.js	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This file contains utility functions used by other tests.
+ * @subtest
+ */
+
+var Files = Java.type('java.nio.file.Files'),
+    Paths = Java.type('java.nio.file.Paths'),
+    System = Java.type('java.lang.System')
+
+var File = java.io.File
+var windows = System.getProperty("os.name").startsWith("Windows")
+var winCyg = false
+
+var outPath = {
+    windows:0, //C:\dir
+    mixed:1    //C:/dir
+}
+
+if (windows) {
+    //Is there any better way to diffrentiate between cygwin/command prompt on windows
+    var term = System.getenv("TERM")
+    winCyg = term ? true:false
+}
+
+/**
+ * Returns which command is selected from PATH
+ * @param cmd name of the command searched from PATH
+ */
+function which(cmd) {
+    var path = System.getenv("PATH")
+    var st = new java.util.StringTokenizer(path, File.pathSeparator)
+    while (st.hasMoreTokens()) {
+        var file = new File(st.nextToken(), cmd)
+        if (file.exists()) {
+            return (file.getAbsolutePath())
+        }
+    }
+}
+
+/**
+ * Unix cygpath implementation
+ * Supports only two outputs,windows(C:\dir\) and mixed(C:/dir/)
+ */
+ 
+function cygpath(path,mode) {
+   
+    var newpath = path
+    if(path.startsWith("/cygdrive/")){
+        var str = path.substring(10)
+        var index = str.indexOf('/',0)
+        var drv = str.substring(0,index)
+        var rstr = drv.toUpperCase() + ":"
+        newpath = str.replaceFirst(drv,rstr)
+    }
+    if (mode == outPath.windows)
+        return Paths.get(newpath).toString()
+    else {
+        newpath = newpath.replaceAll('\\\\','/')
+        return newpath
+    }                   
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/nashorn/api/scripting/test/JDK_8148140_Test.java	Thu Jan 12 06:59:38 2017 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.nashorn.api.scripting.test;
+
+import java.util.Arrays;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.AbstractJSObject;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/**
+ * @bug 8148140
+ * @summary arguments are handled differently in apply for JS functions and AbstractJSObjects
+ */
+public class JDK_8148140_Test {
+
+    ScriptEngine engine;
+
+    static final String RESULT = "[1, 2, 3]";
+
+    @BeforeClass
+    public void setupTest() {
+        engine = new ScriptEngineManager().getEngineByName("js");
+        engine.put("f", new AbstractJSObject() {
+            @Override
+            public boolean isFunction() {
+                return true;
+            }
+            @Override
+            public Object call(Object thiz, Object... args) {
+                return Arrays.deepToString(args);
+            }
+        });
+    }
+
+    @Test
+    public void testCallF() throws ScriptException {
+        assertEquals(RESULT, engine.eval("f(1,2,3)"));
+    }
+
+    @Test
+    public void testApplyF() throws ScriptException {
+        assertEquals(RESULT, engine.eval("Function.prototype.apply.call(f, null, [1,2,3])"));
+    }
+
+}
--- a/test/src/jdk/nashorn/api/scripting/test/ScopeTest.java	Tue Nov 08 05:26:18 2016 +0000
+++ b/test/src/jdk/nashorn/api/scripting/test/ScopeTest.java	Thu Jan 12 06:59:38 2017 +0000
@@ -30,6 +30,8 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 import javax.script.Bindings;
+import javax.script.Compilable;
+import javax.script.CompiledScript;
 import javax.script.Invocable;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
@@ -911,4 +913,27 @@
          Object value = ((Invocable)engine).invokeFunction("newfunc");
          assertTrue(((Number)value).intValue() == 42);
     }
+
+    // @bug 8150219 ReferenceError in 1.8.0_72
+    // When we create a Global for a non-default ScriptContext that needs one keep the
+    // ScriptContext associated with the Global so that invoke methods work as expected.
+    @Test
+    public void invokeFunctionWithCustomScriptContextTest() throws Exception {
+        final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
+
+        // create an engine and a ScriptContext, but don't set it as default
+        ScriptContext scriptContext = new SimpleScriptContext();
+
+        // Set some value in the context
+        scriptContext.setAttribute("myString", "foo", ScriptContext.ENGINE_SCOPE);
+
+        // Evaluate script with custom context and get back a function
+        final String script = "function (c) { return myString.indexOf(c); }";
+        CompiledScript compiledScript = ((Compilable)engine).compile(script);
+        Object func = compiledScript.eval(scriptContext);
+
+        // Invoked function should be able to see context it was evaluated with
+        Object result = ((Invocable) engine).invokeMethod(func, "call", func, "o", null);
+        assertTrue(((Number)result).intValue() == 1);
+    }
 }