コード例 #1
0
ファイル: ObjMethod.cs プロジェクト: makufiru/clojure-clr
        protected static void EmitBody(ObjExpr objx, CljILGen ilg, Type retType, Expr body)
        {
            MaybePrimitiveExpr be = (MaybePrimitiveExpr)body;

            if (Util.IsPrimitive(retType) && be.CanEmitPrimitive)
            {
                Type bt = Compiler.MaybePrimitiveType(be);
                if (bt == retType)
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                }
                else if (retType == typeof(long) && bt == typeof(int))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_I8);
                }
                else if (retType == typeof(double) && bt == typeof(float))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_R8);
                }
                else if (retType == typeof(int) && bt == typeof(long))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long);
                }
                else if (retType == typeof(float) && bt == typeof(double))
                {
                    be.EmitUnboxed(RHC.Return, objx, ilg);
                    ilg.Emit(OpCodes.Conv_R4);
                }
                else
                {
                    throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType));
                }
            }
            else
            {
                body.Emit(RHC.Return, objx, ilg);
                if (body.HasNormalExit())
                {
                    if (retType == typeof(void))
                    {
                        ilg.Emit(OpCodes.Pop);
                    }
                    else
                    {
                        EmitUnboxArg(ilg, typeof(object), retType);
                    }
                }
            }
        }
コード例 #2
0
        public bool HasNormalExit()
        {
            if (_defaultExpr.HasNormalExit())
            {
                return(true);
            }

            foreach (Expr e in _thens.Values)
            {
                if (e.HasNormalExit())
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #3
0
 public bool HasNormalExit()
 {
     return(_body.HasNormalExit());
 }
コード例 #4
0
ファイル: ObjMethod.cs プロジェクト: clojure/clojure-clr
 protected static void EmitBody(ObjExpr objx, CljILGen ilg, Type retType, Expr body)
 {
     MaybePrimitiveExpr be = (MaybePrimitiveExpr)body;
     if (Util.IsPrimitive(retType) && be.CanEmitPrimitive)
     {
         Type bt = Compiler.MaybePrimitiveType(be);
         if (bt == retType)
             be.EmitUnboxed(RHC.Return, objx, ilg);
         else if (retType == typeof(long) && bt == typeof(int))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_I8);
         }
         else if (retType == typeof(double) && bt == typeof(float))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_R8);
         }
         else if (retType == typeof(int) && bt == typeof(long))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Call,Compiler.Method_RT_intCast_long);
         }
         else if (retType == typeof(float) && bt == typeof(double))
         {
             be.EmitUnboxed(RHC.Return, objx, ilg);
             ilg.Emit(OpCodes.Conv_R4);
         }
         else
         {
             throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType));
         }
     }
     else
     {
         body.Emit(RHC.Return, objx, ilg);
         if (body.HasNormalExit())
         {
             if (retType == typeof(void))
                 ilg.Emit(OpCodes.Pop);
             else
                 EmitUnboxArg(ilg, typeof(object), retType);
         }
     }
 }
コード例 #5
0
ファイル: IfExpr.cs プロジェクト: willemdijkgraaf/ClojureClr
 public bool HasNormalExit()
 {
     return(_thenExpr.HasNormalExit() || _elseExpr.HasNormalExit());
 }
コード例 #6
0
ファイル: IfExpr.cs プロジェクト: willemdijkgraaf/ClojureClr
        void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed)
        {
            Label nullLabel  = ilg.DefineLabel();
            Label falseLabel = ilg.DefineLabel();
            Label endLabel   = ilg.DefineLabel();
            Label trueLabel  = ilg.DefineLabel();

            GenContext.EmitDebugInfo(ilg, _sourceSpan);

            StaticMethodExpr sme = _testExpr as StaticMethodExpr;

            if (sme != null && sme.CanEmitIntrinsicPredicate())
            {
                sme.EmitIntrinsicPredicate(RHC.Expression, objx, ilg, falseLabel);
            }
            else if (Compiler.MaybePrimitiveType(_testExpr) == typeof(bool))
            {
                ((MaybePrimitiveExpr)_testExpr).EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Brfalse, falseLabel);
            }
            else
            {
                LocalBuilder tempLoc = ilg.DeclareLocal(typeof(Object));
                GenContext.SetLocalName(tempLoc, "test");

                _testExpr.Emit(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Dup);
                ilg.Emit(OpCodes.Stloc, tempLoc);

                ilg.Emit(OpCodes.Brfalse, nullLabel);

                ilg.Emit(OpCodes.Ldloc, tempLoc);
                ilg.Emit(OpCodes.Isinst, typeof(bool));
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Cgt_Un);
                ilg.Emit(OpCodes.Brfalse, trueLabel);

                ilg.Emit(OpCodes.Ldloc, tempLoc);
                ilg.Emit(OpCodes.Unbox_Any, typeof(bool));
                ilg.Emit(OpCodes.Ldc_I4_0);
                ilg.Emit(OpCodes.Ceq);
                ilg.Emit(OpCodes.Brtrue, falseLabel);
            }

            ilg.MarkLabel(trueLabel);

            if (emitUnboxed)
            {
                ((MaybePrimitiveExpr)_thenExpr).EmitUnboxed(rhc, objx, ilg);
            }
            else
            {
                _thenExpr.Emit(rhc, objx, ilg);
            }


            if (_thenExpr.HasNormalExit())
            {
                ilg.Emit(OpCodes.Br, endLabel);
            }

            ilg.MarkLabel(nullLabel);
            ilg.MarkLabel(falseLabel);

            if (emitUnboxed)
            {
                ((MaybePrimitiveExpr)_elseExpr).EmitUnboxed(rhc, objx, ilg);
            }
            else
            {
                _elseExpr.Emit(rhc, objx, ilg);
            }
            ilg.MarkLabel(endLabel);
        }