cranelift: thread source span through jit_hd/jit_at/jit_tl#270
Merged
Conversation
Cranelift JIT runtime errors surfaced with `span: None` because the
JIT_RUNTIME_ERROR TLS cell only stored a bare `VmError`, so the
diagnostic renderer had nothing to underline and emitted empty
`labels: []`. Tree and VM carry the call-site span all the way to the
error; cranelift now matches.
Pack `Span { start, end }` into a u64 immediate (`start << 32 | end`) at
the cranelift call site and pass it as a trailing extern "C" arg. The
helpers store the `(VmError, Span)` pair on error; the JIT entry point
decodes the optional span (`0` round-trips to `None`) onto the surfaced
`VmRuntimeError`.
Scoped to jit_hd, jit_at, jit_tl for v1. The other erroring helpers
(jit_lst, jit_listget, jit_index, jit_jpth, jit_slc, ...) still record
spanless errors; harmonising them is parked. Each new erroring helper
costs +1 u64 arg and +1 iconst at the call site.
Regression test asserts byte-for-byte equality of the `(start, end)` fields in the diagnostic JSON `labels[0]` across VM and cranelift for every v1-scoped helper: jit_hd empty list/text, jit_tl empty list/text, jit_at out-of-range (positive list, negative list, text), and jit_at fractional index. A belt-and-braces sanity test asserts the cranelift case actually has a label (not just that cl and vm both have none). The example file demonstrates the positive path with `-- run` / `-- out` assertions so the cross-engine harness exercises the extended helper ABI: if a future call site forgot the new immediate, the JIT would crash on the arity mismatch before returning.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cranelift JIT runtime errors used to surface with
span: Nonebecause the JIT_RUNTIME_ERROR TLS cell only stored a bareVmError. The diagnostic renderer had nothing to underline so errors came out with emptylabels: [], breaking parity with tree and VM and forcing agents to re-read source code to locate the offending site. Manifesto cost: extra tokens on every cranelift failure.This PR plumbs the call-site
Spanthrough the JIT helper ABI by packing it as a u64 immediate (start << 32 | end) at the cranelift call site and threading it as a trailing extern "C" arg intojit_hd,jit_at,jit_tl. The helpers store the(VmError, Span)pair on error; the entry point decodes the optional span onto the surfacedVmRuntimeError. Zero is theSpan::UNKNOWNsentinel and round-trips toNone.Scoped to those three helpers for v1, as agreed. The other erroring helpers (
jit_lst,jit_listget,jit_index,jit_jpth,jit_slc, ...) keep their existing permissive-nil semantics; widening them is parked. Each newly-promoted helper now costs +1 u64 arg and +1 iconst at the call site, which is the dominant runtime cost of this approach.Repro
Before:
After (matches
--run-vm/--run-tree):What's in the diff
Commit 1,
cranelift: thread source span through jit_hd/jit_at/jit_tlsrc/vm/mod.rs: JIT_RUNTIME_ERROR now holdsOption<(VmError, Option<Span>)>. Newjit_set_runtime_error_with_span(err, span_bits); oldjit_set_runtime_error(err)is a 0-bits wrapper for helpers not yet plumbed.jit_take_runtime_errorreturns the tuple. Newdecode_span_bitshelper.jit_hd,jit_at,jit_tlextern "C" signatures gain a trailingspan_bits: u64and route every error path through the new helper. Inline unit-test calls updated.src/vm/jit_cranelift.rs: Newpack_span_bits(Span) -> i64.helpers.hd/helpers.at/helpers.tldeclared with the new arity. Compile sites for OP_HD / OP_AT / OP_TL packchunk.spans[ip]into an iconst and append it to the call args. JIT entry point attaches the decoded span toVmRuntimeError.Commit 2,
test + example: cross-engine span parity for cranelift errorstests/regression_cranelift_error_span.rs: 9 tests asserting cranelift(start, end)equals VM(start, end)across every v1 helper error path, plus a belt-and-braces "labels not empty" check.examples/cranelift-error-span.ilo: positive-path coverage of the extended helper ABI through the cross-engine harness, so a future call site that forgets the immediate crashes loudly on arity mismatch.Test plan
cargo build --release --features craneliftcargo test --release --features cranelift --test regression_cranelift_error_span(9 passed)cargo test --release --features craneliftfull suite (4700 passed, 0 failed)cargo fmt --checkcargo clippy --release --features cranelift --all-targets -- -D warningsFollow-ups
jit_lst,jit_listget,jit_index,jit_jpth,jit_slc, the arithmetic helpers, ...). Each is mechanically the same change: +1 u64 arg, +1 iconst, swap to_with_span. Parking until a real diagnostic complaint surfaces from one of those paths.VmRuntimeError::call_stackis always empty for cranelift; the helper TLS would need aVec<Frame>push at every JIT call site, which is more invasive.