예제 #1
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);
            }
        }
예제 #2
0
        private static Expression GenResult(ObjExpr objx, GenContext context, Expr expr, bool genUnboxed, Type retType)
        {
            MaybePrimitiveExpr mbExpr = expr as MaybePrimitiveExpr;
            Expression         result = genUnboxed && mbExpr != null
                ? mbExpr.GenCodeUnboxed(RHC.Expression, objx, context)
                : expr.GenCode(RHC.Expression, objx, context);

            if (result.Type != retType)
            {
                if (expr is ThrowExpr)
                {
                    // Fix type on the throw expression
                    UnaryExpression ur = (UnaryExpression)result;
                    result = Expression.Throw(ur.Operand, retType);
                }
                else
                {
                    result = Expression.Convert(result, retType);
                }
            }

            return(result);
        }
예제 #3
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);
        }
예제 #4
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            LabelTarget loopLabel = (LabelTarget)Compiler.LoopLabelVar.deref();

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

            int argCount = _args.count();

            List <ParameterExpression> tempVars     = new List <ParameterExpression>(argCount);
            List <Expression>          tempAssigns  = new List <Expression>(argCount);
            List <Expression>          finalAssigns = new List <Expression>(argCount);

            // Evaluate all the init forms into local variables.
            for (int i = 0; i < _loopLocals.count(); i++)
            {
                LocalBinding lb  = (LocalBinding)_loopLocals.nth(i);
                Expr         arg = (Expr)_args.nth(i);

                ParameterExpression tempVar;
                Expression          valExpr;

                Type primt = lb.PrimitiveType;
                if (primt != null)
                {
                    tempVar = Expression.Parameter(primt, "__local__" + i);

                    MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr;
                    Type pt = Compiler.MaybePrimitiveType(arg);
                    if (pt == primt)
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        // do nothing
                    }
                    else if (primt == typeof(long) && pt == typeof(int))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(double) && pt == typeof(float))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(int) && pt == typeof(long))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else if (primt == typeof(float) && pt == typeof(double))
                    {
                        valExpr = mpeArg.GenCodeUnboxed(RHC.Expression, objx, context);
                        valExpr = Expression.Convert(valExpr, primt);
                    }
                    else
                    {
                        //if (true) //RT.booleanCast(RT.WARN_ON_REFLECTION.deref()))
                        //RT.errPrintWriter().WriteLine
                        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));
                        //valExpr = arg.GenCode(RHC.Expression, objx, context);
                        // valExpr = Expression.Convert(valExpr, primt);
                    }
                }
                else
                {
                    tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i);
                    valExpr = arg.GenCode(RHC.Expression, objx, context);
                }


                //ParameterExpression tempVar = Expression.Parameter(lb.ParamExpression.Type, "__local__" + i);
                //Expression valExpr = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context);
                tempVars.Add(tempVar);

                //if (tempVar.Type == typeof(Object))
                //    tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr)));
                //else
                //    tempAssigns.Add(Expression.Assign(tempVar, Expression.Convert(valExpr, tempVar.Type)));
                if (valExpr.Type.IsPrimitive && !tempVar.Type.IsPrimitive)
                {
                    tempAssigns.Add(Expression.Assign(tempVar, Compiler.MaybeBox(valExpr)));
                }
                else if (!valExpr.Type.IsPrimitive && tempVar.Type.IsPrimitive)
                {
                    tempAssigns.Add(Expression.Assign(tempVar, HostExpr.GenUnboxArg(valExpr, tempVar.Type)));
                }
                else
                {
                    tempAssigns.Add(Expression.Assign(tempVar, valExpr));
                }

                finalAssigns.Add(Expression.Assign(lb.ParamExpression, tempVar));
            }

            List <Expression> exprs = tempAssigns;

            exprs.AddRange(finalAssigns);
            exprs.Add(Expression.Goto(loopLabel));
            // need to do this to get a return value in the type inferencing -- else can't use this in a then or else clause.
            exprs.Add(Expression.Constant(null));
            return(Expression.Block(tempVars, exprs));
        }