code wiki / _hdl_build / nx_wasm_vm_exec_gate.nx

nx_wasm_vm_exec_gate.nx source

↩ module page · 95 lines · 5906 B

1// nx_wasm_vm_exec_gate.nx -- R1+R2: the sovereign WASM VM EXECUTES the real nx_vcodec.wasm and we DIFF it against the 2// native codec. R1 validates the executor on functions that touch NO byte memory (constant accessors + the pure-integer 3// vc_vbits with its calls/control-flow) -- if those match native, the VM's arithmetic, calls, and structured control 4// are sound. R2 then runs the actual codec (vc_wasm_encode -> vc_wasm_decode) on a real 16x16 frame and compares the 5// independent-decoder output to the native packed codec's. If R1 passes but R2 diverges, the fault is the wasm's u8 6// memory access -- the exact thing this VM exists to catch. 7import "nx_syscalls.nx" 8import "nx_gate_emit_lib.nx" 9import "nx_wasm_vm.nx" 10import "nx_vcodec.nx" 11 12func g_abs(v: i64) -> i64 { if v < 0 { return 0 - v } return v } 13 14func main() -> i64 { 15 g_puts("nx_wasm_vm gate R1+R2 (sovereign VM executes the real wasm, DIFF vs native, MEASURED)\n" as *u8) 16 var pass: i64 = 0; var total: i64 = 0 17 18 let box: *i64 = sys_mmap(16) as *i64 19 let wasm: *u8 = sys_read_file("/mnt/c/Users/elder/nishi-core/nxc2/web_assets/_video_build/nx_vcodec.wasm" as *u8, box) 20 if (wasm as i64) == 0 { g_puts(" FAIL cannot read wasm\n" as *u8); g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 } 21 let mod: *WasmMod = wm_new(wasm, box[0]) 22 if wm_parse(mod) != 0 { g_puts(" FAIL parse\n" as *u8); g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 } 23 mod.mem = sys_mmap(mod.mem_bytes) as *u8 24 25 // ---- DIAG: dump vc_cur_off's parsed metadata + first code bytes (parser sanity) ---- 26 let didx: i64 = wm_find_export(mod, "vc_cur_off" as *u8) 27 g_puts(" [diag] vc_cur_off fidx=" as *u8); g_pn(didx); g_puts(" code_off=" as *u8); g_pn(mod.func_code[didx]) 28 g_puts(" end=" as *u8); g_pn(mod.func_end[didx]); g_puts(" nloc=" as *u8); g_pn(mod.func_nloc[didx]); g_puts("\n [diag] first bytes:" as *u8) 29 var dbi: i64 = 0 30 while dbi < 16 { g_puts(" " as *u8); g_pn(mod.bytes[mod.func_code[didx] + dbi] as i64); dbi = dbi + 1 } 31 g_puts("\n" as *u8) 32 33 // ---- R1a: constant accessors (executor skeleton: const + return + block-dispatch) ---- 34 let a_cur: i64 = wm_run(mod, "vc_cur_off" as *u8, 0,0,0,0,0, 0) 35 let a_prev: i64 = wm_run(mod, "vc_prev_off" as *u8, 0,0,0,0,0, 0) 36 let a_str: i64 = wm_run(mod, "vc_stream_off" as *u8, 0,0,0,0,0, 0) 37 let a_dec: i64 = wm_run(mod, "vc_dec_recon_off" as *u8, 0,0,0,0,0, 0) 38 g_puts(" [R1a] accessors via VM: cur=" as *u8); g_pn(a_cur); g_puts(" prev=" as *u8); g_pn(a_prev) 39 g_puts(" stream=" as *u8); g_pn(a_str); g_puts(" dec_recon=" as *u8); g_pn(a_dec); g_puts("\n" as *u8) 40 pass = pass + g_check("R1a executor returns the exact constant offsets (0/16384/65536/49152)" as *u8, 41 (a_cur==0) & (a_prev==16384) & (a_str==65536) & (a_dec==49152)); total=total+1 42 43 // ---- R1b: pure-integer vc_vbits (arith + calls + control), VM vs native, no byte memory ---- 44 var vb_ok: i64 = 1 45 var tv: i64 = 0 46 while tv < 6 { 47 let probe: i64 = (tv*7) - 13 // mix of +/- values 48 let native_vb: i64 = vc_vbits(probe) 49 let vm_vb: i64 = wm_run(mod, "vc_vbits" as *u8, probe, 0,0,0,0, 1) 50 if native_vb != vm_vb { vb_ok = 0 } 51 if tv == 0 { g_puts(" [R1b] vc_vbits sample: native=" as *u8); g_pn(native_vb); g_puts(" vm=" as *u8); g_pn(vm_vb); g_puts("\n" as *u8) } 52 tv = tv + 1 53 } 54 pass = pass + g_check("R1b VM matches native on pure-integer vc_vbits (arith+calls+control sound)" as *u8, vb_ok); total=total+1 55 56 // ---- R2: the codec itself, VM vs native, on a real 16x16 frame ---- 57 let W: i64 = 16; let H: i64 = 16; let N: i64 = W*H; let QP: i64 = 20; let SAD: i64 = 64 58 let cur: *u8 = sys_mmap(N) as *u8 59 let prev: *u8 = sys_mmap(N) as *u8 60 let eR: *u8 = sys_mmap(N) as *u8 61 let dR: *u8 = sys_mmap(N) as *u8 62 let stream: *u8 = sys_mmap(8192) as *u8 63 let blk: *i64 = sys_mmap(16*8) as *i64 64 let mv: *i64 = sys_mmap(2*8) as *i64 65 // a textured frame 66 var y: i64 = 0 67 while y < H { var x: i64 = 0 68 while x < W { var v: i64 = 40 + ((x*11 + y*7) % 120); if (y>=4) { if (y<12) { if (x>=4) { if (x<12) { v = 210 } } } } cur[y*W+x] = v as u8; x = x + 1 } y = y + 1 } 69 // NATIVE: encode -> independent decode 70 vc_enc_frame_packed(cur, prev, eR, W, H, QP, 1, SAD, stream, blk, mv) 71 vc_dec_frame_packed(prev, dR, W, H, QP, stream, blk, mv) 72 // WASM via VM: write the same frame into linear memory at O_CUR (0), run encode then decode 73 var i: i64 = 0; while i < N { mod.mem[i] = cur[i]; i = i + 1 } 74 let wbits: i64 = wm_run(mod, "vc_wasm_encode" as *u8, W, H, QP, 1, SAD, 5) 75 wm_run(mod, "vc_wasm_decode" as *u8, W, H, QP, 0, 0, 3) 76 // compare native dR vs wasm DEC_RECON (offset 49152) 77 var mismatch: i64 = 0; var maxd: i64 = 0 78 i = 0 79 while i < N { 80 let wv: i64 = mod.mem[49152 + i] as i64 81 let nv: i64 = dR[i] as i64 82 let d: i64 = g_abs(wv - nv) 83 if d != 0 { mismatch = mismatch + 1 } 84 if d > maxd { maxd = d } 85 i = i + 1 86 } 87 g_puts(" [R2] codec via VM vs native (16x16): native stream bits=" as *u8); g_pn((vc_enc_frame_packed(cur, prev, eR, W, H, QP, 1, SAD, stream, blk, mv))) 88 g_puts(" wasm stream bits=" as *u8); g_pn(wbits); g_puts("\n" as *u8) 89 g_puts(" [R2] decoded-frame diff (wasm vs native): mismatching px=" as *u8); g_pn(mismatch); g_puts(" / " as *u8); g_pn(N); g_puts(" max-diff=" as *u8); g_pn(maxd); g_puts("\n" as *u8) 90 pass = pass + g_check("R2 wasm codec decodes BIT-EXACT to native (shipped wasm is correct)" as *u8, mismatch == 0); total=total+1 91 92 g_puts("---- wasm_vm exec gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8) 93 if pass == total { g_puts("verdict=GREEN\n" as *u8); sys_exit(0); return 0 } 94 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1 95}