internal static object FunctionDelegate(TotemFunction fn, TotemArgs args) { fn.Code.LazyCompileFirstTarget(fn); return ((Func<TotemFunction, TotemArgs, object>)fn.Code.Target)(fn, args); }
/// <summary> /// Called the 1st time a function is invoked by our OriginalCallTarget* methodSetups /// over in PythonCallTargets. This computes the real delegate which needs to be /// created for the function. Usually this means starting off interpretering. It /// also involves adding the wrapper function for recursion enforcement. /// /// Because this can race against sys.settrace/setprofile we need to take our /// _ThreadIsEnumeratingAndAccountingLock to ensure no one is actively changing all /// of the live functions. /// </summary> internal void LazyCompileFirstTarget(TotemFunction function) { lock (_CodeCreateAndUpdateDelegateLock) { UpdateDelegate(function.Context.LanguageContext, true); } }
internal static TotemGenerator MakeGenerator(TotemFunction function, MutableTuple data, object generatorCode) { Func<MutableTuple, object> next = generatorCode as Func<MutableTuple, object>; if (next == null) next = ((LazyCode<Func<MutableTuple, object>>)generatorCode).EnsureDelegate(); return new TotemGenerator(function, next, data); }
internal static Task<object> MakeAsync(TotemFunction function, MutableTuple data, object generatorCode) { Func<MutableTuple, object> next = generatorCode as Func<MutableTuple, object>; if (next == null) next = ((LazyCode<Func<MutableTuple, object>>)generatorCode).EnsureDelegate(); var gen = new TotemAsyncStateMachine(function, next, data); return gen.Run(); }
/*!*/ public static CodeContext GetParentContextFromFunction(TotemFunction/*!*/ function) { return function.Context; }
/*!*/ public static MutableTuple GetClosureTupleFromFunction(TotemFunction/*!*/ function) { return GetClosureTupleFromContext(function.Context); }