Skip to content

Commit fc836e4

Browse files
authored
Rust style errors (#111)
* Store SourceLocation * Playground errors * Enhance error handling and formatting for runtime and control flow errors - Improve formatted runtime errors for missing tools and source underlines. - Fix segment-local `?.` traversal to ensure proper error handling. - Introduce metadata attachment for Bridge errors to preserve source context. - Update tests to validate new error formatting behavior for throw and panic fallbacks. * Compiler parity * Enhance error handling and source location tracking in code generation and execution * We are done * Perf docs * Cleanup
1 parent de20ece commit fc836e4

41 files changed

Lines changed: 2676 additions & 742 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@stackables/bridge": patch
3+
"@stackables/bridge-core": patch
4+
"@stackables/bridge-compiler": patch
5+
"@stackables/bridge-graphql": patch
6+
"@stackables/bridge-parser": patch
7+
---
8+
9+
Move Bridge source metadata onto BridgeDocument.
10+
11+
Parsed documents now retain their original source text automatically, and can
12+
optionally carry a filename from parse time. Runtime execution, compiler
13+
fallbacks, GraphQL execution, and playground formatting now read that metadata
14+
from the document instead of requiring callers to thread source and filename
15+
through execute options.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
"@stackables/bridge": patch
3+
"@stackables/bridge-core": patch
4+
---
5+
6+
Improve formatted runtime errors for missing tools and source underlines.
7+
8+
`No tool found for "..."` and missing registered tool-function errors now carry
9+
Bridge source locations when they originate from authored bridge wires, so
10+
formatted errors include the filename, line, and highlighted source span.
11+
Control-flow throw fallbacks now preserve their own source span, so
12+
`?? throw "..."` highlights only the throw clause instead of the whole wire.
13+
Caret underlines now render the full inclusive source span instead of stopping
14+
one character short.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@stackables/bridge": patch
3+
"@stackables/bridge-core": patch
4+
"@stackables/bridge-compiler": patch
5+
---
6+
7+
Fix segment-local `?.` traversal so later strict path segments still fail after a guarded null hop, and preserve source formatting for `panic` control-flow errors.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@stackables/bridge": patch
3+
"@stackables/bridge-core": patch
4+
"@stackables/bridge-compiler": patch
5+
"@stackables/bridge-parser": patch
6+
---
7+
8+
Improve runtime error source mapping for ternary conditions and strict path traversal.
9+
10+
Runtime and compiled execution now preserve clause-level source spans for ternary conditions and branches, so formatted errors can highlight only the failing condition or selected branch instead of the whole wire.
11+
Strict path traversal also now fails consistently on primitive property access in both runtime and AOT execution, keeping error messages and behavior aligned.

packages/bridge-compiler/performance.md

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ Tracks engine performance work: what was tried, what failed, and what's planned.
44

55
## Summary
66

7-
| # | Optimisation | Date | Result |
8-
| --- | --------------------- | ---- | ------ |
9-
| 1 | Future work goes here | | |
7+
| # | Optimisation | Date | Result |
8+
| --- | ------------------------------------ | ---------- | ------------------------------------------------ |
9+
| 1 | Strict-path parity via `__path` | March 2026 | ✅ Done (correctness first, measurable slowdown) |
10+
| 2 | Single-segment fast path via `__get` | March 2026 | ✅ Done (partial recovery on compiled hot paths) |
1011

1112
## Baseline (main, March 2026)
1213

@@ -41,4 +42,74 @@ This table is the current perf level. It is updated after a successful optimisat
4142

4243
## Optimisations
4344

44-
### 1. Future work goes here
45+
### 1. Strict-path parity via `__path`
46+
47+
**Date:** March 2026
48+
**Status:** ✅ Done
49+
50+
**Why:**
51+
52+
Runtime source-mapping work tightened strict path traversal semantics so
53+
primitive property access throws at the failing segment instead of silently
54+
flowing through as `undefined`. Compiled execution still had some strict paths
55+
emitted as raw bracket access, which caused AOT/runtime divergence in parity
56+
fuzzing.
57+
58+
**What changed:**
59+
60+
`appendPathExpr(...)` was switched to route compiled path traversal through the
61+
generated `__path(...)` helper so compiled execution matched runtime semantics.
62+
63+
**Result:**
64+
65+
Correctness and parity were restored, but this imposed a noticeable cost on the
66+
compiled hot path because even one-segment accesses paid the generic loop-based
67+
helper.
68+
69+
Observed branch-level compiled numbers before the follow-up optimisation:
70+
71+
| Benchmark | Baseline | With `__path` everywhere | Change |
72+
| -------------------------------------- | -------- | ------------------------ | ------ |
73+
| compiled: passthrough (no tools) | ~644K | ~561K | -13% |
74+
| compiled: simple chain (1 tool) | ~612K | ~536K | -12% |
75+
| compiled: flat array 1000 | ~27.9K | ~14.1K | -49% |
76+
| compiled: array + tool-per-element 100 | ~58.7K | ~45.2K | -23% |
77+
78+
### 2. Single-segment fast path via `__get`
79+
80+
**Date:** March 2026
81+
**Status:** ✅ Done
82+
83+
**Hypothesis:**
84+
85+
The vast majority of compiled property reads in the benchmark suite are short,
86+
especially one-segment accesses. Running every one of them through the generic
87+
`__path(base, path, safe, allowMissingBase)` loop was overpaying for the common
88+
case.
89+
90+
**What changed:**
91+
92+
- Added a generated `__get(base, segment, accessSafe, allowMissingBase)` helper
93+
for the one-segment case.
94+
- Kept the strict primitive-property failure semantics from `__path(...)`.
95+
- Left multi-segment accesses on `__path(...)` so correctness stays uniform.
96+
97+
**Result:**
98+
99+
This recovered a meaningful portion of the compiled regression while preserving
100+
the stricter source-mapping semantics.
101+
102+
| Benchmark | Before `__get` | After `__get` | Change |
103+
| -------------------------------------- | -------------- | ------------- | ------ |
104+
| compiled: passthrough (no tools) | ~561K | ~639K | +14% |
105+
| compiled: simple chain (1 tool) | ~536K | ~583K | +9% |
106+
| compiled: flat array 1000 | ~14.1K | ~15.7K | +11% |
107+
| compiled: nested array 20×10 | ~36.0K | ~39.1K | +9% |
108+
| compiled: array + tool-per-element 100 | ~45.2K | ~50.0K | +11% |
109+
110+
**What remains:**
111+
112+
Compiled performance is much closer to baseline now, but still below the March
113+
2026 table on some heavy array benchmarks. The obvious next step, if needed, is
114+
specialising short strict paths of length 2–3 rather than routing every
115+
multi-segment path through the generic loop helper.

0 commit comments

Comments
 (0)