MCPcopy Create free account
hub / github.com/cortex-js/compute-engine / printStack

Function printStack

src/compute-engine/engine-scope.ts:82–143  ·  view source on GitHub ↗
(
  ce: IComputeEngine,
  options?: { details?: boolean; maxDepth?: number }
)

Source from the content-addressed store, hash-verified

80 * A no-op if the context is not on the stack (already removed).
81 */
82export function removeEvalContext(
83 ce: IComputeEngine,
84 context: EvalContext
85): void {
86 const index = ce._evalContextStack.lastIndexOf(context);
87 if (index < 0) return;
88 ce._evalContextStack.splice(index, 1);
89 discardEvalContext(ce, context);
90}
91
92function discardEvalContext(
93 ce: IComputeEngine,
94 context: EvalContext | undefined
95): void {
96 // A checkpoint standing on this frame has no world left to restore once
97 // the frame's bindings are disposed below — retire it, folding its journal
98 // window downward so older checkpoints still unwind this scope's writes
99 // (`checkpoint.ts`). Gated on the stack so the no-checkpoint path pays one
100 // length read.
101 if (context !== undefined && ce._checkpointStack.length > 0)
102 ce._invalidateCheckpointsOnFrameDiscard(context);
103 // Definitions owned by a scope may subscribe to engine-wide lifecycle
104 // events. Release those subscriptions as soon as the scope is discarded,
105 // rather than retaining otherwise-dead local constants for the lifetime of
106 // the engine. Disposal is intentionally idempotent.
107 for (const binding of context?.lexicalScope.bindings.values() ?? []) {
108 if (isValueDef(binding)) {
109 // Debug invariant (§3 of the binder-mechanism design): stamp BEFORE
110 // disposing, so a later use of this binding reports where its scope died.
111 // A DORMANT pop is exempt: `canonicalizeBinder` pops a scope the
112 // canonical expression keeps and pushes again on every evaluation, so
113 // that pop is not the scope's death and a tombstone there would report
114 // every bound variable of every canonicalized binder.
115 if (ce._debugBindings && !isDormantPop())
116 tombstoneBinding(binding.value, context?.name ?? '<unnamed>');
117 binding.value.dispose();
118 }
119 }
120
121 // Popping an eval context reverts the active assumptions and local
122 // declarations to the enclosing context. Per-expression caches keyed on
123 // `ce._anyVersion` (e.g. `BoxedFunction.sgn`/`.type`) would otherwise keep
124 // returning values computed under the popped scope's assumptions — a stale
125 // read on any expression held across the scope. `assume()`/`forget()`
126 // advance the axis on the way in, but the revert on the way out is silent,
127 // so this event covers it. (A matching event on push is not needed:
128 // `pushEvalContext` copies the current assumptions unchanged, and any
129 // assumption added inside the scope goes through `assume()`.) The
130 // `assumptionsDirty` payload carries the M+E half: `_semanticVersion` (the
131 // key of the `Comprehension` element memo) advances ONLY when this
132 // context's assumptions were modified — a clean pop leaves it untouched so
133 // mutation-keyed caches survive unrelated scoped evaluations (Tycho
134 // item 38).
135 //
136 // The `clean` payload carries the `any` half of the same argument: when
137 // NOTHING advanced any of the three axes while this context was on the
138 // stack (every install of a local binding or value goes through an event
139 // that advances at least one — `declare` and `value-write` including

Callers

nothing calls this directly

Calls 3

defToStringFunction · 0.85
mapMethod · 0.65
entriesMethod · 0.65

Tested by

no test coverage detected