nx_wall_scan_native.nx source
↩ module page · 219 lines · 7439 B
1// nx_wall_scan_native.nx -- substrate-native wall-tier scanner.
2//
3// license_tier: ORIGINAL
4//
5// Substrate-native equivalent of `bench/wall_scan.sh --count`.
6// Walks runtime/*.nx via sys_getdents64 + sys_read_file, classifies
7// each by license_tier header, prints aggregate counts. Zero
8// fork+exec; single binary; typed sealed-verdict per file.
9//
10// Bench against shell-pipeline wall_scan.sh:
11// shell v3: ~2.3s on 5019 files (one grep -nHE + awk)
12// native: measured by `time qemu-riscv64-static nx_wall_scan.elf`
13//
14// Honest verdict on completion.
15
16// nx_safety_envelope:
17// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
18// sil_target: SIL1
19// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
20// verdict: NOT_YET_EVALUATED
21
22import "nx_syscalls.nx"
23import "nx_dirent.nx"
24import "nx_fcntl.nx"
25
26const TIER_NONE: i64 = 0
27const TIER_T0: i64 = 1
28const TIER_REDERIVE: i64 = 2
29const TIER_ORIG: i64 = 3
30const TIER_OTHER: i64 = 4
31
32const DIR_BUF_CAP: i64 = 32768
33const FILE_HEAD_CAP: i64 = 4096 // license headers live in first ~2KB
34const PATH_BUF_CAP: i64 = 512
35
36// Compare buf[off..off+n] against the literal `needle` (caller passes
37// a NUL-terminated needle plus its length).
38func _eq_at(buf: *u8, n: i64, off: i64, needle: *u8, nlen: i64) -> i64 {
39 if off < 0 { return 0 }
40 if off + nlen > n { return 0 }
41 var k: i64 = 0
42 while k < nlen {
43 let a: i64 = buf[off + k] as i64
44 let b: i64 = needle[k] as i64
45 if (a & 255) != (b & 255) { return 0 }
46 k = k + 1
47 }
48 return 1
49}
50
51// Classify a file by scanning its bytes for `// license_tier: VALUE`
52// at start-of-line. Returns one of the TIER_* enum values.
53func classify_bytes(buf: *u8, n: i64) -> i64 {
54 if n <= 0 { return TIER_NONE }
55 let tag: *u8 = "// license_tier:" as *u8
56 let tag_len: i64 = 16
57 var i: i64 = 0
58 while i + tag_len < n {
59 // start-of-file OR previous byte is newline
60 var at_sol: i64 = 0
61 if i == 0 { at_sol = 1 }
62 else {
63 let prev: i64 = buf[i - 1] as i64
64 if (prev & 255) == 10 { at_sol = 1 }
65 }
66 if at_sol == 1 {
67 if _eq_at(buf, n, i, tag, tag_len) == 1 {
68 // Skip leading spaces. Stop at first non-space byte;
69 // `after` is the index of that first non-space byte.
70 var j: i64 = i + tag_len
71 var after: i64 = j
72 var stop: i64 = 0
73 while stop == 0 {
74 if j >= n { after = j; stop = 1 }
75 else {
76 let c: i64 = buf[j] as i64
77 if (c & 255) == 32 { j = j + 1 }
78 else { after = j; stop = 1 }
79 }
80 }
81 // Match each known tier
82 let t0: *u8 = "TIER_0_UNENCUMBERED" as *u8
83 let ir: *u8 = "INDEPENDENT_REDERIVE" as *u8
84 let og: *u8 = "ORIGINAL" as *u8
85 if _eq_at(buf, n, after, t0, 19) == 1 { return TIER_T0 }
86 if _eq_at(buf, n, after, ir, 20) == 1 { return TIER_REDERIVE }
87 if _eq_at(buf, n, after, og, 8) == 1 { return TIER_ORIG }
88 return TIER_OTHER
89 }
90 }
91 i = i + 1
92 }
93 return TIER_NONE
94}
95
96// Build "runtime/<name>" in path_buf. Returns total length.
97func _build_path(path_buf: *u8, name: *u8, name_len: i64) -> i64 {
98 let prefix: *u8 = "runtime/" as *u8
99 var i: i64 = 0
100 while i < 8 { path_buf[i] = prefix[i]; i = i + 1 }
101 var j: i64 = 0
102 while j < name_len {
103 path_buf[8 + j] = name[j]
104 j = j + 1
105 }
106 path_buf[8 + name_len] = 0
107 return 8 + name_len
108}
109
110// Check that name ends in ".nx".
111func _ends_in_nx(name: *u8, n: i64) -> i64 {
112 if n < 3 { return 0 }
113 let dot: i64 = name[n - 3] as i64
114 let nn: i64 = name[n - 2] as i64
115 let xx: i64 = name[n - 1] as i64
116 if (dot & 255) != 46 { return 0 }
117 if (nn & 255) != 110 { return 0 }
118 if (xx & 255) != 120 { return 0 }
119 return 1
120}
121
122// Tiny formatted i64 printer (forward of main).
123func print_i64_field(label: *u8, v: i64) -> i64 {
124 sys_write(1, " " as *u8, 2)
125 var i: i64 = 0
126 while label[i] != 0 { i = i + 1 }
127 sys_write(1, label, i)
128 sys_write(1, " = " as *u8, 3)
129 let buf: *u8 = sys_mmap(32)
130 var n: i64 = 0
131 if v == 0 { buf[0] = 48; n = 1 }
132 else {
133 var x: i64 = v
134 if x < 0 { buf[0] = 45; n = 1; x = 0 - x }
135 var digits: i64 = 0
136 var tmp: i64 = x
137 while tmp > 0 { tmp = tmp / 10; digits = digits + 1 }
138 var k: i64 = 0
139 while k < digits {
140 let d: i64 = x % 10
141 buf[n + digits - 1 - k] = (48 + d) & 0xff
142 x = x / 10
143 k = k + 1
144 }
145 n = n + digits
146 }
147 buf[n] = 10
148 sys_write(1, buf, n + 1)
149 return 0
150}
151
152func main() -> i64 {
153 let dirpath: *u8 = "runtime" as *u8
154 let fd: i64 = nx_open_rd(dirpath)
155 if fd < 0 {
156 sys_write(2, "open runtime: failed\n" as *u8, 21)
157 return 1
158 }
159
160 let dirbuf: *u8 = sys_mmap(DIR_BUF_CAP + 64)
161 let pathbuf: *u8 = sys_mmap(PATH_BUF_CAP)
162 let filebuf_len_p: *i64 = sys_mmap(16) as *i64
163
164 var n_total: i64 = 0
165 var n_missing: i64 = 0
166 var n_t0: i64 = 0
167 var n_rederive: i64 = 0
168 var n_orig: i64 = 0
169 var n_other: i64 = 0
170
171 var d: NxDirent
172 var done: i64 = 0
173 while done == 0 {
174 let n: i64 = nx_dirent_read(fd, dirbuf, DIR_BUF_CAP)
175 if n <= 0 { done = 1 }
176 else {
177 var off: i64 = 0
178 while off < n {
179 off = nx_dirent_iter(dirbuf, off, n, &d)
180 if off < 0 { off = n }
181 else {
182 let name_len: i64 = nx_dirent_name_len(&d)
183 if _ends_in_nx(d.name, name_len) == 1 {
184 n_total = n_total + 1
185 let pn: i64 = _build_path(pathbuf, d.name, name_len)
186 let file: *u8 = sys_read_file(pathbuf, filebuf_len_p)
187 if file == (0 as *u8) {
188 n_missing = n_missing + 1
189 } else {
190 let flen: i64 = filebuf_len_p[0]
191 var scan_len: i64 = flen
192 if flen > FILE_HEAD_CAP { scan_len = FILE_HEAD_CAP }
193 let t: i64 = classify_bytes(file, scan_len)
194 if t == TIER_T0 { n_t0 = n_t0 + 1 }
195 if t == TIER_REDERIVE { n_rederive = n_rederive + 1 }
196 if t == TIER_ORIG { n_orig = n_orig + 1 }
197 if t == TIER_OTHER { n_other = n_other + 1 }
198 if t == TIER_NONE { n_missing = n_missing + 1 }
199 }
200 }
201 }
202 }
203 }
204 }
205
206 sys_close(fd)
207
208 // Print summary as plain text.
209 let hdr: *u8 = "nx_wall_scan_native -- substrate-native sweep\n" as *u8
210 sys_write(1, hdr, 46)
211 print_i64_field("total", n_total)
212 print_i64_field("tier0", n_t0)
213 print_i64_field("rederive", n_rederive)
214 print_i64_field("original", n_orig)
215 print_i64_field("other", n_other)
216 print_i64_field("missing", n_missing)
217 return 0
218}
219