Java Code Examples for jdk.internal.dynalink.linker.LinkerServices#filterInternalObjects()

The following examples show how to use jdk.internal.dynalink.linker.LinkerServices#filterInternalObjects() . 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
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 2
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 3
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}
 
Example 4
Source Project: jdk8u60   File: BeanLinker.java    License: 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 5
Source Project: jdk8u60   File: BeanLinker.java    License: GNU General Public License v2.0 4 votes vote down vote up
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 6
Source Project: jdk8u60   File: BeanLinker.java    License: GNU General Public License v2.0 4 votes vote down vote up
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}
 
Example 7
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 8
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 9
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}
 
Example 10
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 11
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 12
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}
 
Example 13
Source Project: hottub   File: BeanLinker.java    License: 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 14
Source Project: hottub   File: BeanLinker.java    License: GNU General Public License v2.0 4 votes vote down vote up
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 15
Source Project: hottub   File: BeanLinker.java    License: GNU General Public License v2.0 4 votes vote down vote up
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}
 
Example 16
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 17
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation));
}
 
Example 18
private static GuardedInvocationComponent createInternalFilteredGuardedInvocationComponent(
        final MethodHandle invocation, final MethodHandle guard, final Class<?> validatorClass,
        final ValidationType validationType, final LinkerServices linkerServices) {
    return new GuardedInvocationComponent(linkerServices.filterInternalObjects(invocation), guard,
            validatorClass, validationType);
}