Async error handler: dispatch Eval_error to VM handler_stack in resume_vm

When an error occurs during resumed VM execution (after perform/hs-wait),
resume_vm now checks the VM's handler_stack. If a handler exists (from a
compiled guard form's OP_PUSH_HANDLER), it unwinds frames and jumps to
the catch block — exactly like OP_RAISE. This enables try/catch across
async perform/resume boundaries.

The guard form compiles to OP_PUSH_HANDLER which lives on the vm struct
and survives across setTimeout-based async resume. Previously, errors
during resume escaped to the JS console as unhandled exceptions.

Also restored guard in the test runner (was cek-try which doesn't survive
async) and restored error-throwing assertions in run-action.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 22:54:37 +00:00
parent ac193e8839
commit 0410812420
7 changed files with 75 additions and 39 deletions

View File

@@ -852,10 +852,26 @@ let resume_vm vm result =
| None ->
push vm result);
(try run vm
with VmSuspended _ as e ->
(* Re-suspension during resume: the VM hit another perform.
The new VmSuspended carries the current VM state. *)
raise e);
with
| VmSuspended _ as e ->
(* Re-suspension during resume: the VM hit another perform. *)
raise e
| Eval_error msg ->
(* Error during resumed execution. If the VM has a handler on its
handler_stack, dispatch to it (same as OP_RAISE). This enables
try/catch across async perform/resume boundaries — the handler
was pushed before the perform and survives on the vm struct. *)
(match vm.handler_stack with
| entry :: rest ->
vm.handler_stack <- rest;
while List.length vm.frames > entry.h_frame_depth do
match vm.frames with _ :: fs -> vm.frames <- fs | [] -> ()
done;
vm.sp <- entry.h_sp;
entry.h_frame.ip <- entry.h_catch_ip;
push vm (String msg);
run vm
| [] -> raise (Eval_error msg)));
(* Clear reuse_stack — any entries here are stale from the original
suspension and don't apply to the current state. The VM just
completed its execution successfully. *)