Skip to content

fix(errors): preserve Node-compatible stack source positions - #114

Merged
steipete merged 1 commit into
mainfrom
claude/w146-stack-positions
Oct 5, 2026
Merged

steipete merged 1 commit into
mainfrom
claude/w146-stack-positions

Conversation

@steipete

@steipete steipete commented Oct 4, 2026 •

Copy link
Copy Markdown

Connect Bun's stack reporting and transpiler to the syntax positions in the published OpenClaw WebKit engine integrated by #124. Calls, property reads, constructors, and async continuations use the engine's selected locations; returning built-in error constructors retain their frames and new syntax. Runtime transpilation preserves callee parentheses and computed access and maps call, bracket, and template delimiters back to the original source.

Bump the runtime transpiler cache format to 38 so cached output from earlier versions cannot retain the old positions. Keep existing file-name and eval-origin formatting. Update the ErrorEvent inspection caret to the new token confirmed by Node. This continues the source-position work in oven-sh#35179, oven-sh#37396, and oven-sh#41580; thanks @robobun.

Native macOS arm64 validation on candidate 8b774531c290dac5eeb35cd62b7bce517676a2e5:

  • Stack, util, and source-map suites: 343 passed.
  • Minifier suite: 68 passed. Inspection suite: 95 passed, one existing skip.
  • Runtime cache replacement and marked cached-output replay pass at version 38, preserving all 56 coordinate assertions.
  • Rust checks: all 12 targets pass, with zero skips. Independent scoped P2 review and source lint pass.

Unmodified OpenClaw b02eab15853b6471d1869f2a2cb0f135b7aefe4d consumers pass on the candidate and Node 24.21.0: SDK alias 67 passed with one existing skip; ordered loader pair 8 passed, with execution order, shared worker and canonical test policy verified.

The plain Darwin selection has zero new regressions on the local macOS 27 host: candidate 20/21 rows versus baseline 19/21. The candidate's only failed file contains two socket-cancellation assertions reproduced unchanged with the pre-stack binary in isolation and the full selection. A baseline-only HTTP failure did not recur on the candidate. The fork-pinned Node 26.3.0 harness is used; the OpenClaw consumer controls use Node 24.21.0. No assertions or selections were weakened. Both exact-head native CI lanes pass in run 37298205240.

The cache oracle improves from 2/56 matching positions on the baseline to 56/56 on both candidate runs. The committed production WebKit manifest remains unchanged.

Formatting, source lints, JavaScript typechecking, Clippy, Miri and cargo tests pass. The Rust workflow succeeds; its explicitly advisory mordant job reports the unchanged preexisting bare-bool-argument style finding in src/resolver/package_json.rs, with no suppression or baseline change in this PR.

steipete added a commit to openclaw/WebKit that referenced this pull request Oct 4, 2026
Make JSC stack positions select the same syntax tokens as Node 24: call and constructor starts, property reads, and async `await` continuations. Keep those positions separate from exception-expression divots and debugger line tables. Both captured `StackFrame` and live `StackVisitor` readers use the metadata; executable line overrides and release-private builtin position policy are preserved.

The two sparse vectors are owned by each unlinked code block, remapped through bytecode rewriting/optimization, and decoded into owned storage on both cache paths. The cache revision advances with the metadata. Property reads and calls retain distinct tokens, so `(null.x)()` can fail at `x` before reaching the call.

The paired Bun adapter in [openclaw/bun#114](openclaw/bun#114) also preserves error constructors and runtime call syntax. Rewriting `new Error()` into `Error()` moved the reported column and made a returning arrow eligible for JSC proper-tail-call elision. Preserving `new` restores the frame without disabling tail calls. Callee parentheses, computed access, and opening delimiter mappings are required for the broader normal-transpile corpus; TypeScript generic/non-null suffixes and cache invalidation are covered.

This continues the source-position work in [oven-sh/bun#35179](oven-sh/bun#35179), [WebKit#37396](oven-sh/bun#37396), and [WebKit#41580](oven-sh/bun#41580) by @robobun.

Native Linux qualification on one c7a.24xlarge host, with the unchanged W113 lane/Docker/ICU recipe:

- 1,509,853 FFI checks; 121 JSC stress configurations; interpreter/JIT/bytecode-optimizer/eager-FTL modes; owned and persistent cold/warm caches. Each cache path creates three files totaling 33,024 bytes.
- Raw JSC positions improve from 13/30 to 30/30 in the call corpus and from 4/28 to 28/28 in the added cases. The live visitor matches Node at 1:22, 2:21, 3:1. Async continuation control passes.
- Paired Bun: 47/47 fork-selection results with zero regressions, 343 CallSite/util/source-map tests, and 68 minifier tests. Normal transpilation matches all 30 call shapes, all 28 added cases on both stack surfaces, and 14 TypeScript/generic/non-null/astral cases. The JavaScript/TypeScript module corpus and 58 raw-eval rows match as well.
- Runtime cache replacement and warm replay match all 56 added observations. Existing custom-stack generated-versus-mapped and filename/eval-origin policies are preserved.
- OpenClaw loader pair 8/8, SDK under its existing native-loader policy 67 pass/1 skip, Slack ordered shared-worker sequence 26/26, and real Proxyline probe pass. The original shared SDK policy retains its same two baseline tsconfig resolver failures.
- ABBA, eight samples per arm: exception creation/formatting +7.6%; fresh 350-module startup 0.998× baseline. The exception overhead is an explicit tradeoff.
- Final complete engine and Bun branch reviews are scoped-clean through P2. Exact-head [CI run 37240058657](https://github.com/openclaw/WebKit/actions/runs/37240058657) is green at `6e69d757023aa75398a670f487f90fe2a57e2b99`.

Qualification caught and corrected a namespace-only result-checker assumption, repeated C++ default arguments in unity builds, private-builtin position leakage, missing transpiler delimiter metadata, TypeScript non-null suffix tracking, and the omitted live-stack reader. Exact position goldens were checked against Node; the original astral inline-snapshot assertion remains intact and passes.

The Bun draft remains stacked on manifest commit `cf636c2f14914b3ba4b319874312d654cc5ea064` and also needs the namespace adapter from Bun oven-sh#106. Native baseline and candidate both include that adapter because current engine main requires its API. This PR does not publish artifacts or change the artifact recipe; batch publication stays with the coordinator.
@steipete
steipete changed the base branch from claude/w146-manifest-base to main October 5, 2026 10:41
@steipete
steipete force-pushed the claude/w146-stack-positions branch from 57ec08b to 8b77453 Compare October 5, 2026 10:41
@steipete
steipete marked this pull request as ready for review October 5, 2026 10:50
@steipete
steipete merged commit ea0d868 into main Oct 5, 2026
10 of 11 checks passed
@steipete
steipete deleted the claude/w146-stack-positions branch October 5, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant