java.lang.invoke.LambdaForm.Name Java Examples

The following examples show how to use java.lang.invoke.LambdaForm.Name. 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: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 6 votes vote down vote up
/**
 *
 * @param name
 * @param paramIndex
 */
private void emitPushArgument(Name name, int paramIndex) {
    Object arg = name.arguments[paramIndex];
    char ptype = name.function.parameterType(paramIndex);
    MethodType mtype = name.function.methodType();
    if (arg instanceof Name) {
        Name n = (Name) arg;
        emitLoadInsn(n.type, n.index());
        emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
    } else if ((arg == null || arg instanceof String) && ptype == 'L') {
        emitConst(arg);
    } else {
        if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
            emitConst(arg);
        } else {
            mv.visitLdcInsn(constantPlaceholder(arg));
            emitImplicitConversion('L', mtype.parameterType(paramIndex));
        }
    }
}
 
Example #2
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Emit an invoke for the given name.
 */
void emitInvoke(Name name) {
    if (true) {
        // push receiver
        MethodHandle target = name.function.resolvedHandle;
        assert(target != null) : name.exprString();
        mv.visitLdcInsn(constantPlaceholder(target));
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
    } else {
        // load receiver
        emitAloadInsn(0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
        mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
        mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
        // TODO more to come
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    MethodType type = name.function.methodType();
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
 
Example #3
Source File: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 6 votes vote down vote up
/**
 * Emit an invoke for the given name.
 *
 * @param name
 */
void emitInvoke(Name name) {
    if (true) {
        // push receiver
        MethodHandle target = name.function.resolvedHandle;
        assert(target != null) : name.exprString();
        mv.visitLdcInsn(constantPlaceholder(target));
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
    } else {
        // load receiver
        emitAloadInsn(0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
        mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
        mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
        // TODO more to come
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    MethodType type = name.function.methodType();
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
 
Example #4
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 6 votes vote down vote up
private void emitPushArgument(Name name, int paramIndex) {
    Object arg = name.arguments[paramIndex];
    char ptype = name.function.parameterType(paramIndex);
    MethodType mtype = name.function.methodType();
    if (arg instanceof Name) {
        Name n = (Name) arg;
        emitLoadInsn(n.type, n.index());
        emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
    } else if ((arg == null || arg instanceof String) && ptype == 'L') {
        emitConst(arg);
    } else {
        if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
            emitConst(arg);
        } else {
            mv.visitLdcInsn(constantPlaceholder(arg));
            emitImplicitConversion('L', mtype.parameterType(paramIndex));
        }
    }
}
 
Example #5
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
private void emitPushArgument(Name name, int paramIndex) {
    Object arg = name.arguments[paramIndex];
    char ptype = name.function.parameterType(paramIndex);
    MethodType mtype = name.function.methodType();
    if (arg instanceof Name) {
        Name n = (Name) arg;
        emitLoadInsn(n.type, n.index());
        emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
    } else if ((arg == null || arg instanceof String) && ptype == 'L') {
        emitConst(arg);
    } else {
        if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
            emitConst(arg);
        } else {
            mv.visitLdcInsn(constantPlaceholder(arg));
            emitImplicitConversion('L', mtype.parameterType(paramIndex));
        }
    }
}
 
Example #6
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Emit an invoke for the given name.
 */
void emitInvoke(Name name) {
    if (true) {
        // push receiver
        MethodHandle target = name.function.resolvedHandle;
        assert(target != null) : name.exprString();
        mv.visitLdcInsn(constantPlaceholder(target));
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
    } else {
        // load receiver
        emitAloadInsn(0);
        mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
        mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
        mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
        // TODO more to come
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    MethodType type = name.function.methodType();
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
}
 
Example #7
Source File: BoundMethodHandle.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Wrap a constructor call in a {@link LambdaForm}.
 *
 * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
 * are turned into bytecode, because the call to the allocator is routed through an MH, and the
 * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
 * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
 * {@link MethodHandle#linkToSpecial}.
 *
 * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
 * result of the {@code <init>} invocation. This entry is replaced.
 */
private static MethodHandle linkConstructor(MethodHandle cmh) {
    final LambdaForm lf = cmh.form;
    final int initNameIndex = lf.names.length - 1;
    final Name initName = lf.names[initNameIndex];
    final MemberName ctorMN = initName.function.member;
    final MethodType ctorMT = ctorMN.getInvocationType();

    // obtain function member (call target)
    // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
    final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
    MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
    try {
        linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
        assert(linkerMN.isStatic());
    } catch (ReflectiveOperationException ex) {
        throw newInternalError(ex);
    }
    // extend arguments array
    Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
    newArgs[newArgs.length - 1] = ctorMN;
    // replace function
    final NamedFunction nf = new NamedFunction(linkerMN);
    final Name linkedCtor = new Name(nf, newArgs);
    linkedCtor.initIndex(initNameIndex);
    lf.names[initNameIndex] = linkedCtor;
    return cmh;
}
 
Example #8
Source File: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
/**
 * Emit bytecode for the selectAlternative idiom.
 *
 * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
 *
 *   Lambda(a0:L,a1:I)=>{
 *     t2:I=foo.test(a1:I);
 *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
 *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
 *
 * @param selectAlternativeName
 * @param invokeBasicName
 */
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
    MethodType type = selectAlternativeName.function.methodType();

    Name receiver = (Name) invokeBasicName.arguments[0];

    Label L_fallback = new Label();
    Label L_done     = new Label();

    // load test result
    emitPushArgument(selectAlternativeName, 0);
    mv.visitInsn(Opcodes.ICONST_1);

    // if_icmpne L_fallback
    mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);

    // invoke selectAlternativeName.arguments[1]
    MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
    emitPushArgument(selectAlternativeName, 1);  // get 2nd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // goto L_done
    mv.visitJumpInsn(Opcodes.GOTO, L_done);

    // L_fallback:
    mv.visitLabel(L_fallback);

    // invoke selectAlternativeName.arguments[2]
    MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
    emitPushArgument(selectAlternativeName, 2);  // get 3rd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // L_done:
    mv.visitLabel(L_done);
}
 
Example #9
Source File: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
/**
 * Emit an invoke for the given name, using the MemberName directly.
 *
 * @param name
 */
void emitStaticInvoke(MemberName member, Name name) {
    assert(member.equals(name.function.member()));
    String cname = getInternalName(member.getDeclaringClass());
    String mname = member.getName();
    String mtype;
    byte refKind = member.getReferenceKind();
    if (refKind == REF_invokeSpecial) {
        // in order to pass the verifier, we need to convert this to invokevirtual in all cases
        assert(member.canBeStaticallyBound()) : member;
        refKind = REF_invokeVirtual;
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    if (member.isMethod()) {
        mtype = member.getMethodType().toMethodDescriptorString();
        mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype);
    } else {
        mtype = MethodType.toFieldDescriptorString(member.getFieldType());
        mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
    }
}
 
Example #10
Source File: BoundMethodHandle.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
/**
 * Wrap a constructor call in a {@link LambdaForm}.
 *
 * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
 * are turned into bytecode, because the call to the allocator is routed through an MH, and the
 * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
 * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
 * {@link MethodHandle#linkToSpecial}.
 *
 * The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
 * result of the {@code <init>} invocation. This entry is replaced.
 */
private static MethodHandle linkConstructor(MethodHandle cmh) {
    final LambdaForm lf = cmh.form;
    final int initNameIndex = lf.names.length - 1;
    final Name initName = lf.names[initNameIndex];
    final MemberName ctorMN = initName.function.member;
    final MethodType ctorMT = ctorMN.getInvocationType();

    // obtain function member (call target)
    // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
    final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
    MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
    try {
        linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
        assert(linkerMN.isStatic());
    } catch (ReflectiveOperationException ex) {
        throw newInternalError(ex);
    }
    // extend arguments array
    Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
    newArgs[newArgs.length - 1] = ctorMN;
    // replace function
    final NamedFunction nf = new NamedFunction(linkerMN);
    final Name linkedCtor = new Name(nf, newArgs);
    linkedCtor.initIndex(initNameIndex);
    lf.names[initNameIndex] = linkedCtor;
    return cmh;
}
 
Example #11
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Emit bytecode for the selectAlternative idiom.
 *
 * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
 * <blockquote><pre>{@code
 *   Lambda(a0:L,a1:I)=>{
 *     t2:I=foo.test(a1:I);
 *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
 *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
 * }</pre></blockquote>
 */
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
    MethodType type = selectAlternativeName.function.methodType();

    Name receiver = (Name) invokeBasicName.arguments[0];

    Label L_fallback = new Label();
    Label L_done     = new Label();

    // load test result
    emitPushArgument(selectAlternativeName, 0);
    mv.visitInsn(Opcodes.ICONST_1);

    // if_icmpne L_fallback
    mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);

    // invoke selectAlternativeName.arguments[1]
    MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
    emitPushArgument(selectAlternativeName, 1);  // get 2nd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // goto L_done
    mv.visitJumpInsn(Opcodes.GOTO, L_done);

    // L_fallback:
    mv.visitLabel(L_fallback);

    // invoke selectAlternativeName.arguments[2]
    MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
    emitPushArgument(selectAlternativeName, 2);  // get 3rd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // L_done:
    mv.visitLabel(L_done);
}
 
Example #12
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Emit an invoke for the given name, using the MemberName directly.
 */
void emitStaticInvoke(MemberName member, Name name) {
    assert(member.equals(name.function.member()));
    String cname = getInternalName(member.getDeclaringClass());
    String mname = member.getName();
    String mtype;
    byte refKind = member.getReferenceKind();
    if (refKind == REF_invokeSpecial) {
        // in order to pass the verifier, we need to convert this to invokevirtual in all cases
        assert(member.canBeStaticallyBound()) : member;
        refKind = REF_invokeVirtual;
    }

    if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
        // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
        // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
        refKind = REF_invokeInterface;
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    if (member.isMethod()) {
        mtype = member.getMethodType().toMethodDescriptorString();
        mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
                           member.getDeclaringClass().isInterface());
    } else {
        mtype = MethodType.toFieldDescriptorString(member.getFieldType());
        mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
    }
}
 
Example #13
Source File: BoundMethodHandle.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Wrap a constructor call in a {@link LambdaForm}.
 *
 * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
 * are turned into bytecode, because the call to the allocator is routed through an MH, and the
 * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
 * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
 * {@link MethodHandle#linkToSpecial}.
 *
 * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void}
 * result of the {@code <init>} invocation. This entry is replaced.
 */
private static MethodHandle linkConstructor(MethodHandle cmh) {
    final LambdaForm lf = cmh.form;
    final int initNameIndex = lf.names.length - 1;
    final Name initName = lf.names[initNameIndex];
    final MemberName ctorMN = initName.function.member;
    final MethodType ctorMT = ctorMN.getInvocationType();

    // obtain function member (call target)
    // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
    final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
    MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
    try {
        linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
        assert(linkerMN.isStatic());
    } catch (ReflectiveOperationException ex) {
        throw newInternalError(ex);
    }
    // extend arguments array
    Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
    newArgs[newArgs.length - 1] = ctorMN;
    // replace function
    final NamedFunction nf = new NamedFunction(linkerMN);
    final Name linkedCtor = new Name(nf, newArgs);
    linkedCtor.initIndex(initNameIndex);
    lf.names[initNameIndex] = linkedCtor;
    return cmh;
}
 
Example #14
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Emit bytecode for the selectAlternative idiom.
 *
 * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
 * <blockquote><pre>{@code
 *   Lambda(a0:L,a1:I)=>{
 *     t2:I=foo.test(a1:I);
 *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
 *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
 * }</pre></blockquote>
 */
private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
    MethodType type = selectAlternativeName.function.methodType();

    Name receiver = (Name) invokeBasicName.arguments[0];

    Label L_fallback = new Label();
    Label L_done     = new Label();

    // load test result
    emitPushArgument(selectAlternativeName, 0);
    mv.visitInsn(Opcodes.ICONST_1);

    // if_icmpne L_fallback
    mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);

    // invoke selectAlternativeName.arguments[1]
    MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
    emitPushArgument(selectAlternativeName, 1);  // get 2nd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // goto L_done
    mv.visitJumpInsn(Opcodes.GOTO, L_done);

    // L_fallback:
    mv.visitLabel(L_fallback);

    // invoke selectAlternativeName.arguments[2]
    MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
    emitPushArgument(selectAlternativeName, 2);  // get 3rd argument of selectAlternative
    emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
    emitInvoke(invokeBasicName);

    // L_done:
    mv.visitLabel(L_done);
}
 
Example #15
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Emit an invoke for the given name, using the MemberName directly.
 */
void emitStaticInvoke(MemberName member, Name name) {
    assert(member.equals(name.function.member()));
    String cname = getInternalName(member.getDeclaringClass());
    String mname = member.getName();
    String mtype;
    byte refKind = member.getReferenceKind();
    if (refKind == REF_invokeSpecial) {
        // in order to pass the verifier, we need to convert this to invokevirtual in all cases
        assert(member.canBeStaticallyBound()) : member;
        refKind = REF_invokeVirtual;
    }

    if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
        // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
        // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
        refKind = REF_invokeInterface;
    }

    // push arguments
    for (int i = 0; i < name.arguments.length; i++) {
        emitPushArgument(name, i);
    }

    // invocation
    if (member.isMethod()) {
        mtype = member.getMethodType().toMethodDescriptorString();
        mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype,
                           member.getDeclaringClass().isInterface());
    } else {
        mtype = MethodType.toFieldDescriptorString(member.getFieldType());
        mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
    }
}
 
Example #16
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Generate an invoker method for the passed {@link LambdaForm}.
 */
private byte[] generateCustomizedCodeBytes() {
    classFilePrologue();

    // Suppress this method in backtraces displayed to the user.
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);

    // Mark this method as a compiled LambdaForm
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);

    // Force inlining of this invoker method.
    mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);

    // iterate over the form's names, generating bytecode instructions for each
    // start iterating at the first name following the arguments
    for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
        Name name = lambdaForm.names[i];
        MemberName member = name.function.member();

        if (isSelectAlternative(member)) {
            // selectAlternative idiom
            // FIXME: make sure this idiom is really present!
            emitSelectAlternative(name, lambdaForm.names[i + 1]);
            i++;  // skip MH.invokeBasic of the selectAlternative result
        } else if (isStaticallyInvocable(member)) {
            emitStaticInvoke(member, name);
        } else {
            emitInvoke(name);
        }

        // store the result from evaluating to the target name in a local if required
        // (if this is the last value, i.e., the one that is going to be returned,
        // avoid store/load/return and just return)
        if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
            // return value - do nothing
        } else if (name.type != 'V') {
            // non-void: actually assign
            emitStoreInsn(name.type, name.index());
        }
    }

    // return statement
    emitReturn();

    classFileEpilogue();
    bogusMethod(lambdaForm);

    final byte[] classFile = cw.toByteArray();
    maybeDump(className, classFile);
    return classFile;
}
 
Example #17
Source File: BoundMethodHandle.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
 * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
 * getter.
 */
Name getterName(Name mhName, int i) {
    MethodHandle mh = getters[i];
    assert(mh != null) : this+"."+i;
    return new Name(mh, mhName);
}
 
Example #18
Source File: InvokerBytecodeGenerator.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
 */
private void emitReturn() {
    // return statement
    if (lambdaForm.result == -1) {
        // void
        mv.visitInsn(Opcodes.RETURN);
    } else {
        LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
        char rtype = Wrapper.basicTypeChar(invokerType.returnType());

        // put return value on the stack if it is not already there
        if (lambdaForm.result != lambdaForm.names.length - 1) {
            emitLoadInsn(rn.type, lambdaForm.result);
        }

        // potentially generate cast
        // rtype is the return type of the invoker - generated code must conform to this
        // rn.type is the type of the result Name in the LF
        if (rtype != rn.type) {
            // need cast
            if (rtype == 'L') {
                // possibly cast the primitive to the correct type for boxing
                char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
                if (boxedType != rn.type) {
                    emitPrimCast(rn.type, boxedType);
                }
                // cast primitive to reference ("boxing")
                emitBoxing(invokerType.returnType());
            } else {
                // to-primitive cast
                if (rn.type != 'L') {
                    // prim-to-prim cast
                    emitPrimCast(rn.type, rtype);
                } else {
                    // ref-to-prim cast ("unboxing")
                    throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
                }
            }
        }

        // generate actual return statement
        emitReturnInsn(invokerType.returnType());
    }
}
 
Example #19
Source File: BoundMethodHandle.java    From jdk-1.7-annotated with Apache License 2.0 4 votes vote down vote up
/**
 * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
 * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
 * getter.
 */
Name getterName(Name mhName, int i) {
    MethodHandle mh = getters[i];
    assert(mh != null) : this+"."+i;
    return new Name(mh, mhName);
}
 
Example #20
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
 */
private void emitReturn() {
    // return statement
    if (lambdaForm.result == -1) {
        // void
        mv.visitInsn(Opcodes.RETURN);
    } else {
        LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
        char rtype = Wrapper.basicTypeChar(invokerType.returnType());

        // put return value on the stack if it is not already there
        if (lambdaForm.result != lambdaForm.names.length - 1) {
            emitLoadInsn(rn.type, lambdaForm.result);
        }

        // potentially generate cast
        // rtype is the return type of the invoker - generated code must conform to this
        // rn.type is the type of the result Name in the LF
        if (rtype != rn.type) {
            // need cast
            if (rtype == 'L') {
                // possibly cast the primitive to the correct type for boxing
                char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
                if (boxedType != rn.type) {
                    emitPrimCast(rn.type, boxedType);
                }
                // cast primitive to reference ("boxing")
                emitBoxing(invokerType.returnType());
            } else {
                // to-primitive cast
                if (rn.type != 'L') {
                    // prim-to-prim cast
                    emitPrimCast(rn.type, rtype);
                } else {
                    // ref-to-prim cast ("unboxing")
                    throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
                }
            }
        }

        // generate actual return statement
        emitReturnInsn(invokerType.returnType());
    }
}
 
Example #21
Source File: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 4 votes vote down vote up
/**
 * Generate an invoker method for the passed {@link LambdaForm}.
 */
private byte[] generateCustomizedCodeBytes() {
    classFilePrologue();

    // Suppress this method in backtraces displayed to the user.
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);

    // Mark this method as a compiled LambdaForm
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);

    // Force inlining of this invoker method.
    mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);

    // iterate over the form's names, generating bytecode instructions for each
    // start iterating at the first name following the arguments
    for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
        Name name = lambdaForm.names[i];
        MemberName member = name.function.member();

        if (isSelectAlternative(member)) {
            // selectAlternative idiom
            // FIXME: make sure this idiom is really present!
            emitSelectAlternative(name, lambdaForm.names[i + 1]);
            i++;  // skip MH.invokeBasic of the selectAlternative result
        } else if (isStaticallyInvocable(member)) {
            emitStaticInvoke(member, name);
        } else {
            emitInvoke(name);
        }

        // store the result from evaluating to the target name in a local if required
        // (if this is the last value, i.e., the one that is going to be returned,
        // avoid store/load/return and just return)
        if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
            // return value - do nothing
        } else if (name.type != 'V') {
            // non-void: actually assign
            emitStoreInsn(name.type, name.index());
        }
    }

    // return statement
    emitReturn();

    classFileEpilogue();
    bogusMethod(lambdaForm);

    final byte[] classFile = cw.toByteArray();
    maybeDump(className, classFile);
    return classFile;
}
 
Example #22
Source File: InvokerBytecodeGenerator.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Generate an invoker method for the passed {@link LambdaForm}.
 */
private byte[] generateCustomizedCodeBytes() {
    classFilePrologue();

    // Suppress this method in backtraces displayed to the user.
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);

    // Mark this method as a compiled LambdaForm
    mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);

    // Force inlining of this invoker method.
    mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);

    // iterate over the form's names, generating bytecode instructions for each
    // start iterating at the first name following the arguments
    for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
        Name name = lambdaForm.names[i];
        MemberName member = name.function.member();

        if (isSelectAlternative(member)) {
            // selectAlternative idiom
            // FIXME: make sure this idiom is really present!
            emitSelectAlternative(name, lambdaForm.names[i + 1]);
            i++;  // skip MH.invokeBasic of the selectAlternative result
        } else if (isStaticallyInvocable(member)) {
            emitStaticInvoke(member, name);
        } else {
            emitInvoke(name);
        }

        // store the result from evaluating to the target name in a local if required
        // (if this is the last value, i.e., the one that is going to be returned,
        // avoid store/load/return and just return)
        if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
            // return value - do nothing
        } else if (name.type != 'V') {
            // non-void: actually assign
            emitStoreInsn(name.type, name.index());
        }
    }

    // return statement
    emitReturn();

    classFileEpilogue();
    bogusMethod(lambdaForm);

    final byte[] classFile = cw.toByteArray();
    maybeDump(className, classFile);
    return classFile;
}
 
Example #23
Source File: BoundMethodHandle.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
/**
 * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
 * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
 * getter.
 */
Name getterName(Name mhName, int i) {
    MethodHandle mh = getters[i];
    assert(mh != null) : this+"."+i;
    return new Name(mh, mhName);
}
 
Example #24
Source File: InvokerBytecodeGenerator.java    From jdk-1.7-annotated with Apache License 2.0 4 votes vote down vote up
/**
 * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
 */
private void emitReturn() {
    // return statement
    if (lambdaForm.result == -1) {
        // void
        mv.visitInsn(Opcodes.RETURN);
    } else {
        LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
        char rtype = Wrapper.basicTypeChar(invokerType.returnType());

        // put return value on the stack if it is not already there
        if (lambdaForm.result != lambdaForm.names.length - 1) {
            emitLoadInsn(rn.type, lambdaForm.result);
        }

        // potentially generate cast
        // rtype is the return type of the invoker - generated code must conform to this
        // rn.type is the type of the result Name in the LF
        if (rtype != rn.type) {
            // need cast
            if (rtype == 'L') {
                // possibly cast the primitive to the correct type for boxing
                char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
                if (boxedType != rn.type) {
                    emitPrimCast(rn.type, boxedType);
                }
                // cast primitive to reference ("boxing")
                emitBoxing(invokerType.returnType());
            } else {
                // to-primitive cast
                if (rn.type != 'L') {
                    // prim-to-prim cast
                    emitPrimCast(rn.type, rtype);
                } else {
                    // ref-to-prim cast ("unboxing")
                    throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
                }
            }
        }

        // generate actual return statement
        emitReturnInsn(invokerType.returnType());
    }
}