code wiki / _hdl_build / nx_cand_build_run.nx

nx_cand_build_run.nx source

↩ module page · 101 lines · 5689 B

1// nx_cand_build_run.nx -- build a CANDIDATE sovereign compiler from current source and use it to 2// build+run a target module, WITHOUT swapping the live _offc/nx_cc_sovereign.elf. This is the 3// zero-risk way to exercise a NEW compiler intrinsic (here __mul256_wide): the live compiler that 4// ~7400 organs depend on is never touched; the candidate lives only at /tmp. 5// phase 1: live cc compiles runtime/nx_compile_x86.nx -> /tmp/candcc.s ; nxasm -> /tmp/candcc.elf 6// phase 2: candcc compiles runtime/<argv1>.nx -> /tmp/<argv1>.s ; nxasm -> /tmp/<argv1>.elf ; run it 7// Retry-guards nx_cc's empty/truncated-.s nondeterminism (same guard as nx_sov_build_run). 8// Usage: nx_cand_build_run <module-basename-in-runtime>. license_tier: ORIGINAL 9import "nx_syscalls.nx" 10import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 11const CBR_MAGIC_65536: i64 = 65536 12 13const CBR_MIN_ASM: i64 = 128 14const CBR_RETRIES: i64 = 14 15const LIVE_CC: *u8 = "_offc/nx_cc_sovereign.elf" 16const ASM_TOOL: *u8 = "_offc/nxasm_x86_main.elf" 17const CAND_SRC: *u8 = "runtime/nx_compile_x86.nx" 18const CAND_S: *u8 = "/tmp/candcc.s" 19const CAND_CC: *u8 = "/tmp/candcc.elf" 20 21func cbr_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 22// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 23// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 24// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 25// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 26func cbr_putn(v: i64) -> i64 { nxi_out(v); return 0 } 27func cbr_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { dst[off+i] = s[i]; i = i + 1 } return off + i } 28 29func cbr_run(path: *u8, argv: *i64, envp: *i64, redir_out: i64, redir_err: i64) -> i64 { 30 let pid: i64 = sys_fork() 31 if pid == 0 { 32 if redir_out >= 0 { sys_dup3(redir_out, 1, 0) } 33 if redir_err >= 0 { sys_dup3(redir_err, 2, 0) } 34 sys_execve(path, argv, envp); sys_exit(127) 35 } 36 let st: *i64 = sys_mmap(16) as *i64 37 sys_wait4(pid, st, 0) 38 let sig: i64 = st[0] & 0x7f 39 if sig != 0 { return 128 + sig } 40 return (st[0] >> 8) & 0xff 41} 42func cbr_filesize(path: *u8) -> i64 { 43 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } 44 let buf: *u8 = sys_mmap(CBR_MAGIC_65536); var total: i64 = 0 45 var n: i64 = sys_read(fd, buf, CBR_MAGIC_65536); while n > 0 { total = total + n; n = sys_read(fd, buf, CBR_MAGIC_65536) } 46 sys_close(fd); return total 47} 48 49// compile src.nx with `compiler` -> sout (.s), assemble -> eout (.elf); retry-guarded. 1=ok 0=fail. 50func cbr_build(compiler: *u8, srcpath: *u8, sout: *u8, eout: *u8, envp: *i64, devnull: i64) -> i64 { 51 var tries: i64 = 0 52 while tries < CBR_RETRIES { 53 let sfd: i64 = sys_openat_wr(sout, 0x1a4) 54 let cc: *i64 = sys_mmap(8*4) as *i64 55 cc[0] = compiler as i64; cc[1] = srcpath as i64; cc[2] = 0 56 let rc_c: i64 = cbr_run(compiler, cc, envp, sfd, devnull) 57 sys_close(sfd) 58 if rc_c == 0 { if cbr_filesize(sout) > CBR_MIN_ASM { 59 let aa: *i64 = sys_mmap(8*4) as *i64 60 aa[0] = ASM_TOOL as i64; aa[1] = sout as i64; aa[2] = eout as i64; aa[3] = 0 61 let rc_a: i64 = cbr_run(ASM_TOOL, aa, envp, 0 - 1, 0 - 1) 62 if rc_a == 0 { return 1 } 63 } } 64 tries = tries + 1 65 } 66 return 0 67} 68 69func main(argc: i64, argv: *i64) -> i64 { 70 if argc < 2 { cbr_puts("usage: nx_cand_build_run <module-basename>\n" as *u8); return 2 } 71 let name: *u8 = argv[1] as *u8 72 let envp: *i64 = sys_mmap(8*4) as *i64 73 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 74 let devnull: i64 = sys_openat_wr("/dev/null" as *u8, 0x1a4) 75 76 cbr_puts("[cand] phase1: building candidate compiler from " as *u8); cbr_puts(CAND_SRC); cbr_puts("\n" as *u8) 77 if cbr_build(LIVE_CC, CAND_SRC, CAND_S, CAND_CC, envp, devnull) == 0 { 78 cbr_puts("[cand] FAIL: candidate compiler did not build (source compile/asm error)\n" as *u8); sys_exit(3); return 3 79 } 80 cbr_puts("[cand] candidate compiler ready -> " as *u8); cbr_puts(CAND_CC); cbr_puts("\n" as *u8) 81 82 // resolve the target source: runtime/<name>.nx then runtime/_hdl_build/<name>.nx 83 let src: *u8 = sys_mmap(512); var o: i64 = 0 84 o = cbr_cat(src, 0, "runtime/" as *u8); o = cbr_cat(src, o, name); o = cbr_cat(src, o, ".nx" as *u8); src[o] = 0 as u8 85 let chk: i64 = sys_openat_rd(src) 86 if chk < 0 { o = cbr_cat(src, 0, "runtime/_hdl_build/" as *u8); o = cbr_cat(src, o, name); o = cbr_cat(src, o, ".nx" as *u8); src[o] = 0 as u8 } else { sys_close(chk) } 87 88 let tsout: *u8 = sys_mmap(256); o = cbr_cat(tsout, 0, "/tmp/" as *u8); o = cbr_cat(tsout, o, name); o = cbr_cat(tsout, o, ".s" as *u8); tsout[o] = 0 as u8 89 let teout: *u8 = sys_mmap(256); o = cbr_cat(teout, 0, "/tmp/" as *u8); o = cbr_cat(teout, o, name); o = cbr_cat(teout, o, ".cand.elf" as *u8); teout[o] = 0 as u8 90 91 cbr_puts("[cand] phase2: building " as *u8); cbr_puts(name); cbr_puts(" with the candidate compiler\n" as *u8) 92 if cbr_build(CAND_CC, src, tsout, teout, envp, devnull) == 0 { 93 cbr_puts("[cand] FAIL: target did not build with the candidate compiler\n" as *u8); sys_exit(4); return 4 94 } 95 cbr_puts("[cand] running " as *u8); cbr_puts(teout); cbr_puts("\n" as *u8) 96 let rv: *i64 = sys_mmap(8*4) as *i64 97 rv[0] = teout as i64; rv[1] = 0 98 let rc: i64 = cbr_run(teout, rv, envp, 0 - 1, 0 - 1) 99 cbr_puts("[cand] target exit=" as *u8); cbr_putn(rc); cbr_puts("\n" as *u8) 100 sys_exit(rc); return rc 101}