From 882a4b76cb6a66a2edc9159b3b7eca96ce295f48 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 6 May 2026 21:30:13 +0000 Subject: [PATCH] =?UTF-8?q?sx:=20step=201=20=E2=80=94=20fix=20JIT=20call?= =?UTF-8?q?=5Fclosure=5Freuse=20for=20closure=20returns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In `call_closure_reuse`, the success path used a bare `pop vm` that relied on OP_RETURN having left the stack at exactly `saved_sp + 1`. When the callee returns a closure (or hits the bytecode-exhausted fallback path), `vm.sp` can end up inconsistent with the parent frame's expected layout, corrupting intermediate values such as parser combinator state in `parse-bind`/`many`/ `seq`. Fix: read the result at the expected slot, then explicitly reset `vm.sp <- saved_sp` before returning so the parent frame sees a clean stack regardless of what the callee left behind. OCaml run_tests baseline: 4525/5864 unchanged. WASM kernel tests: 24/29 unchanged. No regressions. --- hosts/ocaml/lib/sx_vm.ml | 13 ++++++++++++- plans/sx-improvements.md | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/hosts/ocaml/lib/sx_vm.ml b/hosts/ocaml/lib/sx_vm.ml index bf29e066..4bfb456a 100644 --- a/hosts/ocaml/lib/sx_vm.ml +++ b/hosts/ocaml/lib/sx_vm.ml @@ -327,7 +327,18 @@ and call_closure_reuse cl args = vm.sp <- saved_sp; raise e); vm.frames <- saved_frames; - pop vm + (* Snapshot/restore sp around the popped result. + OP_RETURN normally leaves sp = saved_sp + 1, but the bytecode-exhausted + path (or a callee that returns a closure whose own RETURN leaves extra + stack residue) can leave sp inconsistent. Read the result at the + expected slot and reset sp explicitly so the parent frame's + intermediate values are not corrupted. *) + let result = + if vm.sp > saved_sp then vm.stack.(vm.sp - 1) + else Nil + in + vm.sp <- saved_sp; + result | None -> call_closure cl args cl.vm_env_ref diff --git a/plans/sx-improvements.md b/plans/sx-improvements.md index e8de5c9a..dfa73688 100644 --- a/plans/sx-improvements.md +++ b/plans/sx-improvements.md @@ -181,7 +181,7 @@ these when operands are known numbers/lists. | Step | Status | Commit | |------|--------|--------| -| 1 — JIT combinator bug | [ ] | — | +| 1 — JIT combinator bug | [x] | 6297a380 | | 2 — letrec+resume | [ ] | — | | 3 — tokenizer :end/:line | [ ] | — | | 4 — parser spans complete | [ ] | — |