Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/main/compiler/CompilerScope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ export class CompilerScope {
}

private emitNode(node: NodeView) {
this.emitComment(`${node.ref} ${node.nodeUid}`);
const sym = this.symbols.getNodeSym(node.nodeUid);
const nodeUid = node.nodeUid;
this.emitComment(`${node.ref} ${nodeUid}`);
const sym = this.symbols.getNodeSym(nodeUid);
this.code.block(`${this.asyncSym(node)}function ${sym}(params, ctx) {`, `}`, () => {
if (this.isNodeCached(node)) {
this.code.line(`let $c = ctx.cache.get("${node.nodeUid}");`);
Expand All @@ -73,17 +74,19 @@ export class CompilerScope {
this.emitNodeBodyIntrospect(node);
}
});
// Emit friendlier function names for stack trace introspection
this.code.line(`Object.defineProperty(${sym}, 'name', { value: ${JSON.stringify(nodeUid)} });`);
}

private emitNodeBodyIntrospect(node: NodeView) {
const resSym = '$r';
const nodeUid = node.nodeUid;
this.code.line(`let ${resSym};`);
this.code.line(`ctx.nodeUid = ${JSON.stringify(node.nodeUid)}`);
if (this.options.introspect) {
const nodeUid = node.nodeUid;
this.code.block('try {', '}', () => {
if (!node.supportsSubgraph()) {
// For subgraphs, pending check is done prior to calling the subgraph the first time.
// For subgraphs, pending check is done prior to calling the subgraph the first time
// (see getSubgraphExpr which calls checkPendingNode instead of doing it here)
this.code.line(`ctx.checkPendingNode(${JSON.stringify(nodeUid)});`);
}
this.code.line(`ctx.nodeEvaluated.emit({` +
Expand Down
9 changes: 6 additions & 3 deletions src/main/runtime/GraphEvalContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,20 @@ export class GraphEvalContext implements t.GraphEvalContext {

readonly lib = runtimeLib;

nodeUid = '';
pendingNodeUids: Set<string>;
// Introspection events delegate to root context.
nodeEvaluated: Event<t.NodeResult>;
scopeCaptured: Event<t.ScopeData>;
// Pending nodes are stored on root context and inherited by child contexts.
pendingNodeUids: Set<string>;
// Each context maintains its own cache. Subscopes have separate caches
// and do not delegate to parent contexts.
cache = new Map<string, any>();
// Locals are stored per-context. Lookups delegate up the hierarchy.
locals = new Map<string, any>();

scopeData: any = undefined;
// Scope data is maintained by each context separately.
// Compiler populates it via setScopeData when emitting nodes with subgraphs.
private scopeData: any = undefined;

constructor(
readonly parent: GraphEvalContext | null = null,
Expand Down
9 changes: 4 additions & 5 deletions src/main/types/ctx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@ import { Event } from 'nanoevent';
import { RuntimeLib } from './runtime-lib.js';
import { SchemaSpec } from './schema.js';

export interface Deferred {
resolve: () => unknown;
}

export interface GraphEvalContext {
readonly lib: RuntimeLib;

nodeUid: string;
cache: Map<string, any>;
locals: Map<string, any>;
nodeEvaluated: Event<NodeResult>;
Expand Down Expand Up @@ -40,6 +35,10 @@ export interface GraphEvalContext {
resolveDeferred(value: unknown): unknown;
}

export interface Deferred {
resolve: () => unknown;
}

export interface NodeResult {
nodeUid: string;
result?: any;
Expand Down