changeset 1654:cdacfe806770

Merge
author lana
date Wed, 23 Mar 2016 21:45:59 -0700
parents 8e70b6afdbce 975eff39b182
children 3ac5d360070e
files src/jdk.dynalink/share/classes/jdk/dynalink/beans/messages.properties
diffstat 48 files changed, 946 insertions(+), 180 deletions(-) [+]
line wrap: on
line diff
--- a/make/build.xml	Wed Mar 23 19:33:47 2016 -0700
+++ b/make/build.xml	Wed Mar 23 21:45:59 2016 -0700
@@ -93,7 +93,21 @@
         <os family="windows"/>
       </not>
     </condition>
-  </target>
+
+    <!--set windows cygwin/cmd specific properties-->
+    <property environment="env"/>
+    <condition property="test-sys-prop-no-security.os.not.windows.cmd">
+     <not>
+      <and>
+        <os family="windows"/>
+        <not>
+          <isset property="env.SHELL"/>
+        </not>
+      </and>
+     </not>
+    </condition>
+   </target>
+  
 
   <!-- check minimum ant version required to be 1.8.4 -->
   <target name="check-ant-version">
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/CallSiteDescriptor.java	Wed Mar 23 21:45:59 2016 -0700
@@ -83,7 +83,6 @@
 
 package jdk.dynalink;
 
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
 import java.util.Objects;
@@ -105,28 +104,28 @@
  * descriptors (typically, values passed in additional parameters to the
  * bootstrap method. Since the descriptors must be immutable, you can set up a
  * cache for equivalent descriptors to have the call sites share them.
+ * <p>
+ * The class extends {@link SecureLookupSupplier} for security-checked access to
+ * the {@code MethodHandles.Lookup} object it carries. This lookup should be used
+ * to find method handles to set as targets of the call site described by this
+ * descriptor.
  */
-public class CallSiteDescriptor {
-    private final MethodHandles.Lookup lookup;
+public class CallSiteDescriptor extends SecureLookupSupplier {
     private final Operation operation;
     private final MethodType methodType;
 
     /**
-     * The name of a runtime permission to invoke the {@link #getLookup()}
-     * method.
-     */
-    public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup";
-
-    private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(GET_LOOKUP_PERMISSION_NAME);
-
-    /**
      * Creates a new call site descriptor.
      * @param lookup the lookup object describing the class the call site belongs to.
+     * When creating descriptors from a {@link java.lang.invoke} bootstrap method,
+     * it should be the lookup passed to the bootstrap.
      * @param operation the dynamic operation at the call site.
-     * @param methodType the method type of the call site.
+     * @param methodType the method type of the call site. When creating
+     * descriptors from a {@link java.lang.invoke} bootstrap method, it should be
+     * the method type passed to the bootstrap.
      */
     public CallSiteDescriptor(final Lookup lookup, final Operation operation, final MethodType methodType) {
-        this.lookup = Objects.requireNonNull(lookup, "lookup");
+        super(lookup);
         this.operation = Objects.requireNonNull(operation, "name");
         this.methodType = Objects.requireNonNull(methodType, "methodType");
     }
@@ -149,34 +148,6 @@
     }
 
     /**
-     * Returns the lookup that should be used to find method handles to set as
-     * targets of the call site described by this descriptor. When creating
-     * descriptors from a {@link java.lang.invoke} bootstrap method, it should
-     * be the lookup passed to the bootstrap.
-     * @return the lookup that should be used to find method handles to set as
-     * targets of the call site described by this descriptor.
-     * @throws SecurityException if the lookup isn't the
-     * {@link MethodHandles#publicLookup()} and a security manager is present,
-     * and a check for {@code RuntimePermission("dynalink.getLookup")} fails.
-     */
-    public final Lookup getLookup() {
-        final SecurityManager sm = System.getSecurityManager();
-        if (sm != null && lookup != MethodHandles.publicLookup()) {
-            sm.checkPermission(GET_LOOKUP_PERMISSION);
-        }
-        return lookup;
-    }
-
-    /**
-     * Returns the value of {@link #getLookup()} without a security check. Can
-     * be used by subclasses to access the lookup quickly.
-     * @return same as returned value of {@link #getLookup()}.
-     */
-    protected final Lookup getLookupPrivileged() {
-        return lookup;
-    }
-
-    /**
      * Creates a new call site descriptor from this descriptor, which is
      * identical to this, except it changes the method type. Invokes
      * {@link #changeMethodTypeInternal(MethodType)} and checks that it returns
@@ -211,7 +182,7 @@
      * @return a new call site descriptor, with the method type changed.
      */
     protected CallSiteDescriptor changeMethodTypeInternal(final MethodType newMethodType) {
-        return new CallSiteDescriptor(lookup, operation, newMethodType);
+        return new CallSiteDescriptor(getLookupPrivileged(), operation, newMethodType);
     }
 
     /**
@@ -233,7 +204,7 @@
         final CallSiteDescriptor other = (CallSiteDescriptor)obj;
         return operation.equals(other.operation) &&
                methodType.equals(other.methodType) &&
-               lookupsEqual(lookup, other.lookup);
+               lookupsEqual(getLookupPrivileged(), other.getLookupPrivileged());
     }
 
     /**
@@ -257,7 +228,7 @@
      */
     @Override
     public int hashCode() {
-        return operation.hashCode() + 31 * methodType.hashCode() + 31 * 31 * lookupHashCode(lookup);
+        return operation.hashCode() + 31 * methodType.hashCode() + 31 * 31 * lookupHashCode(getLookupPrivileged());
     }
 
     /**
@@ -279,7 +250,7 @@
     @Override
     public String toString() {
         final String mt = methodType.toString();
-        final String l = lookup.toString();
+        final String l = getLookupPrivileged().toString();
         final String o = operation.toString();
         final StringBuilder b = new StringBuilder(o.length() + mt.length() + 1 + l.length());
         return b.append(o).append(mt).append('@').append(l).toString();
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/LinkerServicesImpl.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/LinkerServicesImpl.java	Wed Mar 23 21:45:59 2016 -0700
@@ -85,7 +85,10 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
+import java.util.Objects;
+import java.util.function.Supplier;
 import jdk.dynalink.linker.ConversionComparator.Comparison;
 import jdk.dynalink.linker.GuardedInvocation;
 import jdk.dynalink.linker.GuardingDynamicLinker;
@@ -97,7 +100,7 @@
  * Default implementation of the {@link LinkerServices} interface.
  */
 final class LinkerServicesImpl implements LinkerServices {
-    private static final ThreadLocal<LinkRequest> threadLinkRequest = new ThreadLocal<>();
+    private static final ThreadLocal<SecureLookupSupplier> threadLookupSupplier = new ThreadLocal<>();
 
     private final TypeConverterFactory typeConverterFactory;
     private final GuardingDynamicLinker topLevelLinker;
@@ -138,14 +141,31 @@
         return typeConverterFactory.compareConversion(sourceType, targetType1, targetType2);
     }
 
+    /**
+     * Used to marshal a checked exception out of Supplier.get() in getGuardedInvocation.
+     */
+    private static class LinkerException extends RuntimeException {
+        private static final long serialVersionUID = 1L;
+
+        public LinkerException(final Exception cause) {
+            super(null, cause, true, false);
+        }
+    }
+
     @Override
     public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
-        final LinkRequest prevLinkRequest = threadLinkRequest.get();
-        threadLinkRequest.set(linkRequest);
         try {
-            return topLevelLinker.getGuardedInvocation(linkRequest, this);
-        } finally {
-            threadLinkRequest.set(prevLinkRequest);
+            return getWithLookupInternal(() -> {
+                try {
+                    return topLevelLinker.getGuardedInvocation(linkRequest, this);
+                } catch (final RuntimeException e) {
+                    throw e;
+                } catch (final Exception e) {
+                    throw new LinkerException(e);
+                }
+            }, linkRequest.getCallSiteDescriptor());
+        } catch (final LinkerException e) {
+            throw (Exception)e.getCause();
         }
     }
 
@@ -154,10 +174,32 @@
         return internalObjectsFilter != null ? internalObjectsFilter.transform(target) : target;
     }
 
-    static MethodHandles.Lookup getCurrentLookup() {
-        final LinkRequest currentRequest = threadLinkRequest.get();
-        if (currentRequest != null) {
-            return currentRequest.getCallSiteDescriptor().getLookup();
+    @Override
+    public <T> T getWithLookup(final Supplier<T> operation, final SecureLookupSupplier lookupSupplier) {
+        return getWithLookupInternal(
+                Objects.requireNonNull(operation, "action"),
+                Objects.requireNonNull(lookupSupplier, "lookupSupplier"));
+    }
+
+    private static <T> T getWithLookupInternal(final Supplier<T> operation, final SecureLookupSupplier lookupSupplier) {
+        final SecureLookupSupplier prevLookupSupplier = threadLookupSupplier.get();
+        final boolean differ = prevLookupSupplier != lookupSupplier;
+        if (differ) {
+            threadLookupSupplier.set(lookupSupplier);
+        }
+        try {
+            return operation.get();
+        } finally {
+            if (differ) {
+                threadLookupSupplier.set(prevLookupSupplier);
+            }
+        }
+    }
+
+    static Lookup getCurrentLookup() {
+        final SecureLookupSupplier lookupSupplier = threadLookupSupplier.get();
+        if (lookupSupplier != null) {
+            return lookupSupplier.getLookup();
         }
         return MethodHandles.publicLookup();
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,79 @@
+/*
+ * 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.dynalink;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.util.Objects;
+
+/**
+ * Provides security-checked access to a {@code MethodHandles.Lookup} object.
+ * See {@link #getLookup()} for details.
+ */
+public class SecureLookupSupplier {
+    /**
+     * The name of a runtime permission required to successfully invoke the
+     * {@link #getLookup()} method.
+     */
+    public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup";
+
+    private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
+
+    private final MethodHandles.Lookup lookup;
+
+    /**
+     * Creates a new secure lookup supplier, securing the passed lookup.
+     * @param lookup the lookup to secure. Can not be null.
+     * @throws NullPointerException if null is passed.
+     */
+    public SecureLookupSupplier(final MethodHandles.Lookup lookup) {
+        this.lookup = Objects.requireNonNull(lookup, "lookup");
+    }
+
+    /**
+     * Returns the lookup secured by this {@code SecureLookupSupplier}.
+     * @return the lookup secured by this {@code SecureLookupSupplier}.
+     * @throws SecurityException if the secured lookup isn't the
+     * {@link MethodHandles#publicLookup()}, and a security manager is present,
+     * and a check for {@code RuntimePermission("dynalink.getLookup")} fails.
+     */
+    public final Lookup getLookup() {
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm != null && lookup != MethodHandles.publicLookup()) {
+            sm.checkPermission(GET_LOOKUP_PERMISSION);
+        }
+        return lookup;
+    }
+
+    /**
+     * Returns the value of {@link #getLookup()} without a security check. Can
+     * be used by subclasses to access the lookup quickly.
+     * @return same as returned value of {@link #getLookup()}.
+     */
+    protected final Lookup getLookupPrivileged() {
+        return lookup;
+    }
+}
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java	Wed Mar 23 21:45:59 2016 -0700
@@ -95,6 +95,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.internal.AccessControlContextFactory;
 import jdk.dynalink.linker.support.Lookup;
 
@@ -107,7 +108,7 @@
 class CallerSensitiveDynamicMethod extends SingleDynamicMethod {
     private static final AccessControlContext GET_LOOKUP_CONTEXT =
             AccessControlContextFactory.createAccessControlContext(
-                    CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
+                    SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
 
     // Typed as "AccessibleObject" as it can be either a method or a constructor.
     // If we were Java8-only, we could use java.lang.reflect.Executable
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassLinker.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassLinker.java	Wed Mar 23 21:45:59 2016 -0700
@@ -84,7 +84,6 @@
 package jdk.dynalink.beans;
 
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import jdk.dynalink.beans.GuardedInvocationComponent.ValidationType;
 import jdk.dynalink.linker.support.Lookup;
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/LinkerServicesWithMissingMemberHandlerFactory.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/LinkerServicesWithMissingMemberHandlerFactory.java	Wed Mar 23 21:45:59 2016 -0700
@@ -27,6 +27,8 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodType;
+import java.util.function.Supplier;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.linker.ConversionComparator.Comparison;
 import jdk.dynalink.linker.GuardedInvocation;
 import jdk.dynalink.linker.LinkRequest;
@@ -77,4 +79,9 @@
     public MethodHandle filterInternalObjects(final MethodHandle target) {
         return linkerServices.filterInternalObjects(target);
     }
+
+    @Override
+    public <T> T getWithLookup(final Supplier<T> operation, final SecureLookupSupplier lookupSupplier) {
+        return linkerServices.getWithLookup(operation, lookupSupplier);
+    }
 }
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java	Wed Mar 23 21:45:59 2016 -0700
@@ -98,6 +98,7 @@
 import java.util.Map;
 import java.util.Set;
 import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest;
 import jdk.dynalink.internal.AccessControlContextFactory;
 import jdk.dynalink.internal.InternalTypeUtilities;
@@ -148,7 +149,7 @@
     }
 
     @Override
-    public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
+    MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
         final MethodType callSiteType = callSiteDescriptor.getMethodType();
         // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2)
         final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType,
@@ -218,14 +219,14 @@
                 for(final SingleDynamicMethod method: invokables) {
                     methodHandles.add(method.getTarget(callSiteDescriptor));
                 }
-                return new OverloadedMethod(methodHandles, this, getCallSiteClassLoader(callSiteDescriptor), callSiteType, linkerServices).getInvoker();
+                return new OverloadedMethod(methodHandles, this, getCallSiteClassLoader(callSiteDescriptor), callSiteType, linkerServices, callSiteDescriptor).getInvoker();
             }
         }
     }
 
     private static final AccessControlContext GET_CALL_SITE_CLASS_LOADER_CONTEXT =
             AccessControlContextFactory.createAccessControlContext(
-                    "getClassLoader", CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
+                    "getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
 
     private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
         return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedMethod.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedMethod.java	Wed Mar 23 21:45:59 2016 -0700
@@ -91,6 +91,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.internal.InternalTypeUtilities;
 import jdk.dynalink.linker.LinkerServices;
 import jdk.dynalink.linker.support.Lookup;
@@ -108,6 +109,7 @@
     private final MethodType callSiteType;
     private final MethodHandle invoker;
     private final LinkerServices linkerServices;
+    private final SecureLookupSupplier lookupSupplier;
     private final ArrayList<MethodHandle> fixArgMethods;
     private final ArrayList<MethodHandle> varArgMethods;
 
@@ -115,12 +117,14 @@
             final OverloadedDynamicMethod parent,
             final ClassLoader callSiteClassLoader,
             final MethodType callSiteType,
-            final LinkerServices linkerServices) {
+            final LinkerServices linkerServices,
+            final SecureLookupSupplier lookupSupplier) {
         this.parent = parent;
         this.callSiteClassLoader = callSiteClassLoader;
         final Class<?> commonRetType = getCommonReturnType(methodHandles);
         this.callSiteType = callSiteType.changeReturnType(commonRetType);
         this.linkerServices = linkerServices;
+        this.lookupSupplier = lookupSupplier;
 
         fixArgMethods = new ArrayList<>(methodHandles.size());
         varArgMethods = new ArrayList<>(methodHandles.size());
@@ -173,11 +177,14 @@
                     break;
                 }
                 case 1: {
-                    method = SingleDynamicMethod.getInvocation(methods.get(0), callSiteType, linkerServices);
+                    final List<MethodHandle> fmethods = methods;
+                    method = linkerServices.getWithLookup(
+                            ()->SingleDynamicMethod.getInvocation(fmethods.get(0), callSiteType, linkerServices),
+                            lookupSupplier);
                     break;
                 }
                 default: {
-                    // This is unfortunate - invocation time ambiguity. We can still save the day if
+                    // This is unfortunate - invocation time ambiguity.
                     method = getAmbiguousMethodThrower(argTypes, methods);
                     break;
                 }
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/SingleDynamicMethod.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/SingleDynamicMethod.java	Wed Mar 23 21:45:59 2016 -0700
@@ -99,7 +99,6 @@
  * arity).
  */
 abstract class SingleDynamicMethod extends DynamicMethod {
-
     private static final MethodHandle CAN_CONVERT_TO = Lookup.findOwnStatic(MethodHandles.lookup(), "canConvertTo", boolean.class, LinkerServices.class, Class.class, Object.class);
 
     SingleDynamicMethod(final String name) {
@@ -129,8 +128,8 @@
 
     @Override
     MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
-        return getInvocation(getTarget(callSiteDescriptor), callSiteDescriptor.getMethodType(),
-                linkerServices);
+        return linkerServices.getWithLookup(()->getInvocation(getTarget(callSiteDescriptor),
+                callSiteDescriptor.getMethodType(), linkerServices), callSiteDescriptor);
     }
 
     @Override
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/messages.properties	Wed Mar 23 19:33:47 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#  Copyright 2009-2013 Attila Szegedi
-#
-#  Licensed under either the Apache License, Version 2.0 (the "Apache 
-#  License") or the BSD License (the "BSD License"), with licensee
-#  being free to choose either of the two at their discretion.
-#
-#  You may not use this file except in compliance with either the Apache 
-#  License or the BSD License.
-#
-#  A copy of the BSD License is available in the root directory of the 
-#  source distribution of the project under the file name
-#  "Dynalink-License-BSD.txt".
-#
-#  A copy of the Apache License is available in the root directory of the
-#  source distribution of the project under the file name 
-#  "Dynalink-License-Apache-2.0.txt". Alternatively, you may obtain a 
-#  copy of the Apache License at <http://www.apache.org/licenses/LICENSE-2.0>
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See your chosen License for the specific language governing permissions
-#  and limitations under that License.
-
-couldNotDiscoverAccessibleMethods=Could not discover accessible methods of class {0}, trying its superclasses and interfaces.
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java	Wed Mar 23 21:45:59 2016 -0700
@@ -85,7 +85,7 @@
 
 import java.lang.invoke.MethodHandles;
 import java.util.function.Supplier;
-import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.beans.BeansLinker;
 import jdk.dynalink.linker.support.TypeUtilities;
 
@@ -132,7 +132,7 @@
      * (e.g. to convert some object from the dynamic language into a Java
      * interface for interoperability). Invoking the {@link Supplier#get()}
      * method on the passed supplier will be subject to the same security checks
-     * as {@link CallSiteDescriptor#getLookup()}. An implementation should avoid
+     * as {@link SecureLookupSupplier#getLookup()}. An implementation should avoid
      * retrieving the lookup if it is not needed so as to avoid the expense of
      * {@code AccessController.doPrivileged} call.
      * @return a guarded invocation that can take an object (if it passes guard)
@@ -142,6 +142,7 @@
      * can always handle the conversion, it can return an unconditional
      * invocation (one whose guard is null).
      * @throws Exception if there was an error during creation of the converter
+     * @see LinkerServices#getWithLookup(Supplier, SecureLookupSupplier)
      */
     public GuardedInvocation convertToType(Class<?> sourceType, Class<?> targetType, Supplier<MethodHandles.Lookup> lookupSupplier) throws Exception;
 }
--- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java	Wed Mar 23 21:45:59 2016 -0700
@@ -86,8 +86,10 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.util.function.Supplier;
 import jdk.dynalink.DynamicLinker;
 import jdk.dynalink.DynamicLinkerFactory;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.linker.ConversionComparator.Comparison;
 import jdk.dynalink.linker.support.TypeUtilities;
 
@@ -217,4 +219,34 @@
      * filtered for wrapping and unwrapping.
      */
     public MethodHandle filterInternalObjects(final MethodHandle target);
+
+    /**
+     * Executes an operation within the context of a particular
+     * {@code MethodHandles.Lookup} lookup object. Normally, methods on
+     * {@code LinkerServices} are invoked as part of the linking mechanism in
+     * which case Dynalink internally maintains a per-thread current lookup
+     * (the one belonging to the descriptor of the call site being linked). This
+     * lookup can be retrieved by any {@link GuardingTypeConverterFactory}
+     * involved in linking if it needs to generate lookup-sensitive converters.
+     * However, linker services' methods can be invoked outside the linking
+     * process too when implementing invocation-time dispatch schemes, invoking
+     * conversions at runtime, etc. If it becomes necessary to use any type
+     * converter in this situation, and it needs a lookup, it will normally only
+     * get {@link MethodHandles#publicLookup()} as the thread is not engaged in
+     * a linking operation. If there is a way to meaningfully associate the
+     * operation to the context of some caller class, consider performing it
+     * within an invocation of this method and passing a full-strength lookup
+     * for that class, as it will associate that lookup with the current thread
+     * for the duration of the operation. Note that since you are passing a
+     * {@link SecureLookupSupplier}, any invoked type converter factories will
+     * still need to hold the necessary runtime permission to be able to get the
+     * lookup should they need it.
+     * @param <T> the type of the return value provided by the passed-in supplier.
+     * @param operation the operation to execute in context of the specified lookup.
+     * @param lookupSupplier secure supplier of the lookup
+     * @return the return value of the action
+     * @throws NullPointerException if either action or lookupSupplier are null.
+     * @see GuardingTypeConverterFactory#convertToType(Class, Class, Supplier)
+     */
+    public <T> T getWithLookup(final Supplier<T> operation, final SecureLookupSupplier lookupSupplier);
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/ScriptUtils.java	Wed Mar 23 21:45:59 2016 -0700
@@ -171,7 +171,7 @@
 
         final LinkerServices linker = Bootstrap.getLinkerServices();
         final Object objToConvert = unwrap(obj);
-        final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(),  clazz);
+        final MethodHandle converter = linker.getTypeConverter(objToConvert.getClass(), clazz);
         if (converter == null) {
             // no supported conversion!
             throw new UnsupportedOperationException("conversion not supported");
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java	Wed Mar 23 21:45:59 2016 -0700
@@ -257,6 +257,9 @@
     //is this a rest of compilation
     private final int[] continuationEntryPoints;
 
+    // Scope object creators needed for for-of and for-in loops
+    private Deque<FieldObjectCreator<?>> scopeObjectCreators = new ArrayDeque<>();
+
     /**
      * Constructor.
      *
@@ -1297,6 +1300,9 @@
     private void popBlockScope(final Block block) {
         final Label breakLabel = block.getBreakLabel();
 
+        if (block.providesScopeCreator()) {
+            scopeObjectCreators.pop();
+        }
         if(!block.needsScope() || lc.isFunctionBody()) {
             emitBlockBreakLabel(breakLabel);
             return;
@@ -1812,6 +1818,14 @@
         }.store();
         body.accept(this);
 
+        if (forNode.needsScopeCreator() && lc.getCurrentBlock().providesScopeCreator()) {
+            // for-in loops with lexical declaration need a new scope for each iteration.
+            final FieldObjectCreator<?> creator = scopeObjectCreators.peek();
+            assert creator != null;
+            creator.createForInIterationScope(method);
+            method.storeCompilerConstant(SCOPE);
+        }
+
         if(method.isReachable()) {
             method._goto(continueLabel);
         }
@@ -1923,12 +1937,16 @@
              * Create a new object based on the symbols and values, generate
              * bootstrap code for object
              */
-            new FieldObjectCreator<Symbol>(this, tuples, true, hasArguments) {
+            final FieldObjectCreator<Symbol> creator = new FieldObjectCreator<Symbol>(this, tuples, true, hasArguments) {
                 @Override
                 protected void loadValue(final Symbol value, final Type type) {
                     method.load(value, type);
                 }
-            }.makeObject(method);
+            };
+            creator.makeObject(method);
+            if (block.providesScopeCreator()) {
+                scopeObjectCreators.push(creator);
+            }
             // program function: merge scope into global
             if (isFunctionBody && function.isProgram()) {
                 method.invoke(ScriptRuntime.MERGE_SCOPE);
@@ -3294,8 +3312,10 @@
         final boolean needsScope = identSymbol.isScope();
 
         if (init == null) {
-            if (needsScope && varNode.isBlockScoped()) {
-                // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ)
+            // Block-scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ).
+            // However, don't do this for CONST which always has an initializer except in the special case of
+            // for-in/of loops, in which it is initialized in the loop header and should be left untouched here.
+            if (needsScope && varNode.isLet()) {
                 method.loadCompilerConstant(SCOPE);
                 method.loadUndefined(Type.OBJECT);
                 final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0);
@@ -4480,7 +4500,7 @@
                     final Symbol symbol = node.getSymbol();
                     assert symbol != null;
                     if (symbol.isScope()) {
-                        final int flags = getScopeCallSiteFlags(symbol);
+                        final int flags = getScopeCallSiteFlags(symbol) | (node.isDeclaredHere() ? CALLSITE_DECLARE : 0);
                         if (isFastScope(symbol)) {
                             storeFastScopeVar(symbol, flags);
                         } else {
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/FieldObjectCreator.java	Wed Mar 23 21:45:59 2016 -0700
@@ -120,6 +120,25 @@
         }
     }
 
+    /**
+     * Create a scope for a for-in/of loop as defined in ES6 13.7.5.13 step 5.g.iii
+     *
+     * @param method the method emitter
+     */
+    void createForInIterationScope(final MethodEmitter method) {
+        assert fieldObjectClass != null;
+        assert isScope();
+        assert getMap() != null;
+
+        final String className = getClassName();
+        method._new(fieldObjectClass).dup();
+        loadMap(method); //load the map
+        loadScope(method);
+        // We create a scope identical to the currently active one, so use its parent as our parent
+        method.invoke(ScriptObject.GET_PROTO);
+        method.invoke(constructorNoLookup(className, PropertyMap.class, ScriptObject.class));
+    }
+
     @Override
     public void populateRange(final MethodEmitter method, final Type objectType, final int objectSlot, final int start, final int end) {
         method.load(objectType, objectSlot);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Lower.java	Wed Mar 23 21:45:59 2016 -0700
@@ -97,6 +97,7 @@
 final class Lower extends NodeOperatorVisitor<BlockLexicalContext> implements Loggable {
 
     private final DebugLogger log;
+    private final boolean es6;
 
     // Conservative pattern to test if element names consist of characters valid for identifiers.
     // This matches any non-zero length alphanumeric string including _ and $ and not starting with a digit.
@@ -144,6 +145,7 @@
         });
 
         this.log = initLogger(compiler.getContext());
+        this.es6 = compiler.getScriptEnvironment()._es6;
     }
 
     @Override
@@ -257,8 +259,9 @@
         }
 
         newForNode = checkEscape(newForNode);
-        if(newForNode.isForIn()) {
-            // Wrap it in a block so its internally created iterator is restricted in scope
+        if(!es6 && newForNode.isForIn()) {
+            // Wrap it in a block so its internally created iterator is restricted in scope, unless we are running
+            // in ES6 mode, in which case the parser already created a block to capture let/const declarations.
             addStatementEnclosedInBlock(newForNode);
         } else {
             addStatement(newForNode);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Block.java	Wed Mar 23 21:45:59 2016 -0700
@@ -462,6 +462,19 @@
         return next;
     }
 
+    /**
+     * Determine whether this block needs to provide its scope object creator for use by its child nodes.
+     * This is only necessary for synthetic parent blocks of for-in loops with lexical declarations.
+     *
+     * @see ForNode#needsScopeCreator()
+     * @return true if child nodes need access to this block's scope creator
+     */
+    public boolean providesScopeCreator() {
+        return needsScope() && isSynthetic()
+                && (getLastStatement() instanceof ForNode)
+                && ((ForNode) getLastStatement()).needsScopeCreator();
+    }
+
     @Override
     public boolean isBreakableWithoutLabel() {
         return false;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ForNode.java	Wed Mar 23 21:45:59 2016 -0700
@@ -274,4 +274,15 @@
     public boolean hasPerIterationScope() {
         return (flags & PER_ITERATION_SCOPE) != 0;
     }
+
+    /**
+     * Returns true if this for-node needs the scope creator of its containing block to create
+     * per-iteration scope. This is only true for for-in loops with lexical declarations.
+     *
+     * @see Block#providesScopeCreator()
+     * @return true if the containing block's scope object creator is required in codegen
+     */
+    public boolean needsScopeCreator() {
+        return isForIn() && hasPerIterationScope();
+    }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/Global.java	Wed Mar 23 21:45:59 2016 -0700
@@ -1057,6 +1057,9 @@
     private ScriptObject   builtinArrayIteratorPrototype;
     private ScriptObject   builtinStringIteratorPrototype;
 
+    private ScriptFunction builtInJavaExtend;
+    private ScriptFunction builtInJavaTo;
+
     /*
      * ECMA section 13.2.3 The [[ThrowTypeError]] Function Object
      */
@@ -2085,10 +2088,39 @@
     private synchronized ScriptObject getBuiltinJavaApi() {
         if (this.builtinJavaApi == null) {
             this.builtinJavaApi = initConstructor("Java", ScriptObject.class);
+            this.builtInJavaExtend = (ScriptFunction)builtinJavaApi.get("extend");
+            this.builtInJavaTo = (ScriptFunction)builtinJavaApi.get("to");
         }
         return this.builtinJavaApi;
     }
 
+    /**
+     * Returns true if the passed function is the built-in "Java.extend".
+     * @param fn the function in question
+     * @return true if the function is built-in "Java.extend"
+     */
+    public static boolean isBuiltInJavaExtend(final ScriptFunction fn) {
+        if(!"extend".equals(fn.getName())) {
+            // Avoid hitting the thread local if the name doesn't match.
+            return false;
+        }
+        return fn == Context.getGlobal().builtInJavaExtend;
+    }
+
+    /**
+     * Returns true if the passed function is the built-in "Java.to".
+     * @param fn the function in question
+     * @return true if the function is built-in "Java.to"
+     */
+    public static boolean isBuiltInJavaTo(final ScriptFunction fn) {
+        if(!"to".equals(fn.getName())) {
+            // Avoid hitting the thread local if the name doesn't match.
+            return false;
+        }
+        return fn == Context.getGlobal().builtInJavaTo;
+    }
+
+
     private synchronized ScriptFunction getBuiltinRangeError() {
         if (this.builtinRangeError == null) {
             this.builtinRangeError = initErrorSubtype("RangeError", getErrorPrototype());
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/LinkedMap.java	Wed Mar 23 21:45:59 2016 -0700
@@ -62,7 +62,7 @@
      */
     static class Node {
         private final Object key;
-        private final Object value;
+        private volatile Object value;
 
         private volatile boolean alive = true;
         private volatile Node prev;
@@ -103,6 +103,14 @@
         public Object getValue() {
             return value;
         }
+
+        /**
+         * Set the node's value
+         * @param value the new value
+         */
+        void setValue(final Object value) {
+            this.value = value;
+        }
     }
 
     /**
@@ -150,12 +158,14 @@
      * @param value the value
      */
     public void set(final Object key, final Object value) {
-        final Node newNode = new Node(key, value);
-        final Node oldNode = data.put(key, newNode);
-        if (oldNode != null) {
-            unlink(oldNode);
+        Node node = data.get(key);
+        if (node != null) {
+            node.setValue(value);
+        } else {
+            node = new Node(key, value);
+            data.put(key, node);
+            link(node);
         }
-        link(newNode);
     }
 
     /**
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJava.java	Wed Mar 23 21:45:59 2016 -0700
@@ -37,6 +37,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Queue;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.beans.BeansLinker;
 import jdk.dynalink.beans.StaticClass;
 import jdk.dynalink.linker.support.TypeUtilities;
@@ -64,7 +65,6 @@
  */
 @ScriptClass("Java")
 public final class NativeJava {
-
     // initialized by nasgen
     @SuppressWarnings("unused")
     private static PropertyMap $nasgenmap$;
@@ -391,6 +391,9 @@
 
         if(targetClass.isArray()) {
             try {
+                if (self instanceof SecureLookupSupplier) {
+                    return JSType.toJavaArrayWithLookup(obj, targetClass.getComponentType(), (SecureLookupSupplier)self);
+                }
                 return JSType.toJavaArray(obj, targetClass.getComponentType());
             } catch (final Exception exp) {
                 throw typeError(exp, "java.array.conversion.failed", targetClass.getName());
@@ -468,7 +471,7 @@
                 // Usually writable properties are a subset as 'write-only' properties are rare
                 props.addAll(BeansLinker.getReadableStaticPropertyNames(clazz));
                 props.addAll(BeansLinker.getStaticMethodNames(clazz));
-            } catch (Exception ignored) {}
+            } catch (final Exception ignored) {}
             return props;
         } else if (object instanceof JSObject) {
             final JSObject jsObj = ((JSObject)object);
@@ -484,7 +487,7 @@
                 // Usually writable properties are a subset as 'write-only' properties are rare
                 props.addAll(BeansLinker.getReadableInstancePropertyNames(clazz));
                 props.addAll(BeansLinker.getInstanceMethodNames(clazz));
-            } catch (Exception ignored) {}
+            } catch (final Exception ignored) {}
             return props;
         }
 
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java	Wed Mar 23 21:45:59 2016 -0700
@@ -1104,12 +1104,14 @@
                 } finally {
                     defaultNames.pop();
                 }
-            } else if (varType == CONST) {
+            } else if (varType == CONST && isStatement) {
                 throw error(AbstractParser.message("missing.const.assignment", name.getName()));
             }
 
+            // Only set declaration flag on lexically scoped let/const as it adds runtime overhead.
+            final IdentNode actualName = varType == LET || varType == CONST ? name.setIsDeclaredHere() : name;
             // Allocate var node.
-            final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, name.setIsDeclaredHere(), init, varFlags);
+            final VarNode var = new VarNode(varLine, varToken, sourceOrder, finish, actualName, init, varFlags);
             vars.add(var);
             appendStatement(var);
 
@@ -1247,7 +1249,6 @@
 
             expect(LPAREN);
 
-
             switch (type) {
             case VAR:
                 // Var declaration captured in for outer block.
@@ -1257,9 +1258,7 @@
                 break;
             default:
                 if (useBlockScope() && (type == LET || type == CONST)) {
-                    if (type == LET) {
-                        flags |= ForNode.PER_ITERATION_SCOPE;
-                    }
+                    flags |= ForNode.PER_ITERATION_SCOPE;
                     // LET/CONST declaration captured in container block created above.
                     vars = variableStatement(type, false, forStart);
                     break;
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java	Wed Mar 23 21:45:59 2016 -0700
@@ -35,6 +35,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.beans.StaticClass;
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.internal.codegen.CompilerConstants.Call;
@@ -175,6 +176,9 @@
     /** Method handle to convert a JS Object to a Java array. */
     public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
 
+    /** Method handle to convert a JS Object to a Java array. */
+    public static final Call TO_JAVA_ARRAY_WITH_LOOKUP = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArrayWithLookup", Object.class, Object.class, Class.class, SecureLookupSupplier.class);
+
     /** Method handle for void returns. */
     public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
 
@@ -798,7 +802,7 @@
      * @return the value converted to Integer or Double
      */
     public static Number toNarrowestNumber(final long l) {
-        return isRepresentableAsInt(l) ? Integer.valueOf((int) l) : Double.valueOf((double) l);
+        return isRepresentableAsInt(l) ? Integer.valueOf((int) l) : Double.valueOf(l);
     }
 
     /**
@@ -1108,7 +1112,7 @@
      * @return the uint32 value as double
      */
     public static double toUint32Double(final int num) {
-        return (double) toUint32(num);
+        return toUint32(num);
     }
 
     /**
@@ -1319,6 +1323,20 @@
     }
 
     /**
+     * Script object to Java array conversion.
+     *
+     * @param obj script object to be converted to Java array
+     * @param componentType component type of the destination array required
+     * @param lookupSupplier supplier for the lookup of the class invoking the
+     * conversion. Can be used to use protection-domain specific converters
+     * if the target type is a SAM.
+     * @return converted Java array
+     */
+    public static Object toJavaArrayWithLookup(final Object obj, final Class<?> componentType, final SecureLookupSupplier lookupSupplier) {
+        return Bootstrap.getLinkerServices().getWithLookup(()->toJavaArray(obj, componentType), lookupSupplier);
+    }
+
+    /**
      * Java array to java array conversion - but using type conversions implemented by linker.
      *
      * @param src source array
@@ -1744,9 +1762,9 @@
     public static MethodHandle unboxConstant(final Object o) {
         if (o != null) {
             if (o.getClass() == Integer.class) {
-                return MH.constant(int.class, ((Integer)o));
+                return MH.constant(int.class, o);
             } else if (o.getClass() == Double.class) {
-                return MH.constant(double.class, ((Double)o));
+                return MH.constant(double.class, o);
             }
         }
         return MH.constant(Object.class, o);
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptFunction.java	Wed Mar 23 21:45:59 2016 -0700
@@ -29,6 +29,7 @@
 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
 import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
+
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodHandles.Lookup;
@@ -45,6 +46,7 @@
 import java.util.List;
 import java.util.concurrent.atomic.LongAdder;
 import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.linker.GuardedInvocation;
 import jdk.dynalink.linker.LinkRequest;
 import jdk.dynalink.linker.support.Guards;
@@ -129,7 +131,7 @@
     private static final Object LAZY_PROTOTYPE = new Object();
 
     private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
-            AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
+            AccessControlContextFactory.createAccessControlContext(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
 
     private static PropertyMap createStrictModeMap(final PropertyMap map) {
         final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
@@ -955,10 +957,14 @@
                 // It's already (callee, this, args...), just what we need
                 boundHandle = callHandle;
             }
-        } else if (data.isBuiltin() && "extend".equals(data.getName())) {
-            // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
-            // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
+        } else if (data.isBuiltin() && Global.isBuiltInJavaExtend(this)) {
+            // We're binding the current lookup as "self" so the function can do
+            // security-sensitive creation of adapter classes.
             boundHandle = MH.dropArguments(MH.bindTo(callHandle, getLookupPrivileged(desc)), 0, type.parameterType(0), type.parameterType(1));
+        } else if (data.isBuiltin() && Global.isBuiltInJavaTo(this)) {
+            // We're binding the current call site descriptor as "self" so the function can do
+            // security-sensitive creation of adapter classes.
+            boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc), 0, type.parameterType(0), type.parameterType(1));
         } else if (scopeCall && needsWrappedThis()) {
             // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
             // (this, args...) => ([this], args...)
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/SetMethodCreator.java	Wed Mar 23 21:45:59 2016 -0700
@@ -145,8 +145,7 @@
         final boolean isStrict  = NashornCallSiteDescriptor.isStrict(desc);
         final MethodHandle methodHandle;
 
-        if (NashornCallSiteDescriptor.isDeclaration(desc)) {
-            assert property.needsDeclaration();
+        if (NashornCallSiteDescriptor.isDeclaration(desc) && property.needsDeclaration()) {
             // This is a LET or CONST being declared. The property is already there but flagged as needing declaration.
             // We create a new PropertyMap with the flag removed. The map is installed with a fast compare-and-set
             // method if the pre-callsite map is stable (which should be the case for function scopes except for
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java	Wed Mar 23 21:45:59 2016 -0700
@@ -32,8 +32,10 @@
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.util.function.Supplier;
 import jdk.dynalink.CallSiteDescriptor;
 import jdk.dynalink.NamedOperation;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.StandardOperation;
 import jdk.dynalink.beans.BeansLinker;
 import jdk.dynalink.linker.ConversionComparator.Comparison;
@@ -153,7 +155,7 @@
         if (arg instanceof ConsString) {
             return arg.toString();
         } else if (mirrorAlways && arg instanceof ScriptObject) {
-            return ScriptUtils.wrap((ScriptObject)arg);
+            return ScriptUtils.wrap(arg);
         } else {
             return arg;
         }
@@ -250,5 +252,10 @@
         public MethodHandle filterInternalObjects(final MethodHandle target) {
             return linkerServices.filterInternalObjects(target);
         }
+
+        @Override
+        public <T> T getWithLookup(final Supplier<T> operation, final SecureLookupSupplier lookupSupplier) {
+            return linkerServices.getWithLookup(operation, lookupSupplier);
+        }
     }
 }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java	Wed Mar 23 21:45:59 2016 -0700
@@ -43,6 +43,7 @@
 import jdk.dynalink.CompositeOperation;
 import jdk.dynalink.NamedOperation;
 import jdk.dynalink.Operation;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.StandardOperation;
 import jdk.nashorn.internal.ir.debug.NashornTextifier;
 import jdk.nashorn.internal.runtime.AccessControlContextFactory;
@@ -161,7 +162,7 @@
     };
 
     private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
-            AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
+            AccessControlContextFactory.createAccessControlContext(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
 
     @SuppressWarnings("unchecked")
     private static final Map<String, Reference<NamedOperation>>[] NAMED_OPERATIONS =
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Wed Mar 23 19:33:47 2016 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Wed Mar 23 21:45:59 2016 -0700
@@ -42,6 +42,7 @@
 import java.util.function.Supplier;
 import javax.script.Bindings;
 import jdk.dynalink.CallSiteDescriptor;
+import jdk.dynalink.SecureLookupSupplier;
 import jdk.dynalink.linker.ConversionComparator;
 import jdk.dynalink.linker.GuardedInvocation;
 import jdk.dynalink.linker.GuardingTypeConverterFactory;
@@ -53,6 +54,7 @@
 import jdk.nashorn.api.scripting.JSObject;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import jdk.nashorn.api.scripting.ScriptUtils;
+import jdk.nashorn.internal.codegen.CompilerConstants.Call;
 import jdk.nashorn.internal.objects.NativeArray;
 import jdk.nashorn.internal.runtime.AccessControlContextFactory;
 import jdk.nashorn.internal.runtime.JSType;
@@ -67,7 +69,7 @@
  */
 final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory, ConversionComparator {
     private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
-            AccessControlContextFactory.createAccessControlContext(CallSiteDescriptor.GET_LOOKUP_PERMISSION_NAME);
+            AccessControlContextFactory.createAccessControlContext(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
 
     private static final ClassValue<MethodHandle> ARRAY_CONVERTERS = new ClassValue<MethodHandle>() {
         @Override
@@ -111,7 +113,7 @@
 
     @Override
     public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType, final Supplier<MethodHandles.Lookup> lookupSupplier) throws Exception {
-        GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
+        GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType, lookupSupplier);
         if(gi == null) {
             gi = getSamTypeConverter(sourceType, targetType, lookupSupplier);
         }
@@ -128,13 +130,13 @@
      * @return a guarded invocation that converts from the source type to the target type.
      * @throws Exception if something goes wrong
      */
-    private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception {
+    private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType, final Supplier<MethodHandles.Lookup> lookupSupplier) throws Exception {
         final MethodHandle mh = JavaArgumentConverters.getConverter(targetType);
         if (mh != null) {
             return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
         }
 
-        final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType);
+        final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType, lookupSupplier);
         if(arrayConverter != null) {
             return arrayConverter;
         }
@@ -183,7 +185,7 @@
      * either the source type is neither NativeArray, nor a superclass of it, or if the target type is not an array
      * type, List, Queue, Deque, or Collection.
      */
-    private static GuardedInvocation getArrayConverter(final Class<?> sourceType, final Class<?> targetType) {
+    private static GuardedInvocation getArrayConverter(final Class<?> sourceType, final Class<?> targetType, final Supplier<MethodHandles.Lookup> lookupSupplier) {
         final boolean isSourceTypeNativeArray = sourceType == NativeArray.class;
         // If source type is more generic than NativeArray class, we'll need to use a guard
         final boolean isSourceTypeGeneric = !isSourceTypeNativeArray && sourceType.isAssignableFrom(NativeArray.class);
@@ -191,7 +193,25 @@
         if (isSourceTypeNativeArray || isSourceTypeGeneric) {
             final MethodHandle guard = isSourceTypeGeneric ? IS_NATIVE_ARRAY : null;
             if(targetType.isArray()) {
-                return new GuardedInvocation(ARRAY_CONVERTERS.get(targetType), guard);
+                final MethodHandle mh = ARRAY_CONVERTERS.get(targetType);
+                final MethodHandle mhWithLookup;
+                if (mh.type().parameterCount() == 2) {
+                    assert mh.type().parameterType(1) == SecureLookupSupplier.class;
+                    // We enter this branch when the array's ultimate component
+                    // type is a SAM type; we use a handle to JSType.toJavaArrayWithLookup
+                    // for these in the converter MH and must bind it here with
+                    // a secure supplier for the current lookup. By retrieving
+                    // the lookup, we'll also (correctly) inform the type
+                    // converter that this array converter is lookup specific.
+                    // We then need to wrap the returned lookup into a
+                    // new SecureLookupSupplier in order to bind it to the
+                    // JSType.toJavaArrayWithLookup() parameter.
+                    mhWithLookup = MH.insertArguments(mh, 1,
+                            new SecureLookupSupplier(getCurrentLookup(lookupSupplier)));
+                } else {
+                    mhWithLookup = mh;
+                }
+                return new GuardedInvocation(mhWithLookup, guard);
             } else if(targetType == List.class) {
                 return new GuardedInvocation(TO_LIST, guard);
             } else if(targetType == Deque.class) {
@@ -207,8 +227,24 @@
 
     private static MethodHandle createArrayConverter(final Class<?> type) {
         assert type.isArray();
-        final MethodHandle converter = MH.insertArguments(JSType.TO_JAVA_ARRAY.methodHandle(), 1, type.getComponentType());
-        return MH.asType(converter, converter.type().changeReturnType(type));
+
+        final Class<?> componentType = type.getComponentType();
+        final Call converterCall;
+        // Is the ultimate component type of this array a SAM type?
+        if (isComponentTypeAutoConvertibleFromFunction(componentType)) {
+            converterCall = JSType.TO_JAVA_ARRAY_WITH_LOOKUP;
+        } else {
+            converterCall = JSType.TO_JAVA_ARRAY;
+        }
+        final MethodHandle typeBoundConverter = MH.insertArguments(converterCall.methodHandle(), 1, componentType);
+        return MH.asType(typeBoundConverter, typeBoundConverter.type().changeReturnType(type));
+    }
+
+    private static boolean isComponentTypeAutoConvertibleFromFunction(final Class<?> targetType) {
+        if (targetType.isArray()) {
+            return isComponentTypeAutoConvertibleFromFunction(targetType.getComponentType());
+        }
+        return isAutoConvertibleFromFunction(targetType);
     }
 
     private static GuardedInvocation getMirrorConverter(final Class<?> sourceType, final Class<?> targetType) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/JDK-8150218.js	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,63 @@
+/*
+ * 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-8150218: Autoconversion SAM adapters sometimes don't get privileges
+ *
+ * @test
+ * @run
+ */
+
+function f() {
+    java.lang.System.getProperty("user.dir")
+}
+
+java.security.AccessController.doPrivileged(new java.security.PrivilegedAction(function () {
+    // Control: this used to work even before this improvement
+    new java.lang.Runnable(f).run()
+
+    // SAM type explicitly created through an array needs to get the right permissions too
+    Java.to([f], Java.type("java.lang.Runnable[]"))[0].run()
+
+    // Even when more deeply nested
+    Java.to([[[f]]], Java.type("java.lang.Runnable[][][]"))[0][0][0].run()
+
+    var rt = new (Java.type("jdk.dynalink.test.ArrayRunnableTest"))
+    var n = "runnables"
+
+    // Explicit array passed to vararg setter chosen at run time
+    rt[n] = [f]
+    rt.firstRunnable.run()
+
+    // Automatically packed one-element array passed to vararg setter chosen at run time
+    rt[n] = f
+    rt.firstRunnable.run()
+
+    // Explicit array passed to vararg method overload chosen at run time
+    rt.setRunnablesOverloaded([f])
+    rt.firstRunnable.run()
+
+    // Automatically packed one-element array passed to vararg method overload chosen at run time
+    rt.setRunnablesOverloaded(f)
+    rt.firstRunnable.run()
+}))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/es6/JDK-8151809.js	Wed Mar 23 21:45:59 2016 -0700
@@ -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.
+ */
+
+/**
+ * JDK-8151809: ES6 Map/Set insertion with existing keys changes iteration order
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+function assertSetIteratorResult(result, expectedDone, expectedValue) {
+    Assert.assertEquals(result.done, expectedDone);
+    Assert.assertEquals(result.value, expectedValue);
+}
+
+function assertMapIteratorResult(result, expectedDone, expectedKey, expectedValue) {
+    Assert.assertEquals(result.done, expectedDone);
+    if (expectedDone) {
+        Assert.assertEquals(result.value, undefined);
+    } else {
+        Assert.assertEquals(result.value[0], expectedKey);
+        Assert.assertEquals(result.value[1], expectedValue);
+    }
+}
+
+let set = new Set(["foo", "bar", "foo"]);
+let iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "foo");
+assertSetIteratorResult(iter.next(), false, "bar");
+assertSetIteratorResult(iter.next(), true);
+
+set.add ("foo");
+iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "foo", false);
+assertSetIteratorResult(iter.next(), false, "bar", false);
+assertSetIteratorResult(iter.next(), true);
+
+set.delete("foo");
+set.add ("foo");
+assertSetIteratorResult(iter.next(), true);
+iter = set[Symbol.iterator]();
+assertSetIteratorResult(iter.next(), false, "bar", false);
+assertSetIteratorResult(iter.next(), false, "foo", false);
+assertSetIteratorResult(iter.next(), true);
+
+
+let map = new Map([["foo", 1], ["bar", 2], ["foo", 3]]);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "foo", 3);
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), true);
+
+
+map.set("foo", 4);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "foo", 4);
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), true);
+
+map.delete("foo");
+map.set("foo", 5);
+assertMapIteratorResult(iter.next(), true);
+iter = map[Symbol.iterator]();
+assertMapIteratorResult(iter.next(), false, "bar", 2);
+assertMapIteratorResult(iter.next(), false, "foo", 5);
+assertMapIteratorResult(iter.next(), true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/es6/JDK-8151810.js	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,69 @@
+/*
+ * 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-8151810: for-in iteration does not provide per-iteration scope
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+"use strict";
+
+let array = ["a", "b", "c"];
+let funcs = [];
+
+for (let i in array) {
+    funcs.push(function() { return array[i]; });
+}
+
+Assert.assertEquals(funcs.length, 3);
+
+for (let i = 0; i < 3; i++) {
+    Assert.assertEquals(funcs[i](), array[i]);
+}
+
+funcs = [];
+
+for (let i in array) {
+    for (let j in array) {
+        for (let k in array) {
+            funcs.push(function () {
+                return array[i] + array[j] + array[k];
+            });
+        }
+    }
+}
+
+Assert.assertEquals(funcs.length, 3 * 3 * 3);
+let count = 0;
+
+for (let i = 0; i < 3; i++) {
+    for (let j = 0; j < 3; j++) {
+        for (let k = 0; k < 3; k++) {
+            Assert.assertEquals(funcs[count++](), array[i] + array[j] + array[k]);
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/basic/es6/JDK-8151811.js	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,72 @@
+/*
+ * 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-8151811: Const declarations do not work in for..in loops
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+let array = ["a", "b", "c"];
+let count = 0;
+
+for (const i in array) {
+    try {
+        eval("i = 5");
+        fail("const assignment should have thrown")
+    } catch (e) {
+        Assert.assertTrue(e instanceof TypeError);
+    }
+    Assert.assertTrue(i == count++);
+}
+
+let funcs = [];
+
+for (const i in array) {
+    try {
+        eval("i = 5");
+        fail("const assignment should have thrown")
+    } catch (e) {
+        Assert.assertTrue(e instanceof TypeError);
+    }
+    for (const j in array) {
+        for (const k in array) {
+            funcs.push(function () {
+                return array[i] + array[j] + array[k];
+            });
+        }
+    }
+}
+
+Assert.assertEquals(funcs.length, 3 * 3 * 3);
+count = 0;
+
+for (let i = 0; i < 3; i++) {
+    for (let j = 0; j < 3; j++) {
+        for (let k = 0; k < 3; k++) {
+            Assert.assertEquals(funcs[count++](), array[i] + array[j] + array[k]);
+        }
+    }
+}
--- a/test/script/nosecurity/JDK-8144221.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/JDK-8144221.js	Wed Mar 23 21:45:59 2016 -0700
@@ -26,7 +26,7 @@
  *
  * @test
  * @option -scripting
- * @run
+ * @runif os.not.windows.cmd
  */
 
 // The test generates three different JavaScript source files. The first two
--- a/test/script/nosecurity/JDK-8151291.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/JDK-8151291.js	Wed Mar 23 21:45:59 2016 -0700
@@ -27,7 +27,7 @@
  *
  * @test
  * @option -scripting
- * @run
+ * @runif os.not.windows.cmd
  */
 
 $EXEC(["java", "-version"])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/script/nosecurity/JDK-util.js	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,114 @@
+/*
+ * 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())
+        }
+    }
+}
+
+/**
+ * Removes a given file
+ * @param pathname name of the file
+ */
+function rm(pathname) {
+    var Path = Paths.get(pathname)
+    if (!Files.deleteIfExists(Path))
+        print("File \"${pathname}\" doesn't exist")
+}
+    
+
+
+/**
+ * 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
+    }                   
+
+}
+
+/**
+ * convert given path based on underlying shell programme runs on
+ */
+function toShellPath(path) {
+    if (windows) {
+        if (winCyg) {
+            return cygpath(path,outPath.mixed)
+        }else {
+         var path = cygpath(path,outPath.windows)
+         //convert '\' ->'\\',cmd shell expects this.
+         return path.replaceAll('\\\\','\\\\\\\\')
+       }
+    }else {
+        return path
+    }
+} 
+
--- a/test/script/nosecurity/jjs-common.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-common.js	Wed Mar 23 21:45:59 2016 -0700
@@ -26,15 +26,29 @@
  * @subtest
  * @summary test used by all other jjs-option* test cases
  */
-var javaHome = $ENV.JAVA_HOME,
-    homeJjs = "${javaHome}/bin/jjs",
-    altJjs = $EXEC('which jjs').trim(),
-    homejavac = "${javaHome}/bin/javac",
-    altjavac = $EXEC('which javac').trim()
 
-var Files = Java.type('java.nio.file.Files'),
-    Paths = Java.type('java.nio.file.Paths'),
-    System = Java.type('java.lang.System')
+load(__DIR__ + "JDK-util.js")
+
+var javaHome = System.getenv("JAVA_HOME"),
+    homeJjs = "${javaHome}" + "/bin/jjs",
+    altJjs = which('jjs'),
+    homejavac = "${javaHome}" + "/bin/javac",
+    altjavac = which('javac')
+
+if (windows) {
+    if (winCyg) {
+        //Files.exists() expects proper extension as it talks to windows filesystem even on cygwin
+        //make paths work on on underlying shells cygwin/cmd/linux.
+        homeJjs = toShellPath("${javaHome}" + "/bin/jjs.exe")
+        homejavac = toShellPath("${javaHome}" + "/bin/javac.exe")
+    }
+    else {
+        homeJjs = toShellPath("${javaHome}" + "\\bin\\jjs.exe")
+        homejavac = toShellPath("${javaHome}" + "\\bin\\javac.exe")
+    }
+    altJjs = which('jjs.exe')
+    altjavac = which('javac.exe')
+}
 
 // Initialize default values for variables used in different functions
 var func_cond_p = <<EOD
@@ -62,12 +76,11 @@
 
 // create file to check -flag passing
 var path_f = Paths.get("temp-flag.js")
-var testflag_file = path_f.toAbsolutePath()
+var testflag_file = toShellPath(path_f.toAbsolutePath().toString())
 
 // create file to check -flag functionality
 var path_func = Paths.get("temp-func.js")
-var testfunc_file = path_func.toAbsolutePath()
-
+var testfunc_file = toShellPath(path_func.toAbsolutePath().toString())
 
 function exists(f) {
     return Files.exists(Paths.get(f))
@@ -82,12 +95,12 @@
 
 // write code to testflag_file
 function write_testflag_file() {
-    Files.write(testflag_file, msg_flag.getBytes())
+    Files.write(Paths.get(testflag_file), msg_flag.getBytes())
 }
 
 // write code to testfunc_file
 function write_testfunc_file() {
-    Files.write(testfunc_file, msg_func.getBytes())
+    Files.write(Paths.get(testfunc_file), msg_func.getBytes())
 }
 
 function flag_test_pass() {
@@ -106,7 +119,7 @@
     if (positive) {
         if (eval(func_cond_p))
             print("functionality test PASSED")
-        else
+        else 
             print("functionality test FAILED. stdout: ${out} -- stderr: ${err}")
     }
     else {
@@ -156,8 +169,8 @@
         print("${flag} flag negative test:")
         testjjs_opt("${args_n} ${testflag_file}", false, true)        // negative test
     } finally {
-        $EXEC("rm ${testflag_file}")
-        $EXEC("rm ${testfunc_file}")
+        rm("${testflag_file}")
+        rm("${testfunc_file}")
     }
 }
 
@@ -171,7 +184,7 @@
         print("${flag} flag negative test:")
         testjjs_opt_func("${args_n} ${testfunc_file}", false)        // negative test
     } finally {
-        $EXEC("rm ${testfunc_file}")
+        rm("${testfunc_file}")
     }
 }
 
@@ -185,6 +198,6 @@
         print("${flag} flag negative test:")
         testjjs_opt("${args_n} ${testflag_file}", false, false)        // negative test
     } finally {
-        $EXEC("rm ${testflag_file}")
+        rm("${testflag_file}")
     }
 }
--- a/test/script/nosecurity/jjs-option-cp.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-cp.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,37 +25,44 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test to check if -cp flag and its basic functionality
  */
 
 load(__DIR__ + "jjs-common.js")
 
-var hello = __DIR__ + "Hello.class";
-var helloj = __DIR__ + "Hello.java";
+var hello = __DIR__ + "Hello.class"
+var helloj = __DIR__ + "Hello.java"
+
+hello = toShellPath(hello)
+helloj = toShellPath(helloj)
 
 // code to check -flag
 var msg_flag = "print($OPTIONS._classpath)"
 
 // code to check basic functionality
 var msg_func = <<EOD
-$EXEC("rm -f ${hello}")
+var Files = Java.type('java.nio.file.Files')
+var Paths = Java.type('java.nio.file.Paths')
+Files.deleteIfExists(Paths.get("${hello}"))
 $EXEC("${javac} ${helloj}")
-var v = new Packages.Hello();
+var v = new Packages.Hello()
 if (v.string != 'hello') {
-    throw new Error("Unexpected property value");
+    throw new Error("Unexpected property value")
 }
 EOD
 
+var dir = toShellPath(__DIR__)
+
 // flag test expected output variables
-var e_outp = "__DIR__"
+var e_outp = "${dir}"
 var e_outn = "null"
 
 // functionality test arguments
-var arg_p = "-scripting -cp ${__DIR__}  ${testfunc_file}"
+var arg_p = "-scripting -cp ${dir}  ${testfunc_file}"
 var arg_n = "-scripting ${testfunc_file}"
 
 // Testing starts here
-testjjs_flag_and_func("-cp", " __DIR__")
-$EXEC("rm -f ${hello}")
+testjjs_flag_and_func("-cp", " ${dir}")
+rm("${hello}")
+
--- a/test/script/nosecurity/jjs-option-define.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-define.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test to check -D flag basic functionality
  */
@@ -38,7 +37,7 @@
 // code to check basic functionality
 var msg_func = <<EOD
 try {
-    var System = Java.type('java.lang.System');
+    var System = Java.type('java.lang.System')
     print(System.getProperty('user.name'))
     if (System.getProperty('user.name') != "nashorn9")
         throw new Error("un expected system property user.name value")
--- a/test/script/nosecurity/jjs-option-doe.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-doe.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -doe flag and its basic functionality
  */
--- a/test/script/nosecurity/jjs-option-fv.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-fv.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test if -fv flag its basic funnctionality
  */
--- a/test/script/nosecurity/jjs-option-fx.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-fx.js	Wed Mar 23 21:45:59 2016 -0700
@@ -26,7 +26,6 @@
  * check -fx option.
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -fx flag and its basic functionality
  * the JavaFX primary stage is available to Nashorn as a global property $STAGE with -fx
@@ -35,7 +34,7 @@
 
 load(__DIR__ + "jjs-common.js")
 
-var msg_flag = "print(typeof($STAGE)); exit();";
+var msg_flag = "print(typeof($STAGE)); exit();"
 
 // flag test expected output variables
 var e_outn = "undefined"
--- a/test/script/nosecurity/jjs-option-lang.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-lang.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -lang flag and its basic functionality
  */
--- a/test/script/nosecurity/jjs-option-ot.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-ot.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -ot flag
  */
@@ -33,7 +32,7 @@
 load(__DIR__ + "jjs-common.js")
 
 var args_n = "-scripting -ot=false"
-var msg_flag = "print($OPTIONS._optimistic_types);";
+var msg_flag = "print($OPTIONS._optimistic_types)"
 
 // flag test expected output variables
 var e_outp = "true"
--- a/test/script/nosecurity/jjs-option-scripting.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-scripting.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -scripting flag and its basic functionality
  */
@@ -40,7 +39,7 @@
 var x = "Nashorn"
 var hello = "Hello ${x}"
 if (hello != "Hello Nashorn") {
-    throw new Error("string interploation not working");
+    throw new Error("string interploation not working")
 }
 EOD
 
--- a/test/script/nosecurity/jjs-option-strict.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-strict.js	Wed Mar 23 21:45:59 2016 -0700
@@ -25,7 +25,6 @@
  * JDK-8144113: Nashorn: enable jjs testing. 
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test  -strict flag and its basic functionality
  */
--- a/test/script/nosecurity/jjs-option-version.js	Wed Mar 23 19:33:47 2016 -0700
+++ b/test/script/nosecurity/jjs-option-version.js	Wed Mar 23 21:45:59 2016 -0700
@@ -26,7 +26,6 @@
  * check if jjs version is same as of java.
  * @test
  * @option -scripting
- * @runif os.not.windows
  * @run
  * @summary Test -version flag and its functionality 
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/src/jdk/dynalink/test/ArrayRunnableTest.java	Wed Mar 23 21:45:59 2016 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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.dynalink.test;
+
+public class ArrayRunnableTest {
+    private Runnable[] r;
+    public void setRunnables(final Runnable... r) {
+        this.r = r;
+    }
+
+    public Runnable getFirstRunnable() {
+        return r[0];
+    }
+
+    public void setRunnablesOverloaded(final Runnable... r) {
+        this.r = r;
+    }
+
+    public void setRunnablesOverloaded(final Object... r) {
+        throw new UnsupportedOperationException();
+    }
+}