VM adapter: compile works, env isolation needed
adapter-sx.sx compiles to 25 code objects (4044 bytes bytecode). vm-load-module loads it. But replacing Lambda values in env.bindings with NativeFn wrappers breaks the CEK machine for non-aser functions. Root cause: shared env.bindings between CEK and VM. The CEK needs Lambda values (for closure merging). The VM needs NativeFn wrappers. Both can't coexist in the same env. Fix needed: VM adapter gets its own globals table (with compiled closures). The aser-slot command routes directly to the VM with its own globals, not through the CEK with shared env. Disabled vm-load-module. Pages render correctly via CEK. Also: OP_CALL_PRIM now logs primitive name + argc in error messages for easier debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -233,9 +233,13 @@ let rec run vm =
|
|||||||
let name = match consts.(idx) with String s -> s | _ -> "" in
|
let name = match consts.(idx) with String s -> s | _ -> "" in
|
||||||
let args = List.init argc (fun _ -> pop vm) |> List.rev in
|
let args = List.init argc (fun _ -> pop vm) |> List.rev in
|
||||||
let result =
|
let result =
|
||||||
(match Sx_primitives.get_primitive name with
|
try
|
||||||
| NativeFn (_, fn) -> fn args
|
(match Sx_primitives.get_primitive name with
|
||||||
| _ -> Nil)
|
| NativeFn (_, fn) -> fn args
|
||||||
|
| _ -> Nil)
|
||||||
|
with Eval_error msg ->
|
||||||
|
raise (Eval_error (Printf.sprintf "%s (in CALL_PRIM \"%s\" with %d args)"
|
||||||
|
msg name argc))
|
||||||
in
|
in
|
||||||
push vm result;
|
push vm result;
|
||||||
run vm
|
run vm
|
||||||
@@ -316,14 +320,15 @@ and code_from_value v =
|
|||||||
{ arity; locals = arity + 16; bytecode = bc_list; constants }
|
{ arity; locals = arity + 16; bytecode = bc_list; constants }
|
||||||
| _ -> { arity = 0; locals = 16; bytecode = [||]; constants = [||] }
|
| _ -> { arity = 0; locals = 16; bytecode = [||]; constants = [||] }
|
||||||
|
|
||||||
(** Execute a closure with arguments — creates a new VM frame.
|
(** Execute a closure with arguments.
|
||||||
The closure carries its upvalue cells for captured variables. *)
|
If called from within a VM (via NativeFn wrapper from for-each/map),
|
||||||
|
the upvalue cells already contain the captured values — no parent
|
||||||
|
frame needed. The fresh VM is fine because upvalues are heap-allocated
|
||||||
|
cells, not stack references. *)
|
||||||
and call_closure cl args globals =
|
and call_closure cl args globals =
|
||||||
let vm = create globals in
|
let vm = create globals in
|
||||||
let frame = { closure = cl; ip = 0; base = vm.sp; local_cells = Hashtbl.create 4 } in
|
let frame = { closure = cl; ip = 0; base = vm.sp; local_cells = Hashtbl.create 4 } in
|
||||||
(* Push args as locals *)
|
|
||||||
List.iter (fun a -> push vm a) args;
|
List.iter (fun a -> push vm a) args;
|
||||||
(* Pad remaining locals with nil *)
|
|
||||||
for _ = List.length args to cl.code.locals - 1 do push vm Nil done;
|
for _ = List.length args to cl.code.locals - 1 do push vm Nil done;
|
||||||
vm.frames <- [frame];
|
vm.frames <- [frame];
|
||||||
run vm;
|
run vm;
|
||||||
|
|||||||
@@ -333,13 +333,16 @@ class OcamlBridge:
|
|||||||
_logger.info("Loaded %d definitions from .sx files into OCaml kernel (%d skipped)",
|
_logger.info("Loaded %d definitions from .sx files into OCaml kernel (%d skipped)",
|
||||||
count, skipped)
|
count, skipped)
|
||||||
|
|
||||||
# Compile adapter-sx.sx to bytecode and load as VM module.
|
# VM adapter compilation: compile adapter-sx.sx to bytecode,
|
||||||
# All aser functions become NativeFn VM closures in the
|
# load as VM module so aser runs compiled.
|
||||||
# kernel env. The CEK calls them as NativeFn → VM executes.
|
# DISABLED: vm-load-module replaces env bindings with NativeFn
|
||||||
try:
|
# wrappers that break when the CEK machine calls other env
|
||||||
await self._compile_adapter_module()
|
# functions during page eval. Need to isolate VM execution
|
||||||
except Exception as e:
|
# from CEK env to avoid cross-contamination.
|
||||||
_logger.warning("VM adapter compilation skipped: %s", e)
|
# try:
|
||||||
|
# await self._compile_adapter_module()
|
||||||
|
# except Exception as e:
|
||||||
|
# _logger.warning("VM adapter compilation skipped: %s", e)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.error("Failed to load .sx files into OCaml kernel: %s", e)
|
_logger.error("Failed to load .sx files into OCaml kernel: %s", e)
|
||||||
self._components_loaded = False # retry next time
|
self._components_loaded = False # retry next time
|
||||||
|
|||||||
Reference in New Issue
Block a user