/**
     * 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 Name emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName)
    {
        //assert isStaticallyInvocable(invokeBasicName);

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

        CodeEmitterLabel L_fallback = ilgen.DefineLabel();
        CodeEmitterLabel L_done     = ilgen.DefineLabel();

        // load test result
        emitPushArgument(selectAlternativeName, 0);

        // if_icmpne L_fallback
        ilgen.EmitBrfalse(L_fallback);

        // invoke selectAlternativeName.arguments[1]
        //Class<?>[] preForkClasses = localClasses.clone();
        emitPushArgument(selectAlternativeName, 1); // get 2nd argument of selectAlternative
        emitAstoreInsn(receiver.index());           // store the MH in the receiver slot
        emitStaticInvoke(invokeBasicName);

        // goto L_done
        ilgen.EmitBr(L_done);

        // L_fallback:
        ilgen.MarkLabel(L_fallback);

        // invoke selectAlternativeName.arguments[2]
        //System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);
        emitPushArgument(selectAlternativeName, 2); // get 3rd argument of selectAlternative
        emitAstoreInsn(receiver.index());           // store the MH in the receiver slot
        emitStaticInvoke(invokeBasicName);

        // L_done:
        ilgen.MarkLabel(L_done);
        // for now do not bother to merge typestate; just reset to the dominator state
        //System.arraycopy(preForkClasses, 0, localClasses, 0, preForkClasses.length);

        return(invokeBasicName);  // return what's on stack
    }
示例#2
0
文件: remapper.cs 项目: moayyaed/ikvm
 internal override void Emit(CodeEmitter ilgen, CodeEmitterLabel label)
 {
     ilgen.EmitBr(label);
 }