Goal
Implement JSC__Exception__getStackTrace by retaining structured exception frames in zig-js and populating the pinned Home/Bun ZigStackTrace / ZigStackFrame ABI exactly.
Parent tracking: #134, #140, #163, #164.
Why this is a runtime slice
The current engine exposes formatted Error.prototype.stack text, while upstream reads Exception::stack() and calls populateStackTrace(..., OnlyPosition). Parsing formatted text would lose frame kind, async state, exact function/source ownership, JSC frame indexes, and zero-based positions. This issue therefore owns the structured representation rather than a compatibility stub.
Required implementation
- Add a precise-GC-safe structured frame vector captured at throw/exception creation across tree-walker and VM-trampoline execution.
- Preserve function name, source URL, zero-based line/column, line-start byte, code kind, async/constructor state, and stable frame ordering.
- Retain structured frames through rethrow, Promise rejection, module evaluation, sibling realms, and exception-cell publication.
- Implement the exact
ZigStackTraceandZigStackFrameextern layouts, capacities, truncation, caller-owned output, and BunString ownership rules. - Leave source-line collection to the separate
ZigException__collectSourceLinessurface while matching upstreamOnlyPositionbehavior here. - Cover empty/truncated traces, syntax/runtime errors, recursion, async frames, foreign VM rejection, pending-exception preservation, and precise collection.
- Promote both pinned inventories and update README/API/Home integration evidence.
Evidence gate
- Home and Bun private audits have zero unclassified declarations.
- Compiled Home consumer verifies byte offsets and populated frames.
- Targeted stack/error/module/Promise/GC batch passes with zero leaks.
- Full suite is batched with adjacent slices rather than rerun for every edit.
- Benchmark artifact remains current or is regenerated if measured code changes.