Fri, 31 Jan 2014 00:14:59 +0000
Merge
1.1 --- a/THIRD_PARTY_README Thu Jan 23 20:51:27 2014 +0000 1.2 +++ b/THIRD_PARTY_README Fri Jan 31 00:14:59 2014 +0000 1.3 @@ -1400,7 +1400,7 @@ 1.4 ------------------------------------------------------------------------------- 1.5 1.6 %% This notice is provided with respect to Little CMS 2.4, which may be 1.7 -included with OpenJDK 8. 1.8 +included with JRE 8, JDK 8, and OpenJDK 8. 1.9 1.10 --- begin of LICENSE --- 1.11
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/jdk/internal/dynalink/linker/GuardedTypeConversion.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 3.2 +++ b/src/jdk/internal/dynalink/linker/GuardingTypeConverterFactory.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 4.2 +++ b/src/jdk/internal/dynalink/support/LinkerServicesImpl.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 5.2 +++ b/src/jdk/internal/dynalink/support/TypeConverterFactory.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 6.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 7.2 +++ b/src/jdk/nashorn/internal/objects/NativeJava.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 8.2 +++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 9.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 10.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 11.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 12.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunction.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 13.2 +++ b/src/jdk/nashorn/internal/runtime/linker/AdaptationResult.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 14.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 15.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 16.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 17.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 18.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 19.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterServices.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 20.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 21.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 22.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 23.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 24.2 +++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 25.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 26.2 +++ b/test/script/basic/JDK-8014647.js Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 27.2 +++ b/test/script/basic/JDK-8014647.js.EXPECTED Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 28.2 +++ b/test/script/basic/javaclassoverrides.js Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 29.2 +++ b/test/script/basic/javaclassoverrides.js.EXPECTED Fri Jan 31 00:14:59 2014 +0000 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 Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 31.2 +++ b/test/script/sandbox/classloader.js Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 32.2 +++ b/test/script/sandbox/classloader.js.EXPECTED Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 33.2 +++ b/test/script/sandbox/javaextend.js Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 34.2 +++ b/test/script/sandbox/javaextend.js.EXPECTED Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 35.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Fri Jan 31 00:14:59 2014 +0000 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 Thu Jan 23 20:51:27 2014 +0000 36.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Jan 31 00:14:59 2014 +0000 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 Fri Jan 31 00:14:59 2014 +0000 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 Fri Jan 31 00:14:59 2014 +0000 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 +}