Example #1
0
        public override Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val)
        {
            Expression target  = _target.GenCode(RHC.Expression, objx, context);
            Expression valExpr = val.GenCode(RHC.Expression, objx, context);
            Expression call;

            if (_targetType != null && _tinfo != null)
            {
                Expression convTarget   = Expression.Convert(target, _targetType);
                Expression access       = GenAccess(rhc, objx, convTarget);
                Expression unboxValExpr = HostExpr.GenUnboxArg(valExpr, FieldType);
                //call = Expression.Assign(access, Expression.Convert(valExpr, access.Type));
                call = Expression.Assign(access, unboxValExpr);
            }
            else
            {
                // TODO: Convert to a dynamic call site
                call = Expression.Call(
                    Compiler.Method_Reflector_SetInstanceFieldOrProperty,
                    target,
                    Expression.Constant(_fieldName),
                    Compiler.MaybeBox(valExpr));
            }

            call = Compiler.MaybeAddDebugInfo(call, _spanMap, context.IsDebuggable);
            return(call);
        }
Example #2
0
        public override Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val)
        {
            Expression access       = GenCodeUnboxed(RHC.Expression, objx, context);
            Expression valExpr      = val.GenCode(RHC.Expression, objx, context);
            Expression unboxValExpr = HostExpr.GenUnboxArg(valExpr, FieldType);
            Expression assign       = Expression.Assign(access, unboxValExpr);

            assign = Compiler.MaybeAddDebugInfo(assign, _spanMap, context.IsDebuggable);
            return(assign);
        }
Example #3
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));
        }
Example #4
0
        MethodBuilder GenerateStaticMethod(ObjExpr objx, GenContext context)
        {
            string      methodName = StaticMethodName;
            TypeBuilder tb         = objx.TypeBuilder;

            List <ParameterExpression> parms = new List <ParameterExpression>(_argLocals.count() + 1);
            List <Type> parmTypes            = new List <Type>(_argLocals.count() + 1);

            ParameterExpression thisParm = Expression.Parameter(objx.BaseType, "this");

            if (_thisBinding != null)
            {
                _thisBinding.ParamExpression = thisParm;
                _thisBinding.Tag             = Symbol.intern(null, objx.BaseType.FullName);
            }
            objx.ThisParam = thisParm;
            parms.Add(thisParm);
            parmTypes.Add(objx.BaseType);

            try
            {
                LabelTarget loopLabel = Expression.Label("top");

                Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this));

                Type[] argTypes = StaticMethodArgTypes;

                for (int i = 0; i < _argLocals.count(); i++)
                {
                    LocalBinding        lb   = (LocalBinding)_argLocals.nth(i);
                    ParameterExpression parm = Expression.Parameter(argTypes[i], lb.Name);
                    lb.ParamExpression = parm;
                    parms.Add(parm);
                    parmTypes.Add(argTypes[i]);
                }

                Expression body =
                    Expression.Block(
                        //maybeLoadVarsExpr,
                        Expression.Label(loopLabel),
                        GenBodyCode(StaticReturnType, objx, context));

                //Expression convBody = Compiler.MaybeConvert(body, ReturnType);
                Expression convBody = HostExpr.GenUnboxArg(body, StaticReturnType);

                LambdaExpression lambda = Expression.Lambda(convBody, parms);
                // JVM: Clears locals here.


                // TODO: Cache all the CreateObjectTypeArray values
                MethodBuilder mb = tb.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, StaticReturnType, parmTypes.ToArray());

                //Console.Write("StMd: {0} {1}(", ReturnType.Name, methodName);
                //foreach (Type t in parmTypes)
                //    Console.Write("{0}, ", t.Name);
                //Console.WriteLine(")");

                lambda.CompileToMethod(mb, context.IsDebuggable);

                _staticMethodBuilder = mb;
                return(mb);
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
Example #5
0
        protected Expression GenDlrForMethod(ObjExpr objx, GenContext context)
        {
            if (_method.DeclaringType == (Type)Compiler.CompileStubOrigClassVar.deref())
            {
                _method = FindEquivalentMethod(_method, objx.BaseType);
            }

            int argCount = _args.Count;


            IList <DynamicMetaObject> argsPlus = new List <DynamicMetaObject>(argCount + (IsStaticCall ? 0 : 1));

            if (!IsStaticCall)
            {
                argsPlus.Add(new DynamicMetaObject(Expression.Convert(GenTargetExpression(objx, context), _method.DeclaringType), BindingRestrictions.Empty));
            }

            List <int> refPositions = new List <int>();

            ParameterInfo[] methodParms = _method.GetParameters();

            for (int i = 0; i < argCount; i++)
            {
                HostArg ha = _args[i];

                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object);

                //Type t;

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                    refPositions.Add(i);
                    argsPlus.Add(new DynamicMetaObject(HostExpr.GenUnboxArg(GenTypedArg(objx, context, argType, e), methodParms[i].ParameterType.GetElementType()), BindingRestrictions.Empty));
                    break;

                case HostArg.ParameterType.Standard:
                    Type ptype = methodParms[i].ParameterType;
                    if (ptype.IsGenericParameter)
                    {
                        ptype = argType;
                    }

                    Expression typedArg = GenTypedArg(objx, context, ptype, e);

                    argsPlus.Add(new DynamicMetaObject(typedArg, BindingRestrictions.Empty));

                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }

            // TODO: get rid of use of Default
            OverloadResolverFactory factory = ClojureContext.Default.SharedOverloadResolverFactory;
            DefaultOverloadResolver res     = factory.CreateOverloadResolver(argsPlus, new CallSignature(argCount), IsStaticCall ? CallTypes.None : CallTypes.ImplicitInstance);

            List <MethodBase> methods = new List <MethodBase>();

            methods.Add(_method);

            BindingTarget bt = res.ResolveOverload(_methodName, methods, NarrowingLevel.None, NarrowingLevel.All);

            if (!bt.Success)
            {
                throw new ArgumentException("Conflict in argument matching. -- Internal error.");
            }

            Expression call = bt.MakeExpression();

            if (refPositions.Count > 0)
            {
                ParameterExpression resultParm = Expression.Parameter(typeof(Object[]));

                List <Expression> stmts = new List <Expression>(refPositions.Count + 2);
                stmts.Add(Expression.Assign(resultParm, call));

                // TODO: Fold this into the loop above
                foreach (int i in refPositions)
                {
                    HostArg ha      = _args[i];
                    Expr    e       = ha.ArgExpr;
                    Type    argType = e.HasClrType ? (e.ClrType ?? typeof(object)) : typeof(Object);
                    stmts.Add(Expression.Assign(_args[i].LocalBinding.ParamExpression, Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(i + 1)), argType)));
                }

                Type returnType = HasClrType ? ClrType : typeof(object);
                stmts.Add(Expression.Convert(Expression.ArrayIndex(resultParm, Expression.Constant(0)), returnType));
                call = Expression.Block(new ParameterExpression[] { resultParm }, stmts);
            }

            call = _arithmeticRewriter.Visit(call);

            return(call);
        }