java.lang.invoke.MethodType#dropParameterTypes ( )源码实例Demo

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

private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
源代码2 项目: jdk8u60   文件: RecompilableScriptFunctionData.java
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
源代码6 项目: hottub   文件: RecompilableScriptFunctionData.java
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
private MethodType explicitParams(final MethodType callSiteType) {
    if (CompiledFunction.isVarArgsType(callSiteType)) {
        return null;
    }

    final MethodType noCalleeThisType = callSiteType.dropParameterTypes(0, 2); // (callee, this) is always in call site type
    final int callSiteParamCount = noCalleeThisType.parameterCount();

    // Widen parameters of reference types to Object as we currently don't care for specialization among reference
    // types. E.g. call site saying (ScriptFunction, Object, String) should still link to (ScriptFunction, Object, Object)
    final Class<?>[] paramTypes = noCalleeThisType.parameterArray();
    boolean changed = false;
    for (int i = 0; i < paramTypes.length; ++i) {
        final Class<?> paramType = paramTypes[i];
        if (!(paramType.isPrimitive() || paramType == Object.class)) {
            paramTypes[i] = Object.class;
            changed = true;
        }
    }
    final MethodType generalized = changed ? MethodType.methodType(noCalleeThisType.returnType(), paramTypes) : noCalleeThisType;

    if (callSiteParamCount < getArity()) {
        return generalized.appendParameterTypes(Collections.<Class<?>>nCopies(getArity() - callSiteParamCount, Object.class));
    }
    return generalized;
}
 
源代码8 项目: openjdk-jdk9   文件: LoopCombinatorTest.java
@Test(dataProvider = "countedLoopBodyParameters")
public static void testCountedLoopBodyParameters(MethodType countType, MethodType initType, MethodType bodyType) throws Throwable {
    MethodHandle loop = MethodHandles.countedLoop(
            MethodHandles.empty(countType),
            initType == null ? null : MethodHandles.empty(initType),
            MethodHandles.empty(bodyType));
    // The rule:  If body takes the minimum number of parameters, then take what countType offers.
    // The initType has to just roll with whatever the other two agree on.
    int innerParams = (bodyType.returnType() == void.class ? 1 : 2);
    MethodType expectType = bodyType.dropParameterTypes(0, innerParams);
    if (expectType.parameterCount() == 0)
        expectType = expectType.insertParameterTypes(0, countType.parameterList());
    assertEquals(expectType, loop.type());
}
 
源代码9 项目: TencentKona-8   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码10 项目: jdk8u60   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码11 项目: openjdk-jdk8u   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码12 项目: openjdk-jdk8u-backup   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码13 项目: openjdk-jdk9   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getUnnamedPropertySetter(final ComponentLinkRequest req) throws Exception {
    final CallSiteDescriptor callSiteDescriptor = req.getDescriptor();
    // Must have three arguments: target object, property name, and property value.
    assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

    // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
    final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
    if(nextComponent == null) {
        return getClassGuardedInvocationComponent(compositeSetter, type);
    }
    return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
}
 
源代码14 项目: hottub   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码15 项目: 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;
        }
    }
}
 
源代码16 项目: openjdk-8   文件: 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 项目: jdk8u_nashorn   文件: AbstractJavaLinker.java
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
源代码18 项目: nashorn   文件: 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;
        }
    }
}