Skip to content

Lift srt 3 / rsrt 2 / rsrt 3 closure-bind to native VM dispatch (PR B of ILO-45)#699

Merged
danieljohnmorris merged 3 commits into
nextfrom
feature/lift-srt-rsrt
May 22, 2026
Merged

Lift srt 3 / rsrt 2 / rsrt 3 closure-bind to native VM dispatch (PR B of ILO-45)#699
danieljohnmorris merged 3 commits into
nextfrom
feature/lift-srt-rsrt

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

PR B of ILO-45 — second slice of the tree-walker eval-loop deletion. Adds the descending-sort finalizer opcode and a ctx-threading variant of the keyed-finalize helper, lifting three more HOFs to native VM + Cranelift dispatch.

Builds on PR A (#619) which lifted map 3 / flt 3 / fld 4. After this PR, the only FnRef-taking entries left on the tree-bridge are ct 2 / ct 3 (PR C). Then the non-HOF bridge entries get audited for transitive eval_body reachability (PR D), and only then can the eval loop actually be deleted (PR E).

What's in the diff

Single commit, four files:

  • src/vm/mod.rs
    • New OP_RSRT_BY_KEY = 191 opcode with full ABC contract docstring
    • VM dispatch arm at the existing srt/grp/uniqby finalizer cluster
    • jit_rsrt_by_key extern helper, thin wrapper over rsrt_by_key_finalize
    • Refactor: srt_by_key_finalize and new rsrt_by_key_finalize share srt_by_key_finalize_inner(_, _, descending: bool). The descending path uses Ordering::reverseEqual.reverse() == Equal keeps stable-sort identity on mixed-type keys, matching the tree-walker
    • Refactor: emit_hof_keyed_finalize now delegates to _inner with ctx: None; new emit_hof_keyed_finalize_ctx passes Some(ctx_arg). Threads an extra register through OP_CALL_DYN with argc=2 for the closure-bind path. Non-ctx callers (srt 2 / grp 2 / uniqby 2) emit byte-identical bytecode
    • Three new compiler arms: (Builtin::Rsrt, 2), (Builtin::Srt, 3), (Builtin::Rsrt, 3)
    • Three removals from is_tree_bridge_eligible
  • src/vm/compile_cranelift.rs and src/vm/jit_cranelift.rs
    • New rsrt_by_key: FuncId field in the helpers struct
    • declare_helper(module, "jit_rsrt_by_key", 3, 1) registration
    • Symbol registration in the JIT path (("jit_rsrt_by_key", jit_rsrt_by_key as *const u8))
    • OP_RSRT_BY_KEY dispatch arm mirroring the OP_SRT_BY_KEY arm
    • OP_RSRT_BY_KEY added to the "known opcodes" guard list
  • tests/aot-baselines/obj-baselines.tsv
    • Regenerated. Every hash changed — expected because adding rsrt_by_key to the helpers struct shifts symbol layout for every compiled program. Partial drift would have been the red flag

Test plan

  • cargo test --release --features cranelift — full suite green, no regressions
  • AOT byte-identity test passes against the regenerated baseline
  • Smoke test: descending sort + 3-arg closure-bind variants give identical output across default / --vm / --jit
  • examples/rsrt-by-key.@ already exercises rsrt fn xs and rsrt fn ctx xs — they now go through native dispatch instead of the bridge; output unchanged
  • superpowers:code-reviewer subagent run on the diff — no blockers

Follow-ups

  • PR C: ct 2 / ct 3 — needs an OP_COUNT_BY_PRED finalizer or inline-counter VM loop
  • PR D: audit non-HOF bridge entries (regex / fmt / fs / crypto / calendar / etc) for transitive eval_body reachability; lift any that need it
  • PR E: delete eval_body / eval_stmt / eval_expr / Env / trampoline / ACTIVE_AST_PROGRAM (headline LoC win)

PR B of ILO-45. Adds the descending-sort finalizer opcode and a
ctx-threading variant of the keyed-finalize helper, lifting three more
HOFs off the tree-bridge:

- rsrt fn xs           (2-arg, descending sort by key)
- srt  fn ctx xs       (3-arg, closure-bind ascending)
- rsrt fn ctx xs       (3-arg, closure-bind descending)

New opcode OP_RSRT_BY_KEY=191, dispatch arm in the VM, jit_rsrt_by_key
extern helper, and Cranelift FuncId + dispatch arm in both compile and
JIT paths so AOT and JIT both inherit the lift. The two finalizer
shapes (asc/desc) share srt_by_key_finalize_inner via a descending bool,
so the comparator-reversal logic lives in one place.

emit_hof_keyed_finalize gains an emit_hof_keyed_finalize_ctx sibling
that threads an extra ctx register through OP_CALL_DYN with argc=2,
mirroring PR A's map/flt/fld ctx arms. The non-ctx path is unchanged.

Three more entries removed from is_tree_bridge_eligible. What remains
on the bridge for FnRef-taking builtins: ct 2 / ct 3 (PR C). After that,
non-HOF bridge entries get audited for transitive eval_body reachability
(PR D) before the eval loop itself can be deleted (PR E).

AOT object baselines regenerated for all 136 entries since the new
helper FuncId shifts symbol layout in every compiled program.

Test plan: cargo test --release --features cranelift green. New
opcode exercised via examples/rsrt-by-key.@ (worst-by-abs / longest-
words / top-scaled — already in repo, now go through native dispatch
rather than the bridge). Smoke test across default / --vm / --jit gives
identical output for ascending and descending closure-bind sorts.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 82.60870% with 20 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/vm/compile_cranelift.rs 16.66% 10 Missing ⚠️
src/vm/mod.rs 89.01% 10 Missing ⚠️

📢 Thoughts on this report? Let us know!

Daniel Morris and others added 2 commits May 22, 2026 08:01
After PR B lifted rsrt 3-arg from the tree-bridge to native VM +
Cranelift dispatch, the mget misuse now raises directly with its
native code (ILO-R004 "key must be text or finite number") rather
than being remapped through the bridge to the generic ILO-R009.

The test's intent was "callback errors must surface on every engine"
- still true. Same shape as the existing flatmap test, which already
asserts the shared substring rather than a specific code.
@danieljohnmorris danieljohnmorris merged commit 428c260 into next May 22, 2026
4 checks passed
@danieljohnmorris danieljohnmorris deleted the feature/lift-srt-rsrt branch May 22, 2026 07:32
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