Java 类java.lang.invoke.LambdaForm.Name 实例源码

项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
}
项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 *
 * @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));
        }
    }
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
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));
        }
    }
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 *
 * @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));
        }
    }
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 *
 * @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));
        }
    }
}
项目:jdk-1.7-annotated    文件:BoundMethodHandle.java   
/**
 * 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;
}
项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
    }
}
项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
}
项目:OLD-OpenJDK8    文件:BoundMethodHandle.java   
/**
 * 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;
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
    }
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
}
项目:openjdk-jdk7u-jdk    文件:BoundMethodHandle.java   
/**
 * 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;
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
    }
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
}
项目:openjdk-icedtea7    文件:BoundMethodHandle.java   
/**
 * 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;
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
    }
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 * 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);
}
项目:jdk-1.7-annotated    文件:BoundMethodHandle.java   
/**
 * 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);
}
项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 * 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;
}
项目:jdk-1.7-annotated    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
    }
}
项目:OLD-OpenJDK8    文件:BoundMethodHandle.java   
/**
 * 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);
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
/**
 * 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;
}
项目:OLD-OpenJDK8    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
    }
}
项目:openjdk-jdk7u-jdk    文件:BoundMethodHandle.java   
/**
 * 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);
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 * 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;
}
项目:openjdk-jdk7u-jdk    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
    }
}
项目:openjdk-icedtea7    文件:BoundMethodHandle.java   
/**
 * 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);
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 * 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;
}
项目:openjdk-icedtea7    文件:InvokerBytecodeGenerator.java   
/**
 * 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());
    }
}