コード例 #1
0
ファイル: AFnImplGenerator.cs プロジェクト: ryrency/Misc
        static void DefineDelegateFieldAndOverride(TypeBuilder tb, int numArgs)
        {
            Type         fieldType = FuncTypeHelpers.GetFFuncType(numArgs);
            string       fieldName = "_fn" + numArgs;
            FieldBuilder fb        = tb.DefineField(fieldName, fieldType, FieldAttributes.Public);

            MethodBuilder mb  = tb.DefineMethod("invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(object), CreateObjectTypeArray(numArgs));
            ILGenerator   gen = mb.GetILGenerator();

            Label eqLabel = gen.DefineLabel();

            //  this._fni == null ?
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, fb);
            gen.Emit(OpCodes.Ldnull);
            gen.Emit(OpCodes.Beq, eqLabel);
            //Not equal to Null, invoke it.
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Ldfld, fb);
            for (int i = 0; i < numArgs; i++)
            {
                gen.Emit(OpCodes.Ldarg, i + 1);
            }
            gen.Emit(OpCodes.Call, fb.FieldType.GetMethod("Invoke"));

            gen.Emit(OpCodes.Ret);

            gen.MarkLabel(eqLabel);
            // Equal to Null: throw WrongArityException
            gen.Emit(OpCodes.Ldarg_0);
            gen.Emit(OpCodes.Call, Method_AFn_WrongArityException);
            gen.Emit(OpCodes.Throw);
        }
コード例 #2
0
        internal LambdaExpression GenerateImmediateLambda(RHC rhc, ObjExpr objx, GenContext context)
        {
            List <ParameterExpression> parmExprs = new List <ParameterExpression>(_argLocals.count());

            if (_thisBinding != null)
            {
                _thisBinding.ParamExpression = objx.ThisParam;
            }

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

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

                for (int i = 0; i < _argLocals.count(); i++)
                {
                    LocalBinding b = (LocalBinding)_argLocals.nth(i);

                    ParameterExpression pexpr = Expression.Parameter(typeof(object), b.Name);
                    b.ParamExpression = pexpr;
                    parmExprs.Add(pexpr);
                }

                List <Expression> bodyExprs = new List <Expression>();
                //bodyExprs.AddRange(typedParmInitExprs);
                bodyExprs.Add(Expression.Label(loopLabel));
                bodyExprs.Add(Compiler.MaybeBox(_body.GenCode(rhc, objx, context)));


                Expression block;
                //if (typedParmExprs.Count > 0)
                //    block = Expression.Block(typedParmExprs, bodyExprs);
                //else
                block = Expression.Block(bodyExprs);

                return(Expression.Lambda(
                           FuncTypeHelpers.GetFFuncType(parmExprs.Count),
                           block,
                           Objx.ThisName,
                           parmExprs));
            }
            finally
            {
                Var.popThreadBindings();
            }
        }
コード例 #3
0
        internal LambdaExpression GenerateImmediateLambda(GenContext context)
        {
            List <ParameterExpression> parmExprs          = new List <ParameterExpression>(_argLocals.count());
            List <ParameterExpression> typedParmExprs     = new List <ParameterExpression>();
            List <Expression>          typedParmInitExprs = new List <Expression>();

            //FnExpr fn = context.FnExpr;
            //ParameterExpression thisParm = Expression.Parameter(fn.BaseType, "this");
            //_thisBinding.ParamExpression = thisParm;
            //fn.ThisParam = thisParm;
            FnExpr fn = context.FnExpr;

            _thisBinding.ParamExpression = fn.ThisParam;

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

                Var.pushThreadBindings(RT.map(Compiler.LOOP_LABEL, loopLabel, Compiler.METHODS, this));

                for (int i = 0; i < _argLocals.count(); i++)
                {
                    LocalBinding b = (LocalBinding)_argLocals.nth(i);

                    ParameterExpression pexpr = Expression.Parameter(typeof(object), b.Name);  //asdf-tag
                    b.ParamExpression = pexpr;
                    parmExprs.Add(pexpr);

                    if (b.Tag != null)
                    {
                        // we have a type hint
                        // The ParameterExpression above will be the parameter to the function.
                        // We need to generate another local parameter that is typed.
                        // This will be the parameter tied to the LocalBinding so that the typing information is seen in the body.
                        Type t = Compiler.TagToType(b.Tag);
                        ParameterExpression p2 = Expression.Parameter(t, b.Name);
                        b.ParamExpression = p2;
                        typedParmExprs.Add(p2);
                        typedParmInitExprs.Add(Expression.Assign(p2, Expression.Convert(pexpr, t)));
                    }
                }


                // TODO:  Eventually, type this param to ISeq.
                // This will require some reworking with signatures in various places around here.
                //if (fn.IsVariadic)
                //    parmExprs.Add(Expression.Parameter(typeof(object), "____REST"));

                // If we have any typed parameters, we need to add an extra block to do the initialization.

                List <Expression> bodyExprs = new List <Expression>();
                bodyExprs.AddRange(typedParmInitExprs);
                bodyExprs.Add(Expression.Label(loopLabel));
                bodyExprs.Add(Compiler.MaybeBox(_body.GenDlr(context)));


                Expression block;
                if (typedParmExprs.Count > 0)
                {
                    block = Expression.Block(typedParmExprs, bodyExprs);
                }
                else
                {
                    block = Expression.Block(bodyExprs);
                }

                return(Expression.Lambda(
                           FuncTypeHelpers.GetFFuncType(parmExprs.Count),
                           block,
                           _fn.ThisName,
                           parmExprs));
            }
            finally
            {
                Var.popThreadBindings();
            }
        }