Merge jdk8u5-b07

Sun, 02 Feb 2014 22:51:24 -0800

author
asaha
date
Sun, 02 Feb 2014 22:51:24 -0800
changeset 797
96ad962a6a88
parent 796
2d9af8fd30cd
parent 730
9cc3fd32fbab
child 798
142454c92c9f

Merge

.hgtags file | annotate | diff | comparison | revisions
     1.1 --- a/.hgtags	Fri Jan 31 22:24:45 2014 -0800
     1.2 +++ b/.hgtags	Sun Feb 02 22:51:24 2014 -0800
     1.3 @@ -237,6 +237,7 @@
     1.4  7346abe2ea03134e1aee3b3d0fccb047235bd221 jdk8-b125
     1.5  095263db862da23fa04d57c7e93e553831132449 jdk8-b126
     1.6  fdfbb745caf0e54775a44e66e39d3025785e0528 jdk8-b127
     1.7 +73cbad0c5d28b8f6e12f634aceeb2b3b4ad09553 jdk8-b128
     1.8  13ca8f1a9eba716295fb7d9c2ddad81390931919 jdk8u5-b01
     1.9  7e7cb9977a3d1244384ffa454a4890764a07b042 jdk8u5-b02
    1.10  2abeb654b57f306f73f3f73bdfa05f93bce2a1f3 jdk8u5-b03
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java	Sun Feb 02 22:51:24 2014 -0800
     2.3 @@ -0,0 +1,102 @@
     2.4 +/*
     2.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Oracle designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Oracle in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.25 + * or visit www.oracle.com if you need additional information or have any
    2.26 + * questions.
    2.27 + */
    2.28 +
    2.29 +/*
    2.30 + * This file is available under and governed by the GNU General Public
    2.31 + * License version 2 only, as published by the Free Software Foundation.
    2.32 + * However, the following notice accompanied the original version of this
    2.33 + * file, and Oracle licenses the original version of this file under the BSD
    2.34 + * license:
    2.35 + */
    2.36 +/*
    2.37 +   Copyright 2009-2013 Attila Szegedi
    2.38 +
    2.39 +   Licensed under both the Apache License, Version 2.0 (the "Apache License")
    2.40 +   and the BSD License (the "BSD License"), with licensee being free to
    2.41 +   choose either of the two at their discretion.
    2.42 +
    2.43 +   You may not use this file except in compliance with either the Apache
    2.44 +   License or the BSD License.
    2.45 +
    2.46 +   If you choose to use this file in compliance with the Apache License, the
    2.47 +   following notice applies to you:
    2.48 +
    2.49 +       You may obtain a copy of the Apache License at
    2.50 +
    2.51 +           http://www.apache.org/licenses/LICENSE-2.0
    2.52 +
    2.53 +       Unless required by applicable law or agreed to in writing, software
    2.54 +       distributed under the License is distributed on an "AS IS" BASIS,
    2.55 +       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    2.56 +       implied. See the License for the specific language governing
    2.57 +       permissions and limitations under the License.
    2.58 +
    2.59 +   If you choose to use this file in compliance with the BSD License, the
    2.60 +   following notice applies to you:
    2.61 +
    2.62 +       Redistribution and use in source and binary forms, with or without
    2.63 +       modification, are permitted provided that the following conditions are
    2.64 +       met:
    2.65 +       * Redistributions of source code must retain the above copyright
    2.66 +         notice, this list of conditions and the following disclaimer.
    2.67 +       * Redistributions in binary form must reproduce the above copyright
    2.68 +         notice, this list of conditions and the following disclaimer in the
    2.69 +         documentation and/or other materials provided with the distribution.
    2.70 +       * Neither the name of the copyright holder nor the names of
    2.71 +         contributors may be used to endorse or promote products derived from
    2.72 +         this software without specific prior written permission.
    2.73 +
    2.74 +       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    2.75 +       IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
    2.76 +       TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    2.77 +       PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
    2.78 +       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    2.79 +       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    2.80 +       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    2.81 +       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    2.82 +       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    2.83 +       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
    2.84 +       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2.85 +*/
    2.86 +
    2.87 +package jdk.internal.dynalink.linker;
    2.88 +
    2.89 +public class GuardedTypeConversion {
    2.90 +    private final GuardedInvocation conversionInvocation;
    2.91 +    private final boolean cacheable;
    2.92 +
    2.93 +    public GuardedTypeConversion(final GuardedInvocation conversionInvocation, final boolean cacheable) {
    2.94 +        this.conversionInvocation = conversionInvocation;
    2.95 +        this.cacheable = cacheable;
    2.96 +    }
    2.97 +
    2.98 +    public GuardedInvocation getConversionInvocation() {
    2.99 +        return conversionInvocation;
   2.100 +    }
   2.101 +
   2.102 +    public boolean isCacheable() {
   2.103 +        return cacheable;
   2.104 +    }
   2.105 +}
     3.1 --- a/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java	Fri Jan 31 22:24:45 2014 -0800
     3.2 +++ b/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java	Sun Feb 02 22:51:24 2014 -0800
     3.3 @@ -96,19 +96,19 @@
     3.4   */
     3.5  public interface GuardingTypeConverterFactory {
     3.6      /**
     3.7 -     * Returns a guarded invocation that receives an Object of the specified source type and returns an Object converted
     3.8 -     * to the specified target type. The type of the invocation is targetType(sourceType), while the type of the guard
     3.9 -     * is boolean(sourceType). Note that this will never be invoked for type conversions allowed by the JLS 5.3 "Method
    3.10 -     * Invocation Conversion", see {@link TypeUtilities#isMethodInvocationConvertible(Class, Class)} for details. An
    3.11 -     * implementation can assume it is never requested to produce a converter for these conversions.
    3.12 +     * Returns a guarded type conversion that receives an Object of the specified source type and returns an Object
    3.13 +     * converted to the specified target type. The type of the invocation is targetType(sourceType), while the type of
    3.14 +     * the guard is boolean(sourceType). Note that this will never be invoked for type conversions allowed by the JLS
    3.15 +     * 5.3 "Method Invocation Conversion", see {@link TypeUtilities#isMethodInvocationConvertible(Class, Class)} for
    3.16 +     * details. An implementation can assume it is never requested to produce a converter for these conversions.
    3.17       *
    3.18       * @param sourceType source type
    3.19       * @param targetType the target type.
    3.20 -     * @return a guarded invocation that can take an object (if it passes guard) and returns another object that is its
    3.21 -     * representation coerced into the target type. In case the factory is certain it is unable to handle a conversion,
    3.22 -     * it can return null. In case the factory is certain that it can always handle the conversion, it can return an
    3.23 -     * unconditional invocation (one whose guard is null).
    3.24 +     * @return a guarded type conversion that contains a guarded invocation that can take an object (if it passes guard)
    3.25 +     * and return another object that is its representation coerced into the target type. In case the factory is certain
    3.26 +     * it is unable to handle a conversion, it can return null. In case the factory is certain that it can always handle
    3.27 +     * the conversion, it can return an unconditional invocation (one whose guard is null).
    3.28       * @throws Exception if there was an error during creation of the converter
    3.29       */
    3.30 -    public GuardedInvocation convertToType(Class<?> sourceType, Class<?> targetType) throws Exception;
    3.31 +    public GuardedTypeConversion convertToType(Class<?> sourceType, Class<?> targetType) throws Exception;
    3.32  }
     4.1 --- a/src/jdk/internal/dynalink/support/LinkerServicesImpl.java	Fri Jan 31 22:24:45 2014 -0800
     4.2 +++ b/src/jdk/internal/dynalink/support/LinkerServicesImpl.java	Sun Feb 02 22:51:24 2014 -0800
     4.3 @@ -98,6 +98,9 @@
     4.4   */
     4.5  public class LinkerServicesImpl implements LinkerServices {
     4.6  
     4.7 +    private static final RuntimePermission GET_CURRENT_LINK_REQUEST = new RuntimePermission("dynalink.getCurrentLinkRequest");
     4.8 +    private static final ThreadLocal<LinkRequest> threadLinkRequest = new ThreadLocal<>();
     4.9 +
    4.10      private final TypeConverterFactory typeConverterFactory;
    4.11      private final GuardingDynamicLinker topLevelLinker;
    4.12  
    4.13 @@ -135,6 +138,26 @@
    4.14  
    4.15      @Override
    4.16      public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest) throws Exception {
    4.17 -        return topLevelLinker.getGuardedInvocation(linkRequest, this);
    4.18 +        final LinkRequest prevLinkRequest = threadLinkRequest.get();
    4.19 +        threadLinkRequest.set(linkRequest);
    4.20 +        try {
    4.21 +            return topLevelLinker.getGuardedInvocation(linkRequest, this);
    4.22 +        } finally {
    4.23 +            threadLinkRequest.set(prevLinkRequest);
    4.24 +        }
    4.25 +    }
    4.26 +
    4.27 +    /**
    4.28 +     * Returns the currently processed link request, or null if the method is invoked outside of the linking process.
    4.29 +     * @return the currently processed link request, or null.
    4.30 +     * @throws SecurityException if the calling code doesn't have the {@code "dynalink.getCurrentLinkRequest"} runtime
    4.31 +     * permission.
    4.32 +     */
    4.33 +    public static LinkRequest getCurrentLinkRequest() {
    4.34 +        SecurityManager sm = System.getSecurityManager();
    4.35 +        if(sm != null) {
    4.36 +            sm.checkPermission(GET_CURRENT_LINK_REQUEST);
    4.37 +        }
    4.38 +        return threadLinkRequest.get();
    4.39      }
    4.40  }
     5.1 --- a/src/jdk/internal/dynalink/support/TypeConverterFactory.java	Fri Jan 31 22:24:45 2014 -0800
     5.2 +++ b/src/jdk/internal/dynalink/support/TypeConverterFactory.java	Sun Feb 02 22:51:24 2014 -0800
     5.3 @@ -94,6 +94,7 @@
     5.4  import jdk.internal.dynalink.linker.ConversionComparator;
     5.5  import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
     5.6  import jdk.internal.dynalink.linker.GuardedInvocation;
     5.7 +import jdk.internal.dynalink.linker.GuardedTypeConversion;
     5.8  import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
     5.9  import jdk.internal.dynalink.linker.LinkerServices;
    5.10  
    5.11 @@ -134,8 +135,8 @@
    5.12                  @Override
    5.13                  protected MethodHandle computeValue(Class<?> targetType) {
    5.14                      if(!canAutoConvert(sourceType, targetType)) {
    5.15 -                        final MethodHandle converter = getTypeConverterNull(sourceType, targetType);
    5.16 -                        if(converter != null) {
    5.17 +                        final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType);
    5.18 +                        if(converter != IDENTITY_CONVERSION) {
    5.19                              return converter;
    5.20                          }
    5.21                      }
    5.22 @@ -145,6 +146,24 @@
    5.23          }
    5.24      };
    5.25  
    5.26 +    private final ClassValue<ClassMap<Boolean>> canConvert = new ClassValue<ClassMap<Boolean>>() {
    5.27 +        @Override
    5.28 +        protected ClassMap<Boolean> computeValue(final Class<?> sourceType) {
    5.29 +            return new ClassMap<Boolean>(getClassLoader(sourceType)) {
    5.30 +                @Override
    5.31 +                protected Boolean computeValue(Class<?> targetType) {
    5.32 +                    try {
    5.33 +                        return getTypeConverterNull(sourceType, targetType) != null;
    5.34 +                    } catch (RuntimeException e) {
    5.35 +                        throw e;
    5.36 +                    } catch (Exception e) {
    5.37 +                        throw new RuntimeException(e);
    5.38 +                    }
    5.39 +                }
    5.40 +            };
    5.41 +        }
    5.42 +    };
    5.43 +
    5.44      private static final ClassLoader getClassLoader(final Class<?> clazz) {
    5.45          return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
    5.46              @Override
    5.47 @@ -253,7 +272,7 @@
    5.48       * @return true if there can be a conversion, false if there can not.
    5.49       */
    5.50      public boolean canConvert(final Class<?> from, final Class<?> to) {
    5.51 -        return canAutoConvert(from, to) || getTypeConverterNull(from, to) != null;
    5.52 +        return canAutoConvert(from, to) || canConvert.get(from).get(to).booleanValue();
    5.53      }
    5.54  
    5.55      /**
    5.56 @@ -294,9 +313,21 @@
    5.57          return TypeUtilities.isMethodInvocationConvertible(fromType, toType);
    5.58      }
    5.59  
    5.60 +    /*private*/ MethodHandle getCacheableTypeConverterNull(Class<?> sourceType, Class<?> targetType) {
    5.61 +        final MethodHandle converter = getCacheableTypeConverter(sourceType, targetType);
    5.62 +        return converter == IDENTITY_CONVERSION ? null : converter;
    5.63 +    }
    5.64 +
    5.65      /*private*/ MethodHandle getTypeConverterNull(Class<?> sourceType, Class<?> targetType) {
    5.66 -        final MethodHandle converter = converterMap.get(sourceType).get(targetType);
    5.67 -        return converter == IDENTITY_CONVERSION ? null : converter;
    5.68 +        try {
    5.69 +            return getCacheableTypeConverterNull(sourceType, targetType);
    5.70 +        } catch(NotCacheableConverter e) {
    5.71 +            return e.converter;
    5.72 +        }
    5.73 +    }
    5.74 +
    5.75 +    /*private*/ MethodHandle getCacheableTypeConverter(Class<?> sourceType, Class<?> targetType) {
    5.76 +        return converterMap.get(sourceType).get(targetType);
    5.77      }
    5.78  
    5.79      /**
    5.80 @@ -309,22 +340,44 @@
    5.81       * @return a method handle performing the conversion.
    5.82       */
    5.83      public MethodHandle getTypeConverter(Class<?> sourceType, Class<?> targetType) {
    5.84 -        return converterIdentityMap.get(sourceType).get(targetType);
    5.85 +        try {
    5.86 +            return converterIdentityMap.get(sourceType).get(targetType);
    5.87 +        } catch(NotCacheableConverter e) {
    5.88 +            return e.converter;
    5.89 +        }
    5.90      }
    5.91  
    5.92      /*private*/ MethodHandle createConverter(Class<?> sourceType, Class<?> targetType) throws Exception {
    5.93          final MethodType type = MethodType.methodType(targetType, sourceType);
    5.94          final MethodHandle identity = IDENTITY_CONVERSION.asType(type);
    5.95          MethodHandle last = identity;
    5.96 +        boolean cacheable = true;
    5.97          for(int i = factories.length; i-- > 0;) {
    5.98 -            final GuardedInvocation next = factories[i].convertToType(sourceType, targetType);
    5.99 +            final GuardedTypeConversion next = factories[i].convertToType(sourceType, targetType);
   5.100              if(next != null) {
   5.101 -                next.assertType(type);
   5.102 -                last = next.compose(last);
   5.103 +                cacheable = cacheable && next.isCacheable();
   5.104 +                final GuardedInvocation conversionInvocation = next.getConversionInvocation();
   5.105 +                conversionInvocation.assertType(type);
   5.106 +                last = conversionInvocation.compose(last);
   5.107              }
   5.108          }
   5.109 -        return last == identity ? IDENTITY_CONVERSION : last;
   5.110 +        if(last == identity) {
   5.111 +            return IDENTITY_CONVERSION;
   5.112 +        }
   5.113 +        if(cacheable) {
   5.114 +            return last;
   5.115 +        }
   5.116 +        throw new NotCacheableConverter(last);
   5.117      }
   5.118  
   5.119      /*private*/ static final MethodHandle IDENTITY_CONVERSION = MethodHandles.identity(Object.class);
   5.120 +
   5.121 +    private static class NotCacheableConverter extends RuntimeException {
   5.122 +        final MethodHandle converter;
   5.123 +
   5.124 +        NotCacheableConverter(final MethodHandle converter) {
   5.125 +            super("", null, false, false);
   5.126 +            this.converter = converter;
   5.127 +        }
   5.128 +    }
   5.129  }
     6.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Fri Jan 31 22:24:45 2014 -0800
     6.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Sun Feb 02 22:51:24 2014 -0800
     6.3 @@ -32,6 +32,7 @@
     6.4  import java.io.InputStream;
     6.5  import java.io.InputStreamReader;
     6.6  import java.io.Reader;
     6.7 +import java.lang.invoke.MethodHandles;
     6.8  import java.lang.reflect.Method;
     6.9  import java.lang.reflect.Modifier;
    6.10  import java.net.URL;
    6.11 @@ -104,7 +105,7 @@
    6.12      private volatile Property         contextProperty;
    6.13  
    6.14      // default options passed to Nashorn Options object
    6.15 -    private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" };
    6.16 +    private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
    6.17  
    6.18      // Nashorn script engine error message management
    6.19      private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
    6.20 @@ -355,7 +356,8 @@
    6.21                  if (! isInterfaceImplemented(clazz, realSelf)) {
    6.22                      return null;
    6.23                  }
    6.24 -                return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz).invoke(realSelf));
    6.25 +                return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz,
    6.26 +                        MethodHandles.publicLookup()).invoke(realSelf));
    6.27              } finally {
    6.28                  if (globalChanged) {
    6.29                      Context.setGlobal(oldGlobal);
     7.1 --- a/src/jdk/nashorn/internal/objects/NativeJava.java	Fri Jan 31 22:24:45 2014 -0800
     7.2 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java	Sun Feb 02 22:51:24 2014 -0800
     7.3 @@ -28,6 +28,7 @@
     7.4  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
     7.5  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
     7.6  
     7.7 +import java.lang.invoke.MethodHandles;
     7.8  import java.lang.reflect.Array;
     7.9  import java.util.Collection;
    7.10  import java.util.Deque;
    7.11 @@ -463,12 +464,14 @@
    7.12       * </pre>
    7.13       * We can see several important concepts in the above example:
    7.14       * <ul>
    7.15 -     * <li>Every specified list of Java types will have exactly one extender subclass in Nashorn - repeated invocations
    7.16 -     * of {@code extend} for the same list of types will yield the same extender type. It's a generic adapter that
    7.17 -     * delegates to whatever JavaScript functions its implementation object has on a per-instance basis.</li>
    7.18 +     * <li>Every specified list of Java types will have one extender subclass in Nashorn per caller protection domain -
    7.19 +     * repeated invocations of {@code extend} for the same list of types for scripts same protection domain will yield
    7.20 +     * the same extender type. It's a generic adapter that delegates to whatever JavaScript functions its implementation
    7.21 +     * object has on a per-instance basis.</li>
    7.22       * <li>If the Java method is overloaded (as in the above example {@code List.add()}), then your JavaScript adapter
    7.23       * must be prepared to deal with all overloads.</li>
    7.24 -     * <li>You can't invoke {@code super.*()} from adapters for now.</li>
    7.25 +     * <li>To invoke super methods from adapters, call them on the adapter instance prefixing them with {@code super$},
    7.26 +     * or use the special {@link #_super(Object, Object) super-adapter}.</li>
    7.27       * <li>It is also possible to specify an ordinary JavaScript object as the last argument to {@code extend}. In that
    7.28       * case, it is treated as a class-level override. {@code extend} will return an extender class where all instances
    7.29       * will have the methods implemented by functions on that object, just as if that object were passed as the last
    7.30 @@ -486,15 +489,18 @@
    7.31       * t.join()
    7.32       * </pre>
    7.33       * As you can see, you don't have to pass any object when you create a new instance of {@code R1} as its
    7.34 -     * {@code run()} function was defined already when extending the class. Of course, you can still provide
    7.35 -     * instance-level overrides on these objects. The order of precedence is instance-level method, class-level method,
    7.36 -     * superclass method, or {@code UnsupportedOperationException} if the superclass method is abstract. If we continue
    7.37 -     * our previous example:
    7.38 +     * {@code run()} function was defined already when extending the class. If you also want to add instance-level
    7.39 +     * overrides on these objects, you will have to repeatedly use {@code extend()} to subclass the class-level adapter.
    7.40 +     * For such adapters, the order of precedence is instance-level method, class-level method, superclass method, or
    7.41 +     * {@code UnsupportedOperationException} if the superclass method is abstract. If we continue our previous example:
    7.42       * <pre>
    7.43 -     * var r2 = new R1(function() { print("r2.run() invoked!") })
    7.44 +     * var R2 = Java.extend(R1);
    7.45 +     * var r2 = new R2(function() { print("r2.run() invoked!") })
    7.46       * r2.run()
    7.47       * </pre>
    7.48       * We'll see it'll print {@code "r2.run() invoked!"}, thus overriding on instance-level the class-level behavior.
    7.49 +     * Note that you must use {@code Java.extend} to explicitly create an instance-override adapter class from a
    7.50 +     * class-override adapter class, as the class-override adapter class is no longer abstract.
    7.51       * </li>
    7.52       * </ul>
    7.53       * @param self not used
    7.54 @@ -541,7 +547,18 @@
    7.55          } catch(final ClassCastException e) {
    7.56              throw typeError("extend.expects.java.types");
    7.57          }
    7.58 -        return JavaAdapterFactory.getAdapterClassFor(stypes, classOverrides);
    7.59 +        // Note that while the public API documentation claims self is not used, we actually use it.
    7.60 +        // ScriptFunction.findCallMethod will bind the lookup object into it, and we can then use that lookup when
    7.61 +        // requesting the adapter class. Note that if Java.extend is invoked with no lookup object, it'll pass the
    7.62 +        // public lookup which'll result in generation of a no-permissions adapter. A typical situation this can happen
    7.63 +        // is when the extend function is bound.
    7.64 +        final MethodHandles.Lookup lookup;
    7.65 +        if(self instanceof MethodHandles.Lookup) {
    7.66 +            lookup = (MethodHandles.Lookup)self;
    7.67 +        } else {
    7.68 +            lookup = MethodHandles.publicLookup();
    7.69 +        }
    7.70 +        return JavaAdapterFactory.getAdapterClassFor(stypes, classOverrides, lookup);
    7.71      }
    7.72  
    7.73      /**
     8.1 --- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Fri Jan 31 22:24:45 2014 -0800
     8.2 +++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java	Sun Feb 02 22:51:24 2014 -0800
     8.3 @@ -33,6 +33,7 @@
     8.4  import jdk.nashorn.internal.objects.annotations.Constructor;
     8.5  import jdk.nashorn.internal.objects.annotations.Function;
     8.6  import jdk.nashorn.internal.objects.annotations.ScriptClass;
     8.7 +import jdk.nashorn.internal.runtime.Context;
     8.8  import jdk.nashorn.internal.runtime.NativeJavaPackage;
     8.9  import jdk.nashorn.internal.runtime.PropertyMap;
    8.10  import jdk.nashorn.internal.runtime.ScriptObject;
    8.11 @@ -156,8 +157,9 @@
    8.12              } else if (obj instanceof NativeJavaPackage) {
    8.13                  final String pkgName  = ((NativeJavaPackage)obj).getName();
    8.14                  final String fullName = pkgName.isEmpty() ? name : (pkgName + "." + name);
    8.15 +                final Context context = Global.instance().getContext();
    8.16                  try {
    8.17 -                    return StaticClass.forClass(Class.forName(fullName));
    8.18 +                    return StaticClass.forClass(context.findClass(fullName));
    8.19                  } catch (final ClassNotFoundException e) {
    8.20                      // IGNORE
    8.21                  }
     9.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java	Fri Jan 31 22:24:45 2014 -0800
     9.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java	Sun Feb 02 22:51:24 2014 -0800
     9.3 @@ -645,10 +645,12 @@
     9.4              targetObj.addBoundProperties(source, props);
     9.5          } else if (source instanceof StaticClass) {
     9.6              final Class<?> clazz = ((StaticClass)source).getRepresentedClass();
     9.7 +            Bootstrap.checkReflectionAccess(clazz, true);
     9.8              bindBeanProperties(targetObj, source, BeansLinker.getReadableStaticPropertyNames(clazz),
     9.9                      BeansLinker.getWritableStaticPropertyNames(clazz), BeansLinker.getStaticMethodNames(clazz));
    9.10          } else {
    9.11              final Class<?> clazz = source.getClass();
    9.12 +            Bootstrap.checkReflectionAccess(clazz, false);
    9.13              bindBeanProperties(targetObj, source, BeansLinker.getReadableInstancePropertyNames(clazz),
    9.14                      BeansLinker.getWritableInstancePropertyNames(clazz), BeansLinker.getInstanceMethodNames(clazz));
    9.15          }
    9.16 @@ -663,7 +665,6 @@
    9.17          propertyNames.addAll(writablePropertyNames);
    9.18  
    9.19          final Class<?> clazz = source.getClass();
    9.20 -        Bootstrap.checkReflectionAccess(clazz);
    9.21  
    9.22          final MethodType getterType = MethodType.methodType(Object.class, clazz);
    9.23          final MethodType setterType = MethodType.methodType(Object.class, clazz, Object.class);
    10.1 --- a/src/jdk/nashorn/internal/runtime/Context.java	Fri Jan 31 22:24:45 2014 -0800
    10.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java	Sun Feb 02 22:51:24 2014 -0800
    10.3 @@ -647,6 +647,19 @@
    10.4      }
    10.5  
    10.6      /**
    10.7 +     * Checks that the given package name can be accessed from no permissions context.
    10.8 +     *
    10.9 +     * @param pkgName package name
   10.10 +     * @throw SecurityException if not accessible
   10.11 +     */
   10.12 +    public static void checkPackageAccess(final String pkgName) {
   10.13 +        final SecurityManager sm = System.getSecurityManager();
   10.14 +        if (sm != null) {
   10.15 +            checkPackageAccess(sm, pkgName.endsWith(".")? pkgName : pkgName + ".");
   10.16 +        }
   10.17 +    }
   10.18 +
   10.19 +    /**
   10.20       * Checks that the given package can be accessed from no permissions context.
   10.21       *
   10.22       * @param sm current security manager instance
    11.1 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Fri Jan 31 22:24:45 2014 -0800
    11.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java	Sun Feb 02 22:51:24 2014 -0800
    11.3 @@ -85,6 +85,8 @@
    11.4       */
    11.5      public NativeJavaPackage(final String name, final ScriptObject proto) {
    11.6          super(proto, null);
    11.7 +        // defense-in-path, check here for sensitive packages
    11.8 +        Context.checkPackageAccess(name);
    11.9          this.name = name;
   11.10      }
   11.11  
    12.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Fri Jan 31 22:24:45 2014 -0800
    12.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java	Sun Feb 02 22:51:24 2014 -0800
    12.3 @@ -26,14 +26,13 @@
    12.4  package jdk.nashorn.internal.runtime;
    12.5  
    12.6  import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
    12.7 +import static jdk.nashorn.internal.lookup.Lookup.MH;
    12.8  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    12.9  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   12.10 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   12.11  
   12.12  import java.lang.invoke.MethodHandle;
   12.13  import java.lang.invoke.MethodHandles;
   12.14  import java.lang.invoke.MethodType;
   12.15 -
   12.16  import jdk.internal.dynalink.CallSiteDescriptor;
   12.17  import jdk.internal.dynalink.linker.GuardedInvocation;
   12.18  import jdk.internal.dynalink.linker.LinkRequest;
   12.19 @@ -524,7 +523,11 @@
   12.20              }
   12.21          } else {
   12.22              final MethodHandle callHandle = getBestInvoker(type.dropParameterTypes(0, 1), request.getArguments());
   12.23 -            if (scopeCall) {
   12.24 +            if (data.isBuiltin() && "extend".equals(data.getName())) {
   12.25 +                // NOTE: the only built-in named "extend" is NativeJava.extend. As a special-case we're binding the
   12.26 +                // current lookup as its "this" so it can do security-sensitive creation of adapter classes.
   12.27 +                boundHandle = MH.dropArguments(MH.bindTo(callHandle, desc.getLookup()), 0, Object.class, Object.class);
   12.28 +            } else if (scopeCall) {
   12.29                  // Make a handle that drops the passed "this" argument and substitutes either Global or Undefined
   12.30                  // (this, args...) => (args...)
   12.31                  boundHandle = MH.bindTo(callHandle, needsWrappedThis() ? Context.getGlobalTrusted() : ScriptRuntime.UNDEFINED);
    13.1 --- a/src/jdk/nashorn/internal/runtime/linker/AdaptationResult.java	Fri Jan 31 22:24:45 2014 -0800
    13.2 +++ b/src/jdk/nashorn/internal/runtime/linker/AdaptationResult.java	Sun Feb 02 22:51:24 2014 -0800
    13.3 @@ -47,7 +47,8 @@
    13.4          ERROR_NON_PUBLIC_CLASS,
    13.5          ERROR_NO_ACCESSIBLE_CONSTRUCTOR,
    13.6          ERROR_MULTIPLE_SUPERCLASSES,
    13.7 -        ERROR_NO_COMMON_LOADER
    13.8 +        ERROR_NO_COMMON_LOADER,
    13.9 +        ERROR_FINAL_FINALIZER
   13.10      }
   13.11  
   13.12      static final AdaptationResult SUCCESSFUL_RESULT = new AdaptationResult(Outcome.SUCCESS, "");
    14.1 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Fri Jan 31 22:24:45 2014 -0800
    14.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java	Sun Feb 02 22:51:24 2014 -0800
    14.3 @@ -278,9 +278,10 @@
    14.4       * {@code java.lang.invoke} package, as well a {@link Class} and any subclass of {@link ClassLoader}) and there is
    14.5       * a security manager in the system, then it checks the {@code nashorn.JavaReflection} {@code RuntimePermission}.
    14.6       * @param clazz the class being tested
    14.7 +     * @param isStatic is access checked for static members (or instance members)
    14.8       */
    14.9 -    public static void checkReflectionAccess(Class<?> clazz) {
   14.10 -        ReflectionCheckLinker.checkReflectionAccess(clazz);
   14.11 +    public static void checkReflectionAccess(Class<?> clazz, boolean isStatic) {
   14.12 +        ReflectionCheckLinker.checkReflectionAccess(clazz, isStatic);
   14.13      }
   14.14  
   14.15      /**
    15.1 --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Fri Jan 31 22:24:45 2014 -0800
    15.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java	Sun Feb 02 22:51:24 2014 -0800
    15.3 @@ -32,6 +32,7 @@
    15.4  import java.util.Map;
    15.5  import jdk.internal.dynalink.CallSiteDescriptor;
    15.6  import jdk.internal.dynalink.linker.GuardedInvocation;
    15.7 +import jdk.internal.dynalink.linker.GuardedTypeConversion;
    15.8  import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
    15.9  import jdk.internal.dynalink.linker.LinkRequest;
   15.10  import jdk.internal.dynalink.linker.LinkerServices;
   15.11 @@ -79,7 +80,7 @@
   15.12      }
   15.13  
   15.14      @Override
   15.15 -    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   15.16 +    public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   15.17          final boolean sourceIsAlwaysJSObject = JSObject.class.isAssignableFrom(sourceType);
   15.18          if(!sourceIsAlwaysJSObject && !sourceType.isAssignableFrom(JSObject.class)) {
   15.19              return null;
   15.20 @@ -90,7 +91,7 @@
   15.21              return null;
   15.22          }
   15.23  
   15.24 -        return new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType));
   15.25 +        return new GuardedTypeConversion(new GuardedInvocation(converter, sourceIsAlwaysJSObject ? null : IS_JSOBJECT_GUARD).asType(MethodType.methodType(targetType, sourceType)), true);
   15.26      }
   15.27  
   15.28  
    16.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Fri Jan 31 22:24:45 2014 -0800
    16.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java	Sun Feb 02 22:51:24 2014 -0800
    16.3 @@ -59,6 +59,7 @@
    16.4  import java.util.List;
    16.5  import java.util.Set;
    16.6  import jdk.internal.org.objectweb.asm.ClassWriter;
    16.7 +import jdk.internal.org.objectweb.asm.Handle;
    16.8  import jdk.internal.org.objectweb.asm.Label;
    16.9  import jdk.internal.org.objectweb.asm.Opcodes;
   16.10  import jdk.internal.org.objectweb.asm.Type;
   16.11 @@ -66,21 +67,23 @@
   16.12  import jdk.nashorn.internal.runtime.Context;
   16.13  import jdk.nashorn.internal.runtime.ScriptFunction;
   16.14  import jdk.nashorn.internal.runtime.ScriptObject;
   16.15 +import jdk.nashorn.internal.runtime.linker.AdaptationResult.Outcome;
   16.16  import sun.reflect.CallerSensitive;
   16.17  
   16.18  /**
   16.19   * Generates bytecode for a Java adapter class. Used by the {@link JavaAdapterFactory}.
   16.20   * </p><p>
   16.21 - * For every protected or public constructor in the extended class, the adapter class will have between one to three
   16.22 + * For every protected or public constructor in the extended class, the adapter class will have either one or two
   16.23   * public constructors (visibility of protected constructors in the extended class is promoted to public).
   16.24 - * <ul>
   16.25 - * <li>In every case, a constructor taking a trailing ScriptObject argument preceded by original constructor arguments
   16.26 - * is always created on the adapter class. When such a constructor is invoked, the passed ScriptObject's member
   16.27 - * functions are used to implement and/or override methods on the original class, dispatched by name. A single
   16.28 - * JavaScript function will act as the implementation for all overloaded methods of the same name. When methods on an
   16.29 - * adapter instance are invoked, the functions are invoked having the ScriptObject passed in the instance constructor as
   16.30 - * their "this". Subsequent changes to the ScriptObject (reassignment or removal of its functions) are not reflected in
   16.31 - * the adapter instance; the method implementations are bound to functions at constructor invocation time.
   16.32 + * <li>
   16.33 + * <li>For adapter classes with instance-level overrides, a constructor taking a trailing ScriptObject argument preceded
   16.34 + * by original constructor arguments is always created on the adapter class. When such a constructor is invoked, the
   16.35 + * passed ScriptObject's member functions are used to implement and/or override methods on the original class,
   16.36 + * dispatched by name. A single JavaScript function will act as the implementation for all overloaded methods of the
   16.37 + * same name. When methods on an adapter instance are invoked, the functions are invoked having the ScriptObject passed
   16.38 + * in the instance constructor as their "this". Subsequent changes to the ScriptObject (reassignment or removal of its
   16.39 + * functions) are not reflected in the adapter instance; the method implementations are bound to functions at
   16.40 + * constructor invocation time.
   16.41   * {@code java.lang.Object} methods {@code equals}, {@code hashCode}, and {@code toString} can also be overridden. The
   16.42   * only restriction is that since every JavaScript object already has a {@code toString} function through the
   16.43   * {@code Object.prototype}, the {@code toString} in the adapter is only overridden if the passed ScriptObject has a
   16.44 @@ -89,16 +92,17 @@
   16.45   * </li>
   16.46   * <li>
   16.47   * If the original types collectively have only one abstract method, or have several of them, but all share the
   16.48 - * same name, an additional constructor is provided for every original constructor; this one takes a ScriptFunction as
   16.49 - * its last argument preceded by original constructor arguments. This constructor will use the passed function as the
   16.50 - * implementation for all abstract methods. For consistency, any concrete methods sharing the single abstract method
   16.51 - * name will also be overridden by the function. When methods on the adapter instance are invoked, the ScriptFunction is
   16.52 - * invoked with global or UNDEFINED as its "this" depending whether the function is non-strict or not.
   16.53 + * same name, an additional constructor for instance-level override adapter is provided for every original constructor;
   16.54 + * this one takes a ScriptFunction as its last argument preceded by original constructor arguments. This constructor
   16.55 + * will use the passed function as the implementation for all abstract methods. For consistency, any concrete methods
   16.56 + * sharing the single abstract method name will also be overridden by the function. When methods on the adapter instance
   16.57 + * are invoked, the ScriptFunction is invoked with UNDEFINED or Global as its "this" depending whether the function is
   16.58 + * strict or not.
   16.59   * </li>
   16.60   * <li>
   16.61   * If the adapter being generated can have class-level overrides, constructors taking same arguments as the superclass
   16.62 - * constructors are also created. These constructors simply delegate to the superclass constructor. They are used to
   16.63 - * create instances of the adapter class with no instance-level overrides.
   16.64 + * constructors are created. These constructors simply delegate to the superclass constructor. They are simply used to
   16.65 + * create instances of the adapter class, with no instance-level overrides, as they don't have them.
   16.66   * </li>
   16.67   * </ul>
   16.68   * </p><p>
   16.69 @@ -111,16 +115,20 @@
   16.70   * source-level script expression <code>new X(a, b) { ... }</code> (which is a proprietary syntax extension Nashorn uses
   16.71   * to resemble Java anonymous classes) is actually equivalent to <code>new X(a, b, { ... })</code>.
   16.72   * </p><p>
   16.73 - * It is possible to create two different classes: those that can have both class-level and instance-level overrides,
   16.74 - * and those that can only have instance-level overrides. When
   16.75 - * {@link JavaAdapterFactory#getAdapterClassFor(Class[], ScriptObject)} is invoked with non-null {@code classOverrides}
   16.76 - * parameter, an adapter class is created that can have class-level overrides, and the passed script object will be used
   16.77 - * as the implementations for its methods, just as in the above case of the constructor taking a script object. Note
   16.78 - * that in the case of class-level overrides, a new adapter class is created on every invocation, and the implementation
   16.79 - * object is bound to the class, not to any instance. All created instances will share these functions. Of course, when
   16.80 - * instances of such a class are being created, they can still take another object (or possibly a function) in their
   16.81 - * constructor's trailing position and thus provide further instance-specific overrides. The order of invocation is
   16.82 - * always instance-specified method, then a class-specified method, and finally the superclass method.
   16.83 + * It is possible to create two different adapter classes: those that can have class-level overrides, and those that can
   16.84 + * have instance-level overrides. When {@link JavaAdapterFactory#getAdapterClassFor(Class[], ScriptObject)} is invoked
   16.85 + * with non-null {@code classOverrides} parameter, an adapter class is created that can have class-level overrides, and
   16.86 + * the passed script object will be used as the implementations for its methods, just as in the above case of the
   16.87 + * constructor taking a script object. Note that in the case of class-level overrides, a new adapter class is created on
   16.88 + * every invocation, and the implementation object is bound to the class, not to any instance. All created instances
   16.89 + * will share these functions. If it is required to have both class-level overrides and instance-level overrides, the
   16.90 + * class-level override adapter class should be subclassed with an instance-override adapter. Since adapters delegate to
   16.91 + * super class when an overriding method handle is not specified, this will behave as expected. It is not possible to
   16.92 + * have both class-level and instance-level overrides in the same class for security reasons: adapter classes are
   16.93 + * defined with a protection domain of their creator code, and an adapter class that has both class and instance level
   16.94 + * overrides would need to have two potentially different protection domains: one for class-based behavior and one for
   16.95 + * instance-based behavior; since Java classes can only belong to a single protection domain, this could not be
   16.96 + * implemented securely.
   16.97   */
   16.98  final class JavaAdapterBytecodeGenerator {
   16.99      static final Type CONTEXT_TYPE       = Type.getType(Context.class);
  16.100 @@ -171,7 +179,6 @@
  16.101      private static final int MAX_GENERATED_TYPE_NAME_LENGTH = 255;
  16.102  
  16.103      private static final String CLASS_INIT = "<clinit>";
  16.104 -    private static final String STATIC_GLOBAL_FIELD_NAME = "staticGlobal";
  16.105  
  16.106      // Method name prefix for invoking super-methods
  16.107      static final String SUPER_PREFIX = "super$";
  16.108 @@ -199,6 +206,7 @@
  16.109      private final Set<MethodInfo> finalMethods = new HashSet<>(EXCLUDED);
  16.110      private final Set<MethodInfo> methodInfos = new HashSet<>();
  16.111      private boolean autoConvertibleFromFunction = false;
  16.112 +    private boolean hasExplicitFinalizer = false;
  16.113  
  16.114      private final ClassWriter cw;
  16.115  
  16.116 @@ -207,8 +215,8 @@
  16.117       * @param superClass the superclass the adapter will extend.
  16.118       * @param interfaces the interfaces the adapter will implement.
  16.119       * @param commonLoader the class loader that can see all of superClass, interfaces, and Nashorn classes.
  16.120 -     * @param classOverride true to generate the bytecode for the adapter that has both class-level and instance-level
  16.121 -     * overrides, false to generate the bytecode for the adapter that only has instance-level overrides.
  16.122 +     * @param classOverride true to generate the bytecode for the adapter that has class-level overrides, false to
  16.123 +     * generate the bytecode for the adapter that has instance-level overrides.
  16.124       * @throws AdaptationException if the adapter can not be generated for some reason.
  16.125       */
  16.126      JavaAdapterBytecodeGenerator(final Class<?> superClass, final List<Class<?>> interfaces,
  16.127 @@ -230,8 +238,7 @@
  16.128          superClassName = Type.getInternalName(superClass);
  16.129          generatedClassName = getGeneratedClassName(superClass, interfaces);
  16.130  
  16.131 -        cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
  16.132 -
  16.133 +        cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER, generatedClassName, null, superClassName, getInternalTypeNames(interfaces));
  16.134          generateGlobalFields();
  16.135  
  16.136          gatherMethods(superClass);
  16.137 @@ -244,17 +251,16 @@
  16.138          generateConstructors();
  16.139          generateMethods();
  16.140          generateSuperMethods();
  16.141 +        if (hasExplicitFinalizer) {
  16.142 +            generateFinalizerMethods();
  16.143 +        }
  16.144          // }
  16.145          cw.visitEnd();
  16.146      }
  16.147  
  16.148      private void generateGlobalFields() {
  16.149 -        cw.visitField(ACC_PRIVATE | ACC_FINAL, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.150 +        cw.visitField(ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0), GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.151          usedFieldNames.add(GLOBAL_FIELD_NAME);
  16.152 -        if(classOverride) {
  16.153 -            cw.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, STATIC_GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.154 -            usedFieldNames.add(STATIC_GLOBAL_FIELD_NAME);
  16.155 -        }
  16.156      }
  16.157  
  16.158      JavaAdapterClassLoader createAdapterClassLoader() {
  16.159 @@ -305,11 +311,9 @@
  16.160      }
  16.161  
  16.162      private void generateHandleFields() {
  16.163 +        final int flags = ACC_PRIVATE | ACC_FINAL | (classOverride ? ACC_STATIC : 0);
  16.164          for (final MethodInfo mi: methodInfos) {
  16.165 -            cw.visitField(ACC_PRIVATE | ACC_FINAL, mi.methodHandleInstanceFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.166 -            if(classOverride) {
  16.167 -                cw.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.168 -            }
  16.169 +            cw.visitField(flags, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR, null, null).visitEnd();
  16.170          }
  16.171      }
  16.172  
  16.173 @@ -337,7 +341,7 @@
  16.174                  } else {
  16.175                      mv.visitInsn(ACONST_NULL);
  16.176                  }
  16.177 -                mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.178 +                mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.179              }
  16.180              initGlobal = new Label();
  16.181              mv.goTo(initGlobal);
  16.182 @@ -351,15 +355,15 @@
  16.183              mv.aconst(mi.getName());
  16.184              mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
  16.185              mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_OBJECT_DESCRIPTOR);
  16.186 -            mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.187 +            mv.putstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.188          }
  16.189  
  16.190          if(initGlobal != null) {
  16.191              mv.visitLabel(initGlobal);
  16.192          }
  16.193 -        // Assign "staticGlobal = Context.getGlobal()"
  16.194 +        // Assign "global = Context.getGlobal()"
  16.195          invokeGetGlobalWithNullCheck(mv);
  16.196 -        mv.putstatic(generatedClassName, STATIC_GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.197 +        mv.putstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.198  
  16.199          endInitMethod(mv);
  16.200      }
  16.201 @@ -390,21 +394,21 @@
  16.202              // Generate a constructor that just delegates to ctor. This is used with class-level overrides, when we want
  16.203              // to create instances without further per-instance overrides.
  16.204              generateDelegatingConstructor(ctor);
  16.205 -        }
  16.206 +        } else {
  16.207 +            // Generate a constructor that delegates to ctor, but takes an additional ScriptObject parameter at the
  16.208 +            // beginning of its parameter list.
  16.209 +            generateOverridingConstructor(ctor, false);
  16.210  
  16.211 -        // Generate a constructor that delegates to ctor, but takes an additional ScriptObject parameter at the
  16.212 -        // beginning of its parameter list.
  16.213 -        generateOverridingConstructor(ctor, false);
  16.214 -
  16.215 -        if (samName != null) {
  16.216 -            if (!autoConvertibleFromFunction && ctor.getParameterTypes().length == 0) {
  16.217 -                // If the original type only has a single abstract method name, as well as a default ctor, then it can
  16.218 -                // be automatically converted from JS function.
  16.219 -                autoConvertibleFromFunction = true;
  16.220 +            if (samName != null) {
  16.221 +                if (!autoConvertibleFromFunction && ctor.getParameterTypes().length == 0) {
  16.222 +                    // If the original type only has a single abstract method name, as well as a default ctor, then it can
  16.223 +                    // be automatically converted from JS function.
  16.224 +                    autoConvertibleFromFunction = true;
  16.225 +                }
  16.226 +                // If all our abstract methods have a single name, generate an additional constructor, one that takes a
  16.227 +                // ScriptFunction as its first parameter and assigns it as the implementation for all abstract methods.
  16.228 +                generateOverridingConstructor(ctor, true);
  16.229              }
  16.230 -            // If all our abstract methods have a single name, generate an additional constructor, one that takes a
  16.231 -            // ScriptFunction as its first parameter and assigns it as the implementation for all abstract methods.
  16.232 -            generateOverridingConstructor(ctor, true);
  16.233          }
  16.234      }
  16.235  
  16.236 @@ -430,7 +434,7 @@
  16.237      }
  16.238  
  16.239      /**
  16.240 -     * Generates a constructor for the adapter class. This constructor will take the same arguments as the supertype
  16.241 +     * Generates a constructor for the instance adapter class. This constructor will take the same arguments as the supertype
  16.242       * constructor passed as the argument here, and delegate to it. However, it will take an additional argument of
  16.243       * either ScriptObject or ScriptFunction type (based on the value of the "fromFunction" parameter), and initialize
  16.244       * all the method handle fields of the adapter instance with functions from the script object (or the script
  16.245 @@ -498,7 +502,7 @@
  16.246                  mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
  16.247                  mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", getHandleDescriptor);
  16.248              }
  16.249 -            mv.putfield(generatedClassName, mi.methodHandleInstanceFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.250 +            mv.putfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.251          }
  16.252  
  16.253          // Assign "this.global = Context.getGlobal()"
  16.254 @@ -536,8 +540,7 @@
  16.255      private static class MethodInfo {
  16.256          private final Method method;
  16.257          private final MethodType type;
  16.258 -        private String methodHandleInstanceFieldName;
  16.259 -        private String methodHandleClassFieldName;
  16.260 +        private String methodHandleFieldName;
  16.261  
  16.262          private MethodInfo(final Class<?> clazz, final String name, final Class<?>... argTypes) throws NoSuchMethodException {
  16.263              this(clazz.getDeclaredMethod(name, argTypes));
  16.264 @@ -567,25 +570,20 @@
  16.265              return getName().hashCode() ^ type.hashCode();
  16.266          }
  16.267  
  16.268 -        void setIsCanonical(final Set<String> usedFieldNames, boolean classOverride) {
  16.269 -            methodHandleInstanceFieldName = nextName(usedFieldNames);
  16.270 -            if(classOverride) {
  16.271 -                methodHandleClassFieldName = nextName(usedFieldNames);
  16.272 -            }
  16.273 +        void setIsCanonical(final JavaAdapterBytecodeGenerator self) {
  16.274 +            methodHandleFieldName = self.nextName(getName());
  16.275          }
  16.276 +    }
  16.277  
  16.278 -        String nextName(final Set<String> usedFieldNames) {
  16.279 -            int i = 0;
  16.280 -            final String name = getName();
  16.281 -            String nextName = name;
  16.282 -            while (!usedFieldNames.add(nextName)) {
  16.283 -                final String ordinal = String.valueOf(i++);
  16.284 -                final int maxNameLen = 255 - ordinal.length();
  16.285 -                nextName = (name.length() <= maxNameLen ? name : name.substring(0, maxNameLen)).concat(ordinal);
  16.286 -            }
  16.287 -            return nextName;
  16.288 +    private String nextName(final String name) {
  16.289 +        int i = 0;
  16.290 +        String nextName = name;
  16.291 +        while (!usedFieldNames.add(nextName)) {
  16.292 +            final String ordinal = String.valueOf(i++);
  16.293 +            final int maxNameLen = 255 - ordinal.length();
  16.294 +            nextName = (name.length() <= maxNameLen ? name : name.substring(0, maxNameLen)).concat(ordinal);
  16.295          }
  16.296 -
  16.297 +        return nextName;
  16.298      }
  16.299  
  16.300      private void generateMethods() {
  16.301 @@ -624,23 +622,19 @@
  16.302                  methodDesc, null, exceptionNames));
  16.303          mv.visitCode();
  16.304  
  16.305 -        final Label instanceHandleDefined = new Label();
  16.306 -        final Label classHandleDefined = new Label();
  16.307 +        final Label handleDefined = new Label();
  16.308  
  16.309          final Type asmReturnType = Type.getType(type.returnType());
  16.310  
  16.311 -        // See if we have instance handle defined
  16.312 -        mv.visitVarInsn(ALOAD, 0);
  16.313 -        mv.getfield(generatedClassName, mi.methodHandleInstanceFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.314 -        // stack: [instanceHandle]
  16.315 -        jumpIfNonNullKeepOperand(mv, instanceHandleDefined);
  16.316 -
  16.317 +        // See if we have overriding method handle defined
  16.318          if(classOverride) {
  16.319 -            // See if we have the static handle
  16.320 -            mv.getstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.321 -            // stack: [classHandle]
  16.322 -            jumpIfNonNullKeepOperand(mv, classHandleDefined);
  16.323 +            mv.getstatic(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.324 +        } else {
  16.325 +            mv.visitVarInsn(ALOAD, 0);
  16.326 +            mv.getfield(generatedClassName, mi.methodHandleFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
  16.327          }
  16.328 +        // stack: [handle]
  16.329 +        jumpIfNonNullKeepOperand(mv, handleDefined);
  16.330  
  16.331          // No handle is available, fall back to default behavior
  16.332          if(Modifier.isAbstract(method.getModifiers())) {
  16.333 @@ -654,25 +648,17 @@
  16.334              emitSuperCall(mv, name, methodDesc);
  16.335          }
  16.336  
  16.337 +        mv.visitLabel(handleDefined);
  16.338 +        // Load the creatingGlobal object
  16.339 +        if(classOverride) {
  16.340 +            // If class handle is defined, load the static defining global
  16.341 +            mv.getstatic(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.342 +        } else {
  16.343 +            mv.visitVarInsn(ALOAD, 0);
  16.344 +            mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.345 +        }
  16.346 +        // stack: [creatingGlobal, handle]
  16.347          final Label setupGlobal = new Label();
  16.348 -
  16.349 -        if(classOverride) {
  16.350 -            mv.visitLabel(classHandleDefined);
  16.351 -            // If class handle is defined, load the static defining global
  16.352 -            mv.getstatic(generatedClassName, STATIC_GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.353 -            // stack: [creatingGlobal := classGlobal, classHandle]
  16.354 -            mv.goTo(setupGlobal);
  16.355 -        }
  16.356 -
  16.357 -        mv.visitLabel(instanceHandleDefined);
  16.358 -        // If instance handle is defined, load the instance defining global
  16.359 -        mv.visitVarInsn(ALOAD, 0);
  16.360 -        mv.getfield(generatedClassName, GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
  16.361 -        // stack: [creatingGlobal := instanceGlobal, instanceHandle]
  16.362 -
  16.363 -        // fallthrough to setupGlobal
  16.364 -
  16.365 -        // stack: [creatingGlobal, someHandle]
  16.366          mv.visitLabel(setupGlobal);
  16.367  
  16.368          // Determine the first index for a local variable
  16.369 @@ -685,38 +671,39 @@
  16.370          final int globalsDifferVar  = nextLocalVar++;
  16.371  
  16.372          mv.dup();
  16.373 -        // stack: [creatingGlobal, creatingGlobal, someHandle]
  16.374 +        // stack: [creatingGlobal, creatingGlobal, handle]
  16.375  
  16.376          // Emit code for switching to the creating global
  16.377          // ScriptObject currentGlobal = Context.getGlobal();
  16.378          invokeGetGlobal(mv);
  16.379          mv.dup();
  16.380 +
  16.381          mv.visitVarInsn(ASTORE, currentGlobalVar);
  16.382 -        // stack: [currentGlobal, creatingGlobal, creatingGlobal, someHandle]
  16.383 +        // stack: [currentGlobal, creatingGlobal, creatingGlobal, handle]
  16.384          // if(definingGlobal == currentGlobal) {
  16.385          final Label globalsDiffer = new Label();
  16.386          mv.ifacmpne(globalsDiffer);
  16.387 -        // stack: [someGlobal, someHandle]
  16.388 +        // stack: [creatingGlobal, handle]
  16.389          //     globalsDiffer = false
  16.390          mv.pop();
  16.391 -        // stack: [someHandle]
  16.392 +        // stack: [handle]
  16.393          mv.iconst(0); // false
  16.394 -        // stack: [false, someHandle]
  16.395 +        // stack: [false, handle]
  16.396          final Label invokeHandle = new Label();
  16.397          mv.goTo(invokeHandle);
  16.398          mv.visitLabel(globalsDiffer);
  16.399          // } else {
  16.400          //     Context.setGlobal(definingGlobal);
  16.401 -        // stack: [someGlobal, someHandle]
  16.402 +        // stack: [creatingGlobal, handle]
  16.403          invokeSetGlobal(mv);
  16.404 -        // stack: [someHandle]
  16.405 +        // stack: [handle]
  16.406          //     globalsDiffer = true
  16.407          mv.iconst(1);
  16.408 -        // stack: [true, someHandle]
  16.409 +        // stack: [true, handle]
  16.410  
  16.411          mv.visitLabel(invokeHandle);
  16.412          mv.visitVarInsn(ISTORE, globalsDifferVar);
  16.413 -        // stack: [someHandle]
  16.414 +        // stack: [handle]
  16.415  
  16.416          // Load all parameters back on stack for dynamic invocation.
  16.417          int varOffset = 1;
  16.418 @@ -847,6 +834,42 @@
  16.419          mv.areturn(methodType.getReturnType());
  16.420      }
  16.421  
  16.422 +    private void generateFinalizerMethods() {
  16.423 +        final String finalizerDelegateName = nextName("access$");
  16.424 +        generateFinalizerDelegate(finalizerDelegateName);
  16.425 +        generateFinalizerOverride(finalizerDelegateName);
  16.426 +    }
  16.427 +
  16.428 +    private void generateFinalizerDelegate(final String finalizerDelegateName) {
  16.429 +        // Generate a delegate that will be invoked from the no-permission trampoline. Note it can be private, as we'll
  16.430 +        // refer to it with a MethodHandle constant pool entry in the overridden finalize() method (see
  16.431 +        // generateFinalizerOverride()).
  16.432 +        final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PRIVATE | ACC_STATIC,
  16.433 +                finalizerDelegateName, Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE), null, null));
  16.434 +
  16.435 +        // Simply invoke super.finalize()
  16.436 +        mv.visitVarInsn(ALOAD, 0);
  16.437 +        mv.checkcast(Type.getType(generatedClassName));
  16.438 +        mv.invokespecial(superClassName, "finalize", Type.getMethodDescriptor(Type.VOID_TYPE), false);
  16.439 +
  16.440 +        mv.visitInsn(RETURN);
  16.441 +        endMethod(mv);
  16.442 +    }
  16.443 +
  16.444 +    private void generateFinalizerOverride(final String finalizerDelegateName) {
  16.445 +        final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, "finalize",
  16.446 +                VOID_NOARG_METHOD_DESCRIPTOR, null, null));
  16.447 +        // Overridden finalizer will take a MethodHandle to the finalizer delegating method, ...
  16.448 +        mv.aconst(new Handle(Opcodes.H_INVOKESTATIC, generatedClassName, finalizerDelegateName,
  16.449 +                Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE)));
  16.450 +        mv.visitVarInsn(ALOAD, 0);
  16.451 +        // ...and invoke it through JavaAdapterServices.invokeNoPermissions
  16.452 +        mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "invokeNoPermissions",
  16.453 +                Type.getMethodDescriptor(METHOD_HANDLE_TYPE, OBJECT_TYPE), false);
  16.454 +        mv.visitInsn(RETURN);
  16.455 +        endMethod(mv);
  16.456 +    }
  16.457 +
  16.458      private static String[] getExceptionNames(final Class<?>[] exceptions) {
  16.459          final String[] exceptionNames = new String[exceptions.length];
  16.460          for (int i = 0; i < exceptions.length; ++i) {
  16.461 @@ -867,16 +890,32 @@
  16.462       * class.
  16.463       * @param type the type defining the methods.
  16.464       */
  16.465 -    private void gatherMethods(final Class<?> type) {
  16.466 +    private void gatherMethods(final Class<?> type) throws AdaptationException {
  16.467          if (Modifier.isPublic(type.getModifiers())) {
  16.468              final Method[] typeMethods = type.isInterface() ? type.getMethods() : type.getDeclaredMethods();
  16.469  
  16.470              for (final Method typeMethod: typeMethods) {
  16.471 +                final String name = typeMethod.getName();
  16.472 +                if(name.startsWith(SUPER_PREFIX)) {
  16.473 +                    continue;
  16.474 +                }
  16.475                  final int m = typeMethod.getModifiers();
  16.476                  if (Modifier.isStatic(m)) {
  16.477                      continue;
  16.478                  }
  16.479                  if (Modifier.isPublic(m) || Modifier.isProtected(m)) {
  16.480 +                    // Is it a "finalize()"?
  16.481 +                    if(name.equals("finalize") && typeMethod.getParameterCount() == 0) {
  16.482 +                        if(type != Object.class) {
  16.483 +                            hasExplicitFinalizer = true;
  16.484 +                            if(Modifier.isFinal(m)) {
  16.485 +                                // Must be able to override an explicit finalizer
  16.486 +                                throw new AdaptationException(Outcome.ERROR_FINAL_FINALIZER, type.getCanonicalName());
  16.487 +                            }
  16.488 +                        }
  16.489 +                        continue;
  16.490 +                    }
  16.491 +
  16.492                      final MethodInfo mi = new MethodInfo(typeMethod);
  16.493                      if (Modifier.isFinal(m) || isCallerSensitive(typeMethod)) {
  16.494                          finalMethods.add(mi);
  16.495 @@ -884,7 +923,7 @@
  16.496                          if (Modifier.isAbstract(m)) {
  16.497                              abstractMethodNames.add(mi.getName());
  16.498                          }
  16.499 -                        mi.setIsCanonical(usedFieldNames, classOverride);
  16.500 +                        mi.setIsCanonical(this);
  16.501                      }
  16.502                  }
  16.503              }
  16.504 @@ -905,7 +944,7 @@
  16.505          }
  16.506      }
  16.507  
  16.508 -    private void gatherMethods(final List<Class<?>> classes) {
  16.509 +    private void gatherMethods(final List<Class<?>> classes) throws AdaptationException {
  16.510          for(final Class<?> c: classes) {
  16.511              gatherMethods(c);
  16.512          }
    17.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Fri Jan 31 22:24:45 2014 -0800
    17.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java	Sun Feb 02 22:51:24 2014 -0800
    17.3 @@ -27,10 +27,6 @@
    17.4  
    17.5  import java.security.AccessControlContext;
    17.6  import java.security.AccessController;
    17.7 -import java.security.AllPermission;
    17.8 -import java.security.CodeSigner;
    17.9 -import java.security.CodeSource;
   17.10 -import java.security.Permissions;
   17.11  import java.security.PrivilegedAction;
   17.12  import java.security.ProtectionDomain;
   17.13  import java.security.SecureClassLoader;
   17.14 @@ -45,11 +41,10 @@
   17.15   */
   17.16  @SuppressWarnings("javadoc")
   17.17  final class JavaAdapterClassLoader {
   17.18 -    private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
   17.19      private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
   17.20  
   17.21      private final String className;
   17.22 -    private volatile byte[] classBytes;
   17.23 +    private final byte[] classBytes;
   17.24  
   17.25      JavaAdapterClassLoader(String className, byte[] classBytes) {
   17.26          this.className = className.replace('/', '.');
   17.27 @@ -57,23 +52,18 @@
   17.28      }
   17.29  
   17.30      /**
   17.31 -     * clear classBytes after loading class.
   17.32 -     */
   17.33 -    void clearClassBytes() {
   17.34 -       this.classBytes = null;
   17.35 -    }
   17.36 -
   17.37 -    /**
   17.38       * Loads the generated adapter class into the JVM.
   17.39       * @param parentLoader the parent class loader for the generated class loader
   17.40 +     * @param protectionDomain the protection domain for the generated class
   17.41       * @return the generated adapter class
   17.42       */
   17.43 -    StaticClass generateClass(final ClassLoader parentLoader) {
   17.44 +    StaticClass generateClass(final ClassLoader parentLoader, final ProtectionDomain protectionDomain) {
   17.45 +        assert protectionDomain != null;
   17.46          return AccessController.doPrivileged(new PrivilegedAction<StaticClass>() {
   17.47              @Override
   17.48              public StaticClass run() {
   17.49                  try {
   17.50 -                    return StaticClass.forClass(Class.forName(className, true, createClassLoader(parentLoader)));
   17.51 +                    return StaticClass.forClass(Class.forName(className, true, createClassLoader(parentLoader, protectionDomain)));
   17.52                  } catch (final ClassNotFoundException e) {
   17.53                      throw new AssertionError(e); // cannot happen
   17.54                  }
   17.55 @@ -88,7 +78,7 @@
   17.56      // it even more by separating its invocation into a separate static method on the adapter class, but then someone
   17.57      // with ability to introspect on the class and use setAccessible(true) on it could invoke the method. It's a
   17.58      // security tradeoff...
   17.59 -    private ClassLoader createClassLoader(final ClassLoader parentLoader) {
   17.60 +    private ClassLoader createClassLoader(final ClassLoader parentLoader, final ProtectionDomain protectionDomain) {
   17.61          return new SecureClassLoader(parentLoader) {
   17.62              private final ClassLoader myLoader = getClass().getClassLoader();
   17.63  
   17.64 @@ -112,21 +102,10 @@
   17.65              protected Class<?> findClass(final String name) throws ClassNotFoundException {
   17.66                  if(name.equals(className)) {
   17.67                      assert classBytes != null : "what? already cleared .class bytes!!";
   17.68 -                    return defineClass(name, classBytes, 0, classBytes.length, GENERATED_PROTECTION_DOMAIN);
   17.69 +                    return defineClass(name, classBytes, 0, classBytes.length, protectionDomain);
   17.70                  }
   17.71                  throw new ClassNotFoundException(name);
   17.72              }
   17.73          };
   17.74      }
   17.75 -
   17.76 -    private static ProtectionDomain createGeneratedProtectionDomain() {
   17.77 -        // Generated classes need to have AllPermission. Since we require the "createClassLoader" RuntimePermission, we
   17.78 -        // can create a class loader that'll load new classes with any permissions. Our generated classes are just
   17.79 -        // delegating adapters, so having AllPermission can't cause anything wrong; the effective set of permissions for
   17.80 -        // the executing script functions will still be limited by the permissions of the caller and the permissions of
   17.81 -        // the script.
   17.82 -        final Permissions permissions = new Permissions();
   17.83 -        permissions.add(new AllPermission());
   17.84 -        return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
   17.85 -    }
   17.86  }
    18.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Fri Jan 31 22:24:45 2014 -0800
    18.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java	Sun Feb 02 22:51:24 2014 -0800
    18.3 @@ -29,17 +29,23 @@
    18.4  
    18.5  import java.lang.invoke.MethodHandle;
    18.6  import java.lang.invoke.MethodHandles;
    18.7 +import java.lang.invoke.MethodHandles.Lookup;
    18.8  import java.lang.invoke.MethodType;
    18.9  import java.lang.reflect.Modifier;
   18.10  import java.security.AccessControlContext;
   18.11  import java.security.AccessController;
   18.12 +import java.security.CodeSigner;
   18.13 +import java.security.CodeSource;
   18.14 +import java.security.Permissions;
   18.15  import java.security.PrivilegedAction;
   18.16 +import java.security.ProtectionDomain;
   18.17  import java.util.ArrayList;
   18.18  import java.util.Arrays;
   18.19  import java.util.Collections;
   18.20  import java.util.HashMap;
   18.21  import java.util.List;
   18.22  import java.util.Map;
   18.23 +import java.util.concurrent.ConcurrentHashMap;
   18.24  import jdk.internal.dynalink.beans.StaticClass;
   18.25  import jdk.internal.dynalink.support.LinkRequestImpl;
   18.26  import jdk.nashorn.internal.objects.NativeJava;
   18.27 @@ -70,6 +76,8 @@
   18.28  
   18.29  @SuppressWarnings("javadoc")
   18.30  public final class JavaAdapterFactory {
   18.31 +    private static final ProtectionDomain MINIMAL_PERMISSION_DOMAIN = createMinimalPermissionDomain();
   18.32 +
   18.33      // context with permissions needs for AdapterInfo creation
   18.34      private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
   18.35          ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
   18.36 @@ -99,20 +107,45 @@
   18.37       * @param classOverrides a JavaScript object with functions serving as the class-level overrides and
   18.38       * implementations. These overrides are defined for all instances of the class, and can be further overridden on a
   18.39       * per-instance basis by passing additional objects in the constructor.
   18.40 +     * @param lookup the lookup object identifying the caller class. The generated adapter class will have the
   18.41 +     * protection domain of the caller class iff the lookup object is full-strength, otherwise it will be completely
   18.42 +     * unprivileged.
   18.43       * @return an adapter class. See this class' documentation for details on the generated adapter class.
   18.44       * @throws ECMAException with a TypeError if the adapter class can not be generated because the original class is
   18.45       * final, non-public, or has no public or protected constructors.
   18.46       */
   18.47 -    public static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides) {
   18.48 +    public static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final MethodHandles.Lookup lookup) {
   18.49 +        return getAdapterClassFor(types, classOverrides, getProtectionDomain(lookup));
   18.50 +    }
   18.51 +
   18.52 +    private static StaticClass getAdapterClassFor(final Class<?>[] types, ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
   18.53          assert types != null && types.length > 0;
   18.54          final SecurityManager sm = System.getSecurityManager();
   18.55          if (sm != null) {
   18.56              for (Class<?> type : types) {
   18.57                  // check for restricted package access
   18.58                  Context.checkPackageAccess(type);
   18.59 +                // check for classes, interfaces in reflection
   18.60 +                ReflectionCheckLinker.checkReflectionAccess(type, true);
   18.61              }
   18.62          }
   18.63 -        return getAdapterInfo(types).getAdapterClassFor(classOverrides);
   18.64 +        return getAdapterInfo(types).getAdapterClass(classOverrides, protectionDomain);
   18.65 +    }
   18.66 +
   18.67 +    private static ProtectionDomain getProtectionDomain(final MethodHandles.Lookup lookup) {
   18.68 +        if((lookup.lookupModes() & Lookup.PRIVATE) == 0) {
   18.69 +            return MINIMAL_PERMISSION_DOMAIN;
   18.70 +        }
   18.71 +        return getProtectionDomain(lookup.lookupClass());
   18.72 +    }
   18.73 +
   18.74 +    private static ProtectionDomain getProtectionDomain(final Class<?> clazz) {
   18.75 +        return AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
   18.76 +            @Override
   18.77 +            public ProtectionDomain run() {
   18.78 +                return clazz.getProtectionDomain();
   18.79 +            }
   18.80 +        });
   18.81      }
   18.82  
   18.83      /**
   18.84 @@ -127,10 +160,10 @@
   18.85       * @return the constructor method handle.
   18.86       * @throws Exception if anything goes wrong
   18.87       */
   18.88 -    public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   18.89 -        final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null);
   18.90 +    public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType, final MethodHandles.Lookup lookup) throws Exception {
   18.91 +        final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null, lookup);
   18.92          return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
   18.93 -                NashornCallSiteDescriptor.get(MethodHandles.publicLookup(),  "dyn:new",
   18.94 +                NashornCallSiteDescriptor.get(lookup, "dyn:new",
   18.95                          MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
   18.96                          adapterClass, null)).getInvocation(), adapterClass);
   18.97      }
   18.98 @@ -218,10 +251,10 @@
   18.99          private static final ClassAndLoader SCRIPT_OBJECT_LOADER = new ClassAndLoader(ScriptObject.class, true);
  18.100  
  18.101          private final ClassLoader commonLoader;
  18.102 -        private final JavaAdapterClassLoader adapterGenerator;
  18.103 -        // Cacheable adapter class that is shared by all adapter instances that don't have class overrides, only
  18.104 -        // instance overrides.
  18.105 -        final StaticClass instanceAdapterClass;
  18.106 +        // TODO: soft reference the JavaAdapterClassLoader objects. They can be recreated when needed.
  18.107 +        private final JavaAdapterClassLoader classAdapterGenerator;
  18.108 +        private final JavaAdapterClassLoader instanceAdapterGenerator;
  18.109 +        private final Map<CodeSource, StaticClass> instanceAdapters = new ConcurrentHashMap<>();
  18.110          final boolean autoConvertibleFromFunction;
  18.111          final AdaptationResult adaptationResult;
  18.112  
  18.113 @@ -229,11 +262,8 @@
  18.114              this.commonLoader = findCommonLoader(definingLoader);
  18.115              final JavaAdapterBytecodeGenerator gen = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, false);
  18.116              this.autoConvertibleFromFunction = gen.isAutoConvertibleFromFunction();
  18.117 -            final JavaAdapterClassLoader jacl = gen.createAdapterClassLoader();
  18.118 -            this.instanceAdapterClass = jacl.generateClass(commonLoader);
  18.119 -            // loaded Class - no need to keep class bytes around
  18.120 -            jacl.clearClassBytes();
  18.121 -            this.adapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();
  18.122 +            instanceAdapterGenerator = gen.createAdapterClassLoader();
  18.123 +            this.classAdapterGenerator = new JavaAdapterBytecodeGenerator(superClass, interfaces, commonLoader, true).createAdapterClassLoader();
  18.124              this.adaptationResult = AdaptationResult.SUCCESSFUL_RESULT;
  18.125          }
  18.126  
  18.127 @@ -243,22 +273,42 @@
  18.128  
  18.129          AdapterInfo(final AdaptationResult adaptationResult) {
  18.130              this.commonLoader = null;
  18.131 -            this.adapterGenerator = null;
  18.132 -            this.instanceAdapterClass = null;
  18.133 +            this.classAdapterGenerator = null;
  18.134 +            this.instanceAdapterGenerator = null;
  18.135              this.autoConvertibleFromFunction = false;
  18.136              this.adaptationResult = adaptationResult;
  18.137          }
  18.138  
  18.139 -        StaticClass getAdapterClassFor(ScriptObject classOverrides) {
  18.140 +        StaticClass getAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
  18.141              if(adaptationResult.getOutcome() != AdaptationResult.Outcome.SUCCESS) {
  18.142                  throw adaptationResult.typeError();
  18.143              }
  18.144 -            if(classOverrides == null) {
  18.145 +            return classOverrides == null ? getInstanceAdapterClass(protectionDomain) :
  18.146 +                getClassAdapterClass(classOverrides, protectionDomain);
  18.147 +        }
  18.148 +
  18.149 +        private StaticClass getInstanceAdapterClass(final ProtectionDomain protectionDomain) {
  18.150 +            CodeSource codeSource = protectionDomain.getCodeSource();
  18.151 +            if(codeSource == null) {
  18.152 +                codeSource = MINIMAL_PERMISSION_DOMAIN.getCodeSource();
  18.153 +            }
  18.154 +            StaticClass instanceAdapterClass = instanceAdapters.get(codeSource);
  18.155 +            if(instanceAdapterClass != null) {
  18.156                  return instanceAdapterClass;
  18.157              }
  18.158 +            // Any "unknown source" code source will default to no permission domain.
  18.159 +            final ProtectionDomain effectiveDomain = codeSource.equals(MINIMAL_PERMISSION_DOMAIN.getCodeSource()) ?
  18.160 +                    MINIMAL_PERMISSION_DOMAIN : protectionDomain;
  18.161 +
  18.162 +            instanceAdapterClass = instanceAdapterGenerator.generateClass(commonLoader, effectiveDomain);
  18.163 +            final StaticClass existing = instanceAdapters.putIfAbsent(codeSource, instanceAdapterClass);
  18.164 +            return existing == null ? instanceAdapterClass : existing;
  18.165 +        }
  18.166 +
  18.167 +        private StaticClass getClassAdapterClass(final ScriptObject classOverrides, final ProtectionDomain protectionDomain) {
  18.168              JavaAdapterServices.setClassOverrides(classOverrides);
  18.169              try {
  18.170 -                return adapterGenerator.generateClass(commonLoader);
  18.171 +                return classAdapterGenerator.generateClass(commonLoader, protectionDomain);
  18.172              } finally {
  18.173                  JavaAdapterServices.setClassOverrides(null);
  18.174              }
  18.175 @@ -283,4 +333,12 @@
  18.176              throw new AdaptationException(AdaptationResult.Outcome.ERROR_NO_COMMON_LOADER, classAndLoader.getRepresentativeClass().getCanonicalName());
  18.177          }
  18.178      }
  18.179 +
  18.180 +    private static ProtectionDomain createMinimalPermissionDomain() {
  18.181 +        // Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
  18.182 +        final Permissions permissions = new Permissions();
  18.183 +        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
  18.184 +        permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
  18.185 +        return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
  18.186 +    }
  18.187  }
    19.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java	Fri Jan 31 22:24:45 2014 -0800
    19.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java	Sun Feb 02 22:51:24 2014 -0800
    19.3 @@ -25,10 +25,28 @@
    19.4  
    19.5  package jdk.nashorn.internal.runtime.linker;
    19.6  
    19.7 +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
    19.8 +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
    19.9 +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC;
   19.10 +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
   19.11 +import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
   19.12 +import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
   19.13  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
   19.14  
   19.15  import java.lang.invoke.MethodHandle;
   19.16 +import java.lang.invoke.MethodHandles;
   19.17  import java.lang.invoke.MethodType;
   19.18 +import java.security.AccessController;
   19.19 +import java.security.CodeSigner;
   19.20 +import java.security.CodeSource;
   19.21 +import java.security.Permissions;
   19.22 +import java.security.PrivilegedAction;
   19.23 +import java.security.ProtectionDomain;
   19.24 +import java.security.SecureClassLoader;
   19.25 +import jdk.internal.org.objectweb.asm.ClassWriter;
   19.26 +import jdk.internal.org.objectweb.asm.Opcodes;
   19.27 +import jdk.internal.org.objectweb.asm.Type;
   19.28 +import jdk.internal.org.objectweb.asm.commons.InstructionAdapter;
   19.29  import jdk.nashorn.internal.runtime.Context;
   19.30  import jdk.nashorn.internal.runtime.ScriptFunction;
   19.31  import jdk.nashorn.internal.runtime.ScriptObject;
   19.32 @@ -40,6 +58,7 @@
   19.33   */
   19.34  public final class JavaAdapterServices {
   19.35      private static final ThreadLocal<ScriptObject> classOverrides = new ThreadLocal<>();
   19.36 +    private static final MethodHandle NO_PERMISSIONS_INVOKER = createNoPermissionsInvoker();
   19.37  
   19.38      private JavaAdapterServices() {
   19.39      }
   19.40 @@ -55,7 +74,7 @@
   19.41       */
   19.42      public static MethodHandle getHandle(final ScriptFunction fn, final MethodType type) {
   19.43          // JS "this" will be global object or undefined depending on if 'fn' is strict or not
   19.44 -        return adaptHandle(fn.getBoundInvokeHandle(fn.isStrict()? ScriptRuntime.UNDEFINED : Context.getGlobal()), type);
   19.45 +        return bindAndAdaptHandle(fn, fn.isStrict()? ScriptRuntime.UNDEFINED : Context.getGlobal(), type);
   19.46      }
   19.47  
   19.48      /**
   19.49 @@ -83,7 +102,7 @@
   19.50  
   19.51          final Object fnObj = sobj.get(name);
   19.52          if (fnObj instanceof ScriptFunction) {
   19.53 -            return adaptHandle(((ScriptFunction)fnObj).getBoundInvokeHandle(sobj), type);
   19.54 +            return bindAndAdaptHandle((ScriptFunction)fnObj, sobj, type);
   19.55          } else if(fnObj == null || fnObj instanceof Undefined) {
   19.56              return null;
   19.57          } else {
   19.58 @@ -103,11 +122,67 @@
   19.59          return overrides;
   19.60      }
   19.61  
   19.62 +    /**
   19.63 +     * Takes a method handle and an argument to it, and invokes the method handle passing it the argument. Basically
   19.64 +     * equivalent to {@code method.invokeExact(arg)}, except that the method handle will be invoked in a protection
   19.65 +     * domain with absolutely no permissions.
   19.66 +     * @param method the method handle to invoke. The handle must have the exact type of {@code void(Object)}.
   19.67 +     * @param arg the argument to pass to the handle.
   19.68 +     * @throws Throwable if anything goes wrong.
   19.69 +     */
   19.70 +    public static void invokeNoPermissions(final MethodHandle method, final Object arg) throws Throwable {
   19.71 +        NO_PERMISSIONS_INVOKER.invokeExact(method, arg);
   19.72 +    }
   19.73 +
   19.74      static void setClassOverrides(ScriptObject overrides) {
   19.75          classOverrides.set(overrides);
   19.76      }
   19.77  
   19.78 -    private static MethodHandle adaptHandle(final MethodHandle handle, final MethodType type) {
   19.79 -        return Bootstrap.getLinkerServices().asType(ScriptObject.pairArguments(handle, type, false), type);
   19.80 +    private static MethodHandle bindAndAdaptHandle(final ScriptFunction fn, final Object self, final MethodType type) {
   19.81 +        return Bootstrap.getLinkerServices().asType(ScriptObject.pairArguments(fn.getBoundInvokeHandle(self), type, false), type);
   19.82 +    }
   19.83 +
   19.84 +    private static MethodHandle createNoPermissionsInvoker() {
   19.85 +        final String className = "NoPermissionsInvoker";
   19.86 +
   19.87 +        final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
   19.88 +        cw.visit(Opcodes.V1_7, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, className, null, "java/lang/Object", null);
   19.89 +        final Type objectType = Type.getType(Object.class);
   19.90 +        final Type methodHandleType = Type.getType(MethodHandle.class);
   19.91 +        final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invoke",
   19.92 +                Type.getMethodDescriptor(Type.VOID_TYPE, methodHandleType, objectType), null, null));
   19.93 +        mv.visitCode();
   19.94 +        mv.visitVarInsn(ALOAD, 0);
   19.95 +        mv.visitVarInsn(ALOAD, 1);
   19.96 +        mv.invokevirtual(methodHandleType.getInternalName(), "invokeExact", Type.getMethodDescriptor(
   19.97 +                Type.VOID_TYPE, objectType), false);
   19.98 +        mv.visitInsn(RETURN);
   19.99 +        mv.visitMaxs(0, 0);
  19.100 +        mv.visitEnd();
  19.101 +        cw.visitEnd();
  19.102 +        final byte[] bytes = cw.toByteArray();
  19.103 +
  19.104 +        final ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
  19.105 +            @Override
  19.106 +            public ClassLoader run() {
  19.107 +                return new SecureClassLoader(null) {
  19.108 +                    @Override
  19.109 +                    protected Class<?> findClass(String name) throws ClassNotFoundException {
  19.110 +                        if(name.equals(className)) {
  19.111 +                            return defineClass(name, bytes, 0, bytes.length, new ProtectionDomain(
  19.112 +                                    new CodeSource(null, (CodeSigner[])null), new Permissions()));
  19.113 +                        }
  19.114 +                        throw new ClassNotFoundException(name);
  19.115 +                    }
  19.116 +                };
  19.117 +            }
  19.118 +        });
  19.119 +
  19.120 +        try {
  19.121 +            return MethodHandles.lookup().findStatic(Class.forName(className, true, loader), "invoke",
  19.122 +                    MethodType.methodType(void.class, MethodHandle.class, Object.class));
  19.123 +        } catch(ReflectiveOperationException e) {
  19.124 +            throw new AssertionError(e.getMessage(), e);
  19.125 +        }
  19.126      }
  19.127  }
    20.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Fri Jan 31 22:24:45 2014 -0800
    20.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java	Sun Feb 02 22:51:24 2014 -0800
    20.3 @@ -25,19 +25,20 @@
    20.4  
    20.5  package jdk.nashorn.internal.runtime.linker;
    20.6  
    20.7 +import static jdk.nashorn.internal.lookup.Lookup.MH;
    20.8  import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
    20.9  import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
   20.10 -import static jdk.nashorn.internal.lookup.Lookup.MH;
   20.11  
   20.12  import java.lang.invoke.MethodHandle;
   20.13  import java.lang.invoke.MethodType;
   20.14  import java.lang.reflect.Method;
   20.15  import java.lang.reflect.Modifier;
   20.16 +import java.util.HashMap;
   20.17  import java.util.Map;
   20.18 -import java.util.HashMap;
   20.19  import jdk.internal.dynalink.CallSiteDescriptor;
   20.20  import jdk.internal.dynalink.beans.BeansLinker;
   20.21  import jdk.internal.dynalink.linker.GuardedInvocation;
   20.22 +import jdk.internal.dynalink.linker.GuardedTypeConversion;
   20.23  import jdk.internal.dynalink.linker.GuardingDynamicLinker;
   20.24  import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
   20.25  import jdk.internal.dynalink.linker.LinkRequest;
   20.26 @@ -134,9 +135,9 @@
   20.27      }
   20.28  
   20.29      @Override
   20.30 -    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   20.31 +    public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   20.32          final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
   20.33 -        return gi == null ? null : gi.asType(MH.type(targetType, sourceType));
   20.34 +        return gi == null ? null : new GuardedTypeConversion(gi.asType(MH.type(targetType, sourceType)), true);
   20.35      }
   20.36  
   20.37      /**
    21.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Fri Jan 31 22:24:45 2014 -0800
    21.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java	Sun Feb 02 22:51:24 2014 -0800
    21.3 @@ -29,7 +29,10 @@
    21.4  
    21.5  import java.lang.invoke.MethodHandle;
    21.6  import java.lang.invoke.MethodHandles;
    21.7 +import java.lang.invoke.MethodHandles.Lookup;
    21.8  import java.lang.reflect.Modifier;
    21.9 +import java.security.AccessController;
   21.10 +import java.security.PrivilegedAction;
   21.11  import java.util.Deque;
   21.12  import java.util.List;
   21.13  import java.util.Map;
   21.14 @@ -37,16 +40,17 @@
   21.15  import jdk.internal.dynalink.CallSiteDescriptor;
   21.16  import jdk.internal.dynalink.linker.ConversionComparator;
   21.17  import jdk.internal.dynalink.linker.GuardedInvocation;
   21.18 +import jdk.internal.dynalink.linker.GuardedTypeConversion;
   21.19  import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
   21.20  import jdk.internal.dynalink.linker.LinkRequest;
   21.21  import jdk.internal.dynalink.linker.LinkerServices;
   21.22  import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
   21.23  import jdk.internal.dynalink.support.Guards;
   21.24 +import jdk.internal.dynalink.support.LinkerServicesImpl;
   21.25  import jdk.nashorn.api.scripting.JSObject;
   21.26  import jdk.nashorn.api.scripting.ScriptObjectMirror;
   21.27  import jdk.nashorn.api.scripting.ScriptUtils;
   21.28  import jdk.nashorn.internal.objects.NativeArray;
   21.29 -import jdk.nashorn.internal.runtime.Context;
   21.30  import jdk.nashorn.internal.runtime.JSType;
   21.31  import jdk.nashorn.internal.runtime.ScriptFunction;
   21.32  import jdk.nashorn.internal.runtime.ScriptObject;
   21.33 @@ -100,9 +104,16 @@
   21.34      }
   21.35  
   21.36      @Override
   21.37 -    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   21.38 -        final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
   21.39 -        return gi == null ? null : gi.asType(MH.type(targetType, sourceType));
   21.40 +    public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
   21.41 +        GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
   21.42 +        if(gi != null) {
   21.43 +            return new GuardedTypeConversion(gi.asType(MH.type(targetType, sourceType)), true);
   21.44 +        }
   21.45 +        gi = getSamTypeConverter(sourceType, targetType);
   21.46 +        if(gi != null) {
   21.47 +            return new GuardedTypeConversion(gi.asType(MH.type(targetType, sourceType)), false);
   21.48 +        }
   21.49 +        return null;
   21.50      }
   21.51  
   21.52      /**
   21.53 @@ -126,12 +137,7 @@
   21.54              return arrayConverter;
   21.55          }
   21.56  
   21.57 -        final GuardedInvocation mirrorConverter = getMirrorConverter(sourceType, targetType);
   21.58 -        if(mirrorConverter != null) {
   21.59 -            return mirrorConverter;
   21.60 -        }
   21.61 -
   21.62 -        return getSamTypeConverter(sourceType, targetType);
   21.63 +        return getMirrorConverter(sourceType, targetType);
   21.64      }
   21.65  
   21.66      /**
   21.67 @@ -150,13 +156,23 @@
   21.68          final boolean isSourceTypeGeneric = sourceType.isAssignableFrom(ScriptFunction.class);
   21.69  
   21.70          if ((isSourceTypeGeneric || ScriptFunction.class.isAssignableFrom(sourceType)) && isAutoConvertibleFromFunction(targetType)) {
   21.71 -            final MethodHandle ctor = JavaAdapterFactory.getConstructor(ScriptFunction.class, targetType);
   21.72 +            final MethodHandle ctor = JavaAdapterFactory.getConstructor(ScriptFunction.class, targetType, getCurrentLookup());
   21.73              assert ctor != null; // if isAutoConvertibleFromFunction() returned true, then ctor must exist.
   21.74              return new GuardedInvocation(ctor, isSourceTypeGeneric ? IS_SCRIPT_FUNCTION : null);
   21.75          }
   21.76          return null;
   21.77      }
   21.78  
   21.79 +    private static Lookup getCurrentLookup() {
   21.80 +        final LinkRequest currentRequest = AccessController.doPrivileged(new PrivilegedAction<LinkRequest>() {
   21.81 +            @Override
   21.82 +            public LinkRequest run() {
   21.83 +                return LinkerServicesImpl.getCurrentLinkRequest();
   21.84 +            }
   21.85 +        });
   21.86 +        return currentRequest == null ? MethodHandles.publicLookup() : currentRequest.getCallSiteDescriptor().getLookup();
   21.87 +    }
   21.88 +
   21.89      /**
   21.90       * Returns a guarded invocation that converts from a source type that is NativeArray to a Java array or List or
   21.91       * Deque type.
    22.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Fri Jan 31 22:24:45 2014 -0800
    22.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java	Sun Feb 02 22:51:24 2014 -0800
    22.3 @@ -31,6 +31,7 @@
    22.4  import java.lang.invoke.MethodHandles;
    22.5  import jdk.internal.dynalink.linker.ConversionComparator;
    22.6  import jdk.internal.dynalink.linker.GuardedInvocation;
    22.7 +import jdk.internal.dynalink.linker.GuardedTypeConversion;
    22.8  import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
    22.9  import jdk.internal.dynalink.linker.LinkRequest;
   22.10  import jdk.internal.dynalink.linker.LinkerServices;
   22.11 @@ -75,13 +76,13 @@
   22.12       * @return a conditional converter from source to target type
   22.13       */
   22.14      @Override
   22.15 -    public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) {
   22.16 +    public GuardedTypeConversion convertToType(final Class<?> sourceType, final Class<?> targetType) {
   22.17          final MethodHandle mh = JavaArgumentConverters.getConverter(targetType);
   22.18          if (mh == null) {
   22.19              return null;
   22.20          }
   22.21  
   22.22 -        return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : GUARD_PRIMITIVE).asType(mh.type().changeParameterType(0, sourceType));
   22.23 +        return new GuardedTypeConversion(new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : GUARD_PRIMITIVE).asType(mh.type().changeParameterType(0, sourceType)), true);
   22.24      }
   22.25  
   22.26      /**
    23.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Fri Jan 31 22:24:45 2014 -0800
    23.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java	Sun Feb 02 22:51:24 2014 -0800
    23.3 @@ -65,7 +65,7 @@
    23.4              return null;
    23.5          }
    23.6          final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
    23.7 -        Bootstrap.checkReflectionAccess(receiverClass);
    23.8 +        Bootstrap.checkReflectionAccess(receiverClass, true);
    23.9          final CallSiteDescriptor desc = request.getCallSiteDescriptor();
   23.10          // We intercept "new" on StaticClass instances to provide additional capabilities
   23.11          if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
   23.12 @@ -76,7 +76,8 @@
   23.13              if (NashornLinker.isAbstractClass(receiverClass)) {
   23.14                  // Change this link request into a link request on the adapter class.
   23.15                  final Object[] args = request.getArguments();
   23.16 -                args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null);
   23.17 +                args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
   23.18 +                        linkRequest.getCallSiteDescriptor().getLookup());
   23.19                  final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
   23.20                  final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
   23.21                  // Finally, modify the guard to test for the original abstract class.
    24.1 --- a/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Fri Jan 31 22:24:45 2014 -0800
    24.2 +++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java	Sun Feb 02 22:51:24 2014 -0800
    24.3 @@ -26,6 +26,7 @@
    24.4  package jdk.nashorn.internal.runtime.linker;
    24.5  
    24.6  import java.lang.reflect.Modifier;
    24.7 +import java.lang.reflect.Proxy;
    24.8  import jdk.internal.dynalink.CallSiteDescriptor;
    24.9  import jdk.internal.dynalink.linker.GuardedInvocation;
   24.10  import jdk.internal.dynalink.linker.LinkRequest;
   24.11 @@ -47,6 +48,7 @@
   24.12          if (type == Class.class || ClassLoader.class.isAssignableFrom(type)) {
   24.13              return true;
   24.14          }
   24.15 +
   24.16          final String name = type.getName();
   24.17          return name.startsWith("java.lang.reflect.") || name.startsWith("java.lang.invoke.");
   24.18      }
   24.19 @@ -59,9 +61,25 @@
   24.20          return null;
   24.21      }
   24.22  
   24.23 -    static void checkReflectionAccess(Class<?> clazz) {
   24.24 +    private static boolean isReflectiveCheckNeeded(final Class<?> type, final boolean isStatic) {
   24.25 +         // special handling for Proxy subclasses
   24.26 +         if (Proxy.class.isAssignableFrom(type)) {
   24.27 +            if (Proxy.isProxyClass(type)) {
   24.28 +                // real Proxy class - filter only static access
   24.29 +                return isStatic;
   24.30 +            }
   24.31 +
   24.32 +            // fake Proxy subclass - filter it always!
   24.33 +            return true;
   24.34 +        }
   24.35 +
   24.36 +        // check for any other reflective Class
   24.37 +        return isReflectionClass(type);
   24.38 +    }
   24.39 +
   24.40 +    static void checkReflectionAccess(final Class<?> clazz, final boolean isStatic) {
   24.41          final SecurityManager sm = System.getSecurityManager();
   24.42 -        if (sm != null && isReflectionClass(clazz)) {
   24.43 +        if (sm != null && isReflectiveCheckNeeded(clazz, isStatic)) {
   24.44              checkReflectionPermission(sm);
   24.45          }
   24.46      }
   24.47 @@ -77,6 +95,7 @@
   24.48                  if(CallSiteDescriptorFactory.tokenizeOperators(desc).contains("getProp")) {
   24.49                      if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) {
   24.50                          if (Context.isAccessibleClass((Class<?>)self) && !isReflectionClass((Class<?>)self)) {
   24.51 +
   24.52                              // If "getProp:static" passes access checks, allow access.
   24.53                              return;
   24.54                          }
    25.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Fri Jan 31 22:24:45 2014 -0800
    25.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties	Sun Feb 02 22:51:24 2014 -0800
    25.3 @@ -130,6 +130,7 @@
    25.4  type.error.extend.ERROR_NO_ACCESSIBLE_CONSTRUCTOR=Can not extend class {0} as it has no public or protected constructors.
    25.5  type.error.extend.ERROR_MULTIPLE_SUPERCLASSES=Can not extend multiple classes {0}. At most one of the specified types can be a class, the rest must all be interfaces.
    25.6  type.error.extend.ERROR_NO_COMMON_LOADER=Can not find a common class loader for ScriptObject and {0}.
    25.7 +type.error.extend.ERROR_FINAL_FINALIZER=Can not extend class because {0} has a final finalize method.
    25.8  type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures.
    25.9  type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
   25.10  type.error.method.not.constructor=Java method {0} can't be used as a constructor.
    26.1 --- a/test/script/basic/JDK-8014647.js	Fri Jan 31 22:24:45 2014 -0800
    26.2 +++ b/test/script/basic/JDK-8014647.js	Sun Feb 02 22:51:24 2014 -0800
    26.3 @@ -32,9 +32,10 @@
    26.4  var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
    26.5  var r1 = new RunnableImpl1()
    26.6  var r2 = new RunnableImpl2()
    26.7 -var r3 = new RunnableImpl2(function() { print("I'm runnable 3!") })
    26.8 +var RunnableImpl3 = Java.extend(RunnableImpl2);
    26.9 +var r3 = new RunnableImpl3({ run: function() { print("I'm runnable 3!") }})
   26.10  r1.run()
   26.11  r2.run()
   26.12  r3.run()
   26.13 -print("r1.class === r2.class: " + (r1.class === r2.class))
   26.14 -print("r2.class === r3.class: " + (r2.class === r3.class))
   26.15 +print("r1.class !== r2.class: " + (r1.class !== r2.class))
   26.16 +print("r2.class !== r3.class: " + (r2.class !== r3.class))
    27.1 --- a/test/script/basic/JDK-8014647.js.EXPECTED	Fri Jan 31 22:24:45 2014 -0800
    27.2 +++ b/test/script/basic/JDK-8014647.js.EXPECTED	Sun Feb 02 22:51:24 2014 -0800
    27.3 @@ -1,5 +1,5 @@
    27.4  I'm runnable 1!
    27.5  I'm runnable 2!
    27.6  I'm runnable 3!
    27.7 -r1.class === r2.class: false
    27.8 -r2.class === r3.class: true
    27.9 +r1.class !== r2.class: true
   27.10 +r2.class !== r3.class: true
    28.1 --- a/test/script/basic/javaclassoverrides.js	Fri Jan 31 22:24:45 2014 -0800
    28.2 +++ b/test/script/basic/javaclassoverrides.js	Sun Feb 02 22:51:24 2014 -0800
    28.3 @@ -46,7 +46,8 @@
    28.4  var r1 = new R1
    28.5  var r2 = new R2
    28.6  // Create one with an instance-override too
    28.7 -var r3 = new R2(function() { print("r3.run() invoked") })
    28.8 +var R3 = Java.extend(R2)
    28.9 +var r3 = new R3({ run: function() { print("r3.run() invoked") }})
   28.10  
   28.11  // Run 'em - we're passing them through a Thread to make sure they indeed
   28.12  // are full-blown Runnables
   28.13 @@ -60,9 +61,9 @@
   28.14  runInThread(r3)
   28.15  
   28.16  // Two class-override classes differ
   28.17 -print("r1.class != r2.class: " + (r1.class != r2.class))
   28.18 -// However, adding instance-overrides doesn't change the class
   28.19 -print("r2.class == r3.class: " + (r2.class == r3.class))
   28.20 +print("r1.class !== r2.class: " + (r1.class !== r2.class))
   28.21 +// instance-override class also differs
   28.22 +print("r2.class !== r3.class: " + (r2.class !== r3.class))
   28.23  
   28.24  function checkAbstract(r) {
   28.25      try {
   28.26 @@ -77,10 +78,10 @@
   28.27  // overrides nor instance overrides are present
   28.28  var RAbstract = Java.extend(java.lang.Runnable, {})
   28.29  checkAbstract(new RAbstract()) // class override (empty)
   28.30 -checkAbstract(new RAbstract() {}) // class+instance override (empty)
   28.31 +checkAbstract(new (Java.extend(RAbstract))() {}) // class+instance override (empty)
   28.32  
   28.33  // Check we delegate to superclass if neither class
   28.34  // overrides nor instance overrides are present
   28.35  var ExtendsList = Java.extend(java.util.ArrayList, {})
   28.36  print("(new ExtendsList).size() = " + (new ExtendsList).size())
   28.37 -print("(new ExtendsList(){}).size() = " + (new ExtendsList(){}).size())
   28.38 \ No newline at end of file
   28.39 +print("(new (Java.extend(ExtendsList)){}).size() = " + (new (Java.extend(ExtendsList)){}).size())
    29.1 --- a/test/script/basic/javaclassoverrides.js.EXPECTED	Fri Jan 31 22:24:45 2014 -0800
    29.2 +++ b/test/script/basic/javaclassoverrides.js.EXPECTED	Sun Feb 02 22:51:24 2014 -0800
    29.3 @@ -1,9 +1,9 @@
    29.4  R1.run() invoked
    29.5  R2.run() invoked
    29.6  r3.run() invoked
    29.7 -r1.class != r2.class: true
    29.8 -r2.class == r3.class: true
    29.9 +r1.class !== r2.class: true
   29.10 +r2.class !== r3.class: true
   29.11  Got exception: java.lang.UnsupportedOperationException
   29.12  Got exception: java.lang.UnsupportedOperationException
   29.13  (new ExtendsList).size() = 0
   29.14 -(new ExtendsList(){}).size() = 0
   29.15 +(new (Java.extend(ExtendsList)){}).size() = 0
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/test/script/sandbox/classbind.js	Sun Feb 02 22:51:24 2014 -0800
    30.3 @@ -0,0 +1,41 @@
    30.4 +/*
    30.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    30.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    30.7 + * 
    30.8 + * This code is free software; you can redistribute it and/or modify it
    30.9 + * under the terms of the GNU General Public License version 2 only, as
   30.10 + * published by the Free Software Foundation.
   30.11 + * 
   30.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   30.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   30.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   30.15 + * version 2 for more details (a copy is included in the LICENSE file that
   30.16 + * accompanied this code).
   30.17 + * 
   30.18 + * You should have received a copy of the GNU General Public License version
   30.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   30.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   30.21 + * 
   30.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   30.23 + * or visit www.oracle.com if you need additional information or have any
   30.24 + * questions.
   30.25 + */
   30.26 +
   30.27 +/**
   30.28 + * Try to bind properties of StaticClass representing Class.
   30.29 + *
   30.30 + * @test
   30.31 + * @bug JDK-8032943: Improve reflection in Nashorn
   30.32 + */
   30.33 +
   30.34 +
   30.35 +var obj = {}
   30.36 +
   30.37 +try {
   30.38 +    Object.bindProperties(obj, Java.type("java.lang.Class"));
   30.39 +    fail("SecurityException should have been thrown");
   30.40 +} catch (e) {
   30.41 +    if (! (e instanceof java.lang.SecurityException)) {
   30.42 +        fail("SecurityException expected, got " + e);
   30.43 +    }
   30.44 +}
    31.1 --- a/test/script/sandbox/classloader.js	Fri Jan 31 22:24:45 2014 -0800
    31.2 +++ b/test/script/sandbox/classloader.js	Sun Feb 02 22:51:24 2014 -0800
    31.3 @@ -26,6 +26,7 @@
    31.4   *
    31.5   * @test
    31.6   * @security
    31.7 + * @bug JDK-8032954: Nashorn: extend Java.extend
    31.8   */
    31.9  
   31.10  try {
   31.11 @@ -39,3 +40,24 @@
   31.12      }
   31.13  }
   31.14  
   31.15 +try {
   31.16 +    Java.extend(Java.type('java.lang.ClassLoader'));
   31.17 +    fail("should have thrown SecurityException");
   31.18 +} catch (e) {
   31.19 +    if (e instanceof java.lang.SecurityException) {
   31.20 +        print(e);
   31.21 +    } else {
   31.22 +        fail("expected SecurityException, got " + e);
   31.23 +    }
   31.24 +}
   31.25 +
   31.26 +try {
   31.27 +    Java.extend(Java.type("javax.management.loading.MLet"));
   31.28 +    fail("should have thrown SecurityException");
   31.29 +} catch (e) {
   31.30 +    if (e instanceof java.lang.SecurityException) {
   31.31 +        print(e);
   31.32 +    } else {
   31.33 +        fail("expected SecurityException, got " + e);
   31.34 +    }
   31.35 +}
    32.1 --- a/test/script/sandbox/classloader.js.EXPECTED	Fri Jan 31 22:24:45 2014 -0800
    32.2 +++ b/test/script/sandbox/classloader.js.EXPECTED	Sun Feb 02 22:51:24 2014 -0800
    32.3 @@ -1,1 +1,3 @@
    32.4  java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "nashorn.JavaReflection")
    32.5 +java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "nashorn.JavaReflection")
    32.6 +java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "nashorn.JavaReflection")
    33.1 --- a/test/script/sandbox/javaextend.js	Fri Jan 31 22:24:45 2014 -0800
    33.2 +++ b/test/script/sandbox/javaextend.js	Sun Feb 02 22:51:24 2014 -0800
    33.3 @@ -51,6 +51,21 @@
    33.4      print(e)
    33.5  }
    33.6  
    33.7 +// Can't extend a class with explicit non-overridable finalizer
    33.8 +try {
    33.9 +    Java.extend(model("ClassWithFinalFinalizer"))
   33.10 +} catch(e) {
   33.11 +    print(e)
   33.12 +}
   33.13 +
   33.14 +// Can't extend a class with inherited non-overridable finalizer
   33.15 +try {
   33.16 +    Java.extend(model("ClassWithInheritedFinalFinalizer"))
   33.17 +} catch(e) {
   33.18 +    print(e)
   33.19 +}
   33.20 +
   33.21 +
   33.22  // Can't extend two classes
   33.23  try {
   33.24      Java.extend(java.lang.Thread,java.lang.Number)
    34.1 --- a/test/script/sandbox/javaextend.js.EXPECTED	Fri Jan 31 22:24:45 2014 -0800
    34.2 +++ b/test/script/sandbox/javaextend.js.EXPECTED	Sun Feb 02 22:51:24 2014 -0800
    34.3 @@ -1,6 +1,8 @@
    34.4  TypeError: Can not extend final class jdk.nashorn.test.models.FinalClass.
    34.5  TypeError: Can not extend class jdk.nashorn.test.models.NoAccessibleConstructorClass as it has no public or protected constructors.
    34.6  TypeError: Can not extend/implement non-public class/interface jdk.nashorn.test.models.NonPublicClass.
    34.7 +TypeError: Can not extend class because jdk.nashorn.test.models.ClassWithFinalFinalizer has a final finalize method.
    34.8 +TypeError: Can not extend class because jdk.nashorn.test.models.ClassWithFinalFinalizer has a final finalize method.
    34.9  TypeError: Can not extend multiple classes java.lang.Number and java.lang.Thread. At most one of the specified types can be a class, the rest must all be interfaces.
   34.10  abcdabcd
   34.11  run-object
    35.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java	Fri Jan 31 22:24:45 2014 -0800
    35.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java	Sun Feb 02 22:51:24 2014 -0800
    35.3 @@ -27,11 +27,14 @@
    35.4  
    35.5  import static org.testng.Assert.fail;
    35.6  
    35.7 +import java.lang.reflect.Method;
    35.8 +import java.lang.reflect.InvocationHandler;
    35.9 +import java.lang.reflect.Proxy;
   35.10  import java.util.Objects;
   35.11  import javax.script.Invocable;
   35.12  import javax.script.ScriptEngine;
   35.13 +import javax.script.ScriptEngineManager;
   35.14  import javax.script.ScriptException;
   35.15 -import javax.script.ScriptEngineManager;
   35.16  import org.testng.annotations.Test;
   35.17  
   35.18  /**
   35.19 @@ -127,6 +130,23 @@
   35.20          }
   35.21      }
   35.22  
   35.23 +
   35.24 +    @Test
   35.25 +    public void securitySystemExitFromFinalizerThread() throws ScriptException {
   35.26 +        if (System.getSecurityManager() == null) {
   35.27 +            // pass vacuously
   35.28 +            return;
   35.29 +        }
   35.30 +
   35.31 +        final ScriptEngineManager m = new ScriptEngineManager();
   35.32 +        final ScriptEngine e = m.getEngineByName("nashorn");
   35.33 +        e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" +
   35.34 +                "new o(new java.util.ArrayList().iterator())");
   35.35 +        System.gc();
   35.36 +        System.runFinalization();
   35.37 +        // NOTE: this test just exits the VM if it fails.
   35.38 +    }
   35.39 +
   35.40      @Test
   35.41      public void securitySystemLoadLibrary() {
   35.42          if (System.getSecurityManager() == null) {
   35.43 @@ -183,4 +203,98 @@
   35.44              }
   35.45          }
   35.46      }
   35.47 +
   35.48 +    // @bug 8032948: Nashorn linkages awry
   35.49 +    public static class FakeProxy extends Proxy {
   35.50 +        public FakeProxy(InvocationHandler ih) {
   35.51 +            super(ih);
   35.52 +        }
   35.53 +
   35.54 +        public static Class<?> makeProxyClass(ClassLoader cl, Class<?>... ifaces) {
   35.55 +            return Proxy.getProxyClass(cl, ifaces);
   35.56 +        }
   35.57 +    }
   35.58 +
   35.59 +    @Test
   35.60 +    public void fakeProxySubclassAccessCheckTest() throws ScriptException {
   35.61 +        if (System.getSecurityManager() == null) {
   35.62 +            // pass vacuously
   35.63 +            return;
   35.64 +        }
   35.65 +
   35.66 +        final ScriptEngineManager m = new ScriptEngineManager();
   35.67 +        final ScriptEngine e = m.getEngineByName("nashorn");
   35.68 +
   35.69 +        e.put("name", ScriptEngineSecurityTest.class.getName());
   35.70 +        e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
   35.71 +        e.put("intfs", new Class[] { Runnable.class });
   35.72 +
   35.73 +        String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);";
   35.74 +
   35.75 +        // Should not be able to call static methods of Proxy via fake subclass
   35.76 +        try {
   35.77 +            Class c = (Class)e.eval(getClass);
   35.78 +            fail("should have thrown SecurityException");
   35.79 +        } catch (final Exception exp) {
   35.80 +            if (! (exp instanceof SecurityException)) {
   35.81 +                fail("SecurityException expected, got " + exp);
   35.82 +            }
   35.83 +        }
   35.84 +    }
   35.85 +
   35.86 +    @Test
   35.87 +    public void fakeProxySubclassAccessCheckTest2() throws ScriptException {
   35.88 +        if (System.getSecurityManager() == null) {
   35.89 +            // pass vacuously
   35.90 +            return;
   35.91 +        }
   35.92 +
   35.93 +        final ScriptEngineManager m = new ScriptEngineManager();
   35.94 +        final ScriptEngine e = m.getEngineByName("nashorn");
   35.95 +
   35.96 +        e.put("name", ScriptEngineSecurityTest.class.getName());
   35.97 +        e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
   35.98 +        e.put("intfs", new Class[] { Runnable.class });
   35.99 +
  35.100 +        String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);";
  35.101 +
  35.102 +        // Should not be able to call static methods of Proxy via fake subclass
  35.103 +        try {
  35.104 +            Class c = (Class)e.eval(getClass);
  35.105 +            fail("should have thrown SecurityException");
  35.106 +        } catch (final Exception exp) {
  35.107 +            if (! (exp instanceof SecurityException)) {
  35.108 +                fail("SecurityException expected, got " + exp);
  35.109 +            }
  35.110 +        }
  35.111 +    }
  35.112 +
  35.113 +    @Test
  35.114 +    public static void proxyStaticAccessCheckTest() throws ScriptException {
  35.115 +        final ScriptEngineManager m = new ScriptEngineManager();
  35.116 +        final ScriptEngine e = m.getEngineByName("nashorn");
  35.117 +        final Runnable r = (Runnable)Proxy.newProxyInstance(
  35.118 +            ScriptEngineTest.class.getClassLoader(),
  35.119 +            new Class[] { Runnable.class },
  35.120 +            new InvocationHandler() {
  35.121 +                @Override
  35.122 +                public Object invoke(Object p, Method m, Object[] a) {
  35.123 +                    return null;
  35.124 +                }
  35.125 +            });
  35.126 +
  35.127 +        e.put("rc", r.getClass());
  35.128 +        e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
  35.129 +        e.put("intfs", new Class[] { Runnable.class });
  35.130 +
  35.131 +        // make sure static methods of Proxy is not accessible via subclass
  35.132 +        try {
  35.133 +            e.eval("rc.static.getProxyClass(cl, intfs)");
  35.134 +            fail("Should have thrown SecurityException");
  35.135 +        } catch (final Exception exp) {
  35.136 +            if (! (exp instanceof SecurityException)) {
  35.137 +                fail("SecurityException expected, got " + exp);
  35.138 +            }
  35.139 +        }
  35.140 +    }
  35.141  }
    36.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Fri Jan 31 22:24:45 2014 -0800
    36.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Sun Feb 02 22:51:24 2014 -0800
    36.3 @@ -33,7 +33,9 @@
    36.4  import java.io.PrintWriter;
    36.5  import java.io.StringReader;
    36.6  import java.io.StringWriter;
    36.7 +import java.lang.reflect.InvocationHandler;
    36.8  import java.lang.reflect.Method;
    36.9 +import java.lang.reflect.Proxy;
   36.10  import java.util.concurrent.Callable;
   36.11  import javax.script.Compilable;
   36.12  import javax.script.CompiledScript;
   36.13 @@ -535,6 +537,29 @@
   36.14          assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
   36.15      }
   36.16  
   36.17 +    // @bug 8032948: Nashorn linkages awry
   36.18 +    @Test
   36.19 +    public void checkProxyAccess() throws ScriptException {
   36.20 +        final ScriptEngineManager m = new ScriptEngineManager();
   36.21 +        final ScriptEngine e = m.getEngineByName("nashorn");
   36.22 +        final boolean[] reached = new boolean[1];
   36.23 +        final Runnable r = (Runnable)Proxy.newProxyInstance(
   36.24 +            ScriptEngineTest.class.getClassLoader(),
   36.25 +            new Class[] { Runnable.class },
   36.26 +            new InvocationHandler() {
   36.27 +                @Override
   36.28 +                public Object invoke(Object p, Method m, Object[] a) {
   36.29 +                    reached[0] = true;
   36.30 +                    return null;
   36.31 +                }
   36.32 +            });
   36.33 +
   36.34 +        e.put("r", r);
   36.35 +        e.eval("r.run()");
   36.36 +
   36.37 +        assertTrue(reached[0]);
   36.38 +    }
   36.39 +
   36.40      private static final String LINE_SEPARATOR = System.getProperty("line.separator");
   36.41  
   36.42      // Returns String that would be the result of calling PrintWriter.println
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/test/src/jdk/nashorn/test/models/ClassWithFinalFinalizer.java	Sun Feb 02 22:51:24 2014 -0800
    37.3 @@ -0,0 +1,31 @@
    37.4 +/*
    37.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    37.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    37.7 + *
    37.8 + * This code is free software; you can redistribute it and/or modify it
    37.9 + * under the terms of the GNU General Public License version 2 only, as
   37.10 + * published by the Free Software Foundation.  Oracle designates this
   37.11 + * particular file as subject to the "Classpath" exception as provided
   37.12 + * by Oracle in the LICENSE file that accompanied this code.
   37.13 + *
   37.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   37.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   37.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   37.17 + * version 2 for more details (a copy is included in the LICENSE file that
   37.18 + * accompanied this code).
   37.19 + *
   37.20 + * You should have received a copy of the GNU General Public License version
   37.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   37.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   37.23 + *
   37.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   37.25 + * or visit www.oracle.com if you need additional information or have any
   37.26 + * questions.
   37.27 + */
   37.28 +
   37.29 +package jdk.nashorn.test.models;
   37.30 +
   37.31 +public class ClassWithFinalFinalizer {
   37.32 +    protected final void finalize() {
   37.33 +    }
   37.34 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/test/src/jdk/nashorn/test/models/ClassWithInheritedFinalFinalizer.java	Sun Feb 02 22:51:24 2014 -0800
    38.3 @@ -0,0 +1,29 @@
    38.4 +/*
    38.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    38.7 + *
    38.8 + * This code is free software; you can redistribute it and/or modify it
    38.9 + * under the terms of the GNU General Public License version 2 only, as
   38.10 + * published by the Free Software Foundation.  Oracle designates this
   38.11 + * particular file as subject to the "Classpath" exception as provided
   38.12 + * by Oracle in the LICENSE file that accompanied this code.
   38.13 + *
   38.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   38.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   38.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   38.17 + * version 2 for more details (a copy is included in the LICENSE file that
   38.18 + * accompanied this code).
   38.19 + *
   38.20 + * You should have received a copy of the GNU General Public License version
   38.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   38.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   38.23 + *
   38.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   38.25 + * or visit www.oracle.com if you need additional information or have any
   38.26 + * questions.
   38.27 + */
   38.28 +
   38.29 +package jdk.nashorn.test.models;
   38.30 +
   38.31 +public class ClassWithInheritedFinalFinalizer extends ClassWithFinalFinalizer {
   38.32 +}

mercurial