示例#1
0
        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
        internal void EmitAssignLocal(CljILGen ilg, LocalBinding lb, Expr val)
        {
            if (!IsMutable(lb))
                throw new ArgumentException("Cannot assign to non-mutable: ", lb.Name);

            FieldBuilder fb = null;
            bool hasField = ClosedOverFieldsMap.TryGetValue(lb, out fb);

            ilg.Emit(OpCodes.Ldarg_0);  // this

            Type primt = lb.PrimitiveType;
            if (primt != null)
            {
                MaybePrimitiveExpr mbe = val as MaybePrimitiveExpr;
                if (!(mbe != null && mbe.CanEmitPrimitive))
                    throw new ArgumentException("Must assign primitive to primitive mutable", lb.Name);
                mbe.EmitUnboxed(RHC.Expression, this, ilg);

            }
            else
            {
                val.Emit(RHC.Expression, this, ilg);
            }

            if (hasField)
            {
                ilg.MaybeEmitVolatileOp(IsVolatile(lb));
                ilg.Emit(OpCodes.Stfld, fb);
            }
            else
                ilg.Emit(OpCodes.Stloc, lb.LocalVar);
        }
示例#3
0
        public static void EmitTypedArg(ObjExpr objx, CljILGen ilg, Type paramType, Expr arg)
        {
            Type primt             = Compiler.MaybePrimitiveType(arg);
            MaybePrimitiveExpr mpe = arg as MaybePrimitiveExpr;

            if (primt == paramType)
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
            }
            else if (primt == typeof(int) && paramType == typeof(long))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_I8);
            }
            else if (primt == typeof(long) && paramType == typeof(int))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                if (RT.booleanCast(RT.UncheckedMathVar.deref()))
                {
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_uncheckedIntCast_long);
                }
                else
                {
                    ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long);
                }
            }
            else if (primt == typeof(float) && paramType == typeof(double))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R8);
            }
            else if (primt == typeof(double) && paramType == typeof(float))
            {
                mpe.EmitUnboxed(RHC.Expression, objx, ilg);
                ilg.Emit(OpCodes.Conv_R4);
            }
            else
            {
                arg.Emit(RHC.Expression, objx, ilg);
                HostExpr.EmitUnboxArg(objx, ilg, paramType);
            }
        }
示例#4
0
        public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            for (int i = 0; i < _exprs.count() - 1; i++)
            {
                Expr e = (Expr)_exprs.nth(i);
                e.Emit(RHC.Statement, objx, ilg);
            }
            MaybePrimitiveExpr mbe = (MaybePrimitiveExpr)LastExpr;

            mbe.EmitUnboxed(rhc, objx, ilg);
        }
        private static void EmitExpr(ObjExpr objx, CljILGen ilg, Expr expr, bool emitUnboxed)
        {
            MaybePrimitiveExpr mbe = expr as MaybePrimitiveExpr;

            if (emitUnboxed && mbe != null)
            {
                mbe.EmitUnboxed(RHC.Expression, objx, ilg);
            }
            else
            {
                expr.Emit(RHC.Expression, objx, ilg);
            }
        }
示例#6
0
        public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg)
        {
            Label?loopLabel = (Label)Compiler.LoopLabelVar.deref();

            if (loopLabel == null)
            {
                throw new InvalidOperationException("Recur not in proper context.");
            }

            {
                for (int i = 0; i < _loopLocals.count(); i++)
                {
                    LocalBinding lb  = (LocalBinding)_loopLocals.nth(i);
                    Expr         arg = (Expr)_args.nth(i);

                    Type primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                        Type pt = Compiler.MaybePrimitiveType(arg);
                        if (pt == primt)
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                        }
                        else if (primt == typeof(long) && pt == typeof(int))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_I8);
                        }
                        else if (primt == typeof(double) && pt == typeof(float))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R8);
                        }
                        else if (primt == typeof(int) && pt == typeof(long))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.EmitCall(Compiler.Method_RT_intCast_long);
                        }
                        else if (primt == typeof(float) && pt == typeof(double))
                        {
                            mpeArg.EmitUnboxed(RHC.Expression, objx, ilg);
                            ilg.Emit(OpCodes.Conv_R4);
                        }
                        else
                        {
                            throw new ArgumentException(String.Format(
                                                            "{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                                            _source, _spanMap != null ? (int)_spanMap.valAt(RT.StartLineKey, 0) : 0,
                                                            lb.Name, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name));
                        }
                    }
                    else
                    {
                        arg.Emit(RHC.Expression, objx, ilg);
                    }
                }
            }
            for (int i = _loopLocals.count() - 1; i >= 0; i--)
            {
                LocalBinding lb = (LocalBinding)_loopLocals.nth(i);
                //Type primt = lb.PrimitiveType;
                if (lb.IsArg)
                {
                    //ilg.Emit(OpCodes.Starg, lb.Index - (objx.IsStatic ? 0 : 1));
                    ilg.EmitStoreArg(lb.Index);
                }
                else
                {
                    ilg.Emit(OpCodes.Stloc, lb.LocalVar);
                }
            }

            ilg.Emit(OpCodes.Br, loopLabel.Value);
        }