code wiki / _hdl_build / nx_vmleak_gate.nx

nx_vmleak_gate.nx source

↩ module page · 44 lines · 2375 B

1// nx_vmleak_gate.nx -- FAST (<10s, no codec) VM per-operation-allocation leak regression test. Runs 2// probe(100000) in the sovereign wasm VM = 100000 calls + 100000 if-opens = ~300000 internal allocations. 3// Under the OLD per-op sys_mmap-without-free leak this exhausts memory and faults; with the munmap fix it 4// returns 100000. Guards the fix against regression, cheaply. expect_exit: 0 license_tier: ORIGINAL 5import "nx_syscalls.nx" 6import "nx_wasm_vm.nx" 7import "nx_gate_verdict.nx" 8 9const PROBE_WASM: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/web_assets/_video_build/nx_vmleak_probe.wasm" 10 11func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12func g_pn(v: i64) -> i64 { 13 if v==0 { sys_write(1,"0" as *u8,1); return 0 } 14 let b: *u8 = sys_mmap(28); var x: i64 = v; if x<0 { sys_write(1,"-" as *u8,1); x=0-x } 15 var d: i64=0; var y: i64=x 16 while y>0 { d=d+1; y=y/10 } 17 var i: i64=d-1; y=x 18 while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 } 19 sys_write(1,b,d); return 0 20} 21 22func main() -> i64 { 23 g_puts("nx_vmleak_gate -- VM per-op allocation leak regression (probe 100000 calls+ifs)\n" as *u8) 24 let box: *i64 = sys_mmap(16) as *i64 25 let wasm: *u8 = sys_read_file(PROBE_WASM, box) 26 if (wasm as i64) == 0 { g_puts(" FAIL cannot read probe wasm\n" as *u8); g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 } 27 let mod: *WasmMod = wm_new(wasm, box[0]) 28 if wm_parse(mod) != 0 { g_puts(" FAIL parse\n" as *u8); g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 } 29 var mb: i64 = mod.mem_bytes 30 if mb < 65536 { mb = 65536 } 31 mod.mem = sys_mmap(mb) as *u8 32 let N: i64 = 100000 33 let r: i64 = wm_run(mod, "probe" as *u8, N, 0, 0, 0, 0, 1) 34 g_puts(" probe(100000) returned " as *u8); g_pn(r); g_puts(" (expect 100000)\n" as *u8) 35 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 36 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 37 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 38 let ctr__dry: *i64 = gv_ctr() 39 ctr__dry[0] = r 40 ctr__dry[1] = N 41 let rc__dry: i64 = gv_verdict("VMLEAK-GATE" as *u8, ctr__dry, "VM survives 300k allocations: the per-op mmap leak is fixed" as *u8) 42 sys_exit(rc__dry) 43 return rc__dry 44}