public static string create_function(Context ctx, string args, string code) { // prepare function script var data = ScriptingContext.EnsureContext(ctx); var source = string.Format(_createFunctionTemplate, _lambdaFuncName, args, code); // create script that declares the lambda function var script = ctx.ScriptingProvider.CreateScript(new Context.ScriptOptions() { Context = ctx, EmitDebugInformation = Debugger.IsAttached, // CONSIDER Location = new Location(Path.Combine(ctx.RootPath, "runtime-created function"), 0, 0), // TODO: pass from calling script IsSubmission = true }, source); var methods = script.GetGlobalRoutineHandle(_lambdaFuncName).ToArray(); if (methods.Length == 0) { return(null); } var lambdaName = string.Format(_lambdaFormatString, ++data.LastLambdaIndex); var routine = RoutineInfo.CreateUserRoutine(lambdaName, methods); ctx.DeclareFunction(routine); return(lambdaName); }
Context.IScript Context.IScriptingProvider.CreateScript(Context.ScriptOptions options, string code) { var context = ScriptingContext.EnsureContext(options.Context); var script = TryGetOrCreateScript(code, options, context); Debug.Assert(script != null); // context.Submissions.Add(script); // return(script); }
Script CacheLookup(Context.ScriptOptions options, string code, ScriptingContext data) { if (_scripts.TryGetValue(code, out List <Script> candidates)) { foreach (var c in candidates) { // candidate requires that all its dependencies were loaded into context if (c.DependingSubmissions.All(data.Submissions.Contains)) { return(c); } } } return(null); }
Context.IScript Context.IScriptingProvider.CreateScript(Context.ScriptOptions options, string code) { var data = ScriptingContext.EnsureContext(options.Context); var script = CacheLookup(options, code, data); if (script == null) { // TODO: rwlock cache[code] script = Script.Create(options, code, _builder, data.Submissions); EnsureCache(code).Add(script); } Debug.Assert(script != null); // data.Submissions.Add(script); // return(script); }
Script CacheLookupNoLock(List <Script> candidates, Context.ScriptOptions options, string code, ScriptingContext context) { foreach (var c in candidates) { // candidate requires that all its dependencies were loaded into context // TODO: resolve the compiled code dependencies - referenced types and declared functions - instead of "DependingSubmissions" if (c.DependingSubmissions.All(context.Submissions.Contains)) { return(c); } } return(null); }
Script /*!*/ TryGetOrCreateScript(string code, Context.ScriptOptions options, ScriptingContext context) { var script = default(Script); _scriptsLock.EnterUpgradeableReadLock(); try { if (!_scripts.TryGetValue(code, out var subsmissions)) { _scriptsLock.EnterWriteLock(); try { if (!_scripts.TryGetValue(code, out subsmissions)) { _scripts[code] = subsmissions = new List <Script>(1); } } finally { _scriptsLock.ExitWriteLock(); } } if ((script = CacheLookupNoLock(subsmissions, options, code, context)) == null) { _scriptsLock.EnterWriteLock(); try { if ((script = CacheLookupNoLock(subsmissions, options, code, context)) == null) { subsmissions.Add((script = Script.Create(options, code, _builder, context.Submissions))); } } finally { _scriptsLock.ExitWriteLock(); } } } finally { _scriptsLock.ExitUpgradeableReadLock(); } return(script); }