jdk.internal.dynalink.support.Guards Java Examples

The following examples show how to use jdk.internal.dynalink.support.Guards. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AbstractJavaLinker.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
private MethodHandle getGuard(ValidationType validationType, MethodType methodType) {
    switch(validationType) {
        case EXACT_CLASS: {
            return getClassGuard(methodType);
        }
        case INSTANCE_OF: {
            return getAssignableGuard(methodType);
        }
        case IS_ARRAY: {
            return Guards.isArray(0, methodType);
        }
        case NONE: {
            return null;
        }
        default: {
            throw new AssertionError();
        }
    }
}
 
Example #2
Source File: AbstractJavaLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 6 votes vote down vote up
private MethodHandle getGuard(final ValidationType validationType, final MethodType methodType) {
    switch(validationType) {
        case EXACT_CLASS: {
            return getClassGuard(methodType);
        }
        case INSTANCE_OF: {
            return getAssignableGuard(methodType);
        }
        case IS_ARRAY: {
            return Guards.isArray(0, methodType);
        }
        case NONE: {
            return null;
        }
        default: {
            throw new AssertionError();
        }
    }
}
 
Example #3
Source File: BeanLinker.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
private GuardedInvocationComponent getLengthGetter(final CallSiteDescriptor callSiteDescriptor) {
    assertParameterCount(callSiteDescriptor, 1);
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);
    // If declared type of receiver at the call site is already an array, collection, or map, bind without guard.
    // Thing is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance
    // they're dealing with an array, collection, or map, but hey...
    if(declaredType.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType));
    } else if(Collection.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType));
    } else if(Map.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType));
    }

    // Otherwise, create a binding based on the actual type of the argument with an appropriate guard.
    if(clazz.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType), Guards.isArray(0,
                callSiteType), ValidationType.IS_ARRAY);
    } if(Collection.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType), Guards.asType(
                COLLECTION_GUARD, callSiteType), Collection.class, ValidationType.INSTANCE_OF);
    } if(Map.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType), Guards.asType(MAP_GUARD,
                callSiteType), Map.class, ValidationType.INSTANCE_OF);
    }
    // Can't retrieve length for objects that are neither arrays, nor collections, nor maps.
    return null;
}
 
Example #4
Source File: ClassString.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
boolean isVisibleFrom(final ClassLoader classLoader) {
    for(int i = 0; i < classes.length; ++i) {
        if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
            return false;
        }
    }
    return true;
}
 
Example #5
Source File: BeanLinker.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    }
}
 
Example #6
Source File: NashornStaticClassLinker.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
    Bootstrap.checkReflectionAccess(receiverClass);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass.getName());

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null);
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #7
Source File: BeanLinker.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(final Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    } else if(List.class.isAssignableFrom(clazz)) {
        setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
    }
}
 
Example #8
Source File: DynamicMethodLinker.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    if (operator == "call" && !constructor) {
        invocation = dynMethod.getInvocation(
                CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
    } else if (operator == "new" && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

        // Insert null for StaticClass parameter
        invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
    } else {
        return null;
    }

    if (invocation != null) {
        return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
            desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
    }

    return null;
}
 
Example #9
Source File: BeanLinker.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    }
}
 
Example #10
Source File: ClassString.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
boolean isVisibleFrom(final ClassLoader classLoader) {
    for(int i = 0; i < classes.length; ++i) {
        if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
            return false;
        }
    }
    return true;
}
 
Example #11
Source File: BeanLinker.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(final Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    } else if(List.class.isAssignableFrom(clazz)) {
        setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
    }
}
 
Example #12
Source File: DynamicMethodLinker.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    if (operator == "call" && !constructor) {
        invocation = dynMethod.getInvocation(
                CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
    } else if (operator == "new" && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

        // Insert null for StaticClass parameter
        invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
    } else {
        return null;
    }

    if (invocation != null) {
        return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
            desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
    }

    return null;
}
 
Example #13
Source File: NashornStaticClassLinker.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();

    Bootstrap.checkReflectionAccess(receiverClass, true);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        if (! Modifier.isPublic(receiverClass.getModifiers())) {
            throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName());
        }

        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass);

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
                    linkRequest.getCallSiteDescriptor().getLookup());
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #14
Source File: BeanLinker.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(final Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    } else if(List.class.isAssignableFrom(clazz)) {
        setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
    }
}
 
Example #15
Source File: DynamicMethodLinker.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    if (operator == "call" && !constructor) {
        invocation = dynMethod.getInvocation(
                CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
    } else if (operator == "new" && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

        // Insert null for StaticClass parameter
        invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
    } else {
        return null;
    }

    if (invocation != null) {
        return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
            desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
    }

    return null;
}
 
Example #16
Source File: BeanLinker.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
private GuardedInvocationComponent getLengthGetter(CallSiteDescriptor callSiteDescriptor) {
    assertParameterCount(callSiteDescriptor, 1);
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);
    // If declared type of receiver at the call site is already an array, collection, or map, bind without guard.
    // Thing is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance
    // they're dealing with an array, collection, or map, but hey...
    if(declaredType.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType));
    } else if(Collection.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType));
    } else if(Map.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType));
    }

    // Otherwise, create a binding based on the actual type of the argument with an appropriate guard.
    if(clazz.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType), Guards.isArray(0,
                callSiteType), ValidationType.IS_ARRAY);
    } if(Collection.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType), Guards.asType(
                COLLECTION_GUARD, callSiteType), Collection.class, ValidationType.INSTANCE_OF);
    } if(Map.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType), Guards.asType(MAP_GUARD,
                callSiteType), Map.class, ValidationType.INSTANCE_OF);
    }
    // Can't retrieve length for objects that are neither arrays, nor collections, nor maps.
    return null;
}
 
Example #17
Source File: NashornStaticClassLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();

    Bootstrap.checkReflectionAccess(receiverClass, true);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        if (! Modifier.isPublic(receiverClass.getModifiers())) {
            throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName());
        }

        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass);

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
                    linkRequest.getCallSiteDescriptor().getLookup());
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #18
Source File: NashornStaticClassLinker.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(LinkRequest linkRequest, LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
    Bootstrap.checkReflectionAccess(receiverClass, true);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass);

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
                    linkRequest.getCallSiteDescriptor().getLookup());
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #19
Source File: ClassString.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
boolean isVisibleFrom(final ClassLoader classLoader) {
    for(int i = 0; i < classes.length; ++i) {
        if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
            return false;
        }
    }
    return true;
}
 
Example #20
Source File: BeanLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(final Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    } else if(List.class.isAssignableFrom(clazz)) {
        setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
    }
}
 
Example #21
Source File: NashornStaticClassLinker.java    From jdk8u_nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();

    Bootstrap.checkReflectionAccess(receiverClass, true);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        if (! Modifier.isPublic(receiverClass.getModifiers())) {
            throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName());
        }

        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass);

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
                    linkRequest.getCallSiteDescriptor().getLookup());
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #22
Source File: BeanLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
private GuardedInvocationComponent getLengthGetter(final CallSiteDescriptor callSiteDescriptor) {
    assertParameterCount(callSiteDescriptor, 1);
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);
    // If declared type of receiver at the call site is already an array, collection, or map, bind without guard.
    // Thing is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance
    // they're dealing with an array, collection, or map, but hey...
    if(declaredType.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType));
    } else if(Collection.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType));
    } else if(Map.class.isAssignableFrom(declaredType)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType));
    }

    // Otherwise, create a binding based on the actual type of the argument with an appropriate guard.
    if(clazz.isArray()) {
        return new GuardedInvocationComponent(GET_ARRAY_LENGTH.asType(callSiteType), Guards.isArray(0,
                callSiteType), ValidationType.IS_ARRAY);
    } if(Collection.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_COLLECTION_LENGTH.asType(callSiteType), Guards.asType(
                COLLECTION_GUARD, callSiteType), Collection.class, ValidationType.INSTANCE_OF);
    } if(Map.class.isAssignableFrom(clazz)) {
        return new GuardedInvocationComponent(GET_MAP_LENGTH.asType(callSiteType), Guards.asType(MAP_GUARD,
                callSiteType), Map.class, ValidationType.INSTANCE_OF);
    }
    // Can't retrieve length for objects that are neither arrays, nor collections, nor maps.
    return null;
}
 
Example #23
Source File: DynamicMethodLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    if (operator == "call" && !constructor) {
        invocation = dynMethod.getInvocation(
                CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
    } else if (operator == "new" && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

        // Insert null for StaticClass parameter
        invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
    } else {
        return null;
    }

    if (invocation != null) {
        return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
            desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
    }

    return null;
}
 
Example #24
Source File: ClassString.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
boolean isVisibleFrom(final ClassLoader classLoader) {
    for(int i = 0; i < classes.length; ++i) {
        if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
            return false;
        }
    }
    return true;
}
 
Example #25
Source File: BeanLinker.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
BeanLinker(final Class<?> clazz) {
    super(clazz, Guards.getClassGuard(clazz), Guards.getInstanceOfGuard(clazz));
    if(clazz.isArray()) {
        // Some languages won't have a notion of manipulating collections. Exposing "length" on arrays as an
        // explicit property is beneficial for them.
        // REVISIT: is it maybe a code smell that "dyn:getLength" is not needed?
        setPropertyGetter("length", GET_ARRAY_LENGTH, ValidationType.IS_ARRAY);
    } else if(List.class.isAssignableFrom(clazz)) {
        setPropertyGetter("length", GET_COLLECTION_LENGTH, ValidationType.INSTANCE_OF);
    }
}
 
Example #26
Source File: DynamicMethodLinker.java    From jdk8u_nashorn with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    if (operator == "call" && !constructor) {
        invocation = dynMethod.getInvocation(
                CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices);
    } else if (operator == "new" && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

        // Insert null for StaticClass parameter
        invocation = MethodHandles.insertArguments(ctorInvocation, 0, (Object)null);
    } else {
        return null;
    }

    if (invocation != null) {
        return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0,
            desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver));
    }

    return null;
}
 
Example #27
Source File: NashornStaticClassLinker.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final LinkRequest request = linkRequest.withoutRuntimeContext(); // Nashorn has no runtime context
    final Object self = request.getReceiver();
    if (self.getClass() != StaticClass.class) {
        return null;
    }
    final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();

    Bootstrap.checkReflectionAccess(receiverClass, true);
    final CallSiteDescriptor desc = request.getCallSiteDescriptor();
    // We intercept "new" on StaticClass instances to provide additional capabilities
    if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
        if (! Modifier.isPublic(receiverClass.getModifiers())) {
            throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName());
        }

        // make sure new is on accessible Class
        Context.checkPackageAccess(receiverClass);

        // Is the class abstract? (This includes interfaces.)
        if (NashornLinker.isAbstractClass(receiverClass)) {
            // Change this link request into a link request on the adapter class.
            final Object[] args = request.getArguments();
            args[0] = JavaAdapterFactory.getAdapterClassFor(new Class<?>[] { receiverClass }, null,
                    linkRequest.getCallSiteDescriptor().getLookup());
            final LinkRequest adapterRequest = request.replaceArguments(request.getCallSiteDescriptor(), args);
            final GuardedInvocation gi = checkNullConstructor(delegate(linkerServices, adapterRequest), receiverClass);
            // Finally, modify the guard to test for the original abstract class.
            return gi.replaceMethods(gi.getInvocation(), Guards.getIdentityGuard(self));
        }
        // If the class was not abstract, just delegate linking to the standard StaticClass linker. Make an
        // additional check to ensure we have a constructor. We could just fall through to the next "return"
        // statement, except we also insert a call to checkNullConstructor() which throws an ECMAScript TypeError
        // with a more intuitive message when no suitable constructor is found.
        return checkNullConstructor(delegate(linkerServices, request), receiverClass);
    }
    // In case this was not a "new" operation, just delegate to the the standard StaticClass linker.
    return delegate(linkerServices, request);
}
 
Example #28
Source File: AbstractJavaLinker.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
private MethodHandle getAssignableGuard(final MethodType type) {
    return Guards.asType(assignableGuard, type);
}
 
Example #29
Source File: BeanLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getElementGetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);
    final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
            linkerServices, operations);

    // If declared type of receiver at the call site is already an array, a list or map, bind without guard. Thing
    // is, it'd be quite stupid of a call site creator to go though invokedynamic when it knows in advance they're
    // dealing with an array, or a list or map, but hey...
    // Note that for arrays and lists, using LinkerServices.asType() will ensure that any language specific linkers
    // in use will get a chance to perform any (if there's any) implicit conversion to integer for the indices.
    final GuardedInvocationComponent gic;
    final CollectionType collectionType;
    if(declaredType.isArray()) {
        gic = createInternalFilteredGuardedInvocationComponent(MethodHandles.arrayElementGetter(declaredType), linkerServices);
        collectionType = CollectionType.ARRAY;
    } else if(List.class.isAssignableFrom(declaredType)) {
        gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, linkerServices);
        collectionType = CollectionType.LIST;
    } else if(Map.class.isAssignableFrom(declaredType)) {
        gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, linkerServices);
        collectionType = CollectionType.MAP;
    } else if(clazz.isArray()) {
        gic = getClassGuardedInvocationComponent(linkerServices.filterInternalObjects(MethodHandles.arrayElementGetter(clazz)), callSiteType);
        collectionType = CollectionType.ARRAY;
    } else if(List.class.isAssignableFrom(clazz)) {
        gic = createInternalFilteredGuardedInvocationComponent(GET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class, ValidationType.INSTANCE_OF,
                linkerServices);
        collectionType = CollectionType.LIST;
    } else if(Map.class.isAssignableFrom(clazz)) {
        gic = createInternalFilteredGuardedInvocationComponent(GET_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class, ValidationType.INSTANCE_OF,
                linkerServices);
        collectionType = CollectionType.MAP;
    } else {
        // Can't retrieve elements for objects that are neither arrays, nor list, nor maps.
        return nextComponent;
    }

    // We can have "dyn:getElem:foo", especially in composites, i.e. "dyn:getElem|getProp|getMethod:foo"
    final String fixedKey = getFixedKey(callSiteDescriptor);
    // Convert the key to a number if we're working with a list or array
    final Object typedFixedKey;
    if(collectionType != CollectionType.MAP && fixedKey != null) {
        typedFixedKey = convertKeyToInteger(fixedKey, linkerServices);
        if(typedFixedKey == null) {
            // key is not numeric, it can never succeed
            return nextComponent;
        }
    } else {
        typedFixedKey = fixedKey;
    }

    final GuardedInvocation gi = gic.getGuardedInvocation();
    final Binder binder = new Binder(linkerServices, callSiteType, typedFixedKey);
    final MethodHandle invocation = gi.getInvocation();

    if(nextComponent == null) {
        return gic.replaceInvocation(binder.bind(invocation));
    }

    final MethodHandle checkGuard;
    switch(collectionType) {
    case LIST:
        checkGuard = convertArgToInt(RANGE_CHECK_LIST, linkerServices, callSiteDescriptor);
        break;
    case MAP:
        // TODO: A more complex solution could be devised for maps, one where we do a get() first, and fold it
        // into a GWT that tests if it returned null, and if it did, do another GWT with containsKey()
        // that returns constant null (on true), or falls back to next component (on false)
        checkGuard = linkerServices.filterInternalObjects(CONTAINS_MAP);
        break;
    case ARRAY:
        checkGuard = convertArgToInt(RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
        break;
    default:
        throw new AssertionError();
    }
    final MethodPair matchedInvocations = matchReturnTypes(binder.bind(invocation),
            nextComponent.getGuardedInvocation().getInvocation());
    return nextComponent.compose(matchedInvocations.guardWithTest(binder.bindTest(checkGuard)), gi.getGuard(),
            gic.getValidatorClass(), gic.getValidationType());
}
 
Example #30
Source File: NashornBottomLinker.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
private static GuardedInvocation linkBean(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)linkRequest.getCallSiteDescriptor();
    final Object self = linkRequest.getReceiver();
    final String operator = desc.getFirstOperator();
    switch (operator) {
    case "new":
        if(BeansLinker.isDynamicMethod(self)) {
            throw typeError("method.not.constructor", ScriptRuntime.safeToString(self));
        }
        throw typeError("not.a.function", ScriptRuntime.safeToString(self));
    case "call":
        // Support dyn:call on any object that supports some @FunctionalInterface
        // annotated interface. This way Java method, constructor references or
        // implementations of java.util.function.* interfaces can be called as though
        // those are script functions.
        final Method m = getFunctionalInterfaceMethod(self.getClass());
        if (m != null) {
            final MethodType callType = desc.getMethodType();
            // 'callee' and 'thiz' passed from script + actual arguments
            if (callType.parameterCount() != m.getParameterCount() + 2) {
                throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
            }
            return new GuardedInvocation(
                    // drop 'thiz' passed from the script.
                    MH.dropArguments(desc.getLookup().unreflect(m), 1, callType.parameterType(1)),
                    Guards.getInstanceOfGuard(m.getDeclaringClass())).asType(callType);
        }
        if(BeansLinker.isDynamicMethod(self)) {
            throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
        }
        throw typeError("not.a.function", ScriptRuntime.safeToString(self));
    case "callMethod":
    case "getMethod":
        throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
    case "getProp":
    case "getElem":
        if (desc.getOperand() != null) {
            return getInvocation(EMPTY_PROP_GETTER, self, linkerServices, desc);
        }
        return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
    case "setProp":
    case "setElem":
        if (desc.getOperand() != null) {
            return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
        }
        return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
    default:
        break;
    }
    throw new AssertionError("unknown call type " + desc);
}