WIP: bytecode when/do/perform — host-callback _driveAsync fix + debugging
Root cause identified: nested cek_call_or_suspend calls on same VM overwrite pending_cek. First call suspends (thunk's hs-wait), second call from synchronous dom-listen callback overwrites before resume. sandbox host-callback: removed _driveAsync call to prevent duplicate resume chains. Still 3/6 in Node.js test — issue is in OCaml call stack nesting, not JS async. Next: prevent pending_cek overwrite in nested CEK→VM→CEK→VM chains. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -952,7 +952,14 @@ let () = _vm_suspension_to_dict := (fun exn ->
|
|||||||
Hashtbl.replace d "__vm_suspended" (Bool true);
|
Hashtbl.replace d "__vm_suspended" (Bool true);
|
||||||
Hashtbl.replace d "request" request;
|
Hashtbl.replace d "request" request;
|
||||||
Hashtbl.replace d "resume" (NativeFn ("vm-resume", fun args ->
|
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)
|
Some (Dict d)
|
||||||
| _ -> None)
|
| _ -> None)
|
||||||
let () = _cek_eval_lambda_ref := (fun f args ->
|
let () = _cek_eval_lambda_ref := (fun f args ->
|
||||||
|
|||||||
@@ -1391,9 +1391,10 @@ async function modeSandbox(page, expr, files, setup, stack, bytecode) {
|
|||||||
if (typeof fn === 'function' && fn.__sx_handle === undefined) return fn;
|
if (typeof fn === 'function' && fn.__sx_handle === undefined) return fn;
|
||||||
if (fn && fn.__sx_handle !== undefined) {
|
if (fn && fn.__sx_handle !== undefined) {
|
||||||
return function() {
|
return function() {
|
||||||
const r = K.callFn(fn, Array.from(arguments));
|
// Do NOT call _driveAsync here — the suspension propagates through
|
||||||
window._driveAsync(r);
|
// the normal CEK/VM return path. The outer callFn handles it.
|
||||||
return r;
|
// Calling _driveAsync would create a duplicate resume chain.
|
||||||
|
return K.callFn(fn, Array.from(arguments));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return function() {};
|
return function() {};
|
||||||
|
|||||||
Reference in New Issue
Block a user