The sx-get links were doing full page refreshes because click handlers never attached. Root causes: VM frame management bug, missing primitives, CEK/VM type dispatch mismatch, and silent error swallowing. Fixes: - VM frame exhaustion: frames <- [] now properly pops to rest_frames - length primitive: add alias for len in OCaml primitives - call_sx_fn: use sx_call directly instead of eval_expr (CEK checks for type "lambda" but VmClosure reports "function") - Boot error surfacing: Sx.init() now has try/catch + failure summary - Callback error surfacing: catch-all handler for non-Eval_error exceptions - Silent JIT failures: log before CEK fallback instead of swallowing - vm→env sync: loadModule now calls sync_vm_to_env() - sx_build_bytecode MCP tool added for bytecode compilation Tests: 50 new tests across test-vm.sx and test-vm-primitives.sx covering nested VM calls, frame integrity, CEK bridge, primitive availability, cross-module symbol resolution, and callback dispatch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 line
9.8 KiB
JSON
1 line
9.8 KiB
JSON
{"magic":"SXBC","version":1,"hash":"b3cae03948f7a615","module":{"bytecode":[51,1,0,128,0,0,5,51,3,0,128,2,0,5,1,5,0,51,6,0,1,7,0,51,8,0,1,9,0,51,10,0,1,11,0,51,12,0,1,13,0,51,14,0,1,15,0,51,16,0,1,17,0,51,18,0,1,19,0,51,20,0,1,21,0,51,14,0,1,22,0,51,23,0,1,24,0,51,14,0,1,25,0,51,18,0,1,26,0,51,16,0,1,27,0,51,16,0,1,28,0,51,29,0,1,30,0,51,31,0,1,32,0,51,16,0,1,33,0,51,14,0,1,34,0,51,35,0,1,36,0,51,14,0,1,37,0,51,38,0,1,39,0,51,16,0,1,40,0,51,16,0,1,41,0,51,14,0,1,42,0,51,16,0,1,43,0,51,14,0,1,44,0,51,14,0,65,27,0,128,4,0,5,51,46,0,128,45,0,5,51,48,0,128,47,0,5,51,50,0,128,49,0,5,51,52,0,128,51,0,5,51,54,0,128,53,0,5,51,56,0,128,55,0,5,51,58,0,128,57,0,5,51,60,0,128,59,0,5,51,62,0,128,61,0,5,51,64,0,128,63,0,5,51,66,0,128,65,0,5,51,68,0,128,67,0,5,51,70,0,128,69,0,5,51,72,0,128,71,0,5,51,74,0,128,73,0,5,51,76,0,128,75,0,5,51,78,0,128,77,0,5,51,80,0,128,79,0,50],"constants":[{"t":"s","v":"assert"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,17,0,16,1,6,34,4,0,5,1,2,0,52,1,0,1,32,1,0,2,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"error"},{"t":"s","v":"Assertion failed"}],"arity":2}},{"t":"s","v":"assert="},{"t":"code","v":{"bytecode":[16,0,16,1,52,1,0,2,52,0,0,1,33,28,0,16,2,6,34,15,0,5,1,4,0,16,1,1,5,0,16,0,52,3,0,4,52,2,0,1,32,1,0,2,50],"constants":[{"t":"s","v":"not"},{"t":"s","v":"="},{"t":"s","v":"error"},{"t":"s","v":"str"},{"t":"s","v":"Expected "},{"t":"s","v":", got "}],"arity":3}},{"t":"s","v":"default-platform"},{"t":"s","v":"current-user"},{"t":"code","v":{"bytecode":[2,50],"constants":[]}},{"t":"s","v":"csrf-token"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"s","v":"test-csrf-token"}]}},{"t":"s","v":"app-url"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"s","v":"/mock-app-url"}],"arity":2}},{"t":"s","v":"frag"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"s","v":""}],"arity":3}},{"t":"s","v":"sleep"},{"t":"code","v":{"bytecode":[2,50],"constants":[],"arity":1}},{"t":"s","v":"local-storage-set"},{"t":"code","v":{"bytecode":[2,50],"constants":[],"arity":2}},{"t":"s","v":"set-cookie"},{"t":"code","v":{"bytecode":[2,50],"constants":[],"arity":3}},{"t":"s","v":"url-for"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"s","v":"/mock-url"}],"arity":2}},{"t":"s","v":"create-element"},{"t":"s","v":"request-path"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"s","v":"/"}]}},{"t":"s","v":"config"},{"t":"s","v":"set-attr"},{"t":"s","v":"set-text"},{"t":"s","v":"remove-child"},{"t":"s","v":"fetch"},{"t":"code","v":{"bytecode":[1,0,0,1,1,0,1,2,0,1,3,0,1,4,0,3,65,3,0,50],"constants":[{"t":"s","v":"status"},{"t":"n","v":200},{"t":"s","v":"body"},{"t":"s","v":""},{"t":"s","v":"ok"}],"arity":2}},{"t":"s","v":"query"},{"t":"code","v":{"bytecode":[52,0,0,0,50],"constants":[{"t":"s","v":"list"}],"arity":3}},{"t":"s","v":"add-class"},{"t":"s","v":"get-element"},{"t":"s","v":"now"},{"t":"code","v":{"bytecode":[1,0,0,50],"constants":[{"t":"n","v":0}]}},{"t":"s","v":"abort"},{"t":"s","v":"action"},{"t":"code","v":{"bytecode":[1,0,0,3,65,1,0,50],"constants":[{"t":"s","v":"ok"}],"arity":3}},{"t":"s","v":"remove-class"},{"t":"s","v":"append-child"},{"t":"s","v":"request-arg"},{"t":"s","v":"emit-dom"},{"t":"s","v":"local-storage-get"},{"t":"s","v":"get-cookie"},{"t":"s","v":"make-harness"},{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,6,0,20,1,0,32,9,0,20,1,0,16,0,52,2,0,2,17,1,1,3,0,52,4,0,0,1,5,0,16,1,1,6,0,1,7,0,65,0,0,1,8,0,65,0,0,1,9,0,2,65,3,0,65,3,0,50],"constants":[{"t":"s","v":"nil?"},{"t":"s","v":"default-platform"},{"t":"s","v":"merge"},{"t":"s","v":"log"},{"t":"s","v":"list"},{"t":"s","v":"platform"},{"t":"s","v":"state"},{"t":"s","v":"cookies"},{"t":"s","v":"storage"},{"t":"s","v":"dom"}],"arity":1}},{"t":"s","v":"harness-reset!"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,2,0,0,52,0,0,3,5,16,0,1,3,0,1,4,0,65,0,0,1,5,0,65,0,0,1,6,0,2,65,3,0,52,0,0,3,5,16,0,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"log"},{"t":"s","v":"list"},{"t":"s","v":"state"},{"t":"s","v":"cookies"},{"t":"s","v":"storage"},{"t":"s","v":"dom"}],"arity":1}},{"t":"s","v":"harness-log"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,17,2,16,1,52,2,0,1,33,5,0,16,2,32,11,0,51,4,0,1,1,16,2,52,3,0,2,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"log"},{"t":"s","v":"nil?"},{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[16,0,1,2,0,52,1,0,2,18,0,52,0,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"get"},{"t":"s","v":"op"}],"arity":1,"upvalue-count":1}}],"arity":2}},{"t":"s","v":"harness-get"},{"t":"code","v":{"bytecode":[16,0,1,1,0,52,0,0,2,16,1,52,0,0,2,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"state"}],"arity":2}},{"t":"s","v":"harness-set!"},{"t":"code","v":{"bytecode":[16,0,1,2,0,52,1,0,2,16,1,16,2,52,0,0,3,5,2,50],"constants":[{"t":"s","v":"dict-set!"},{"t":"s","v":"get"},{"t":"s","v":"state"}],"arity":3}},{"t":"s","v":"make-interceptor"},{"t":"code","v":{"bytecode":[51,0,0,1,2,1,0,1,1,50],"constants":[{"t":"code","v":{"bytecode":[16,0,52,0,0,1,33,7,0,18,0,48,0,32,122,0,1,2,0,16,0,52,3,0,1,52,1,0,2,33,13,0,18,0,16,0,52,4,0,1,48,1,32,93,0,1,5,0,16,0,52,3,0,1,52,1,0,2,33,22,0,18,0,16,0,52,4,0,1,16,0,1,2,0,52,6,0,2,48,2,32,55,0,1,7,0,16,0,52,3,0,1,52,1,0,2,33,31,0,18,0,16,0,52,4,0,1,16,0,1,2,0,52,6,0,2,16,0,1,5,0,52,6,0,2,48,3,32,8,0,18,0,16,0,52,8,0,2,17,1,18,1,1,10,0,52,9,0,2,17,2,20,11,0,16,2,1,12,0,16,0,1,13,0,16,1,1,14,0,18,2,65,3,0,48,2,5,16,1,50],"constants":[{"t":"s","v":"empty?"},{"t":"s","v":"="},{"t":"n","v":1},{"t":"s","v":"len"},{"t":"s","v":"first"},{"t":"n","v":2},{"t":"s","v":"nth"},{"t":"n","v":3},{"t":"s","v":"apply"},{"t":"s","v":"get"},{"t":"s","v":"log"},{"t":"s","v":"append!"},{"t":"s","v":"args"},{"t":"s","v":"result"},{"t":"s","v":"op"}],"arity":1,"upvalue-count":3}}],"arity":3}},{"t":"s","v":"install-interceptors"},{"t":"code","v":{"bytecode":[51,1,0,1,0,1,1,16,0,1,4,0,52,3,0,2,52,2,0,1,52,0,0,2,5,16,1,50],"constants":[{"t":"s","v":"for-each"},{"t":"code","v":{"bytecode":[18,0,1,1,0,52,0,0,2,16,0,52,0,0,2,17,1,20,2,0,18,0,16,0,16,1,48,3,17,2,20,3,0,18,1,16,0,16,2,49,3,50],"constants":[{"t":"s","v":"get"},{"t":"s","v":"platform"},{"t":"s","v":"make-interceptor"},{"t":"s","v":"env-bind!"}],"arity":1,"upvalue-count":2}},{"t":"s","v":"keys"},{"t":"s","v":"get"},{"t":"s","v":"platform"}],"arity":2}},{"t":"s","v":"io-calls"},{"t":"code","v":{"bytecode":[51,1,0,1,1,16,0,1,3,0,52,2,0,2,52,0,0,2,50],"constants":[{"t":"s","v":"filter"},{"t":"code","v":{"bytecode":[16,0,1,2,0,52,1,0,2,18,0,52,0,0,2,50],"constants":[{"t":"s","v":"="},{"t":"s","v":"get"},{"t":"s","v":"op"}],"arity":1,"upvalue-count":1}},{"t":"s","v":"get"},{"t":"s","v":"log"}],"arity":2}},{"t":"s","v":"io-call-count"},{"t":"code","v":{"bytecode":[20,1,0,16,0,16,1,48,2,52,0,0,1,50],"constants":[{"t":"s","v":"len"},{"t":"s","v":"io-calls"}],"arity":2}},{"t":"s","v":"io-call-nth"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,48,2,17,3,16,2,16,3,52,2,0,1,52,1,0,2,33,11,0,16,3,16,2,52,3,0,2,32,1,0,2,50],"constants":[{"t":"s","v":"io-calls"},{"t":"s","v":"<"},{"t":"s","v":"len"},{"t":"s","v":"nth"}],"arity":3}},{"t":"s","v":"io-call-args"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,16,2,48,3,17,3,16,3,52,1,0,1,33,4,0,2,32,9,0,16,3,1,3,0,52,2,0,2,50],"constants":[{"t":"s","v":"io-call-nth"},{"t":"s","v":"nil?"},{"t":"s","v":"get"},{"t":"s","v":"args"}],"arity":3}},{"t":"s","v":"io-call-result"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,16,2,48,3,17,3,16,3,52,1,0,1,33,4,0,2,32,9,0,16,3,1,3,0,52,2,0,2,50],"constants":[{"t":"s","v":"io-call-nth"},{"t":"s","v":"nil?"},{"t":"s","v":"get"},{"t":"s","v":"result"}],"arity":3}},{"t":"s","v":"assert-io-called"},{"t":"code","v":{"bytecode":[20,0,0,20,2,0,16,0,16,1,48,2,1,3,0,52,1,0,2,1,5,0,16,1,1,6,0,52,4,0,3,49,2,50],"constants":[{"t":"s","v":"assert"},{"t":"s","v":">"},{"t":"s","v":"io-call-count"},{"t":"n","v":0},{"t":"s","v":"str"},{"t":"s","v":"Expected IO operation "},{"t":"s","v":" to be called but it was not"}],"arity":2}},{"t":"s","v":"assert-no-io"},{"t":"code","v":{"bytecode":[20,0,0,20,2,0,16,0,16,1,48,2,1,3,0,52,1,0,2,1,5,0,16,1,1,6,0,20,2,0,16,0,16,1,48,2,1,7,0,52,4,0,5,49,2,50],"constants":[{"t":"s","v":"assert"},{"t":"s","v":"="},{"t":"s","v":"io-call-count"},{"t":"n","v":0},{"t":"s","v":"str"},{"t":"s","v":"Expected IO operation "},{"t":"s","v":" not to be called but it was called "},{"t":"s","v":" time(s)"}],"arity":2}},{"t":"s","v":"assert-io-count"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,48,2,17,3,20,1,0,16,3,16,2,52,2,0,2,1,4,0,16,1,1,5,0,16,2,1,6,0,16,3,1,7,0,52,3,0,7,49,2,50],"constants":[{"t":"s","v":"io-call-count"},{"t":"s","v":"assert"},{"t":"s","v":"="},{"t":"s","v":"str"},{"t":"s","v":"Expected "},{"t":"s","v":" to be called "},{"t":"s","v":" time(s) but was called "},{"t":"s","v":" time(s)"}],"arity":3}},{"t":"s","v":"assert-io-args"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,16,2,48,3,17,4,20,1,0,20,2,0,16,4,16,3,48,2,1,4,0,16,2,1,5,0,16,1,1,6,0,16,3,52,3,0,1,1,7,0,16,4,52,3,0,1,52,3,0,8,49,2,50],"constants":[{"t":"s","v":"io-call-args"},{"t":"s","v":"assert"},{"t":"s","v":"equal?"},{"t":"s","v":"str"},{"t":"s","v":"Expected call "},{"t":"s","v":" to "},{"t":"s","v":" with args "},{"t":"s","v":" but got "}],"arity":4}},{"t":"s","v":"assert-io-result"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,16,2,48,3,17,4,20,1,0,20,2,0,16,4,16,3,48,2,1,4,0,16,2,1,5,0,16,1,1,6,0,16,3,52,3,0,1,1,7,0,16,4,52,3,0,1,52,3,0,8,49,2,50],"constants":[{"t":"s","v":"io-call-result"},{"t":"s","v":"assert"},{"t":"s","v":"equal?"},{"t":"s","v":"str"},{"t":"s","v":"Expected call "},{"t":"s","v":" to "},{"t":"s","v":" to return "},{"t":"s","v":" but got "}],"arity":4}},{"t":"s","v":"assert-state"},{"t":"code","v":{"bytecode":[20,0,0,16,0,16,1,48,2,17,3,20,1,0,20,2,0,16,3,16,2,48,2,1,4,0,16,1,1,5,0,16,2,52,3,0,1,1,6,0,16,3,52,3,0,1,52,3,0,6,49,2,50],"constants":[{"t":"s","v":"harness-get"},{"t":"s","v":"assert"},{"t":"s","v":"equal?"},{"t":"s","v":"str"},{"t":"s","v":"Expected state "},{"t":"s","v":" to be "},{"t":"s","v":" but got "}],"arity":3}}]}} |