VM global_env sync + isomorphic nav store primitives
Reverse hook syncs VM GLOBAL_SET mutations back to global_env so CEK reads see JIT-written values. Isomorphic nav: store primitives, event-bridge, client? predicate. Browser JS and bytecode rebuilt. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -223,6 +223,13 @@ let () =
|
||||
if env == global_env then
|
||||
Hashtbl.replace _vm_globals name v)
|
||||
|
||||
(* Reverse hook: sync VM GLOBAL_SET mutations back to global_env.
|
||||
Without this, set! inside JIT-compiled functions writes to _vm_globals
|
||||
but leaves global_env stale — CEK reads then see the old value. *)
|
||||
let () =
|
||||
Sx_types._vm_global_set_hook := Some (fun name v ->
|
||||
Hashtbl.replace global_env.bindings (Sx_types.intern name) v)
|
||||
|
||||
(* ================================================================== *)
|
||||
(* Core API *)
|
||||
(* ================================================================== *)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -50,7 +50,12 @@ let sx_call f args =
|
||||
Thunk (l.l_body, local)
|
||||
| Continuation (k, _) ->
|
||||
k (match args with x :: _ -> x | [] -> Nil)
|
||||
| _ -> raise (Eval_error ("Not callable: " ^ inspect f))
|
||||
| _ ->
|
||||
let nargs = List.length args in
|
||||
let args_preview = if nargs = 0 then "" else
|
||||
let s = String.concat ", " (List.map (fun a -> let s = inspect a in if String.length s > 40 then String.sub s 0 40 ^ ".." else s) args) in
|
||||
" with args=[" ^ s ^ "]" in
|
||||
raise (Eval_error ("Not callable: " ^ inspect f ^ args_preview))
|
||||
|
||||
(* Initialize forward ref so primitives can call SX functions *)
|
||||
let () = Sx_primitives._sx_call_fn := sx_call
|
||||
|
||||
@@ -185,8 +185,18 @@ let make_env () =
|
||||
let env_extend parent =
|
||||
{ bindings = Hashtbl.create 16; parent = Some parent }
|
||||
|
||||
(* Optional hook: called after every env_bind with (env, name, value).
|
||||
Used by browser kernel to sync VM globals table. *)
|
||||
let _env_bind_hook : (env -> string -> value -> unit) option ref = ref None
|
||||
|
||||
(* Optional hook: called after VM GLOBAL_SET writes to vm.globals.
|
||||
Used by browser kernel to sync mutations back to global_env. *)
|
||||
let _vm_global_set_hook : (string -> value -> unit) option ref = ref None
|
||||
|
||||
let env_bind env name v =
|
||||
Hashtbl.replace env.bindings (intern name) v; Nil
|
||||
Hashtbl.replace env.bindings (intern name) v;
|
||||
(match !_env_bind_hook with Some f -> f env name v | None -> ());
|
||||
Nil
|
||||
|
||||
(* Internal: scope-chain lookup with pre-interned ID *)
|
||||
let rec env_has_id env id =
|
||||
|
||||
@@ -303,7 +303,11 @@ and run vm =
|
||||
in find_env env
|
||||
| None -> false
|
||||
in
|
||||
if not written then Hashtbl.replace vm.globals name (peek vm)
|
||||
if not written then begin
|
||||
let v = peek vm in
|
||||
Hashtbl.replace vm.globals name v;
|
||||
(match !Sx_types._vm_global_set_hook with Some f -> f name v | None -> ())
|
||||
end
|
||||
|
||||
(* ---- Control flow ---- *)
|
||||
| 32 (* OP_JUMP *) ->
|
||||
|
||||
Reference in New Issue
Block a user