private bool TryCallWorker(object[] args, out object ret) { // check to see if we can lazily optimize this function, // and if optimize it and call the optimized version. if ((FunctionType & FunctionType.OptimizeChecked) == 0) { if (TryOptimizedCall(args, out ret)) { return(true); } FunctionType |= FunctionType.OptimizeChecked; } PerfTrack.NoteEvent(PerfTrack.Categories.Methods, this); object instance; ParamTree pt = GetParamTreeAndInstance(args.Length, out instance); if (pt != null) { DispatchWalker dw = new DispatchWalker(pt, instance, args); MethodBinding mb; if (dw.TryGetBinding(out mb)) { ret = Invoke(mb); return(true); } } ret = null; return(false); }
/// <summary> /// Gets the appropriate param tree and the instance we should use for this param tree. /// /// We need to hand back the instance here as well because we could end up w/ a mixed-dispatch /// case where we have a static & instance methods colliding under the same name but w/ a different /// number of arguments. In that case we're willing to drop the instance & bind to a static method, but /// only if there's no other override to try. /// </summary> private ParamTree GetParamTreeAndInstance(int argCnt, out object instance) { instance = HasInstance ? Instance: null; if (paramTrees == null) { paramTrees = ParamTree.BuildAllTrees(MethodTracker.GetTrackerArray(Targets), FunctionType); } ParamTree possibility = null; for (int i = 0; i < paramTrees.Length; i++) { if (paramTrees[i].ArgumentCount == argCnt) { if (instance == null) { return(paramTrees[i]); } if ((paramTrees[i].FunctionType & FunctionType.FunctionMethodMask) == (FunctionType.Method | FunctionType.Function)) { // if we have no other matches, go w/ this one... (dropping the instance) possibility = paramTrees[i]; } } else if (instance != null && paramTrees[i].ArgumentCount == argCnt + 1) { return(paramTrees[i]); } } if (possibility != null) { instance = null; return(possibility); } if ((paramTrees[paramTrees.Length - 1].FunctionType & FunctionType.Params) != 0) { return(paramTrees[paramTrees.Length - 1]); } return(null); }
public DispatchWalker(ParamTree paramTree, object instance, object[] arguments) { args = arguments; pt = paramTree; inst = instance; }