Revert VM HOF primitives — broke OCaml JIT CALL_PRIM dispatch

Registering map/for-each/reduce as PRIMITIVES caused the compiler to
emit CALL_PRIM for them everywhere. The OCaml VM's call-primitive
can't invoke VM closures, causing "Undefined symbol: resource" crashes.

Revert vm.sx to original CALL_PRIM handler. Remove map/for-each/reduce
from JS PRIMITIVES so compiler emits OP_CALL instead (handled by
vm-call which dispatches correctly).

3 JS VM tests remain failing (VM closure interop) but production is stable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 10:18:07 +00:00
parent 1b13872369
commit d9aa19cfe9
3 changed files with 555 additions and 537 deletions

View File

@@ -3243,35 +3243,6 @@ def fixups_js(has_html, has_sx, has_dom, has_signals=False, has_deps=False, has_
// Aliases for VM bytecode compatibility
PRIMITIVES["length"] = PRIMITIVES["len"];
// VM-compatible HOF primitives — use callPrimFn which handles native, lambda, and VM closures
function callPrimFn(f, args) {
if (typeof f === "function") return f.apply(null, args);
if (f && f._lambda) return cekCall(f, args);
if (f && f["vm-code"]) {
// VM closure — call through call-primitive dispatch
var cp = PRIMITIVES["vm-call-closure"];
if (cp) return cp(f, args);
}
return cekCall(f, args);
}
PRIMITIVES["map"] = function(fn, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
var result = [];
for (var i = 0; i < lst.length; i++) result.push(callPrimFn(fn, [lst[i]]));
return result;
};
PRIMITIVES["for-each"] = function(fn, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
for (var i = 0; i < lst.length; i++) callPrimFn(fn, [lst[i]]);
return NIL;
};
PRIMITIVES["reduce"] = function(fn, init, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = init; init = tmp; }
var acc = init;
for (var i = 0; i < lst.length; i++) acc = callPrimFn(fn, [acc, lst[i]]);
return acc;
};
// FFI library functions — defined in dom.sx/browser.sx but not transpiled.
// Registered here so runtime-evaluated SX code (data-init, islands) can use them.
PRIMITIVES["prevent-default"] = preventDefault_;

1032
lib/vm.sx

File diff suppressed because it is too large Load Diff

View File

@@ -24,7 +24,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-31T09:56:06Z";
var SX_VERSION = "2026-03-31T10:16:31Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -6776,35 +6776,6 @@ PRIMITIVES["resource"] = resource;
// Aliases for VM bytecode compatibility
PRIMITIVES["length"] = PRIMITIVES["len"];
// VM-compatible HOF primitives — use callPrimFn which handles native, lambda, and VM closures
function callPrimFn(f, args) {
if (typeof f === "function") return f.apply(null, args);
if (f && f._lambda) return cekCall(f, args);
if (f && f["vm-code"]) {
// VM closure — call through call-primitive dispatch
var cp = PRIMITIVES["vm-call-closure"];
if (cp) return cp(f, args);
}
return cekCall(f, args);
}
PRIMITIVES["map"] = function(fn, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
var result = [];
for (var i = 0; i < lst.length; i++) result.push(callPrimFn(fn, [lst[i]]));
return result;
};
PRIMITIVES["for-each"] = function(fn, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
for (var i = 0; i < lst.length; i++) callPrimFn(fn, [lst[i]]);
return NIL;
};
PRIMITIVES["reduce"] = function(fn, init, lst) {
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = init; init = tmp; }
var acc = init;
for (var i = 0; i < lst.length; i++) acc = callPrimFn(fn, [acc, lst[i]]);
return acc;
};
// FFI library functions — defined in dom.sx/browser.sx but not transpiled.
// Registered here so runtime-evaluated SX code (data-init, islands) can use them.
PRIMITIVES["prevent-default"] = preventDefault_;