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); }
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); }
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)); } } }
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)); } }