Exemplo n.º 1
0
 internal override void Generate(CodeGenContext context, CodeEmitter ilgen)
 {
     base.Generate(context, ilgen);
     if (typeType != null)
     {
         ilgen.Emit(OpCodes.Isinst, typeType);
     }
     else
     {
         if (typeWrapper.IsGhost || typeWrapper.IsGhostArray)
         {
             ilgen.Emit(OpCodes.Dup);
             typeWrapper.EmitInstanceOf(ilgen);
             CodeEmitterLabel endLabel = ilgen.DefineLabel();
             ilgen.EmitBrtrue(endLabel);
             ilgen.Emit(OpCodes.Pop);
             ilgen.Emit(OpCodes.Ldnull);
             ilgen.MarkLabel(endLabel);
         }
         else
         {
             ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD);
         }
     }
 }
Exemplo n.º 2
0
 internal override void Generate(CodeGenContext context, CodeEmitter ilgen)
 {
     base.Generate(context, ilgen);
     if (typeType != null)
     {
         ilgen.Emit(OpCodes.Isinst, typeType);
     }
     else
     {
         if (typeWrapper.IsGhost || typeWrapper.IsGhostArray)
         {
             ilgen.Emit(OpCodes.Dup);
             // NOTE we pass a null context, but that shouldn't be a problem, because
             // typeWrapper should never be an UnloadableTypeWrapper
             typeWrapper.EmitInstanceOf(null, ilgen);
             CodeEmitterLabel endLabel = ilgen.DefineLabel();
             ilgen.Emit(OpCodes.Brtrue_S, endLabel);
             ilgen.Emit(OpCodes.Pop);
             ilgen.Emit(OpCodes.Ldnull);
             ilgen.MarkLabel(endLabel);
         }
         else
         {
             ilgen.Emit(OpCodes.Isinst, typeWrapper.TypeAsTBD);
         }
     }
 }
    /**
     * 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
    }
Exemplo n.º 4
0
        internal override void Generate(CodeGenContext context, CodeEmitter ilgen)
        {
            CodeEmitterLabel l;

            if (context[Name] == null)
            {
                l             = ilgen.DefineLabel();
                context[Name] = l;
            }
            else
            {
                l = (CodeEmitterLabel)context[Name];
            }
            ilgen.MarkLabel(l);
        }