コード例 #1
0
        /// <summary>
        /// Reduces the provided DynamicExpression into site.Target(site, *args).
        /// </summary>
        public Expression ReduceDyn(DynamicExpression node, out SiteInfo siteInfo)
        {
            MaybeInit();

            if (RewriteDelegate(node.DelegateType, out Type delegateType))
            {
                node = Expression.MakeDynamic(delegateType, node.Binder, node.Arguments);
            }

            CallSite cs = CallSite.Create(node.DelegateType, node.Binder);
            // TODO: fix this eventually to return the SiteInfo and not the Expression

            Expression access = RewriteCallSite(cs, _typeGen, delegateType ?? node.DelegateType, out siteInfo);

            // ($site = siteExpr).Target.Invoke($site, *args)
            ParameterExpression site = Expression.Variable(cs.GetType(), "$site");

            return(Expression.Block(
                       new[] { site },
                       Expression.Call(
                           Expression.Field(
                               Expression.Assign(site, access),
                               cs.GetType().GetField("Target")
                               ),
                           node.DelegateType.GetMethod("Invoke"),
                           ClrExtensions.ArrayInsert(site, node.Arguments)
                           )
                       ));
        }
コード例 #2
0
        private Expression GenerateComplexCall(ObjExpr objx, GenContext context)
        {
            Expression call;

            Expression target = GenTargetExpression(objx, context);

            List <Expression>          exprs       = new List <Expression>(_args.Count);
            List <ParameterExpression> sbParams    = new List <ParameterExpression>();
            List <Expression>          sbInits     = new List <Expression>();
            List <Expression>          sbTransfers = new List <Expression>();

            GenerateComplexArgList(objx, context, _args, out exprs, out sbParams, out sbInits, out sbTransfers);

            Expression[] argExprs = ClrExtensions.ArrayInsert <Expression>(target, exprs);

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

            // TODO: Get rid of Default
            InvokeMemberBinder binder = new ClojureInvokeMemberBinder(ClojureContext.Default, _methodName, argExprs.Length, IsStaticCall);
            //DynamicExpression dyn = Expression.Dynamic(binder, returnType, argExprs);
            DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), argExprs);

            //if (context.Mode == CompilerMode.File)
            if (context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn);
            }
            else
            {
                call = dyn;
            }

            if (returnType == typeof(void))
            {
                call = Expression.Block(call, Expression.Default(typeof(object)));
            }
            else
            {
                call = Expression.Convert(call, returnType);
            }

            if (sbParams.Count > 0)
            {
                // We have ref/out params.  Construct the complicated call;

                ParameterExpression   callValParam = Expression.Parameter(returnType, "__callVal");
                ParameterExpression[] allParams    = ClrExtensions.ArrayInsert <ParameterExpression>(callValParam, sbParams);

                call = Expression.Block(
                    returnType,
                    allParams,
                    Expression.Block(sbInits),
                    Expression.Assign(callValParam, call),
                    Expression.Block(sbTransfers),
                    callValParam);
            }

            return(call);
        }
コード例 #3
0
ファイル: FnMethod.cs プロジェクト: terkhorn/clojure-clr
        internal void LightEmit(ObjExpr fn, Type fnType)
        {
            if (DynMethod != null)
            {
                return;
            }

            if (Prim != null || fn.IsStatic)
            {
                throw new InvalidOperationException("No light compile allowed for static methods or methods with primitive interfaces");
            }

            Type[] argTypes = ClrExtensions.ArrayInsert(fnType, GetArgTypes());

            DynamicMethod meth = new DynamicMethod(GetMethodName(), GetReturnType(), argTypes, true);

            CljILGen baseIlg = new CljILGen(meth.GetILGenerator());

            try
            {
                Label loopLabel = baseIlg.DefineLabel();
                Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this));

                //GenContext.EmitDebugInfo(baseIlg, SpanMap);

                baseIlg.MarkLabel(loopLabel);
                _body.Emit(RHC.Return, fn, baseIlg);
                if (_body.HasNormalExit())
                {
                    baseIlg.Emit(OpCodes.Ret);
                }
            }
            finally
            {
                Var.popThreadBindings();
            }

            DynMethod = meth;
        }
コード例 #4
0
        // TODO: See if it is worth removing the code duplication with MethodExp.GenDlr.

        private Expression GenerateComplexCall(RHC rhc, ObjExpr objx, GenContext context)
        {
            Expression call;

            Expression target = GenTargetExpression(objx, context);

            List <Expression>          exprs       = new List <Expression>(_args.Count);
            List <ParameterExpression> sbParams    = new List <ParameterExpression>();
            List <Expression>          sbInits     = new List <Expression>();
            List <Expression>          sbTransfers = new List <Expression>();

            MethodExpr.GenerateComplexArgList(objx, context, _args, out exprs, out sbParams, out sbInits, out sbTransfers);

            Expression[] argExprs = ClrExtensions.ArrayInsert <Expression>(target, exprs);


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

            if (returnType == stubType)
            {
                returnType = objx.BaseType;
            }

            // TODO: get rid of Default
            CreateInstanceBinder binder = new ClojureCreateInstanceBinder(ClojureContext.Default, _args.Count);
            DynamicExpression    dyn    = Expression.Dynamic(binder, typeof(object), argExprs);

            // I'd like to use returnType in place of typeof(object) in the previous,
            // But I can't override ReturnType in DefaultCreateInstanceBinder and this causes an error.
            // Look for the conversion below.

            //if (context.Mode == CompilerMode.File)
            if (context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn);
            }
            else
            {
                call = dyn;
            }

            call = Expression.Convert(call, returnType);

            if (sbParams.Count > 0)
            {
                // We have ref/out params.  Construct the complicated call;

                ParameterExpression   callValParam = Expression.Parameter(returnType, "__callVal");
                ParameterExpression[] allParams    = ClrExtensions.ArrayInsert <ParameterExpression>(callValParam, sbParams);

                call = Expression.Block(
                    returnType,
                    allParams,
                    Expression.Block(sbInits),
                    Expression.Assign(callValParam, call),
                    Expression.Block(sbTransfers),
                    callValParam);
            }

            return(call);
        }