java.lang.invoke.MethodHandles#filterArguments ( )源码实例Demo

下面列出了java.lang.invoke.MethodHandles#filterArguments ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

源代码1 项目: Bytecoder   文件: ObjectMethods.java
/**
 * Generates a method handle for the {@code equals} method for a given data class
 * @param receiverClass   the data class
 * @param getters         the list of getters
 * @return the method handle
 */
private static MethodHandle makeEquals(Class<?> receiverClass,
                                      List<MethodHandle> getters) {
    MethodType rr = MethodType.methodType(boolean.class, receiverClass, receiverClass);
    MethodType ro = MethodType.methodType(boolean.class, receiverClass, Object.class);
    MethodHandle instanceFalse = MethodHandles.dropArguments(FALSE, 0, receiverClass, Object.class); // (RO)Z
    MethodHandle instanceTrue = MethodHandles.dropArguments(TRUE, 0, receiverClass, Object.class); // (RO)Z
    MethodHandle isSameObject = OBJECT_EQ.asType(ro); // (RO)Z
    MethodHandle isInstance = MethodHandles.dropArguments(CLASS_IS_INSTANCE.bindTo(receiverClass), 0, receiverClass); // (RO)Z
    MethodHandle accumulator = MethodHandles.dropArguments(TRUE, 0, receiverClass, receiverClass); // (RR)Z

    for (MethodHandle getter : getters) {
        MethodHandle equalator = equalator(getter.type().returnType()); // (TT)Z
        MethodHandle thisFieldEqual = MethodHandles.filterArguments(equalator, 0, getter, getter); // (RR)Z
        accumulator = MethodHandles.guardWithTest(thisFieldEqual, accumulator, instanceFalse.asType(rr));
    }

    return MethodHandles.guardWithTest(isSameObject,
                                       instanceTrue,
                                       MethodHandles.guardWithTest(isInstance, accumulator.asType(ro), instanceFalse));
}
 
源代码2 项目: hottub   文件: BeanLinker.java
private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
    final Class<?> sourceType = desc.getMethodType().parameterType(1);
    if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
        return mh;
    } else if(ls.canConvert(sourceType, Number.class)) {
        final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
        return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
                mh.type().parameterType(1))));
    }
    return mh;
}
 
源代码3 项目: TencentKona-8   文件: TypeConverterFactory.java
private static MethodHandle applyConverters(final MethodHandle handle, final int pos, final List<MethodHandle> converters) {
    if(converters.isEmpty()) {
        return handle;
    }
    final MethodHandle newHandle =
            MethodHandles.filterArguments(handle, pos, converters.toArray(new MethodHandle[converters.size()]));
    converters.clear();
    return newHandle;
}
 
源代码4 项目: openjdk-8-source   文件: BeanLinker.java
private static MethodHandle convertArgToInt(MethodHandle mh, LinkerServices ls, CallSiteDescriptor desc) {
    final Class<?> sourceType = desc.getMethodType().parameterType(1);
    if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
        return mh;
    } else if(ls.canConvert(sourceType, Number.class)) {
        final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
        return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
                mh.type().parameterType(1))));
    }
    return mh;
}
 
源代码5 项目: jdk8u60   文件: BeanLinker.java
private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
    final Class<?> sourceType = desc.getMethodType().parameterType(1);
    if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
        return mh;
    } else if(ls.canConvert(sourceType, Number.class)) {
        final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
        return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
                mh.type().parameterType(1))));
    }
    return mh;
}
 
源代码6 项目: nashorn   文件: BeanLinker.java
private static MethodHandle convertArgToInt(MethodHandle mh, LinkerServices ls, CallSiteDescriptor desc) {
    final Class<?> sourceType = desc.getMethodType().parameterType(1);
    if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
        return mh;
    } else if(ls.canConvert(sourceType, Number.class)) {
        final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
        return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
                mh.type().parameterType(1))));
    }
    return mh;
}
 
源代码7 项目: openjdk-8   文件: TypeConverterFactory.java
private static MethodHandle applyConverters(MethodHandle handle, int pos, List<MethodHandle> converters) {
    if(converters.isEmpty()) {
        return handle;
    }
    final MethodHandle newHandle =
            MethodHandles.filterArguments(handle, pos, converters.toArray(new MethodHandle[converters.size()]));
    converters.clear();
    return newHandle;
}
 
源代码8 项目: openjdk-jdk8u-backup   文件: BeanLinker.java
private static MethodHandle convertArgToInt(final MethodHandle mh, final LinkerServices ls, final CallSiteDescriptor desc) {
    final Class<?> sourceType = desc.getMethodType().parameterType(1);
    if(TypeUtilities.isMethodInvocationConvertible(sourceType, Number.class)) {
        return mh;
    } else if(ls.canConvert(sourceType, Number.class)) {
        final MethodHandle converter = ls.getTypeConverter(sourceType, Number.class);
        return MethodHandles.filterArguments(mh, 1, converter.asType(converter.type().changeReturnType(
                mh.type().parameterType(1))));
    }
    return mh;
}
 
源代码9 项目: TencentKona-8   文件: MethodHandleFactory.java
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
    final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
    return debug(mh, "filterArguments", target, pos, filters);
}
 
源代码10 项目: nashorn   文件: AbstractJavaLinker.java
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;
        }
    }
}
 
源代码11 项目: openjdk-8   文件: AbstractJavaLinker.java
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;
        }
    }
}
 
源代码12 项目: jdk8u60   文件: JavaSuperAdapterLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
        throws Exception {
    final Object objSuperAdapter = linkRequest.getReceiver();
    if(!(objSuperAdapter instanceof JavaSuperAdapter)) {
        return null;
    }

    final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
    if(!CallSiteDescriptorFactory.tokenizeOperators(descriptor).contains(GET_METHOD)) {
        // We only handle getMethod
        return null;
    }

    final Object adapter = ((JavaSuperAdapter)objSuperAdapter).getAdapter();

    // Replace argument (javaSuperAdapter, ...) => (adapter, ...) when delegating to BeansLinker
    final Object[] args = linkRequest.getArguments();
    args[0] = adapter;

    // Use R(T0, ...) => R(adapter.class, ...) call site type when delegating to BeansLinker.
    final MethodType type = descriptor.getMethodType();
    final Class<?> adapterClass = adapter.getClass();
    final boolean hasFixedName = descriptor.getNameTokenCount() > 2;
    final String opName = hasFixedName ? (DYN_GET_METHOD_FIXED + descriptor.getNameToken(
            CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD;

    final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(descriptor.getLookup(), opName,
            type.changeParameterType(0, adapterClass), 0);

    // Delegate to BeansLinker
    final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
            BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
            linkerServices);

    final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
    if(guardedInv == null) {
        // Short circuit the lookup here for non-existent methods by linking an empty getter. If we just returned
        // null instead, BeansLinker would find final methods on the JavaSuperAdapter instead: getClass() and
        // wait().
        return new GuardedInvocation(MethodHandles.dropArguments(EMPTY_GETTER, 1,type.parameterList().subList(1,
                type.parameterCount())), guard).asType(descriptor);
    }

    final MethodHandle invocation = guardedInv.getInvocation();
    final MethodType invType = invocation.type();
    // For invocation typed R(T0, ...) create a dynamic method binder of type Object(R, T0)
    final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(Object.class,
            invType.returnType(), invType.parameterType(0)));
    // For invocation typed R(T0, T1, ...) create a dynamic method binder of type Object(R, T0, T1, ...)
    final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2,
            invType.parameterList().subList(1, invType.parameterCount()));
    // Finally, fold the invocation into the binder to produce a method handle that will bind every returned
    // DynamicMethod object from dyn:getMethod calls to the actual receiver
    // Object(R(T0, T1, ...), T0, T1, ...)
    final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation);

    final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type);
    final MethodHandle adaptedInvocation;
    if(hasFixedName) {
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter);
    } else {
        // Add a filter that'll prepend "super$" to each name passed to the variable-name "dyn:getMethod".
        final MethodHandle typedAddPrefix = asFilterType(ADD_PREFIX_TO_METHOD_NAME, 1, invType, type);
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter, typedAddPrefix);
    }

    return guardedInv.replaceMethods(adaptedInvocation, guard).asType(descriptor);
}
 
源代码13 项目: jdk8u60   文件: AbstractJavaLinker.java
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;
        }
    }
}
 
源代码14 项目: openjdk-8-source   文件: JavaSuperAdapterLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
        throws Exception {
    final Object objSuperAdapter = linkRequest.getReceiver();
    if(!(objSuperAdapter instanceof JavaSuperAdapter)) {
        return null;
    }

    final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
    if(!CallSiteDescriptorFactory.tokenizeOperators(descriptor).contains(GET_METHOD)) {
        // We only handle getMethod
        return null;
    }

    final Object adapter = ((JavaSuperAdapter)objSuperAdapter).getAdapter();

    // Replace argument (javaSuperAdapter, ...) => (adapter, ...) when delegating to BeansLinker
    final Object[] args = linkRequest.getArguments();
    args[0] = adapter;

    // Use R(T0, ...) => R(adapter.class, ...) call site type when delegating to BeansLinker.
    final MethodType type = descriptor.getMethodType();
    final Class<?> adapterClass = adapter.getClass();
    final boolean hasFixedName = descriptor.getNameTokenCount() > 2;
    final String opName = hasFixedName ? (DYN_GET_METHOD_FIXED + descriptor.getNameToken(
            CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD;

    final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(descriptor.getLookup(), opName,
            type.changeParameterType(0, adapterClass), 0);

    // Delegate to BeansLinker
    final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
            BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
            linkerServices);

    final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
    if(guardedInv == null) {
        // Short circuit the lookup here for non-existent methods by linking an empty getter. If we just returned
        // null instead, BeansLinker would find final methods on the JavaSuperAdapter instead: getClass() and
        // wait().
        return new GuardedInvocation(MethodHandles.dropArguments(EMPTY_GETTER, 1,type.parameterList().subList(1,
                type.parameterCount())), guard).asType(descriptor);
    }

    final MethodHandle invocation = guardedInv.getInvocation();
    final MethodType invType = invocation.type();
    // For invocation typed R(T0, ...) create a dynamic method binder of type R(R, T0)
    final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(invType.returnType(),
            invType.returnType(), invType.parameterType(0)));
    // For invocation typed R(T0, T1, ...) create a dynamic method binder of type R(R, T0, T1, ...)
    final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2,
            invType.parameterList().subList(1, invType.parameterCount()));
    // Finally, fold the invocation into the binder to produce a method handle that will bind every returned
    // DynamicMethod object from dyn:getMethod calls to the actual receiver
    // R(R(T0, T1, ...), T0, T1, ...)
    final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation);

    final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type);
    final MethodHandle adaptedInvocation;
    if(hasFixedName) {
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter);
    } else {
        // Add a filter that'll prepend "super$" to each name passed to the variable-name "dyn:getMethod".
        final MethodHandle typedAddPrefix = asFilterType(ADD_PREFIX_TO_METHOD_NAME, 1, invType, type);
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter, typedAddPrefix);
    }

    return guardedInv.replaceMethods(adaptedInvocation, guard).asType(descriptor);
}
 
源代码15 项目: openjdk-jdk8u   文件: AbstractJavaLinker.java
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;
        }
    }
}
 
源代码16 项目: jdk8u_nashorn   文件: MethodHandleFactory.java
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
    final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
    return debug(mh, "filterArguments", target, pos, filters);
}
 
源代码17 项目: openjdk-jdk9   文件: MethodHandleFactory.java
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
    final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
    return debug(mh, "filterArguments", target, pos, filters);
}
 
源代码18 项目: openjdk-8   文件: MethodHandleFactory.java
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
    return MethodHandles.filterArguments(target, pos, filters);
}
 
源代码19 项目: openjdk-jdk8u-backup   文件: MethodHandleFactory.java
@Override
public MethodHandle filterArguments(final MethodHandle target, final int pos, final MethodHandle... filters) {
    final MethodHandle mh = MethodHandles.filterArguments(target, pos, filters);
    return debug(mh, "filterArguments", target, pos, filters);
}
 
源代码20 项目: openjdk-8   文件: JavaSuperAdapterLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
        throws Exception {
    final Object objSuperAdapter = linkRequest.getReceiver();
    if(!(objSuperAdapter instanceof JavaSuperAdapter)) {
        return null;
    }

    final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
    if(!CallSiteDescriptorFactory.tokenizeOperators(descriptor).contains(GET_METHOD)) {
        // We only handle getMethod
        return null;
    }

    final Object adapter = ((JavaSuperAdapter)objSuperAdapter).getAdapter();

    // Replace argument (javaSuperAdapter, ...) => (adapter, ...) when delegating to BeansLinker
    final Object[] args = linkRequest.getArguments();
    args[0] = adapter;

    // Use R(T0, ...) => R(adapter.class, ...) call site type when delegating to BeansLinker.
    final MethodType type = descriptor.getMethodType();
    final Class<?> adapterClass = adapter.getClass();
    final boolean hasFixedName = descriptor.getNameTokenCount() > 2;
    final String opName = hasFixedName ? (DYN_GET_METHOD_FIXED + descriptor.getNameToken(
            CallSiteDescriptor.NAME_OPERAND)) : DYN_GET_METHOD;

    final CallSiteDescriptor newDescriptor = NashornCallSiteDescriptor.get(descriptor.getLookup(), opName,
            type.changeParameterType(0, adapterClass), 0);

    // Delegate to BeansLinker
    final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
            BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
            linkerServices);

    final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
    if(guardedInv == null) {
        // Short circuit the lookup here for non-existent methods by linking an empty getter. If we just returned
        // null instead, BeansLinker would find final methods on the JavaSuperAdapter instead: getClass() and
        // wait().
        return new GuardedInvocation(MethodHandles.dropArguments(EMPTY_GETTER, 1,type.parameterList().subList(1,
                type.parameterCount())), guard).asType(descriptor);
    }

    final MethodHandle invocation = guardedInv.getInvocation();
    final MethodType invType = invocation.type();
    // For invocation typed R(T0, ...) create a dynamic method binder of type R(R, T0)
    final MethodHandle typedBinder = BIND_DYNAMIC_METHOD.asType(MethodType.methodType(invType.returnType(),
            invType.returnType(), invType.parameterType(0)));
    // For invocation typed R(T0, T1, ...) create a dynamic method binder of type R(R, T0, T1, ...)
    final MethodHandle droppingBinder = MethodHandles.dropArguments(typedBinder, 2,
            invType.parameterList().subList(1, invType.parameterCount()));
    // Finally, fold the invocation into the binder to produce a method handle that will bind every returned
    // DynamicMethod object from dyn:getMethod calls to the actual receiver
    // R(R(T0, T1, ...), T0, T1, ...)
    final MethodHandle bindingInvocation = MethodHandles.foldArguments(droppingBinder, invocation);

    final MethodHandle typedGetAdapter = asFilterType(GET_ADAPTER, 0, invType, type);
    final MethodHandle adaptedInvocation;
    if(hasFixedName) {
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter);
    } else {
        // Add a filter that'll prepend "super$" to each name passed to the variable-name "dyn:getMethod".
        final MethodHandle typedAddPrefix = asFilterType(ADD_PREFIX_TO_METHOD_NAME, 1, invType, type);
        adaptedInvocation = MethodHandles.filterArguments(bindingInvocation, 0, typedGetAdapter, typedAddPrefix);
    }

    return guardedInv.replaceMethods(adaptedInvocation, guard).asType(descriptor);
}