code wiki / _hdl_build / nx_sext_wasm_kat_gate.nx

nx_sext_wasm_kat_gate.nx source

↩ module page · 88 lines · 5191 B

1// nx_sext_wasm_kat_gate.nx -- END-TO-END KAT for the WASM lane's subword sign-extend fix (2026-07-10): 2// forks the sovereign pipeline (nx_compile_wat: .nx -> wat; nx_wat_compiler: wat -> wasm) on 3// nx_sext_wasm_kat.nx, loads the wasm in nx_wasm_vm, and asserts the SEMANTICS in-VM: 4// T1 both tools rc=0 (pre-fix: nx_wat_compiler REFUSED -- i64.store32/load32_* were unknown atoms) 5// T2 exports resolve 6// T3 sext_kat() == 0 (*i32 negative+positive round-trip AND *u8 0xA0->160 witness, all in-VM) 7// T4 sext_load_neg() == -100 (the visible sign-extension number; a zero-extend lane returns 4294967196) 8// This is the WASM twin of nx_i32store_probe_gate (x86) -- one language semantic, every backend. 9// Stage first: nx_sov_build_run nx_compile_wat --build-only + nx_sov_build_run nx_wat_compiler --build-only. 10// expect_exit: 0 license_tier: ORIGINAL 11import "nx_syscalls.nx" 12import "nx_wasm_vm.nx" 13import "nx_gate_verdict.nx" 14 15const SW_CWAT: *u8 = "/tmp/nx_compile_wat.sov.elf" 16const SW_WATC: *u8 = "/tmp/nx_wat_compiler.sov.elf" 17const SW_SRC: *u8 = "/mnt/c/Users/elder/nishi-core/nxc2/runtime/nx_sext_wasm_kat.nx" 18const SW_OWAT: *u8 = "/tmp/sextkat.wat" 19const SW_OWASM: *u8 = "/tmp/sextkat.wasm" 20 21func sw_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 22func sw_pn(v: i64) -> i64 { 23 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 24 let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} 25 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 26func sw_check(name: *u8, cond: i64) -> i64 { 27 if cond==1 { sw_puts(" PASS " as *u8) } else { sw_puts(" FAIL " as *u8) } 28 sw_puts(name); sw_puts("\n" as *u8); return cond } 29func sw_run_elf(elf: *u8, a1: *u8, a2: *u8) -> i64 { 30 let pid: i64 = sys_fork() 31 if pid == 0 { 32 let argv: *i64 = sys_mmap(64) as *i64 33 argv[0]=elf as i64; argv[1]=a1 as i64; argv[2]=a2 as i64; argv[3]=0 34 let envp: *i64 = sys_mmap(16) as *i64 35 envp[0]="PATH=/usr/bin:/bin" as *u8 as i64; envp[1]=0 36 sys_execve(elf, argv, envp); sys_exit(127) 37 } 38 let st: *i64 = sys_mmap(16) as *i64; sys_wait4(pid, st, 0) 39 return (st[0] >> 8) & 0xff } 40 41func main() -> i64 { 42 sw_puts("=== nx_sext_wasm_kat_gate: .nx -> wat -> wasm -> nx_wasm_vm, subword sign-extend semantics ===\n" as *u8) 43 var pass: i64 = 0; var total: i64 = 0 44 45 let rc1: i64 = sw_run_elf(SW_CWAT, SW_SRC, SW_OWAT) 46 sw_puts(" [build] nx_compile_wat rc=" as *u8); sw_pn(rc1); sw_puts("\n" as *u8) 47 let rc2: i64 = sw_run_elf(SW_WATC, SW_OWAT, SW_OWASM) 48 sw_puts(" [build] nx_wat_compiler rc=" as *u8); sw_pn(rc2); sw_puts("\n" as *u8) 49 var okb: i64 = 0 50 if rc1 == 0 { if rc2 == 0 { okb = 1 } } 51 pass = pass + sw_check("pipeline rc=0 (pre-fix: WATC REFUSED unknown i64.store32/load32_*)" as *u8, okb); total = total + 1 52 if okb == 0 { sw_puts("NX-SEXT-WASM-KAT-GATE verdict=RED (pipeline)\n" as *u8); return 1 } 53 54 let box: *i64 = sys_mmap(16) as *i64 55 let wasm: *u8 = sys_read_file(SW_OWASM, box) 56 if (wasm as i64)==0 { sw_puts(" FAIL cannot read sextkat.wasm\nNX-SEXT-WASM-KAT-GATE verdict=RED\n" as *u8); return 1 } 57 sw_puts(" [measure] wasm bytes=" as *u8); sw_pn(box[0]); sw_puts("\n" as *u8) 58 let mod: *WasmMod = wm_new(wasm, box[0]) 59 if wm_parse(mod) != 0 { sw_puts(" FAIL wasm parse\nNX-SEXT-WASM-KAT-GATE verdict=RED\n" as *u8); return 1 } 60 mod.mem = sys_mmap(131072) as *u8 61 62 var oke: i64 = 0 63 if wm_find_export(mod, "sext_kat" as *u8) >= 0 { if wm_find_export(mod, "sext_load_neg" as *u8) >= 0 { oke = 1 } } 64 pass = pass + sw_check("exports sext_kat + sext_load_neg resolve" as *u8, oke); total = total + 1 65 66 let k: i64 = wm_run(mod, "sext_kat" as *u8, 0, 0, 0, 0, 0, 0) 67 sw_puts(" [run] sext_kat() fails=" as *u8); sw_pn(k); sw_puts("\n" as *u8) 68 var ok3: i64 = 0 69 if k == 0 { ok3 = 1 } 70 pass = pass + sw_check("in-VM semantics: *i32 neg+pos round-trip AND *u8 0xA0->160 (fails==0)" as *u8, ok3); total = total + 1 71 72 let nv: i64 = wm_run(mod, "sext_load_neg" as *u8, 0, 0, 0, 0, 0, 0) 73 sw_puts(" [run] sext_load_neg() = " as *u8); sw_pn(nv); sw_puts(" (want -100; zero-extend lane would say 4294967196)\n" as *u8) 74 var ok4: i64 = 0 75 if nv == (0 - 100) { ok4 = 1 } 76 pass = pass + sw_check("i64.load32_s sign-extends in the sovereign VM (== -100)" as *u8, ok4); total = total + 1 77 78 sw_puts("NX-SEXT-WASM-KAT-GATE passed " as *u8); sw_pn(pass); sw_puts("/" as *u8); sw_pn(total) 79 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check 80 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled 81 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify. 82 let ctr__dry: *i64 = gv_ctr() 83 ctr__dry[0] = pass 84 ctr__dry[1] = total 85 let rc__dry: i64 = gv_verdict("SEXT-WASM-KAT-GATE" as *u8, ctr__dry, "WASM lane sext-aligned with x86+RV64: signed loads sign-extend, u8 stays zero-extend)" as *u8) 86 sys_exit(rc__dry) 87 return rc__dry 88}