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

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

private static MethodHandle dropReceiver(final MethodHandle mh, final Class<?> receiverClass) {
    MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, receiverClass);
    // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state.
    if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) {
        final MethodType type = mh.type();
        newHandle = newHandle.asVarargsCollector(type.parameterType(type.parameterCount() - 1));
    }
    return newHandle;
}
 
源代码2 项目: jdk8u_nashorn   文件: NativeObject.java
private static MethodHandle getBoundBeanMethodGetter(final Object source, final MethodHandle methodGetter) {
    try {
        // NOTE: we're relying on the fact that "dyn:getMethod:..." return value is constant for any given method
        // name and object linked with BeansLinker. (Actually, an even stronger assumption is true: return value is
        // constant for any given method name and object's class.)
        return MethodHandles.dropArguments(MethodHandles.constant(Object.class,
                Bootstrap.bindCallable(methodGetter.invoke(source), source, null)), 0, Object.class);
    } catch(RuntimeException|Error e) {
        throw e;
    } catch(final Throwable t) {
        throw new RuntimeException(t);
    }
}
 
源代码3 项目: jdk8u60   文件: DynamicMethodLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

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

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

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

    return null;
}
 
源代码4 项目: nashorn   文件: StaticClassIntrospector.java
private static MethodHandle dropReceiver(final MethodHandle mh, final Class<?> receiverClass) {
    MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, receiverClass);
    // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state.
    if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) {
        final MethodType type = mh.type();
        newHandle = newHandle.asVarargsCollector(type.parameterType(type.parameterCount() - 1));
    }
    return newHandle;
}
 
源代码5 项目: openjdk-8-source   文件: ChainedCallSite.java
/**
 * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
 * chain.
 * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
 * @return a method handle for prune-and-invoke
 */
private MethodHandle makePruneAndInvokeMethod(MethodHandle relink) {
    // Bind prune to (this, relink)
    final MethodHandle boundPrune = MethodHandles.insertArguments(PRUNE, 0, this, relink);
    // Make it ignore all incoming arguments
    final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList());
    // Invoke prune, then invoke the call site target with original arguments
    return MethodHandles.foldArguments(MethodHandles.exactInvoker(type()), ignoreArgsPrune);
}
 
源代码6 项目: TencentKona-8   文件: ChainedCallSite.java
/**
 * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
 * chain.
 * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
 * @return a method handle for prune-and-invoke
 */
private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) {
    // Bind prune to (this, relink)
    final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink);
    // Make it ignore all incoming arguments
    final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList());
    // Invoke prune, then invoke the call site target with original arguments
    return MethodHandles.foldArguments(MethodHandles.exactInvoker(type()), ignoreArgsPrune);
}
 
源代码7 项目: jdk8u-jdk   文件: Helper.java
public static MethodHandle addTrailingArgs(MethodHandle target, int nargs,
        List<Class<?>> classes) {
    int targetLen = target.type().parameterCount();
    int extra = (nargs - targetLen);
    if (extra <= 0) {
        return target;
    }
    List<Class<?>> fakeArgs = new ArrayList<>(extra);
    for (int i = 0; i < extra; ++i) {
        fakeArgs.add(classes.get(i % classes.size()));
    }
    return MethodHandles.dropArguments(target, targetLen, fakeArgs);
}
 
源代码8 项目: openjdk-jdk8u   文件: DynamicMethodLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") {
        return null;
    }
    final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR);
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

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

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

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

    return null;
}
 
源代码9 项目: openjdk-jdk9   文件: DynamicMethodLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) {
    final Object receiver = linkRequest.getReceiver();
    if(!(receiver instanceof DynamicMethod)) {
        return null;
    }
    final DynamicMethod dynMethod = (DynamicMethod)receiver;
    final boolean constructor = dynMethod.isConstructor();
    final MethodHandle invocation;

    final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
    final Operation op = NamedOperation.getBaseOperation(desc.getOperation());
    if (op == StandardOperation.CALL && !constructor) {
        invocation = dynMethod.getInvocation(desc.changeMethodType(
                desc.getMethodType().dropParameterTypes(0, 1)), linkerServices);
    } else if (op == StandardOperation.NEW && constructor) {
        final MethodHandle ctorInvocation = dynMethod.getInvocation(desc, linkerServices);
        if(ctorInvocation == null) {
            return null;
        }

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

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

    return null;
}
 
源代码10 项目: beautiful_logger   文件: LoggerImpl.java
private static MethodHandle empty_void(MethodType methodType) {
  if (IS_JAVA_8) {
    return MethodHandles.dropArguments(NOP, 0, methodType.parameterList());  
  }
  return MethodHandles.empty(methodType);
}
 
源代码11 项目: openjdk-jdk8u   文件: MethodHandleFactory.java
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
    final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
    return debug(mh, "dropArguments", target, pos, values);
}
 
源代码12 项目: hottub   文件: MethodHandleFactory.java
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
    final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
    return debug(mh, "dropArguments", target, pos, values);
}
 
源代码13 项目: hottub   文件: BoundCallableLinker.java
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
    final Object objBoundCallable = linkRequest.getReceiver();
    if(!(objBoundCallable instanceof BoundCallable)) {
        return null;
    }

    final CallSiteDescriptor descriptor = linkRequest.getCallSiteDescriptor();
    if (descriptor.getNameTokenCount() < 2 || !"dyn".equals(descriptor.getNameToken(CallSiteDescriptor.SCHEME))) {
        return null;
    }
    final String operation = descriptor.getNameToken(CallSiteDescriptor.OPERATOR);
    // We need to distinguish "dyn:new" from "dyn:call" because "dyn:call" sites have parameter list of the form
    // "callee, this, args", while "dyn:call" sites have "callee, args" -- they lack the "this" parameter.
    final boolean isCall;
    if ("new".equals(operation)) {
        isCall = false;
    } else if ("call".equals(operation)) {
        isCall = true;
    } else {
        // Only dyn:call and dyn:new are supported.
        return null;
    }
    final BoundCallable boundCallable = (BoundCallable)objBoundCallable;
    final Object callable = boundCallable.getCallable();
    final Object boundThis = boundCallable.getBoundThis();

    // We need to ask the linker services for a delegate invocation on the target callable.

    // Replace arguments (boundCallable[, this], args) => (callable[, boundThis], boundArgs, args) when delegating
    final Object[] args = linkRequest.getArguments();
    final Object[] boundArgs = boundCallable.getBoundArgs();
    final int argsLen = args.length;
    final int boundArgsLen = boundArgs.length;
    final Object[] newArgs = new Object[argsLen + boundArgsLen];
    newArgs[0] = callable;
    final int firstArgIndex;
    if (isCall) {
        newArgs[1] = boundThis;
        firstArgIndex = 2;
    } else {
        firstArgIndex = 1;
    }
    System.arraycopy(boundArgs, 0, newArgs, firstArgIndex, boundArgsLen);
    System.arraycopy(args, firstArgIndex, newArgs, firstArgIndex + boundArgsLen, argsLen - firstArgIndex);

    // Use R(T0, T1, T2, ...) => R(callable.class, boundThis.class, boundArg0.class, ..., boundArgn.class, T2, ...)
    // call site type when delegating to underlying linker (for dyn:new, there's no this).
    final MethodType type = descriptor.getMethodType();
    // Use R(T0, ...) => R(callable.class, ...)
    MethodType newMethodType = descriptor.getMethodType().changeParameterType(0, callable.getClass());
    if (isCall) {
        // R(callable.class, T1, ...) => R(callable.class, boundThis.class, ...)
        newMethodType = newMethodType.changeParameterType(1, boundThis == null? Object.class : boundThis.getClass());
    }
    // R(callable.class[, boundThis.class], T2, ...) => R(callable.class[, boundThis.class], boundArg0.class, ..., boundArgn.class, T2, ...)
    for(int i = boundArgs.length; i-- > 0;) {
        newMethodType = newMethodType.insertParameterTypes(firstArgIndex, boundArgs[i] == null ? Object.class : boundArgs[i].getClass());
    }
    final CallSiteDescriptor newDescriptor = descriptor.changeMethodType(newMethodType);

    // Delegate to target's linker
    final GuardedInvocation inv = linkerServices.getGuardedInvocation(linkRequest.replaceArguments(newDescriptor, newArgs));
    if(inv == null) {
        return null;
    }

    // Bind (callable[, boundThis], boundArgs) to the delegate handle
    final MethodHandle boundHandle = MethodHandles.insertArguments(inv.getInvocation(), 0,
            Arrays.copyOf(newArgs, firstArgIndex + boundArgs.length));
    final Class<?> p0Type = type.parameterType(0);
    final MethodHandle droppingHandle;
    if (isCall) {
        // Ignore incoming boundCallable and this
        droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type, type.parameterType(1));
    } else {
        // Ignore incoming boundCallable
        droppingHandle = MethodHandles.dropArguments(boundHandle, 0, p0Type);
    }
    // Identity guard on boundCallable object
    final MethodHandle newGuard = Guards.getIdentityGuard(boundCallable);
    return inv.replaceMethods(droppingHandle, newGuard.asType(newGuard.type().changeParameterType(0, p0Type)));
}
 
源代码14 项目: openjdk-jdk8u-backup   文件: MethodHandleFactory.java
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... values) {
    final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
    return debug(mh, "dropArguments", target, pos, values);
}
 
源代码15 项目: jdk8u60   文件: MethodHandleFactory.java
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final List<Class<?>> values) {
    final MethodHandle mh = MethodHandles.dropArguments(target, pos, values);
    return debug(mh, "dropArguments", target, pos, values);
}
 
源代码16 项目: openjdk-8-source   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(CallSiteDescriptor callSiteDescriptor,
        LinkerServices linkerServices, List<String> operations) throws Exception {
    final MethodType type = callSiteDescriptor.getMethodType();
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

            // 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.
            // We want setters that conform to "R(O, V)"
            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,
                    CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), 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)->R(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 {
                // R(O, N, V)->R(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;
        }
    }
}
 
源代码17 项目: openjdk-8-source   文件: MethodHandleFactory.java
@Override
public MethodHandle dropArguments(final MethodHandle target, final int pos, final Class<?>... valueTypes) {
    return MethodHandles.dropArguments(target, pos, valueTypes);
}
 
源代码18 项目: openjdk-jdk9   文件: LoopCombinatorTest.java
static MethodHandle slap(MethodHandle mh, Class<?> addType) {
    return MethodHandles.dropArguments(mh, mh.type().parameterCount(), addType);
}
 
源代码19 项目: es6draft   文件: NativeCalls.java
private static MethodHandle invalidCallArgumentsHandle(String name, MethodType type, WrongMethodTypeException e) {
    // Add native call name?
    MethodHandle mh = MethodHandles.insertArguments(invalidNativeCallArgumentsMH, 0, e.getMessage());
    return MethodHandles.dropArguments(mh, 1, type.dropParameterTypes(0, 1).parameterArray());
}
 
源代码20 项目: 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;
        }
    }
}