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