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 Emit(CodeEmitter ilgen, CodeEmitterLabel label)
 {
     ilgen.EmitBlt_Un(label);
 }
Exemplo n.º 5
0
 internal override void Emit(CodeEmitter ilgen, CodeEmitterLabel label)
 {
     ilgen.EmitBrfalse(label);
 }
Exemplo n.º 6
0
 internal abstract void Emit(CodeEmitter ilgen, CodeEmitterLabel label);
    /**
     * Emit bytecode for the guardWithCatch idiom.
     *
     * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithCatch):
     * <blockquote><pre>{@code
     *  guardWithCatch=Lambda(a0:L,a1:L,a2:L,a3:L,a4:L,a5:L,a6:L,a7:L)=>{
     *    t8:L=MethodHandle.invokeBasic(a4:L,a6:L,a7:L);
     *    t9:L=MethodHandleImpl.guardWithCatch(a1:L,a2:L,a3:L,t8:L);
     *   t10:I=MethodHandle.invokeBasic(a5:L,t9:L);t10:I}
     * }</pre></blockquote>
     *
     * It is compiled into bytecode equivalent of the following code:
     * <blockquote><pre>{@code
     *  try {
     *      return a1.invokeBasic(a6, a7);
     *  } catch (Throwable e) {
     *      if (!a2.isInstance(e)) throw e;
     *      return a3.invokeBasic(ex, a6, a7);
     *  }}</pre></blockquote>
     */
    private Name emitGuardWithCatch(int pos)
    {
        Name args    = lambdaForm.names[pos];
        Name invoker = lambdaForm.names[pos + 1];
        Name result  = lambdaForm.names[pos + 2];

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

        Class      returnType = result.function._resolvedHandle().type().returnType();
        MethodType type       = args.function._resolvedHandle().type()
                                .dropParameterTypes(0, 1)
                                .changeReturnType(returnType);

        // Normal case
        ilgen.BeginExceptionBlock();
        // load target
        emitPushArgument(invoker, 0);
        emitPushArguments(args, 1); // skip 1st argument: method handle
        EmitInvokeBasic(type.basicType());
        CodeEmitterLocal returnValue = null;

        if (returnType != java.lang.Void.TYPE)
        {
            returnValue = ilgen.DeclareLocal(TypeWrapper.FromClass(returnType).TypeAsLocalOrStackType);
            ilgen.Emit(OpCodes.Stloc, returnValue);
        }
        ilgen.EmitLeave(L_done);

        // Exceptional case
        ilgen.BeginCatchBlock(typeof(Exception));

        // [IKVM] map the exception and store it in a local and exit the handler
        ilgen.EmitLdc_I4(0);
        ilgen.Emit(OpCodes.Call, ByteCodeHelperMethods.mapException.MakeGenericMethod(typeof(Exception)));
        CodeEmitterLocal exception = ilgen.DeclareLocal(typeof(Exception));

        ilgen.Emit(OpCodes.Stloc, exception);
        ilgen.EmitLeave(L_handler);
        ilgen.EndExceptionBlock();

        // Check exception's type
        ilgen.MarkLabel(L_handler);
        // load exception class
        emitPushArgument(invoker, 1);
        ilgen.Emit(OpCodes.Ldloc, exception);
        CoreClasses.java.lang.Class.Wrapper.GetMethodWrapper("isInstance", "(Ljava.lang.Object;)Z", false).EmitCall(ilgen);
        CodeEmitterLabel L_rethrow = ilgen.DefineLabel();

        ilgen.EmitBrfalse(L_rethrow);

        // Invoke catcher
        // load catcher
        emitPushArgument(invoker, 2);
        ilgen.Emit(OpCodes.Ldloc, exception);
        emitPushArguments(args, 1); // skip 1st argument: method handle
        MethodType catcherType = type.insertParameterTypes(0, CoreClasses.java.lang.Throwable.Wrapper.ClassObject);

        EmitInvokeBasic(catcherType.basicType());
        if (returnValue != null)
        {
            ilgen.Emit(OpCodes.Stloc, returnValue);
        }
        ilgen.EmitBr(L_done);

        ilgen.MarkLabel(L_rethrow);
        ilgen.Emit(OpCodes.Ldloc, exception);
        ilgen.Emit(OpCodes.Call, Compiler.unmapExceptionMethod);
        ilgen.Emit(OpCodes.Throw);

        ilgen.MarkLabel(L_done);
        if (returnValue != null)
        {
            ilgen.Emit(OpCodes.Ldloc, returnValue);
        }

        return(result);
    }