jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType Java Examples

The following examples show how to use jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType. 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-jdk8u 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 #2
Source File: AbstractJavaLinker.java    From jdk8u_nashorn 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: AbstractJavaLinker.java    From hottub 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 #4
Source File: AbstractJavaLinker.java    From jdk8u60 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 #5
Source File: StaticClassLinker.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
SingleClassStaticsLinker(final Class<?> clazz) {
    super(clazz, IS_CLASS.bindTo(clazz));
    // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
    // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
    setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
    constructor = createConstructorMethod(clazz);
}
 
Example #6
Source File: StaticClassLinker.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
SingleClassStaticsLinker(final Class<?> clazz) {
    super(clazz, IS_CLASS.bindTo(clazz));
    // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
    // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
    setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
    constructor = createConstructorMethod(clazz);
}
 
Example #7
Source File: BeanLinker.java    From TencentKona-8 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 #8
Source File: BeanLinker.java    From openjdk-8-source 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 #9
Source File: StaticClassLinker.java    From nashorn with GNU General Public License v2.0 5 votes vote down vote up
SingleClassStaticsLinker(Class<?> clazz) {
    super(clazz, IS_CLASS.bindTo(clazz));
    // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
    // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
    setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
    constructor = createConstructorMethod(clazz);
}
 
Example #10
Source File: StaticClassLinker.java    From jdk8u_nashorn with GNU General Public License v2.0 5 votes vote down vote up
SingleClassStaticsLinker(final Class<?> clazz) {
    super(clazz, IS_CLASS.bindTo(clazz));
    // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
    // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
    setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
    constructor = createConstructorMethod(clazz);
}
 
Example #11
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 #12
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 #13
Source File: BeanLinker.java    From jdk8u60 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 #14
Source File: StaticClassLinker.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
SingleClassStaticsLinker(final Class<?> clazz) {
    super(clazz, IS_CLASS.bindTo(clazz));
    // Map "staticClassObject.class" to StaticClass.getRepresentedClass(). Some adventurous soul could subclass
    // StaticClass, so we use INSTANCE_OF validation instead of EXACT_CLASS.
    setPropertyGetter("class", GET_CLASS, ValidationType.INSTANCE_OF);
    constructor = createConstructorMethod(clazz);
}
 
Example #15
Source File: BeanLinker.java    From nashorn 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 #16
Source File: BeanLinker.java    From openjdk-8 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: BeanLinker.java    From jdk8u_nashorn 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 #18
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 #19
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 #20
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 #21
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 #22
Source File: AbstractJavaLinker.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
GuardedInvocationComponent getClassGuardedInvocationComponent(MethodHandle invocation, MethodType type) {
    return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
 
Example #23
Source File: BeanLinker.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getElementSetter(CallSiteDescriptor callSiteDescriptor,
        LinkerServices linkerServices, List<String> operations) throws Exception {
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);

    final GuardedInvocationComponent gic;
    // 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 boolean isMap;
    if(declaredType.isArray()) {
        gic = new GuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType));
        isMap = false;
    } else if(List.class.isAssignableFrom(declaredType)) {
        gic = new GuardedInvocationComponent(SET_LIST_ELEMENT);
        isMap = false;
    } else if(Map.class.isAssignableFrom(declaredType)) {
        gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT);
        isMap = true;
    } else if(clazz.isArray()) {
        gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementSetter(clazz), callSiteType);
        isMap = false;
    } else if(List.class.isAssignableFrom(clazz)) {
        gic = new GuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
                ValidationType.INSTANCE_OF);
        isMap = false;
    } else if(Map.class.isAssignableFrom(clazz)) {
        gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
                ValidationType.INSTANCE_OF);
        isMap = true;
    } else {
        // Can't set elements for objects that are neither arrays, nor list, nor maps.
        gic = null;
        isMap = false;
    }

    // In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
    // as maps will always succeed in setting the element and will never need to fall back to the next component
    // operation.
    final GuardedInvocationComponent nextComponent = isMap ? null : getGuardedInvocationComponent(
            callSiteDescriptor, linkerServices, operations);
    if(gic == null) {
        return nextComponent;
    }

    // We can have "dyn:setElem:foo", especially in composites, i.e. "dyn:setElem|setProp: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(!isMap && 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 = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
        RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
    return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
            binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
            gic.getValidatorClass(), gic.getValidationType());
}
 
Example #24
Source File: AbstractJavaLinker.java    From nashorn with GNU General Public License v2.0 4 votes vote down vote up
AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) {
    this.method = method;
    this.validationType = validationType;
}
 
Example #25
Source File: AbstractJavaLinker.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) {
    this.method = method;
    this.validationType = validationType;
}
 
Example #26
Source File: AbstractJavaLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
GuardedInvocationComponent getClassGuardedInvocationComponent(final MethodHandle invocation, final MethodType type) {
    return new GuardedInvocationComponent(invocation, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
 
Example #27
Source File: BeanLinker.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getElementSetter(CallSiteDescriptor callSiteDescriptor,
        LinkerServices linkerServices, List<String> operations) throws Exception {
    final MethodType callSiteType = callSiteDescriptor.getMethodType();
    final Class<?> declaredType = callSiteType.parameterType(0);

    final GuardedInvocationComponent gic;
    // 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 boolean isMap;
    if(declaredType.isArray()) {
        gic = new GuardedInvocationComponent(MethodHandles.arrayElementSetter(declaredType));
        isMap = false;
    } else if(List.class.isAssignableFrom(declaredType)) {
        gic = new GuardedInvocationComponent(SET_LIST_ELEMENT);
        isMap = false;
    } else if(Map.class.isAssignableFrom(declaredType)) {
        gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT);
        isMap = true;
    } else if(clazz.isArray()) {
        gic = getClassGuardedInvocationComponent(MethodHandles.arrayElementSetter(clazz), callSiteType);
        isMap = false;
    } else if(List.class.isAssignableFrom(clazz)) {
        gic = new GuardedInvocationComponent(SET_LIST_ELEMENT, Guards.asType(LIST_GUARD, callSiteType), List.class,
                ValidationType.INSTANCE_OF);
        isMap = false;
    } else if(Map.class.isAssignableFrom(clazz)) {
        gic = new GuardedInvocationComponent(PUT_MAP_ELEMENT, Guards.asType(MAP_GUARD, callSiteType), Map.class,
                ValidationType.INSTANCE_OF);
        isMap = true;
    } else {
        // Can't set elements for objects that are neither arrays, nor list, nor maps.
        gic = null;
        isMap = false;
    }

    // In contrast to, say, getElementGetter, we only compute the nextComponent if the target object is not a map,
    // as maps will always succeed in setting the element and will never need to fall back to the next component
    // operation.
    final GuardedInvocationComponent nextComponent = isMap ? null : getGuardedInvocationComponent(
            callSiteDescriptor, linkerServices, operations);
    if(gic == null) {
        return nextComponent;
    }

    // We can have "dyn:setElem:foo", especially in composites, i.e. "dyn:setElem|setProp: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(!isMap && 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 = convertArgToInt(invocation == SET_LIST_ELEMENT ? RANGE_CHECK_LIST :
        RANGE_CHECK_ARRAY, linkerServices, callSiteDescriptor);
    return nextComponent.compose(MethodHandles.guardWithTest(binder.bindTest(checkGuard),
            binder.bind(invocation), nextComponent.getGuardedInvocation().getInvocation()), gi.getGuard(),
            gic.getValidatorClass(), gic.getValidationType());
}
 
Example #28
Source File: AbstractJavaLinker.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

            // We want setters that conform to "Object(O, V)". Note, we aren't doing "R(O, V)" as it might not be
            // valid for us to convert return values proactively. Also, since we don't know what setters will be
            // invoked, we'll conservatively presume Object return type. The one exception is void return.
            final MethodType origType = callSiteDescriptor.getMethodType();
            final MethodType type = origType.returnType() == void.class ? origType : origType.changeReturnType(Object.class);

            // What's below is basically:
            //   foldArguments(guardWithTest(isNotNull, invoke, null|nextComponent.invocation),
            //     get_setter_handle(type, linkerServices))
            // only with a bunch of method signature adjustments. Basically, retrieve method setter
            // MethodHandle; if it is non-null, invoke it, otherwise either return null, or delegate to next
            // component's invocation.

            // Call site type is "ret_type(object_type,property_name_type,property_value_type)", which we'll
            // abbreviate to R(O, N, V) going forward, although we don't really use R here (see above about using
            // Object return type).
            final MethodType setterType = type.dropParameterTypes(1, 2);
            // Bind property setter handle to the expected setter type and linker services. Type is
            // MethodHandle(Object, String, Object)
            final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0,
                    callSiteDescriptor.changeMethodType(setterType), linkerServices);

            // Cast getter to MethodHandle(O, N, V)
            final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType(
                    MethodHandle.class));

            // Handle to invoke the setter R(MethodHandle, O, V)
            final MethodHandle invokeHandle = MethodHandles.exactInvoker(setterType);
            // Handle to invoke the setter, dropping unnecessary fold arguments R(MethodHandle, O, N, V)
            final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandle, 2, type.parameterType(
                    1));
            final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
                    linkerServices, operations);

            final MethodHandle fallbackFolded;
            if(nextComponent == null) {
                // Object(MethodHandle)->Object(MethodHandle, O, N, V); returns constant null
                fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_METHOD_HANDLE, 1,
                        type.parameterList()).asType(type.insertParameterTypes(0, MethodHandle.class));
            } else {
                // Object(O, N, V)->Object(MethodHandle, O, N, V); adapts the next component's invocation to drop the
                // extra argument resulting from fold
                fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
                        0, MethodHandle.class);
            }

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
Example #29
Source File: AbstractJavaLinker.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getPropertyGetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> ops) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Since we can't know what kind of a getter we'll get back on different invocations, we'll just
            // conservatively presume Object. Note we can't just coerce to a narrower call site type as the linking
            // runtime might not allow coercing at that call site.
            final MethodType type = callSiteDescriptor.getMethodType().changeReturnType(Object.class);
            // Must have exactly two arguments: receiver and name
            assertParameterCount(callSiteDescriptor, 2);

            // What's below is basically:
            //   foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle)
            // only with a bunch of method signature adjustments. Basically, retrieve method getter
            // AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null,
            // or delegate to next component's invocation.

            final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
                    AnnotatedDynamicMethod.class));
            final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
                    GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup(), linkerServices);
            final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
                    callSiteBoundMethodGetter);
            // Object(AnnotatedDynamicMethod, Object)->Object(AnnotatedDynamicMethod, T0)
            final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker,
                    MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0)));
            // Since it's in the target of a fold, drop the unnecessary second argument
            // Object(AnnotatedDynamicMethod, T0)->Object(AnnotatedDynamicMethod, T0, T1)
            final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
                    type.parameterType(1));
            final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
                    linkerServices, ops);

            final MethodHandle fallbackFolded;
            if(nextComponent == null) {
                // Object(AnnotatedDynamicMethod)->Object(AnnotatedDynamicMethod, T0, T1); returns constant null
                fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1,
                        type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class));
            } else {
                // Object(T0, T1)->Object(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to
                // drop the extra argument resulting from fold and to change its return type to Object.
                final MethodHandle nextInvocation = nextComponent.getGuardedInvocation().getInvocation();
                final MethodType nextType = nextInvocation.type();
                fallbackFolded = MethodHandles.dropArguments(nextInvocation.asType(
                        nextType.changeReturnType(Object.class)), 0, AnnotatedDynamicMethod.class);
            }

            // fold(Object(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
            final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeGetter, type);
            }
            return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have exactly one argument: receiver
            assertParameterCount(callSiteDescriptor, 1);
            // Fixed name
            final AnnotatedDynamicMethod annGetter = propertyGetters.get(callSiteDescriptor.getNameToken(
                    CallSiteDescriptor.NAME_OPERAND));
            if(annGetter == null) {
                // We have no such property, always delegate to the next component operation
                return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops);
            }
            final MethodHandle getter = annGetter.getInvocation(callSiteDescriptor, linkerServices);
            // NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being
            // overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the
            // method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If
            // we're linking against a field getter, don't make the assumption.
            // NOTE: No delegation to the next component operation if we have a property with this name, even if its
            // value is null.
            final ValidationType validationType = annGetter.validationType;
            // TODO: we aren't using the type that declares the most generic getter here!
            return new GuardedInvocationComponent(getter, getGuard(validationType,
                    callSiteDescriptor.getMethodType()), clazz, validationType);
        }
        default: {
            // Can't do anything with more than 3 name components
            return null;
        }
    }
}
 
Example #30
Source File: AbstractJavaLinker.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor,
        LinkerServices linkerServices, List<String> ops) throws Exception {
    final MethodType type = callSiteDescriptor.getMethodType();
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have exactly two arguments: receiver and name
            assertParameterCount(callSiteDescriptor, 2);

            // What's below is basically:
            //   foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle)
            // only with a bunch of method signature adjustments. Basically, retrieve method getter
            // AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null,
            // or delegate to next component's invocation.

            final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType(
                    AnnotatedDynamicMethod.class));
            final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments(
                    GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup());
            final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0,
                    callSiteBoundMethodGetter);
            // Object(AnnotatedDynamicMethod, Object)->R(AnnotatedDynamicMethod, T0)
            final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker,
                    MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0)));
            // Since it's in the target of a fold, drop the unnecessary second argument
            // R(AnnotatedDynamicMethod, T0)->R(AnnotatedDynamicMethod, T0, T1)
            final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2,
                    type.parameterType(1));
            final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor,
                    linkerServices, ops);

            final MethodHandle fallbackFolded;
            if(nextComponent == null) {
                // Object(AnnotatedDynamicMethod)->R(AnnotatedDynamicMethod, T0, T1); returns constant null
                fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1,
                        type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class));
            } else {
                // R(T0, T1)->R(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to drop the
                // extra argument resulting from fold
                fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(),
                        0, AnnotatedDynamicMethod.class);
            }

            // fold(R(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1))
            final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeGetter, type);
            }
            return nextComponent.compose(compositeGetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have exactly one argument: receiver
            assertParameterCount(callSiteDescriptor, 1);
            // Fixed name
            final AnnotatedDynamicMethod annGetter = propertyGetters.get(callSiteDescriptor.getNameToken(
                    CallSiteDescriptor.NAME_OPERAND));
            if(annGetter == null) {
                // We have no such property, always delegate to the next component operation
                return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops);
            }
            final MethodHandle getter = annGetter.getInvocation(callSiteDescriptor, linkerServices);
            // NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being
            // overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the
            // method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If
            // we're linking against a field getter, don't make the assumption.
            // NOTE: No delegation to the next component operation if we have a property with this name, even if its
            // value is null.
            final ValidationType validationType = annGetter.validationType;
            // TODO: we aren't using the type that declares the most generic getter here!
            return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType,
                    type), clazz, validationType);
        }
        default: {
            // Can't do anything with more than 3 name components
            return null;
        }
    }
}