review quick-wins: JIT gate, crash guards, crit-2 signal-return, regen repair
Server (sx_server.ml):
- HTTP mode: JIT hook now opt-in via SX_SERVING_JIT, matching epoch mode
(was unconditional — live serving-JIT miscompiles J1/J2/J3 de-risked)
- command channel: malformed/non-ASCII line returns an error response
instead of killing the shared process (C1/C1b)
- response cache: soft error pages no longer cached (S4);
http_render_page returns (html, is_error)
Kernel spec + regen:
- crit-2: signal-return frame stored the saved kont under :f but the reader
looked up "saved-kont" — handler value became the whole program's result
and the covering test passed vacuously. Fixed; raise-continuable now also
resumes at the raise site (rest-k, not unwound-k), mirroring signal-condition
- quasiquote: R7RS longhand unquote-splicing aliased to splice-unquote
(used to serialize literally — silent zero-splice)
- guard: re-raise sentinel gensym'd per execution (was forgeable by any
(list '__guard-reraise__ x) value)
- do: IIFE-head form no longer misparses as a Scheme do-loop
- render: area/base/embed/param/track added to HTML_TAGS (were void-only
and rendered as Undefined symbol)
- REGEN REPAIR: checked-in sx_ref.ml carried hand-written additions that
every regeneration silently lost (let-values/define-values/delay/
delay-force registrations, AdtValue define-type) plus 5 regen blockers
(arrow-name mangling, 3-arg get, &rest defines, HO-position helper refs,
transpiler prim-table gaps). Moved into bootstrap.py FIXUPS/skips and the
transpiler prim table — regen is now reproducible, compiles, and tests
at baseline (CI Dockerfile.test steps 3-4 could not previously have
produced a compiling kernel)
Primitives:
- contains?: dict key-check arm per its spec doc
- expt: promotes to float on int63 overflow ((expt 2 100) returned 0)
- mcp_tree parity with sx_primitives: get (Integer indices + 3-arg default),
split (literal substring, was char-class — the historical gotcha lived
here), empty? on ""/{}, contains?, equal?, keyword-name, char-code
(Integer), parse-number (Integer-aware)
Python/docs:
- shared/sx/boundary.py: dead validation now logs a one-time WARNING instead
of silently no-oping (full revival gated: tier-1 declarations deleted and
SX_BOUNDARY_STRICT=1 is live in production compose)
- CLAUDE.md: canonical reference now points at spec/*.sx; island authoring
rules corrected (let IS sequential, bodies ARE implicit begin)
Verification: full suite 5762 passed / 274 failed — fail set byte-identical
to the pre-change baseline (273 in-progress hs-* + pre-existing r7rs radix
shadow). All repros verified fixed on both the native binary and the rebuilt
WASM browser kernel. Review findings: /tmp/sx-review/*.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -430,8 +430,20 @@ let () =
|
||||
register "expt" (fun args ->
|
||||
match args with
|
||||
| [Integer a; Integer b] when b >= 0 ->
|
||||
let rec ipow base e acc = if e = 0 then acc else ipow base (e - 1) (acc * base) in
|
||||
Integer (ipow a b 1)
|
||||
(* Overflow-checked integer power: promote to float instead of
|
||||
silently wrapping int63 ((expt 2 100) used to return 0). *)
|
||||
let mul_ovf x y =
|
||||
if x = 0 || y = 0 then Some 0
|
||||
else let p = x * y in
|
||||
if p / y <> x then None else Some p in
|
||||
let rec ipow base e acc =
|
||||
if e = 0 then Some acc
|
||||
else match mul_ovf acc base with
|
||||
| None -> None
|
||||
| Some acc' -> ipow base (e - 1) acc' in
|
||||
(match ipow a b 1 with
|
||||
| Some n -> Integer n
|
||||
| None -> Number (Float.pow (float_of_int a) (float_of_int b)))
|
||||
| [a; b] -> Number (Float.pow (as_number a) (as_number b))
|
||||
| _ -> raise (Eval_error "expt: 2 args"));
|
||||
register "quotient" (fun args ->
|
||||
@@ -1227,6 +1239,12 @@ let () =
|
||||
else if String.sub s i (String.length sub) = sub then true
|
||||
else find (i + 1)
|
||||
in Bool (find 0)
|
||||
| [Dict d; key] ->
|
||||
(* Dicts: key check (per the spec doc). Keywords evaluate to their
|
||||
string name, so (contains? {:a 1} :a) arrives as String "a". *)
|
||||
(match key with
|
||||
| String k | Keyword k | Symbol k -> Bool (Hashtbl.mem d k)
|
||||
| _ -> Bool false)
|
||||
| _ -> raise (Eval_error "contains?: 2 args"));
|
||||
register "range" (fun args ->
|
||||
match args with
|
||||
|
||||
Reference in New Issue
Block a user