Java Code Examples for java.lang.invoke.MethodHandles#exactInvoker()

The following examples show how to use java.lang.invoke.MethodHandles#exactInvoker() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: AbstractJavaLinker.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
Example 5
Source File: AbstractJavaLinker.java    From openjdk-jdk9 with GNU General Public License v2.0 4 votes vote down vote up
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);
}
 
Example 6
Source File: AbstractJavaLinker.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
private GuardedInvocationComponent getPropertySetter(final CallSiteDescriptor callSiteDescriptor,
        final LinkerServices linkerServices, final List<String> operations) throws Exception {
    switch(callSiteDescriptor.getNameTokenCount()) {
        case 2: {
            // Must have three arguments: target object, property name, and property value.
            assertParameterCount(callSiteDescriptor, 3);

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

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

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

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

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

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

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

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

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

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

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

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

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

            // fold(R(MethodHandle, O, N, V), MethodHandle(O, N, V))
            final MethodHandle compositeSetter = MethodHandles.foldArguments(MethodHandles.guardWithTest(
                        IS_METHOD_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter);
            if(nextComponent == null) {
                return getClassGuardedInvocationComponent(compositeSetter, type);
            }
            return nextComponent.compose(compositeSetter, getClassGuard(type), clazz, ValidationType.EXACT_CLASS);
        }
        case 3: {
            // Must have two arguments: target object and property value
            assertParameterCount(callSiteDescriptor, 2);
            final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices,
                    callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters);
            // If we have a property setter with this name, this composite operation will always stop here
            if(gi != null) {
                return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS);
            }
            // If we don't have a property setter with this name, always fall back to the next operation in the
            // composite (if any)
            return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, operations);
        }
        default: {
            // More than two name components; don't know what to do with it.
            return null;
        }
    }
}
 
Example 10
Source File: AbstractJavaLinker.java    From nashorn with GNU General Public License v2.0 4 votes vote down vote up
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;
        }
    }
}