コード例 #1
0
        public override Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            Type targetType = _targetType;

            Type stubType = Compiler.CompileStubOrigClassVar.isBound ? (Type)Compiler.CompileStubOrigClassVar.deref() : null;

            if (_targetType == stubType)
            {
                targetType = objx.BaseType;
            }

            Expression target = _target.GenCode(RHC.Expression, objx, context);
            Expression call;

            if (targetType != null && _tinfo != null)
            {
                Expression convTarget = Expression.Convert(target, targetType);
                Expression access     = GenAccess(rhc, objx, convTarget);
                call = HostExpr.GenBoxReturn(access, FieldType, objx, context);
            }
            else
            {
                // TODO: Convert to Dynamic call site
                call = Expression.Call(Compiler.Method_Reflector_GetInstanceFieldOrProperty, target, Expression.Constant(_fieldName));
            }
            call = Compiler.MaybeAddDebugInfo(call, _spanMap, context.IsDebuggable);
            return(call);
        }
コード例 #2
0
        public override Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression exc  = _excExpr.GenCode(RHC.Expression, objx, context);
            Expression exc2 = Expression.Convert(exc, typeof(Exception));

            return(Expression.Throw(exc2, typeof(object)));
        }
コード例 #3
0
ファイル: TryExpr.cs プロジェクト: clojurians-org/clojure-clr
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression basicBody = _tryExpr.GenCode(rhc, objx, context);

            if (basicBody.Type == typeof(void))
            {
                basicBody = Expression.Block(basicBody, Expression.Default(typeof(object)));
            }
            Expression tryBody = Expression.Convert(basicBody, typeof(object));

            CatchBlock[] catches = new CatchBlock[_catchExprs.count()];
            for (int i = 0; i < _catchExprs.count(); i++)
            {
                CatchClause         clause   = (CatchClause)_catchExprs.nth(i);
                ParameterExpression parmExpr = Expression.Parameter(clause.Type, clause.Lb.Name);
                clause.Lb.ParamExpression = parmExpr;
                catches[i] = Expression.Catch(parmExpr, Expression.Convert(clause.Handler.GenCode(rhc, objx, context), typeof(object)));
            }

            Expression tryStmt = _finallyExpr == null
                ? catches.Length == 0 ? tryBody : Expression.TryCatch(tryBody, catches)
                : Expression.TryCatchFinally(tryBody, _finallyExpr.GenCode(RHC.Statement, objx, context), catches);

            return(tryStmt);
        }
コード例 #4
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);
        }
コード例 #5
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            int n = _bindingInits.count();
            List <ParameterExpression> parms = new List <ParameterExpression>(n);
            List <Expression>          forms = new List <Expression>(n);

            /// First, set up the environment.
            for (int i = 0; i < n; i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                ParameterExpression parmExpr = Expression.Parameter(typeof(IFn), bi.Binding.Name);
                bi.Binding.ParamExpression = parmExpr;
                parms.Add(parmExpr);
            }

            // Then initialize
            for (int i = 0; i < n; i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                ParameterExpression parmExpr = (ParameterExpression)bi.Binding.ParamExpression;
                forms.Add(Expression.Assign(parmExpr, bi.Init.GenCode(RHC.Expression, objx, context)));
            }

            // The work
            forms.Add(_body.GenCode(rhc, objx, context));
            return(Expression.Block(parms, forms));
        }
コード例 #6
0
ファイル: VarExpr.cs プロジェクト: clojurians-org/clojure-clr
        public Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val)
        {
            // RETYPE: Get rid of Box?
            Expression varExpr = objx.GenVar(context, _var);
            Expression valExpr = val.GenCode(RHC.Expression, objx, context);

            return(Expression.Call(varExpr, Compiler.Method_Var_set, Compiler.MaybeBox(valExpr)));
        }
コード例 #7
0
        protected override Expression GenTargetExpression(ObjExpr objx, GenContext context)
        {
            Expression expr = _target.GenCode(RHC.Expression, objx, context);

            //if ( _target.HasClrType )
            //    expr =  Expression.Convert(expr,_target.ClrType);

            return(expr);
        }
コード例 #8
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            //if (context.Mode == CompilerMode.Immediate)
            if (objx.FnMode == FnMode.Light)
            {
                // This will emit a plain Keyword reference, rather than a callsite.
                InvokeExpr ie = new InvokeExpr(_source, _spanMap, (Symbol)_tag, _kw, RT.vector(_target));
                return(ie.GenCode(rhc, objx, context));
            }
            else
            {
                // pseudo-code:
                //  ILookupThunk thunk = objclass.ThunkField(i)
                //  object target = ...code...
                //  object val = thunk.get(target)
                //  if ( val != thunk )
                //     return val
                //  else
                //     KeywordLookupSite site = objclass.SiteField(i)
                //     thunk = site.fault(target)
                //     objclass.ThunkField(i) = thunk
                //     val = thunk.get(target)
                //     return val

                ParameterExpression thunkParam  = Expression.Parameter(typeof(ILookupThunk), "thunk");
                ParameterExpression targetParam = Expression.Parameter(typeof(object), "target");
                ParameterExpression valParam    = Expression.Parameter(typeof(Object), "val");
                ParameterExpression siteParam   = Expression.Parameter(typeof(KeywordLookupSite), "site");


                Expression assignThunkFromField = Expression.Assign(thunkParam, Expression.Field(null, objx.ThunkField(_siteIndex)));
                Expression assignThunkFromSite  = Expression.Assign(thunkParam, Expression.Call(siteParam, Compiler.Method_ILookupSite_fault, targetParam));
                Expression assignFieldFromThunk = Expression.Assign(Expression.Field(null, objx.ThunkField(_siteIndex)), thunkParam);
                Expression assignTarget         = Expression.Assign(targetParam, _target.GenCode(RHC.Expression, objx, context));
                Expression assignVal            = Expression.Assign(valParam, Expression.Call(thunkParam, Compiler.Method_ILookupThunk_get, targetParam));
                Expression assignSite           = Expression.Assign(siteParam, Expression.Field(null, objx.KeywordLookupSiteField(_siteIndex)));


                Expression block =
                    Expression.Block(typeof(Object), new ParameterExpression[] { thunkParam, valParam, targetParam },
                                     assignThunkFromField,
                                     assignTarget,
                                     assignVal,
                                     Expression.IfThen(
                                         Expression.Equal(valParam, thunkParam),
                                         Expression.Block(typeof(Object), new ParameterExpression[] { siteParam },
                                                          assignSite,
                                                          assignThunkFromSite,
                                                          assignFieldFromThunk,
                                                          assignVal)),
                                     valParam);

                block = Compiler.MaybeAddDebugInfo(block, _spanMap, context.IsDebuggable);
                return(block);
            }
        }
コード例 #9
0
ファイル: LetExpr.cs プロジェクト: clojurians-org/clojure-clr
        private Expression GenCode(RHC rhc, ObjExpr objx, GenContext context, bool genUnboxed)
        {
            LabelTarget loopLabel = Expression.Label();

            List <ParameterExpression> parms = new List <ParameterExpression>();
            List <Expression>          forms = new List <Expression>();

            for (int i = 0; i < _bindingInits.count(); i++)
            {
                BindingInit         bi       = (BindingInit)_bindingInits.nth(i);
                Type                primType = Compiler.MaybePrimitiveType(bi.Init);
                ParameterExpression parmExpr;
                Expression          initExpr;
                if (primType != null)
                {
                    parmExpr = Expression.Parameter(primType, bi.Binding.Name);
                    initExpr = ((MaybePrimitiveExpr)bi.Init).GenCodeUnboxed(RHC.Expression, objx, context);
                }
                else
                {
                    parmExpr = Expression.Parameter(typeof(object), bi.Binding.Name);
                    initExpr = Compiler.MaybeBox(bi.Init.GenCode(RHC.Expression, objx, context));
                }
                bi.Binding.ParamExpression = parmExpr;
                parms.Add(parmExpr);
                forms.Add(Expression.Assign(parmExpr, initExpr));
            }


            forms.Add(Expression.Label(loopLabel));

            try
            {
                if (_isLoop)
                {
                    Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel));
                }

                Expression form = genUnboxed
                    ? ((MaybePrimitiveExpr)_body).GenCodeUnboxed(rhc, objx, context)
                    : _body.GenCode(rhc, objx, context);

                forms.Add(form);
            }
            finally
            {
                if (_isLoop)
                {
                    Var.popThreadBindings();
                }
            }

            Expression block = Expression.Block(parms, forms);

            return(block);
        }
コード例 #10
0
        internal static void GenerateComplexArgList(
            ObjExpr objx,
            GenContext context,
            List <HostArg> args,
            out List <Expression> argExprs,
            out List <ParameterExpression> sbParams,
            out List <Expression> sbInits,
            out List <Expression> sbTransfers)
        {
            argExprs    = new List <Expression>(args.Count);
            sbParams    = new List <ParameterExpression>();
            sbInits     = new List <Expression>();
            sbTransfers = new List <Expression>();

            BindingFlags cflags = BindingFlags.Public | BindingFlags.Instance;

            foreach (HostArg ha in args)
            {
                Expr e       = ha.ArgExpr;
                Type argType = e.HasClrType ? (e.ClrType ?? typeof(Object)) : typeof(Object);

                switch (ha.ParamType)
                {
                case HostArg.ParameterType.ByRef:
                {
#if CLR2
                    Type sbType = typeof(MSC::System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType);
#else
                    Type sbType = typeof(System.Runtime.CompilerServices.StrongBox <>).MakeGenericType(argType);
#endif

                    ParameterExpression sbParam = Expression.Parameter(sbType, String.Format("__sb_{0}", sbParams.Count));
                    //ConstructorInfo[] cinfos = sbType.GetConstructors();
                    Expression sbInit1 =
                        Expression.Assign(
                            sbParam,
                            Expression.New(
                                sbType.GetConstructor(cflags, null, new Type[] { argType }, null),
                                Expression.Convert(ha.LocalBinding.ParamExpression, argType)));
                    Expression sbXfer = Expression.Assign(ha.LocalBinding.ParamExpression, Expression.Field(sbParam, "Value"));
                    sbParams.Add(sbParam);
                    sbInits.Add(sbInit1);
                    sbTransfers.Add(sbXfer);
                    argExprs.Add(sbParam);
                }
                break;

                case HostArg.ParameterType.Standard:
                    argExprs.Add(e.GenCode(RHC.Expression, objx, context));
                    break;

                default:
                    throw Util.UnreachableCode();
                }
            }
        }
コード例 #11
0
        private Expression GenTestForHashes(ObjExpr objx, GenContext context, Expr test, bool genUnboxed)
        {
            Expression exprCode = _expr.GenCode(RHC.Expression, objx, context);
            Expression testCode = test.GenCode(RHC.Expression, objx, context);
            Expression condCode = _testType == _hashIdentityKey
                ? (Expression)Expression.Equal(exprCode, testCode)
                : (Expression)Expression.Call(null, Compiler.Method_Util_equiv, Compiler.MaybeBox(exprCode), Compiler.MaybeBox(testCode));

            return(condCode);
        }
コード例 #12
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);
        }
コード例 #13
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression objExpr  = _expr.GenCode(RHC.Expression, objx, context);
            Expression iobjExpr = Expression.Convert(objExpr, typeof(IObj));

            Expression metaExpr = _meta.GenCode(RHC.Expression, objx, context);

            metaExpr = Expression.Convert(metaExpr, typeof(IPersistentMap));

            Expression ret = Expression.Call(iobjExpr, Compiler.Method_IObj_withMeta, metaExpr);

            return(ret);
        }
コード例 #14
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            List <Expression> exprs = new List <Expression>(_exprs.count());

            for (int i = 0; i < _exprs.count() - 1; i++)
            {
                Expr e = (Expr)_exprs.nth(i);
                exprs.Add(e.GenCode(RHC.Statement, objx, context));
            }
            exprs.Add(LastExpr.GenCode(rhc, objx, context));

            return(Expression.Block(exprs));
        }
コード例 #15
0
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression basicFn = _fexpr.GenCode(RHC.Expression, objx, context);

            basicFn = Expression.Convert(basicFn, typeof(IFn));

            if (_isProtocol)
            {
                return(GenProto(rhc, objx, context, basicFn));
            }

            return(GenNonProto(rhc, objx, context, basicFn));
        }
コード例 #16
0
        internal Expression GenAssignLocal(GenContext context, LocalBinding lb, Expr val)
        {
            if (!IsMutable(lb))
            {
                throw new ArgumentException("Cannot assign to non-mutable: " + lb.Name);
            }

            FieldBuilder fb;

            if (_closedOverFieldsMap.TryGetValue(lb, out fb))
            {
                return(Expression.Assign(Expression.Field(_thisParam, _closedOverFieldsMap[lb]), val.GenCode(RHC.Expression, this, context)));
            }

            return(Expression.Assign(lb.ParamExpression, val.GenCode(RHC.Expression, this, context)));
        }
コード例 #17
0
        public Expression GenCodeUnboxed(RHC rhc, ObjExpr objx, GenContext context)
        {
            List <Expression> exprs = new List <Expression>(_exprs.count());

            for (int i = 0; i < _exprs.count() - 1; i++)
            {
                Expr e = (Expr)_exprs.nth(i);
                exprs.Add(e.GenCode(RHC.Statement, objx, context));
            }

            MaybePrimitiveExpr last = (MaybePrimitiveExpr)LastExpr;

            exprs.Add(last.GenCodeUnboxed(rhc, objx, context));

            return(Expression.Block(exprs));
        }
コード例 #18
0
        internal static Expression GenTypedArg(ObjExpr objx, GenContext context, Type paramType, Expr arg)
        {
            Type primt = Compiler.MaybePrimitiveType(arg);

            if (primt == paramType)
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                return(expr);
            }
            else if (primt == typeof(int) && paramType == typeof(long))
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr, typeof(long));
                return(expr);
            }
            else if (primt == typeof(long) && paramType == typeof(int))
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                if (RT.booleanCast(RT.UncheckedMathVar.deref()))
                {
                    expr = Expression.Call(Compiler.Method_RT_uncheckedIntCast_long, expr);
                }
                else
                {
                    expr = Expression.Call(Compiler.Method_RT_intCast_long, expr);
                }
                return(expr);
            }
            else if (primt == typeof(float) && paramType == typeof(double))
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr, typeof(double));
                return(expr);
            }
            else if (primt == typeof(double) && paramType == typeof(float))
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr, typeof(float));
                return(expr);
            }
            else
            {
                Expression argExpr = arg.GenCode(RHC.Expression, objx, context);
                return(GenUnboxArg(argExpr, paramType));
            }
        }
コード例 #19
0
        public override Expression GenCodeUnboxed(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression target = _target.GenCode(RHC.Expression, objx, context);

            Type returnType = HasClrType ? ClrType : typeof(object);

            // TODO: Get rid of Default
            GetMemberBinder   binder = new ClojureGetZeroArityMemberBinder(ClojureContext.Default, _memberName, false);
            DynamicExpression dyn    = Expression.Dynamic(binder, returnType, new Expression[] { target });

            Expression call = dyn;

            if (context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn);
            }

            call = Compiler.MaybeAddDebugInfo(call, _spanMap, context.IsDebuggable);
            return(call);
        }
コード例 #20
0
        private Expression GenBodyCode(Type retType, ObjExpr objx, GenContext context)
        {
            MaybePrimitiveExpr be = (MaybePrimitiveExpr)_body;

            if (Util.IsPrimitive(retType) && be.CanEmitPrimitive)
            {
                Type bt = Compiler.MaybePrimitiveType(be);
                if (bt == retType)
                {
                    return(be.GenCodeUnboxed(RHC.Return, objx, context));
                }
                else if (retType == typeof(long) && bt == typeof(int))
                {
                    return(Expression.Convert(be.GenCodeUnboxed(RHC.Return, objx, context), typeof(long)));
                }
                else if (retType == typeof(double) && bt == typeof(float))
                {
                    return(Expression.Convert(be.GenCodeUnboxed(RHC.Return, objx, context), typeof(double)));
                }
                else if (retType == typeof(int) && bt == typeof(long))
                {
                    return(Expression.Call(null, Compiler.Method_RT_intCast_long, be.GenCodeUnboxed(RHC.Return, objx, context)));
                }
                else if (retType == typeof(float) && bt == typeof(double))
                {
                    return(Expression.Convert(be.GenCodeUnboxed(RHC.Return, objx, context), typeof(float)));
                }
                else
                {
                    throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType));
                }
            }
            else
            {
                return(_body.GenCode(RHC.Return, objx, context));
                // Java code does: gen.unbox(Type.getType(retClass) here.
                // I don't know how to do the equivalent.
            }
        }
コード例 #21
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);
        }
コード例 #22
0
        private Expression GenTestForInts(ObjExpr objx, GenContext context, Type primExprType, Expr test, bool genUnboxed)
        {
            Expression condCode;

            if (primExprType == null)
            {
                Expression exprCode = _expr.GenCode(RHC.Expression, objx, context);
                Expression testCode = test.GenCode(RHC.Expression, objx, context);
                condCode = Expression.Call(null, Compiler.Method_Util_equiv, Compiler.MaybeBox(exprCode), Compiler.MaybeBox(testCode));
            }
            else if (primExprType == typeof(long) || primExprType == typeof(ulong))
            {
                Expression exprCode = _expr.GenCodeUnboxed(RHC.Expression, objx, context);
                Expression testCode = ((NumberExpr)test).GenCodeUnboxed(RHC.Expression, objx, context);
                condCode = Expression.Equal(exprCode, testCode);
            }
            else if (primExprType == typeof(int) || primExprType == typeof(short) || primExprType == typeof(byte) ||
                     primExprType == typeof(uint) || primExprType == typeof(ushort) || primExprType == typeof(sbyte))
            {
                if (IsShiftMasked)
                {
                    Expression exprCode = Expression.Convert(_expr.GenCodeUnboxed(RHC.Expression, objx, context), typeof(long));
                    Expression testCode = ((NumberExpr)test).GenCodeUnboxed(RHC.Expression, objx, context);
                    condCode = Expression.Equal(exprCode, testCode);
                }
                else
                {
                    condCode = Expression.Constant(true);
                }
            }
            else
            {
                condCode = Expression.Constant(false);
            }
            return(condCode);
        }
コード例 #23
0
ファイル: IfExpr.cs プロジェクト: clojurians-org/clojure-clr
        private Expression GenCode(RHC rhc, ObjExpr objx, GenContext context, bool genUnboxed)
        {
            bool testIsBool = Compiler.MaybePrimitiveType(_testExpr) == typeof(bool);

            Expression testCode;

            if (testIsBool)
            {
                testCode = ((MaybePrimitiveExpr)_testExpr).GenCodeUnboxed(RHC.Expression, objx, context);
            }
            else
            {
                ParameterExpression testVar  = Expression.Parameter(typeof(object), "__test");
                Expression          assign   = Expression.Assign(testVar, Compiler.MaybeBox(_testExpr.GenCode(RHC.Expression, objx, context)));
                Expression          boolExpr =
                    Expression.Not(
                        Expression.OrElse(
                            Expression.Equal(testVar, Expression.Constant(null)),
                            Expression.AndAlso(Expression.TypeIs(testVar, typeof(bool)), Expression.IsFalse(Expression.Unbox(testVar, typeof(bool))))));
                testCode = Expression.Block(typeof(bool), new ParameterExpression[] { testVar }, assign, boolExpr);
            }

            Expression thenCode = genUnboxed ? ((MaybePrimitiveExpr)_thenExpr).GenCodeUnboxed(rhc, objx, context) : _thenExpr.GenCode(rhc, objx, context);

            Expression elseCode = genUnboxed ? ((MaybePrimitiveExpr)_elseExpr).GenCodeUnboxed(rhc, objx, context) : _elseExpr.GenCode(rhc, objx, context);

            Type targetType = typeof(object);

            if (this.HasClrType && this.ClrType != null)
            {
                // In this case, both _thenExpr and _elseExpr have types, and they are the same, or one is null.
                // TODO: Not sure if this works if one has a null value.
                targetType = this.ClrType;
            }

            if (thenCode.Type == typeof(void) && elseCode.Type != typeof(void))
            {
                thenCode = Expression.Block(thenCode, Expression.Default(elseCode.Type));
            }
            else if (elseCode.Type == typeof(void) && thenCode.Type != typeof(void))
            {
                elseCode = Expression.Block(elseCode, Expression.Default(thenCode.Type));
            }
            else if (!Reflector.AreReferenceAssignable(targetType, thenCode.Type) || !Reflector.AreReferenceAssignable(targetType, elseCode.Type))
            // Above: this is the test that Expression.Condition does.
            {
                // Try to reconcile
                if (thenCode.Type.IsAssignableFrom(elseCode.Type) && elseCode.Type != typeof(void))
                {
                    elseCode   = Expression.Convert(elseCode, thenCode.Type);
                    targetType = thenCode.Type;
                }
                else if (elseCode.Type.IsAssignableFrom(thenCode.Type) && thenCode.Type != typeof(void))
                {
                    thenCode   = Expression.Convert(thenCode, elseCode.Type);
                    targetType = elseCode.Type;
                }
                else
                {
                    //if (thenCode.Type == typeof(void))
                    //{
                    //    thenCode = Expression.Block(thenCode, Expression.Default(elseCode.Type));
                    //    targetType = elseCode.Type;
                    //}
                    //else if (elseCode.Type == typeof(void))
                    //{
                    //    elseCode = Expression.Block(elseCode, Expression.Default(thenCode.Type));
                    //    targetType = thenCode.Type;
                    //}
                    //else
                    //{
                    // TODO: Can we find a common ancestor?  probably not.
                    thenCode   = Expression.Convert(thenCode, typeof(object));
                    elseCode   = Expression.Convert(elseCode, typeof(object));
                    targetType = typeof(object);
                    //}
                }
            }

            Expression cond = Expression.Condition(testCode, thenCode, elseCode, targetType);

            cond = Compiler.MaybeAddDebugInfo(cond, _sourceSpan, context.IsDebuggable);
            return(cond);
        }
コード例 #24
0
        private Expression GenProtoFull(RHC rhc, ObjExpr objx, GenContext context, Expression fn)
        {
            Var  v = ((VarExpr)_fexpr).Var;
            Expr e = (Expr)_args.nth(0);

            ParameterExpression targetParam     = Expression.Parameter(typeof(Object), "target");
            ParameterExpression targetTypeParam = Expression.Parameter(typeof(Type), "targetType");
            ParameterExpression vpfnParam       = Expression.Parameter(typeof(AFunction), "vpfn");
            ParameterExpression thisParam       = objx.ThisParam;

            Expression targetParamAssign     = Expression.Assign(targetParam, Expression.Convert(e.GenCode(RHC.Expression, objx, context), targetParam.Type));
            Expression targetTypeParamAssign =
                Expression.Assign(
                    targetTypeParam,
                    Expression.Call(null, Compiler.Method_Util_classOf, targetParam));

            Expression cachedTypeField = Expression.Field(thisParam, objx.CachedTypeField(_siteIndex));

            Expression setCachedClass =
                Expression.Assign(
                    cachedTypeField,
                    targetTypeParam);

            Expression vpfnParamAssign =
                Expression.Assign(
                    vpfnParam,
                    Expression.Convert(Expression.Call(objx.GenVar(context, v), Compiler.Method_Var_getRawRoot), typeof(AFunction)));

            if (_protocolOn == null)
            {
                return(Expression.Block(
                           new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam },
                           targetParamAssign,
                           targetTypeParamAssign,
                           Expression.IfThen(
                               Expression.NotEqual(targetTypeParam, cachedTypeField),
                               setCachedClass),
                           vpfnParamAssign,
                           GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam)));
            }
            else
            {
                Expression[] args = new Expression[_args.count() - 1];
                for (int i = 1; i < _args.count(); i++)
                {
                    Expression bare = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context);
                    args[i - 1] = Compiler.MaybeBox(bare);
                }

                return(Expression.Block(
                           new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam },
                           targetParamAssign,
                           targetTypeParamAssign,
                           Expression.Condition(
                               Expression.And(
                                   Expression.NotEqual(targetTypeParam, cachedTypeField),
                                   Expression.TypeIs(targetParam, _protocolOn)),
                               Compiler.MaybeBox(Expression.Call(Expression.Convert(targetParam, _protocolOn), _onMethod, args)),
                               Expression.Block(
                                   Expression.IfThen(
                                       Expression.NotEqual(targetTypeParam, cachedTypeField),
                                       setCachedClass),
                                   vpfnParamAssign,
                                   GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam)))));
            }
        }
コード例 #25
0
 public Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val)
 {
     Expression varExpr = objx.GenVar(context, _var);
     Expression valExpr = val.GenCode(RHC.Expression,objx,context);
     return Expression.Call(varExpr, Compiler.Method_Var_set, Compiler.MaybeBox(valExpr));
 }
コード例 #26
0
ファイル: CaseExpr.cs プロジェクト: richhickey/clojure-clr
        private Expression GenTestForInts(ObjExpr objx, GenContext context, Type primExprType, Expr test, bool genUnboxed)
        {
            Expression condCode;

            if (primExprType == null)
            {
                Expression exprCode = _expr.GenCode(RHC.Expression, objx, context);
                Expression testCode = test.GenCode(RHC.Expression, objx, context);
                condCode = Expression.Call(null, Compiler.Method_Util_equiv, Compiler.MaybeBox(exprCode), Compiler.MaybeBox(testCode));

            }
            else if (primExprType == typeof(long) || primExprType == typeof(ulong))
            {
                Expression exprCode = _expr.GenCodeUnboxed(RHC.Expression, objx, context);
                Expression testCode = ((NumberExpr)test).GenCodeUnboxed(RHC.Expression, objx, context);
                condCode = Expression.Equal(exprCode, testCode);
            }
            else if (primExprType == typeof(int) || primExprType == typeof(short) || primExprType == typeof(byte)
                  || primExprType == typeof(uint) || primExprType == typeof(ushort) || primExprType == typeof(sbyte))
            {
                if (IsShiftMasked)
                {
                    Expression exprCode = Expression.Convert(_expr.GenCodeUnboxed(RHC.Expression, objx, context),typeof(long));
                    Expression testCode = ((NumberExpr)test).GenCodeUnboxed(RHC.Expression, objx, context);
                    condCode = Expression.Equal(exprCode, testCode);
                }
                else
                    condCode = Expression.Constant(true);
            }
            else
            {
                condCode = Expression.Constant(false);
            }
            return condCode;
        }
コード例 #27
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));
        }
コード例 #28
0
 public Expression GenCodeUnboxed(RHC rhc, ObjExpr objx, GenContext context)
 {
     return(Expression.TypeIs(_expr.GenCode(RHC.Expression, objx, context), _t));;
 }
コード例 #29
0
ファイル: HostExpr.cs プロジェクト: 101v/clojure-clr
 internal static Expression GenTypedArg(ObjExpr objx, GenContext context, Type type, Expr arg)
 {
     if (Compiler.MaybePrimitiveType(arg) == type)
         return ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
     else
     {
         Expression argExpr = arg.GenCode(RHC.Expression, objx, context);
         return GenMaybeUnboxedArg(type, argExpr);
     }
 }
コード例 #30
0
ファイル: DefExpr.cs プロジェクト: clojurians-org/clojure-clr
        public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
        {
            List <Expression> exprs = new List <Expression>();

            ParameterExpression parm = Expression.Parameter(typeof(Var), "v");

            Expression varExpr = objx.GenVar(context, _var);

            if (_isDynamic)
            {
                varExpr = Expression.Call(varExpr, Compiler.Method_Var_setDynamic0);
            }

            exprs.Add(Expression.Assign(parm, varExpr));

            if (_meta != null)
            {
                if (_initProvided || true) //IncludesExplicitMetadata((MapExpr)_meta))
                {
                    exprs.Add(Expression.Call(parm, Compiler.Method_Var_setMeta, Expression.Convert(_meta.GenCode(RHC.Expression, objx, context), typeof(IPersistentMap))));
                }
            }

            if (_initProvided)
            {
                // RETYPE: get rid of Box?
                // Java doesn't Box here, but we have to deal with unboxed bool values
                exprs.Add(Expression.Call(parm, Compiler.Method_Var_bindRoot, Compiler.MaybeBox(_init.GenCode(RHC.Expression, objx, context))));
            }

            exprs.Add(parm);

            return(Expression.Block(new ParameterExpression[] { parm }, exprs));
        }
コード例 #31
0
ファイル: CaseExpr.cs プロジェクト: richhickey/clojure-clr
        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;
        }
コード例 #32
0
ファイル: CaseExpr.cs プロジェクト: richhickey/clojure-clr
 private Expression GenTestForHashes(ObjExpr objx, GenContext context, Expr test, bool genUnboxed)
 {
     Expression exprCode = _expr.GenCode(RHC.Expression, objx, context);
     Expression testCode = test.GenCode(RHC.Expression, objx, context);
     Expression condCode = _testType == _hashIdentityKey
         ? (Expression)Expression.Equal(exprCode, testCode)
         : (Expression)Expression.Call(null, Compiler.Method_Util_equiv, Compiler.MaybeBox(exprCode), Compiler.MaybeBox(testCode));
     return condCode;
 }
コード例 #33
0
ファイル: ObjExpr.cs プロジェクト: davidadsit/clojure-clr
        internal Expression GenAssignLocal(GenContext context, LocalBinding lb, Expr val)
        {
            if (!IsMutable(lb))
                throw new ArgumentException("Cannot assign to non-mutable: " + lb.Name);

            FieldBuilder fb;
            if ( _closedOverFieldsMap.TryGetValue(lb,out fb) )
                return Expression.Assign(Expression.Field(_thisParam,_closedOverFieldsMap[lb]), val.GenCode(RHC.Expression,this,context));

            return Expression.Assign(lb.ParamExpression, val.GenCode(RHC.Expression,this,context));
        }
コード例 #34
0
ファイル: HostExpr.cs プロジェクト: davidadsit/clojure-clr
        internal static Expression GenTypedArg(ObjExpr objx, GenContext context, Type paramType, Expr arg)
        {
            Type primt = Compiler.MaybePrimitiveType(arg);

            if ( primt == paramType )
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                return expr;
            }
            else if ( primt == typeof(int) && paramType == typeof(long) )
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr,typeof(long));
                return expr;
            }
            else if ( primt == typeof(long) && paramType == typeof(int) )
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                if (RT.booleanCast(RT.UNCHECKED_MATH.deref()))
                    expr = Expression.Call(Compiler.Method_RT_uncheckedIntCast_long, expr);
                else
                    expr = Expression.Call(Compiler.Method_RT_intCast_long, expr);
                return expr;
            }
            else if ( primt == typeof(float) && paramType == typeof(double) )
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr,typeof(double));
                return expr;
            }
            else if ( primt == typeof(double) && paramType == typeof(float) )
            {
                Expression expr = ((MaybePrimitiveExpr)arg).GenCodeUnboxed(RHC.Expression, objx, context);
                expr = Expression.Convert(expr,typeof(float));
                return expr;
            }
            else
            {
                Expression argExpr = arg.GenCode(RHC.Expression, objx, context);
                return GenUnboxArg(argExpr, paramType);
            }
        }
コード例 #35
0
 public override Expression GenCode(RHC rhc, ObjExpr objx, GenContext context)
 {
     return(Expression.Block(
                Expression.Call(Compiler.Method_Monitor_Enter, _target.GenCode(RHC.Expression, objx, context)),
                Compiler.NilExprInstance.GenCode(rhc, objx, context)));
 }