diff --git a/hosts/ocaml/lib/sx_vm.ml b/hosts/ocaml/lib/sx_vm.ml index c10e1c14..bda0b056 100644 --- a/hosts/ocaml/lib/sx_vm.ml +++ b/hosts/ocaml/lib/sx_vm.ml @@ -952,7 +952,14 @@ let () = _vm_suspension_to_dict := (fun exn -> Hashtbl.replace d "__vm_suspended" (Bool true); Hashtbl.replace d "request" request; Hashtbl.replace d "resume" (NativeFn ("vm-resume", fun args -> - match args with [result] -> resume_vm vm result | _ -> Nil)); + match args with + | [result] -> + (try resume_vm vm result + with exn2 -> + match !_vm_suspension_to_dict exn2 with + | Some marker -> marker + | None -> raise exn2) + | _ -> Nil)); Some (Dict d) | _ -> None) let () = _cek_eval_lambda_ref := (fun f args -> diff --git a/tests/playwright/sx-inspect.js b/tests/playwright/sx-inspect.js index 2159b291..ea5c0866 100644 --- a/tests/playwright/sx-inspect.js +++ b/tests/playwright/sx-inspect.js @@ -1391,9 +1391,10 @@ async function modeSandbox(page, expr, files, setup, stack, bytecode) { if (typeof fn === 'function' && fn.__sx_handle === undefined) return fn; if (fn && fn.__sx_handle !== undefined) { return function() { - const r = K.callFn(fn, Array.from(arguments)); - window._driveAsync(r); - return r; + // Do NOT call _driveAsync here — the suspension propagates through + // the normal CEK/VM return path. The outer callFn handles it. + // Calling _driveAsync would create a duplicate resume chain. + return K.callFn(fn, Array.from(arguments)); }; } return function() {};