code wiki / _hdl_build / nx_scratch_wasm_gate.nx

nx_scratch_wasm_gate.nx source

↩ module page · 75 lines · 3834 B

1// nx_scratch_wasm_gate.nx -- R0.0b gate, NISHI all the way up. Forks the sovereign compiler ELFs to build 2// nx_scratch_probe.nx -> wasm, then EXECUTES it in the sovereign nx_wasm_vm and checks that the WASM-lane 3// nx_scratch hands out DISTINCT framed buffers (sp_probe == 1496014960, sp_gap == 128). Proves native<->wasm 4// scratch parity -- the multi-word-local idiom now works in the browser lane, no [i64;N] compiler feature. 5// license_tier: ORIGINAL (build-fork spine from nx_aw_push; VM-verify spine from nx_sha256_wasm_vm_gate) 6import "nx_syscalls.nx" 7import "nx_gate_emit_lib.nx" 8import "nx_wasm_vm.nx" 9 10const CWAT_ELF: *u8 = "/tmp/nx_compile_wat.sov.elf" 11const WATC_ELF: *u8 = "/tmp/nx_wat_compiler.sov.elf" 12const SRC_NX: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/runtime/nx_scratch_probe.nx" 13const OUT_WAT: *u8 = "/tmp/scr.wat" 14const OUT_WASM: *u8 = "/tmp/scr.wasm" 15const KAT_PROBE: i64 = 1496014960 16const KAT_GAP: i64 = 128 17 18func run_elf(elf: *u8, a1: *u8, a2: *u8) -> i64 { 19 let pid: i64 = sys_fork() 20 if pid == 0 { 21 let argv: *i64 = sys_mmap(64) as *i64 22 argv[0] = elf as i64 23 var ai: i64 = 1 24 if (a1 as i64) != 0 { argv[ai] = a1 as i64; ai = ai + 1 } 25 if (a2 as i64) != 0 { argv[ai] = a2 as i64; ai = ai + 1 } 26 argv[ai] = 0 27 let envp: *i64 = sys_mmap(16) as *i64 28 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64 29 envp[1] = 0 30 sys_execve(elf, argv, envp) 31 sys_exit(127) 32 } 33 let st: *i64 = sys_mmap(16) as *i64 34 sys_wait4(pid, st, 0) 35 return (st[0] >> 8) & 0xff 36} 37 38func main() -> i64 { 39 g_puts("nx_scratch WASM gate (sovereign compile -> nx_wasm_vm -> framed-scratch parity)\n" as *u8) 40 var pass: i64 = 0 41 var total: i64 = 0 42 43 let rc1: i64 = run_elf(CWAT_ELF, SRC_NX, OUT_WAT) 44 g_puts(" [build] nx_compile_wat rc=" as *u8); g_pn(rc1); g_puts("\n" as *u8) 45 let rc2: i64 = run_elf(WATC_ELF, OUT_WAT, OUT_WASM) 46 g_puts(" [build] nx_wat_compiler rc=" as *u8); g_pn(rc2); g_puts("\n" as *u8) 47 48 let box: *i64 = sys_mmap(16) as *i64 49 let wasm: *u8 = sys_read_file(OUT_WASM, box) 50 if (wasm as i64) == 0 { g_puts(" FAIL cannot read scr.wasm\nverdict=RED\n" as *u8); sys_exit(1); return 1 } 51 g_puts(" [measure] wasm bytes=" as *u8); g_pn(box[0]); g_puts("\n" as *u8) 52 let mod: *WasmMod = wm_new(wasm, box[0]) 53 if wm_parse(mod) != 0 { g_puts(" FAIL wasm parse\nverdict=RED\n" as *u8); sys_exit(1); return 1 } 54 mod.mem = sys_mmap(2162688) as *u8 // >2 MiB: the scratch arena lives high in linear memory 55 56 let fidx: i64 = wm_find_export(mod, "sp_probe" as *u8) 57 g_puts(" [measure] funcs=" as *u8); g_pn(mod.n_funcs); g_puts(" exports=" as *u8); g_pn(mod.n_exports); g_puts(" sp_probe fidx=" as *u8); g_pn(fidx); g_puts("\n" as *u8) 58 pass = pass + g_check("nx_scratch organ compiled to wasm + sp_probe exported" as *u8, fidx >= 0) 59 total = total + 1 60 61 let g: i64 = wm_run(mod, "sp_gap" as *u8, 0, 0, 0, 0, 0, 0) 62 g_puts(" [measure] sp_gap() = " as *u8); g_pn(g); g_puts(" (expect 128 = two DISTINCT 128B allocs)\n" as *u8) 63 pass = pass + g_check("two nx_scratch allocs are DISTINCT + sequential (gap==128)" as *u8, g == KAT_GAP) 64 total = total + 1 65 66 let r: i64 = wm_run(mod, "sp_probe" as *u8, 0, 0, 0, 0, 0, 0) 67 g_puts(" [measure] sp_probe() = " as *u8); g_pn(r); g_puts(" (KAT = " as *u8); g_pn(KAT_PROBE); g_puts(")\n" as *u8) 68 pass = pass + g_check("framed scratch: a,b non-aliasing + save/restore reuse (sp_probe==KAT)" as *u8, r == KAT_PROBE) 69 total = total + 1 70 71 g_puts("---- nx_scratch wasm gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 72 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 73 g_puts("verdict=RED\n" as *u8); sys_exit(1) 74 return 1 75}