示例#1
0
        protected static Expression CallNormal(CodeBlockExpression cbe, params Expression[] ppp)
        {
            bool       needscontext = NeedsContext(cbe); // true;
            int        pc           = ppp.Length;
            MethodInfo dc           = GetDirectCallable(needscontext, pc, cbe.Type);

            List <Variable> paruninit = new List <Variable>(cbe.Block.Parameters);

            for (int i = 0; i < ppp.Length; i++)
            {
                if (ppp[i].Type == typeof(Uninitialized))
                {
                    paruninit[i].SetUnInitialized();
                }
            }

            if (needscontext)
            {
                ppp = ArrayUtils.Insert <Expression>(Ast.CodeContext(), ppp);
            }

            var delegatetype = cbe.Type != typeof(Delegate) ? cbe.Type : CallTargets.GetTargetType(needscontext, pc, false);

            cbe = Ast.CodeBlockReference(cbe.Block, delegatetype);

            cbe.Block.Bind();

            var r = Ast.ComplexCallHelper(cbe, dc, ppp);

            if (SpanHint.IsValid)
            {
                r.SetLoc(SpanHint);
            }
            return(r);
        }
示例#2
0
        protected static Expression CallVarArgs(CodeBlockExpression cbe, Expression[] ppp)
        {
            bool needscontext = NeedsContext(cbe); //true;

            int pc = cbe.Block.ParameterCount;

            Expression[] tail = new Expression[ppp.Length - (pc - 1)];

            Array.Copy(ppp, ppp.Length - tail.Length, tail, 0, tail.Length);

            Expression[] nppp = new Expression[pc];

            Array.Copy(ppp, nppp, ppp.Length - tail.Length);

            if (tail.Length > 0)
            {
                nppp[nppp.Length - 1] = Ast.ComplexCallHelper(MakeList(tail, true), tail);
            }
            else
            {
                nppp[nppp.Length - 1] = Ast.Null();
            }

            ppp = nppp;

            MethodInfo dc = GetDirectCallable(needscontext, pc, cbe.Type);

            if (needscontext)
            {
                ppp = ArrayUtils.Insert <Expression>(Ast.CodeContext(), ppp);
            }

            cbe = Ast.CodeBlockReference(cbe.Block, CallTargets.GetTargetType(needscontext, pc, false));

            cbe.Block.Bind();

            var r = Ast.ComplexCallHelper(cbe, dc, ppp);

            if (SpanHint.IsValid)
            {
                r.SetLoc(SpanHint);
            }
            return(r);
        }
示例#3
0
        public static void AddBuiltins(CodeContext cc, Type builtinstype)
        {
            BuiltinMethod.binder  = binder;
            BuiltinMethod.context = cc;

            Dictionary <string, List <MethodBase> > cpsfree = new Dictionary <string, List <MethodBase> >();
            Dictionary <string, bool> foldable = new Dictionary <string, bool>();

            foreach (MethodInfo mi in builtinstype.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static))
            {
                foreach (BuiltinAttribute ba in mi.GetCustomAttributes(typeof(BuiltinAttribute), false))
                {
                    if (CheckParams(mi))
                    {
                        string            name = ba.Name ?? mi.Name.ToLower();
                        List <MethodBase> meths;

                        foldable[name] = ba.AllowConstantFold;

                        if (!cpsfree.TryGetValue(name, out meths))
                        {
                            cpsfree[name] = meths = new List <MethodBase>();
                        }
                        meths.Add(mi);
                    }
                    else
                    {
                        throw new NotSupportedException("all arguments must be of type object, method: " + mi);
                    }
                }
            }

            foreach (string mn in cpsfree.Keys)
            {
                object s           = SymbolTable.StringToObject(mn);
                var    targets     = cpsfree[mn].ToArray();
                var    paramcounts = new int[targets.Length];
                var    fold        = foldable[mn];

                if (AllIsSimple(targets, paramcounts))
                {
                    Callable c = null;
                    if (targets.Length == 1)
                    {
                        var dt = CallTargets.GetTargetType(false, paramcounts[0], false);
                        var d  = Delegate.CreateDelegate(dt, targets[0] as MethodInfo);
                        c = Closure.Create(d, paramcounts[0]);
                    }
                    else
                    {
                        var d = new Delegate[targets.Length];

                        for (int i = 0; i < d.Length; i++)
                        {
                            var dt = CallTargets.GetTargetType(false, paramcounts[i], false);
                            d[i] = Delegate.CreateDelegate(dt, targets[i] as MethodInfo);
                        }

                        c = Closure.CreateCase(d, paramcounts);
                    }
                    c.AllowConstantFold = fold;
                    cc.Scope.SetName((SymbolId)s, c);
                }
                else
                {
                    cc.Scope.SetName((SymbolId)s, new BuiltinMethod(mn, targets, fold));
                }
            }
        }
示例#4
0
        public override object Call(object[] args)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args cannot be null");
            }

            int nargs = args.Length;

            Callable c;

            if (cache.TryGetValue(-1, out c) ||
                cache.TryGetValue(nargs, out c))
            {
                return(c.Call(args));
            }

            if (!baked)
            {
                try
                {
                    if (methods.Length == 1)
                    {
                        // make c fast
                        MethodBase mb = methods[0];

                        bool needContext = false;

#warning Remove when Mono fixed: https:                         //bugzilla.novell.com/show_bug.cgi?id=655439
                        Type dt = (nargs > 8 || IsParams(mb)) ? // for mono
                                  typeof(CallTargetN) : CallTargets.GetTargetType(needContext, nargs, false);
                        Delegate d = Delegate.CreateDelegate(dt, mb as MethodInfo, false);
                        if (d == null)
                        {
                            d = Delegate.CreateDelegate(typeof(CallTargetN), needContext ? context : null, mb as MethodInfo, false);
                        }

                        if (d != null)
                        {
                            if (dt == typeof(CallTargetN))
                            {
                                cache[-1] = c = Closure.Create(d);
                            }
                            else
                            {
                                cache[nargs] = c = Closure.Create(d);
                            }
                        }
                    }
                    else
                    {
                        Type[] targs = Array.ConvertAll <object, Type>(args, delegate(object input)
                        {
                            if (input == null)
                            {
                                return(typeof(object));
                            }
                            else
                            {
                                return(input.GetType());
                            }
                        });

                        MethodCandidate mc = meth.MakeBindingTarget(CallType.None, targs);
                        if (mc != null)
                        {
                            MethodBase mb = mc.Target.Method;

                            bool needContext = NeedContext(mb);     // TODO: check if can remove

#warning Remove when Mono fixed: https:                             //bugzilla.novell.com/show_bug.cgi?id=655439
                            Type dt = (nargs > 8 || IsParams(mb)) ? // for mono
                                      typeof(CallTargetN) : CallTargets.GetTargetType(needContext, nargs, false);
                            Delegate d = Delegate.CreateDelegate(dt, mb as MethodInfo, false);
                            if (d == null)
                            {
                                d = Delegate.CreateDelegate(typeof(CallTargetN), needContext ? context : null, mb as MethodInfo, false);
                            }

                            if (d != null)
                            {
                                cache[nargs] = c = Closure.Create(d);
                            }
                        }
                    }
                }
                catch
                {
                    ;
                }

                if (c != null)
                {
                    return(c.Call(args));
                }
            }
            // fallback
            baked = true;

            try
            {
                // DO NOT WANT!!!!
                return(meth.CallReflected(context, CallType.None, args));
            }
            catch (ArgumentTypeException ex)
            {
                return(Closure.AssertionViolation(meth.ToString(), ex.Message, args));
            }
        }