code wiki / (root) / nx_js_conformance.nx

nx_js_conformance.nx source

↩ module page · 233 lines · 17198 B

1// nx_js_conformance.nx -- WB-JS-001 conformance HARNESS (test262-lite, no-wave 2// MEASUREMENT, not a pass/fail gate). Composes the sovereign engine READ-ONLY 3// (imports nx_js_eval -> js_run_source) and runs a categorized battery of real JS 4// programs, asserting evaluated VALUES + expected ERRORS. Prints a per-category 5// capability map + an overall conformance permil -- the honest measure of what the 6// engine does today and what's still gapped (drives the next eval rungs). 7// 8// This is a SEPARATE organ (does NOT edit nx_js_eval) so it can ride the engine 9// while the evaluator is authored independently. Each case is a real spec behavior; 10// FAILs are NAMED, never hidden -- the score is the truth, not a wave. license_tier: ORIGINAL 11import "nx_js_eval.nx" 12import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 13 14func jc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 15// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 16// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 17// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 18// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 19func jc_putn(v: i64) -> i64 { nxi_out(v); return 0 } 20func jc_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 21 22// ---- assertion primitives over js_run_source ---- 23func jc_num(s: *u8, want: i64) -> i64 { 24 let out: *i64 = sys_mmap(16) as *i64 25 if js_run_source(s, jc_slen(s), out) != 0 { return 0 } 26 if out[0] != VAL_NUM { return 0 } 27 if out[1] != want { return 0 } 28 return 1 29} 30func jc_bool(s: *u8, want: i64) -> i64 { 31 let out: *i64 = sys_mmap(16) as *i64 32 if js_run_source(s, jc_slen(s), out) != 0 { return 0 } 33 if out[0] != VAL_BOOL { return 0 } 34 if out[1] != want { return 0 } 35 return 1 36} 37func jc_str(s: *u8, want: *u8) -> i64 { 38 let out: *i64 = sys_mmap(16) as *i64 39 if js_run_source(s, jc_slen(s), out) != 0 { return 0 } 40 if out[0] != VAL_STR { return 0 } 41 let rec: *i64 = (out[1]) as *i64 42 let en: i64 = jc_slen(want) 43 if ev_str_len(rec) != en { return 0 } 44 let rb: *u8 = ev_str_bytes(rec) 45 var i: i64 = 0 46 while i < en { if (rb[i] & 0xff) != (want[i] & 0xff) { return 0 } i = i + 1 } 47 return 1 48} 49func jc_err(s: *u8) -> i64 { 50 let out: *i64 = sys_mmap(16) as *i64 51 if js_run_source(s, jc_slen(s), out) == 1 { return 1 } 52 return 0 53} 54 55// run a single case, print PASS/FAIL with the label, return 1/0 to tally. 56func jc_case(ok: i64, label: *u8) -> i64 { 57 if ok == 1 { jc_puts(" ok " as *u8) } else { jc_puts(" FAIL " as *u8) } 58 jc_puts(label); jc_puts("\n" as *u8) 59 return ok 60} 61 62func main() -> i64 { 63 var pass: i64 = 0 64 var tot: i64 = 0 65 jc_puts("nx_js_conformance (WB-JS-001 test262-lite, no-wave measurement)\n" as *u8) 66 67 // ---- arithmetic ---- 68 jc_puts(" [arithmetic]\n" as *u8) 69 pass = pass + jc_case(jc_num("2+2\x00" as *u8, 4), "2+2=4\x00" as *u8); tot=tot+1 70 pass = pass + jc_case(jc_num("10-3\x00" as *u8, 7), "10-3=7\x00" as *u8); tot=tot+1 71 pass = pass + jc_case(jc_num("4*5\x00" as *u8, 20), "4*5=20\x00" as *u8); tot=tot+1 72 pass = pass + jc_case(jc_num("20/4\x00" as *u8, 5), "20/4=5\x00" as *u8); tot=tot+1 73 pass = pass + jc_case(jc_num("17%5\x00" as *u8, 2), "17%5=2\x00" as *u8); tot=tot+1 74 75 // ---- precedence / associativity ---- 76 jc_puts(" [precedence]\n" as *u8) 77 pass = pass + jc_case(jc_num("1+2*3\x00" as *u8, 7), "1+2*3=7\x00" as *u8); tot=tot+1 78 pass = pass + jc_case(jc_num("(1+2)*3\x00" as *u8, 9), "(1+2)*3=9\x00" as *u8); tot=tot+1 79 pass = pass + jc_case(jc_num("10-2-3\x00" as *u8, 5), "10-2-3=5 (left-assoc)\x00" as *u8); tot=tot+1 80 pass = pass + jc_case(jc_num("2+3*4-1\x00" as *u8, 13), "2+3*4-1=13\x00" as *u8); tot=tot+1 81 82 // ---- comparison / equality ---- 83 jc_puts(" [comparison]\n" as *u8) 84 pass = pass + jc_case(jc_bool("2<3\x00" as *u8, 1), "2<3=true\x00" as *u8); tot=tot+1 85 pass = pass + jc_case(jc_bool("3<2\x00" as *u8, 0), "3<2=false\x00" as *u8); tot=tot+1 86 pass = pass + jc_case(jc_bool("5<=5\x00" as *u8, 1), "5<=5=true\x00" as *u8); tot=tot+1 87 pass = pass + jc_case(jc_bool("3==3\x00" as *u8, 1), "3==3=true\x00" as *u8); tot=tot+1 88 pass = pass + jc_case(jc_bool("2===2\x00" as *u8, 1), "2===2=true\x00" as *u8); tot=tot+1 89 pass = pass + jc_case(jc_bool("2!==3\x00" as *u8, 1), "2!==3=true\x00" as *u8); tot=tot+1 90 91 // ---- logical / truthiness ---- 92 jc_puts(" [logical]\n" as *u8) 93 pass = pass + jc_case(jc_num("1&&2\x00" as *u8, 2), "1&&2=2 (operand)\x00" as *u8); tot=tot+1 94 pass = pass + jc_case(jc_num("0||5\x00" as *u8, 5), "0||5=5\x00" as *u8); tot=tot+1 95 pass = pass + jc_case(jc_num("0&&9\x00" as *u8, 0), "0&&9=0\x00" as *u8); tot=tot+1 96 pass = pass + jc_case(jc_bool("!0\x00" as *u8, 1), "!0=true\x00" as *u8); tot=tot+1 97 pass = pass + jc_case(jc_bool("!!5\x00" as *u8, 1), "!!5=true\x00" as *u8); tot=tot+1 98 99 // ---- strings ---- 100 jc_puts(" [strings]\n" as *u8) 101 pass = pass + jc_case(jc_str("'ab'+'cd'\x00" as *u8, "abcd\x00" as *u8), "'ab'+'cd'='abcd'\x00" as *u8); tot=tot+1 102 pass = pass + jc_case(jc_str("'x'+'y'+'z'\x00" as *u8, "xyz\x00" as *u8), "'x'+'y'+'z'='xyz'\x00" as *u8); tot=tot+1 103 pass = pass + jc_case(jc_str("'n='+5\x00" as *u8, "n=5\x00" as *u8), "'n='+5='n=5' (coerce)\x00" as *u8); tot=tot+1 104 pass = pass + jc_case(jc_bool("'a'=='a'\x00" as *u8, 1), "'a'=='a'=true\x00" as *u8); tot=tot+1 105 pass = pass + jc_case(jc_bool("'a'=='b'\x00" as *u8, 0), "'a'=='b'=false\x00" as *u8); tot=tot+1 106 107 // ---- variables / assignment ---- 108 jc_puts(" [variables]\n" as *u8) 109 pass = pass + jc_case(jc_num("var x=5; x+1\x00" as *u8, 6), "var x=5;x+1=6\x00" as *u8); tot=tot+1 110 pass = pass + jc_case(jc_num("var x=5; x=x+10; x\x00" as *u8, 15), "reassign x=15\x00" as *u8); tot=tot+1 111 pass = pass + jc_case(jc_num("var a=1; var b=2; a+b\x00" as *u8, 3), "two vars a+b=3\x00" as *u8); tot=tot+1 112 113 // ---- control flow ---- 114 jc_puts(" [control-flow]\n" as *u8) 115 pass = pass + jc_case(jc_num("var x=10; if(x>5)x=1; else x=0; x\x00" as *u8, 1), "if-true branch\x00" as *u8); tot=tot+1 116 pass = pass + jc_case(jc_num("var x=2; if(x>5)x=1; else x=0; x\x00" as *u8, 0), "if-else branch\x00" as *u8); tot=tot+1 117 pass = pass + jc_case(jc_num("var s=0; var i=1; while(i<=5){s=s+i;i=i+1;} s\x00" as *u8, 15), "while sum 1..5=15\x00" as *u8); tot=tot+1 118 119 // ---- functions / recursion / closures ---- 120 jc_puts(" [functions]\n" as *u8) 121 pass = pass + jc_case(jc_num("function add(a,b){return a+b;} add(2,3)\x00" as *u8, 5), "add(2,3)=5\x00" as *u8); tot=tot+1 122 pass = pass + jc_case(jc_num("function fac(n){if(n<=1){return 1;} return n*fac(n-1);} fac(5)\x00" as *u8, 120), "fac(5)=120\x00" as *u8); tot=tot+1 123 pass = pass + jc_case(jc_num("function fib(n){if(n<2){return n;} return fib(n-1)+fib(n-2);} fib(10)\x00" as *u8, 55), "fib(10)=55\x00" as *u8); tot=tot+1 124 pass = pass + jc_case(jc_num("function o(){var x=10; function i(){return x;} return i();} o()\x00" as *u8, 10), "nested fn closes over local=10\x00" as *u8); tot=tot+1 125 126 // ---- objects / arrays (probes the NEXT rung; FAIL here = honest named-open) ---- 127 jc_puts(" [objects/arrays]\n" as *u8) 128 pass = pass + jc_case(jc_num("var o={x:10}; o.x\x00" as *u8, 10), "object literal + member read {x:10}.x=10\x00" as *u8); tot=tot+1 129 pass = pass + jc_case(jc_num("var o={}; o.a=5; o.a\x00" as *u8, 5), "object member assign o.a=5\x00" as *u8); tot=tot+1 130 pass = pass + jc_case(jc_num("var a=[10,20,30]; a[1]\x00" as *u8, 20), "array literal + index a[1]=20\x00" as *u8); tot=tot+1 131 pass = pass + jc_case(jc_num("[1,2,3,4].length\x00" as *u8, 4), "array .length=4\x00" as *u8); tot=tot+1 132 pass = pass + jc_case(jc_num("'hello'.length\x00" as *u8, 5), "string .length=5\x00" as *u8); tot=tot+1 133 134 // ---- extended control flow (for / do-while / break / continue) ---- 135 jc_puts(" [control-flow-ext]\n" as *u8) 136 pass = pass + jc_case(jc_num("var s=0; for(var i=0;i<5;i=i+1){s=s+i;} s\x00" as *u8, 10), "for loop sum 0..4 = 10\x00" as *u8); tot=tot+1 137 pass = pass + jc_case(jc_num("var i=0; var s=0; do{s=s+i;i=i+1;}while(i<3); s\x00" as *u8, 3), "do-while sum 0..2 = 3\x00" as *u8); tot=tot+1 138 pass = pass + jc_case(jc_num("var s=0; var i=0; while(i<10){if(i==3)break; s=s+i; i=i+1;} s\x00" as *u8, 3), "break at i==3 -> 0+1+2=3\x00" as *u8); tot=tot+1 139 pass = pass + jc_case(jc_num("var s=0; var i=0; while(i<5){i=i+1; if(i==3)continue; s=s+i;} s\x00" as *u8, 12), "continue skip 3 -> 1+2+4+5=12\x00" as *u8); tot=tot+1 140 141 // ---- extended operators (ternary / compound assign) ---- 142 jc_puts(" [operators-ext]\n" as *u8) 143 pass = pass + jc_case(jc_num("var x=5; x>3?100:200\x00" as *u8, 100), "ternary true -> 100\x00" as *u8); tot=tot+1 144 pass = pass + jc_case(jc_num("var x=2; x>3?100:200\x00" as *u8, 200), "ternary false -> 200\x00" as *u8); tot=tot+1 145 pass = pass + jc_case(jc_num("var x=10; x+=5; x\x00" as *u8, 15), "compound += -> 15\x00" as *u8); tot=tot+1 146 pass = pass + jc_case(jc_num("var x=10; x-=3; x\x00" as *u8, 7), "compound -= -> 7\x00" as *u8); tot=tot+1 147 pass = pass + jc_case(jc_num("var x=4; x*=3; x\x00" as *u8, 12), "compound *= -> 12\x00" as *u8); tot=tot+1 148 149 // ---- R-JS-UPDATE (rung 5a): ++/-- prefix/postfix on ident/member/index ---- 150 jc_puts(" [update-ops]\n" as *u8) 151 pass = pass + jc_case(jc_num("var i=5; i++; i\x00" as *u8, 6), "i++ -> 6\x00" as *u8); tot=tot+1 152 pass = pass + jc_case(jc_num("var i=5; var j=i++; j*10+i\x00" as *u8, 56), "postfix returns OLD (56)\x00" as *u8); tot=tot+1 153 pass = pass + jc_case(jc_num("var i=5; var j=++i; j*10+i\x00" as *u8, 66), "prefix returns NEW (66)\x00" as *u8); tot=tot+1 154 pass = pass + jc_case(jc_num("var s=0; for(var i=0;i<5;i++){s+=i;} s\x00" as *u8, 10), "for(...;i++) sum=10\x00" as *u8); tot=tot+1 155 pass = pass + jc_case(jc_num("var o={n:1}; o.n++; o.n\x00" as *u8, 2), "o.n++ -> 2\x00" as *u8); tot=tot+1 156 pass = pass + jc_case(jc_num("var a=[7]; a[0]--; a[0]\x00" as *u8, 6), "a[0]-- -> 6\x00" as *u8); tot=tot+1 157 158 // ---- R-JS-F64 / P8 (real-JS IEEE-double number model): non-exact div -> double; /0 -> Inf/NaN ---- 159 jc_puts(" [numbers-f64]\n" as *u8) 160 pass = pass + jc_case(jc_str("''+7/2\x00" as *u8, "3.5\x00" as *u8), "7/2 = 3.5 (not int 3)\x00" as *u8); tot=tot+1 161 pass = pass + jc_case(jc_num("6/2\x00" as *u8, 3), "6/2 = 3 (exact stays int)\x00" as *u8); tot=tot+1 162 pass = pass + jc_case(jc_str("''+1/0\x00" as *u8, "Infinity\x00" as *u8), "1/0 = Infinity (not error)\x00" as *u8); tot=tot+1 163 pass = pass + jc_case(jc_str("''+(0-1/0)\x00" as *u8, "-Infinity\x00" as *u8), "-1/0 = -Infinity\x00" as *u8); tot=tot+1 164 pass = pass + jc_case(jc_str("''+0/0\x00" as *u8, "NaN\x00" as *u8), "0/0 = NaN\x00" as *u8); tot=tot+1 165 pass = pass + jc_case(jc_str("''+5%0\x00" as *u8, "NaN\x00" as *u8), "5%0 = NaN\x00" as *u8); tot=tot+1 166 pass = pass + jc_case(jc_num("7%3\x00" as *u8, 1), "7%3 = 1 (int mod exact)\x00" as *u8); tot=tot+1 167 pass = pass + jc_case(jc_str("''+1/4\x00" as *u8, "0.25\x00" as *u8), "1/4 = 0.25\x00" as *u8); tot=tot+1 168 169 // ---- OCTANE-ENABLING FEATURES (2026-07-08): bitwise, radix literals, multi-var, prototypes, ctors ---- 170 jc_puts(" [bitwise]\n" as *u8) 171 pass = pass + jc_case(jc_num("5&3\x00" as *u8, 1), "5&3 = 1\x00" as *u8); tot=tot+1 172 pass = pass + jc_case(jc_num("5|2\x00" as *u8, 7), "5|2 = 7\x00" as *u8); tot=tot+1 173 pass = pass + jc_case(jc_num("5^3\x00" as *u8, 6), "5^3 = 6\x00" as *u8); tot=tot+1 174 pass = pass + jc_case(jc_num("~5\x00" as *u8, 0 - 6), "~5 = -6\x00" as *u8); tot=tot+1 175 pass = pass + jc_case(jc_num("1<<4\x00" as *u8, 16), "1<<4 = 16\x00" as *u8); tot=tot+1 176 pass = pass + jc_case(jc_num("255>>2\x00" as *u8, 63), "255>>2 = 63\x00" as *u8); tot=tot+1 177 pass = pass + jc_case(jc_num("13>>1^53256\x00" as *u8, 53262), "richards idle: 13>>1^0xD008\x00" as *u8); tot=tot+1 178 jc_puts(" [radix literals]\n" as *u8) 179 pass = pass + jc_case(jc_num("0xFF\x00" as *u8, 255), "0xFF = 255\x00" as *u8); tot=tot+1 180 pass = pass + jc_case(jc_num("0xD008\x00" as *u8, 53256), "0xD008 = 53256\x00" as *u8); tot=tot+1 181 pass = pass + jc_case(jc_num("0o17\x00" as *u8, 15), "0o17 = 15\x00" as *u8); tot=tot+1 182 pass = pass + jc_case(jc_num("0b1011\x00" as *u8, 11), "0b1011 = 11\x00" as *u8); tot=tot+1 183 jc_puts(" [multi-declarator var]\n" as *u8) 184 pass = pass + jc_case(jc_num("var a=1,b=2,c=3; a+b+c\x00" as *u8, 6), "var a=1,b=2,c=3 -> 6\x00" as *u8); tot=tot+1 185 pass = pass + jc_case(jc_num("var p, q=5; (p==undefined?100:0)+q\x00" as *u8, 105), "var p,q=5 (p undefined)\x00" as *u8); tot=tot+1 186 jc_puts(" [prototype OOP]\n" as *u8) 187 pass = pass + jc_case(jc_num("function F(){this.x=5;}F.prototype.g=function(){return this.x*2;};new F().g()\x00" as *u8, 10), "prototype method + new\x00" as *u8); tot=tot+1 188 pass = pass + jc_case(jc_num("function A(){}A.prototype.k=9;var a=new A();a.k\x00" as *u8, 9), "inherited data property\x00" as *u8); tot=tot+1 189 jc_puts(" [native constructors]\n" as *u8) 190 pass = pass + jc_case(jc_num("new Array(4).length\x00" as *u8, 4), "new Array(4).length = 4\x00" as *u8); tot=tot+1 191 pass = pass + jc_case(jc_num("new Array(7,8,9).length\x00" as *u8, 3), "new Array(7,8,9).length = 3\x00" as *u8); tot=tot+1 192 pass = pass + jc_case(jc_str("var e=new Error('boom'); e.message\x00" as *u8, "boom\x00" as *u8), "new Error(msg).message\x00" as *u8); tot=tot+1 193 194 // ---- R-JS-TRY (rung 5b): try/catch/finally + throw ---- 195 jc_puts(" [try-catch]\n" as *u8) 196 pass = pass + jc_case(jc_num("var r=0; try{throw 5;}catch(e){r=e;} r\x00" as *u8, 5), "throw value caught -> 5\x00" as *u8); tot=tot+1 197 pass = pass + jc_case(jc_num("var r=0; try{var o={}; o.nope();}catch(e){r=7;} r\x00" as *u8, 7), "runtime error caught -> 7\x00" as *u8); tot=tot+1 198 pass = pass + jc_case(jc_str("var r=''; try{r=r+'t';}finally{r=r+'f';} r\x00" as *u8, "tf\x00" as *u8), "finally runs on normal path\x00" as *u8); tot=tot+1 199 pass = pass + jc_case(jc_str("var g=''; function f(){try{return 'A';}finally{g=g+'F';}} f()+g\x00" as *u8, "AF\x00" as *u8), "return runs finally -> AF\x00" as *u8); tot=tot+1 200 pass = pass + jc_case(jc_num("var r=0; try{try{throw 1;}catch(e){throw 2;}}catch(e2){r=e2;} r\x00" as *u8, 2), "nested rethrow -> outer catch\x00" as *u8); tot=tot+1 201 202 // ---- REAL-WORLD SHAPE: hydration-style image extraction (array of objects -> URL list). 203 // This is EXACTLY the compute google-images JS hydration does: walk a data array, 204 // filter, and build the result. If it runs, the engine is READY for the extraction 205 // half of google-images -- only the DOM/fetch DATA-binding (native fns) remains. ---- 206 jc_puts(" [hydration-shape]\n" as *u8) 207 pass = pass + jc_case(jc_str("var data=[{src:'img1',ok:1},{src:'img2',ok:0},{src:'img3',ok:1}]; var r=''; for(var i=0;i<data.length;i=i+1){ if(data[i].ok==1){ r=r+data[i].src+','; } } r\x00" as *u8, "img1,img3,\x00" as *u8), "extract valid image URLs from data-array (array<-obj, index, member, filter, concat)\x00" as *u8); tot=tot+1 208 pass = pass + jc_case(jc_num("var a=[3,1,4,1,5,9,2,6]; var mx=0; for(var i=0;i<a.length;i=i+1){ if(a[i]>mx){mx=a[i];} } mx\x00" as *u8, 9), "scan array for max = 9\x00" as *u8); tot=tot+1 209 210 // ---- error / tamper (must be ReferenceError-class, not silent) ---- 211 jc_puts(" [errors]\n" as *u8) 212 pass = pass + jc_case(jc_err("y+1\x00" as *u8), "undeclared READ y -> error\x00" as *u8); tot=tot+1 213 pass = pass + jc_case(jc_num("z=5; z\x00" as *u8, 5), "assign-to-undeclared -> NON-STRICT auto-global (V8: z=5, NOT error)\x00" as *u8); tot=tot+1 214 pass = pass + jc_case(jc_err("1+\x00" as *u8), "parse '1+' -> error\x00" as *u8); tot=tot+1 215 pass = pass + jc_case(jc_err("(1+2\x00" as *u8), "unclosed paren -> error\x00" as *u8); tot=tot+1 216 217 // ---- report ---- 218 var permil: i64 = 0 219 if tot > 0 { permil = pass * 1000 / tot } 220 jc_puts("---- conformance: passed " as *u8); jc_putn(pass); jc_puts(" / " as *u8); jc_putn(tot) 221 jc_puts(" = " as *u8); jc_putn(permil); jc_puts(" permil\n" as *u8) 222 let lfd: i64 = sys_openat_append("knowledge/status/js_engine.log\x00" as *u8, 0x1a4) 223 if lfd >= 0 { 224 sys_write(lfd, "WB-JS-CONFORMANCE harness=nx_js_conformance pass=" as *u8, 49) 225 let bb: *u8=sys_mmap(28); var m: i64=pass; var k: i64=0; if m==0{bb[0]=48;k=1}; while m>0{bb[k]=48+(m%10);m=m/10;k=k+1}; var z: i64=0; let rv: *u8=sys_mmap(28); while z<k{rv[z]=bb[k-1-z];z=z+1}; sys_write(lfd, rv, k) 226 sys_write(lfd, "/\x00" as *u8, 1) 227 let cc: *u8=sys_mmap(28); var m2: i64=tot; var k2: i64=0; if m2==0{cc[0]=48;k2=1}; while m2>0{cc[k2]=48+(m2%10);m2=m2/10;k2=k2+1}; var z2: i64=0; let rv2: *u8=sys_mmap(28); while z2<k2{rv2[z2]=cc[k2-1-z2];z2=z2+1}; sys_write(lfd, rv2, k2) 228 sys_write(lfd, " (measured, no-wave)\n" as *u8, 21) 229 sys_close(lfd) 230 } 231 sys_exit(0) 232 return 0 233}