code wiki / _hdl_build / nx_jsfuel_probe.nx
nx_jsfuel_probe.nx source
↩ module page · 111 lines · 5374 B
1// nx_jsfuel_probe.nx -- GATE for the JS execution fuel + eval-cell arena (2026-07-27).
2// Teeth:
3// T1 a NESTED infinite loop terminates (defeats the per-loop EV_LOOP_CAP; only global fuel stops it)
4// T2 fuel exhaustion is reported honestly (ev_fuel_exhausted==1) and spend matches the armed budget
5// T3 static page content SURVIVES the fuel-aborted render (fail-safe, not fail-blank)
6// T4 arena cells are ZEROED -- the semantic MAP_ANONYMOUS equivalence the arena must preserve
7// T5 arena cells are DISTINCT + 16B-strided (no aliasing: two cells must not be the same box)
8// T6 arena footprint is BOUNDED (the whole point: 200k steps must not cost 200k pages)
9// 0 = GREEN / 1 = RED.
10import "nx_syscalls.nx"
11import "nx_js_eval.nx"
12
13func fp_p(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
14func fp_pn(v: i64) -> i64 {
15 var m: i64 = v
16 if m < 0 { fp_p("-\x00" as *u8); m = 0 - m }
17 let t: *u8 = sys_mmap(24); var k: i64 = 0
18 if m == 0 { t[0] = 48 as u8; k = 1 } else { while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } }
19 let o: *u8 = sys_mmap(24); var j: i64 = 0
20 while j < k { o[j] = t[k-1-j]; j = j + 1 }
21 sys_write(1, o, k); return 0
22}
23func fp_chk(cond: i64, name: *u8, pp: *i64, tp: *i64) -> i64 {
24 tp[0] = tp[0] + 1
25 fp_p(name)
26 if cond == 1 { pp[0] = pp[0] + 1; fp_p(" ok\x0a\x00" as *u8) } else { fp_p(" FAIL\x0a\x00" as *u8) }
27 return 0
28}
29func fp_has(buf: *u8, blen: i64, needle: *u8, nl: i64) -> i64 {
30 var i: i64 = 0
31 while (i + nl) <= blen {
32 var j: i64 = 0
33 var ok: i64 = 1
34 while j < nl { if (buf[i + j] & 0xff) != (needle[j] & 0xff) { ok = 0; j = nl } else { j = j + 1 } }
35 if ok == 1 { return 1 }
36 i = i + 1
37 }
38 return 0
39}
40
41// argv[1] (optional) = fuel budget for the burn, so this gate doubles as the MEASURING
42// INSTRUMENT that sizes EV_FUEL_PAGE_DEFAULT (arena bytes/step is read off, not guessed).
43func fp_atoi(s: *u8) -> i64 {
44 var v: i64 = 0; var i: i64 = 0
45 while s[i] != (0 as u8) {
46 let c: i64 = s[i] & 0xff
47 if c < 48 { return 0 }
48 if c > 57 { return 0 }
49 v = v * 10 + (c - 48); i = i + 1
50 }
51 return v
52}
53
54func main(argc: i64, argv: *i64) -> i64 {
55 let pp: *i64 = sys_mmap(8) as *i64; pp[0] = 0
56 let tp: *i64 = sys_mmap(8) as *i64; tp[0] = 0
57
58 // ---- T4/T5: arena semantics, measured BEFORE the burn so the deltas are clean.
59 let c1: *i64 = ev_cell()
60 c1[0] = 111; c1[1] = 222
61 let c2: *i64 = ev_cell()
62 var zeroed: i64 = 0
63 if c2[0] == 0 { if c2[1] == 0 { zeroed = 1 } }
64 fp_chk(zeroed, "T4 fresh arena cell is ZEROED (MAP_ANONYMOUS equivalence)\x00" as *u8, pp, tp)
65 var distinct: i64 = 0
66 if ((c2 as i64) - (c1 as i64)) == 16 { if c1[0] == 111 { distinct = 1 } }
67 fp_chk(distinct, "T5 cells are distinct + 16B-strided (no aliasing)\x00" as *u8, pp, tp)
68 let base_bytes: i64 = ev_cell_bytes()
69
70 // ---- T1/T2/T3: a nested infinite loop, rendered through the real page path.
71 let page: *u8 = "<html><body><p id=\"keep\">static-survives</p><script>var i=0; while(true){ var j=0; while(true){ j=j+1; } i=i+1; }</script></body></html>\x00" as *u8
72 var hlen: i64 = 0
73 while page[hlen] != (0 as u8) { hlen = hlen + 1 }
74 let out: *u8 = sys_mmap(65536)
75 var budget: i64 = 200000
76 if argc >= 2 { let b: i64 = fp_atoi(argv[1] as *u8); if b > 0 { budget = b } }
77 let t0: i64 = sys_now_ms()
78 let tree: *DomTree = dt_parse(page, hlen)
79 ev_fuel_arm(budget)
80 js_run_page_scripts_doc(page, hlen, (tree as i64) as *u8, DOM_TREE_SENTINEL)
81 let olen: i64 = dt_serialize(tree, out, 65536)
82 let t1: i64 = sys_now_ms()
83 fp_p(" burn: ms=\x00" as *u8); fp_pn(t1 - t0)
84 fp_p(" olen=\x00" as *u8); fp_pn(olen)
85 fp_p(" fuel_spent=\x00" as *u8); fp_pn(ev_fuel_spent())
86 fp_p(" arena_KiB=\x00" as *u8); fp_pn((ev_cell_bytes() - base_bytes) / 1024)
87 fp_p("\x0a\x00" as *u8)
88
89 fp_chk(1, "T1 nested infinite loop TERMINATED (per-loop cap alone cannot)\x00" as *u8, pp, tp)
90 var fuel_ok: i64 = 0
91 if ev_fuel_exhausted() == 1 { if ev_fuel_spent() > budget { fuel_ok = 1 } }
92 fp_chk(fuel_ok, "T2 fuel exhaustion reported + spend matches budget\x00" as *u8, pp, tp)
93 fp_chk(fp_has(out, olen, "static-survives\x00" as *u8, 15),
94 "T3 static content SURVIVES the aborted render (fail-safe)\x00" as *u8, pp, tp)
95
96 // ---- T6: footprint PER STEP -- budget-relative so the tooth holds at ANY budget.
97 // MEASURED 2026-07-27: 12.5 B/step (200k->2048KiB, 1M->12288KiB, 5M->62464KiB = linear).
98 // The old one-mmap-per-cell scheme cost a RESIDENT 4096 B page per step. Bound at 64 B/step:
99 // ~5x headroom over measured, 64x under a page-per-cell regression -- it cannot pass by luck.
100 let used_b: i64 = ev_cell_bytes() - base_bytes
101 var bounded: i64 = 0
102 if (used_b / budget) <= 64 { bounded = 1 }
103 fp_p(" bytes_per_step=\x00" as *u8); fp_pn(used_b / budget); fp_p("\x0a\x00" as *u8)
104 fp_chk(bounded, "T6 arena bytes/step BOUNDED <=64 (no page-per-cell regression)\x00" as *u8, pp, tp)
105
106 fp_p("JSFUEL-ARENA-GATE pass=\x00" as *u8); fp_pn(pp[0])
107 fp_p("/\x00" as *u8); fp_pn(tp[0]); fp_p("\x0a\x00" as *u8)
108 if pp[0] == tp[0] { fp_p("verdict=GREEN\x0a\x00" as *u8); return 0 }
109 fp_p("verdict=RED\x0a\x00" as *u8)
110 return 1
111}