code wiki / _hdl_build / nx_room_protocol_gate.nx

nx_room_protocol_gate.nx source

↩ module page · 188 lines · 8414 B

1import "nx_gate_base.nx" 2// nx_room_protocol_gate.nx -- the room wire/memory CONTRACT as a Nishi-owned SSOT (api-first). 3// The video room's protocol constants (linear-memory region map + lane/codec params) were hand-duplicated 4// across app.v2.js AND nishi-video.component.js AND the wasm core -- three hand-maintained copies of one 5// contract (violates rule #11 no-magic-numbers + rule #15 DRY). This organ makes NishiLang the SINGLE 6// source of truth: it (1) EMITS the documented contract web_assets/nishi_room_protocol.txt and (2) VALIDATES 7// that BOTH shipped JS clients conform to it. Any client that drifts a constant -> RED. A mobile-native 8// client consumes the SAME contract with ZERO JS. This is the "lean into nishi lang / api-first" rung. 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_syscalls.nx" 11 12func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 13" as *u8); return ok } 14func gn(v: i64) -> i64 { 15 let b: *u8=sys_mmap(28); var m: i64=v; if m<0{sys_write(1,"-" as *u8,1);m=0-m} 16 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} 17 var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 18 19// ---- the SSOT contract table (the ONE authoritative definition) ---- 20func rp_count() -> i64 { return 23 } 21func rp_name(i: i64) -> *u8 { 22 if i==0 { return "R_ID" as *u8 } 23 if i==1 { return "R_PAY" as *u8 } 24 if i==2 { return "R_WOUT" as *u8 } 25 if i==3 { return "R_WIN" as *u8 } 26 if i==4 { return "R_INFO" as *u8 } 27 if i==5 { return "R_F32" as *u8 } 28 if i==6 { return "R_FOUT" as *u8 } 29 if i==7 { return "R_PCM" as *u8 } 30 if i==8 { return "R_SCR" as *u8 } 31 if i==9 { return "R_STAGE" as *u8 } 32 if i==10 { return "R_STAGE2" as *u8 } 33 if i==11 { return "R_FTBL" as *u8 } 34 if i==12 { return "R_FSD" as *u8 } 35 if i==13 { return "R_FSS" as *u8 } 36 if i==14 { return "R_FOUT2" as *u8 } 37 if i==15 { return "R_FSCRA" as *u8 } 38 if i==16 { return "R_FSCRSH" as *u8 } 39 if i==17 { return "R_FDEC" as *u8 } 40 if i==18 { return "R_CHAT" as *u8 } 41 if i==19 { return "R_FST" as *u8 } 42 if i==20 { return "LANES" as *u8 } 43 if i==21 { return "AUDIO_CHUNK" as *u8 } 44 if i==22 { return "R_PLAN" as *u8 } 45 return "" as *u8 } 46func rp_val(i: i64) -> i64 { 47 if i==0 { return 0x200000 } 48 if i==1 { return 0x200100 } 49 if i==2 { return 0x220000 } 50 if i==3 { return 0x240000 } 51 if i==4 { return 0x260000 } 52 if i==5 { return 0x270000 } 53 if i==6 { return 0x280000 } 54 if i==7 { return 0x290000 } 55 if i==8 { return 0x2A0000 } 56 if i==9 { return 0x300000 } 57 if i==10 { return 0x400000 } 58 if i==11 { return 0x3000000 } 59 if i==12 { return 0x3010000 } 60 if i==13 { return 0x3020000 } 61 if i==14 { return 0x3030000 } 62 if i==15 { return 0x3040000 } 63 if i==16 { return 0x3050000 } 64 if i==17 { return 0x3060000 } 65 if i==18 { return 0x3080000 } 66 if i==19 { return 0x3100000 } 67 if i==20 { return 3 } 68 if i==21 { return 1024 } 69 if i==22 { return 0x2B0000 } // mb_plan output region (9 i64) -- the resource-intelligence API 70 return 0 } 71 72func is_ic(c: i64) -> i64 { 73 if c>=48 { if c<=57 { return 1 } } 74 if c>=65 { if c<=90 { return 1 } } 75 if c>=97 { if c<=122 { return 1 } } 76 if c==95 { return 1 } 77 return 0 } 78 79// parse an integer literal at hay[p0..] -- supports 0x hex and decimal 80func parse_int_at(hay: *u8, n: i64, p0: i64) -> i64 { 81 var p: i64 = p0 82 var base: i64 = 10 83 if p+1<n { if (hay[p] as i64)==48 { if (hay[p+1] as i64)==120 { base=16; p=p+2 } } } 84 var v: i64 = 0 85 var g: i64 = 1 86 while g==1 { 87 if p<n { 88 let c: i64 = hay[p] as i64 89 var d: i64 = 0-1 90 if c>=48 { if c<=57 { d=c-48 } } 91 if base==16 { if c>=97 { if c<=102 { d=c-97+10 } } } 92 if base==16 { if c>=65 { if c<=70 { d=c-65+10 } } } 93 if d<0 { g=0 } else { v=v*base+d; p=p+1 } 94 } else { g=0 } 95 } 96 return v } 97 98// find whole-word `name` FOLLOWED BY `= <int>` (a definition, not a usage); return value or -1 99func find_word_int(hay: *u8, n: i64, name: *u8) -> i64 { 100 var nl: i64=0; while name[nl]!=(0 as u8){nl=nl+1} 101 var i: i64=0 102 while i+nl<=n { 103 var j: i64=0; var ok: i64=1 104 while j<nl { if hay[i+j]!=name[j]{ok=0;j=nl} else {j=j+1} } 105 if ok==1 { 106 var bound: i64=1 107 if i>0 { if is_ic(hay[i-1] as i64)==1 { bound=0 } } 108 if i+nl<n { if is_ic(hay[i+nl] as i64)==1 { bound=0 } } 109 if bound==1 { 110 var p: i64=i+nl 111 var g: i64=1 112 while g==1 { if p<n { if (hay[p] as i64)==32 { p=p+1 } else { g=0 } } else { g=0 } } 113 if p<n { if (hay[p] as i64)==61 { 114 p=p+1 115 var g3: i64=1 116 while g3==1 { if p<n { if (hay[p] as i64)==32 { p=p+1 } else { g3=0 } } else { g3=0 } } 117 if p<n { if (hay[p] as i64)>=48 { if (hay[p] as i64)<=57 { return parse_int_at(hay,n,p) } } } 118 } } 119 } 120 } 121 i=i+1 122 } 123 return 0 - 1 } 124 125func fw(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 } 126func fhex(fd: i64, v: i64) -> i64 { 127 sys_write(fd, "0x" as *u8, 2) 128 let t: *u8 = sys_mmap(24); var m: i64=v; var k: i64=0 129 if m==0 { t[0]=48 as u8; k=1 } 130 while m>0 { let d: i64=m%16; if d<10 { t[k]=(48+d) as u8 } else { t[k]=(97+d-10) as u8 } m=m/16; k=k+1 } 131 let b: *u8 = sys_mmap(24); var i: i64=0 132 while i<k { b[i]=t[k-1-i]; i=i+1 } 133 sys_write(fd, b, k); return 0 } 134func fdec(fd: i64, v: i64) -> i64 { 135 let t: *u8 = sys_mmap(24); var m: i64=v; var k: i64=0 136 if m==0 { t[0]=48 as u8; k=1 } 137 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } 138 let b: *u8 = sys_mmap(24); var i: i64=0 139 while i<k { b[i]=t[k-1-i]; i=i+1 } 140 sys_write(fd, b, k); return 0 } 141 142func main() -> i64 { 143 gw("=== nx_room_protocol_gate: Nishi-owned room contract SSOT + client conformance ===\n" as *u8) 144 // read both shipped JS clients 145 let abox: *i64 = sys_mmap(16) as *i64; abox[0]=0 146 let app: *u8 = sys_read_file("sites/nishifamily/video/app.v2.js" as *u8, abox) 147 if (app as i64)==0 { gw("no app.v2.js\n" as *u8); return 1 } 148 let an: i64 = abox[0] 149 let cbox: *i64 = sys_mmap(16) as *i64; cbox[0]=0 150 let comp: *u8 = sys_read_file("sites/nishifamily/video/nishi-video.component.js" as *u8, cbox) 151 if (comp as i64)==0 { gw("no nishi-video.component.js\n" as *u8); return 1 } 152 let cn: i64 = cbox[0] 153 154 // 1. EMIT the documented contract (the SSOT artifact any client -- web OR mobile-native -- consumes) 155 let fd: i64 = sys_openat_wr("web_assets/nishi_room_protocol.txt" as *u8, 0x1a4) 156 if fd < 0 { gw("cannot write nishi_room_protocol.txt\n" as *u8); return 1 } 157 fw(fd, "# Nishi Room Protocol -- SSOT (emitted by nx_room_protocol_gate). Clients CONSUME; never hand-copy.\n" as *u8) 158 fw(fd, "# wasm linear-memory region map + lane/codec params. A mobile-native client uses these with ZERO JS.\n" as *u8) 159 var t: i64 = 0 160 while t < rp_count() { 161 fw(fd, rp_name(t)); fw(fd, "=" as *u8); fhex(fd, rp_val(t)); fw(fd, " (" as *u8); fdec(fd, rp_val(t)); fw(fd, ")\n" as *u8) 162 t = t + 1 163 } 164 sys_close(fd) 165 gw(" emitted web_assets/nishi_room_protocol.txt (" as *u8); gn(rp_count()); gw(" contract constants)\n" as *u8) 166 167 // 2. VALIDATE both clients conform to the SSOT 168 var green: i64 = 1 169 var i: i64 = 0 170 while i < rp_count() { 171 let want: i64 = rp_val(i) 172 let av: i64 = find_word_int(app, an, rp_name(i)) 173 let cv: i64 = find_word_int(comp, cn, rp_name(i)) 174 var okrow: i64 = 1 175 if av != want { okrow = 0 } 176 if cv != want { okrow = 0 } 177 gw(" " as *u8); gw(rp_name(i)) 178 gw(" want=" as *u8); gn(want); gw(" app.v2=" as *u8); gn(av); gw(" component=" as *u8); gn(cv) 179 if okrow==1 { gw(" OK\n" as *u8) } else { gw(" !!! DRIFT\n" as *u8); green=0 } 180 i = i + 1 181 } 182 if green==1 { 183 gw("ROOM-PROTOCOL-GATE verdict=GREEN -- both JS clients conform to the Nishi-owned contract SSOT\n" as *u8) 184 return 0 185 } 186 gw("ROOM-PROTOCOL-GATE verdict=RED -- a client drifted from the SSOT (fix the client, not the contract)\n" as *u8) 187 return 1 188}