code wiki / (root) / nx_emitmap.nx

nx_emitmap.nx source

↩ module page · 395 lines · 20591 B

1// nx_emitmap.nx -- EMISSION PROVENANCE: which function emits this text, and which constant bounds this buffer. 2// 3// WHY (operator 2026-08-23: "you shouldn't have to do so much finding -- we should have everything including 4// documentation and instructions"): the MCP transport answered a bare `{}` to any tools/call payload >= 63 KB, 5// and locating the cause took a dozen manual reads -- the serve loop's one sys_read at TSV_REQ_CAP, the loop 6// reader it never composed, the edge's 413 path. MEASURED BEFORE BUILDING (the spend gate's own instruments): 7// nx_codewiki_ask ranks prose (json_emit, nx_bodyparts), nx_capsearch ranks tool titles, a literal grep over 8// the whole corpus finds "{}" at 11 sites and NONE in the transport, because that body is a COMPOSED emission 9// (byte codes, not a literal), and nx_forkcensus indexes only `.elf` path literals. No incumbent answers the 10// two questions this organ answers in ONE call each: 11// nx_emitmap find <text> [artifact] -> every source block whose COMPOSED emitted text contains <text>, 12// as file:line function (exit 0 found, 1 none, 3 artifact absent) 13// nx_emitmap bound <CONST> [artifact] -> the definition of a *_CAP / *_MAX constant and every line that reads 14// it, as file:line function (exit 0 found, 1 none, 3 artifact absent) 15// nx_emitmap census [artifact] -> (re)build the index over the WHOLE compile corpus (exit 0; 1 REFUSED 16// when the corpus exceeds the enumerator's declared slot table -- a 17// refusal, never a silently truncated census) 18// COMPOSED, NOT LITERAL: emitted text is harvested per line by nx_refusal_shape_lib's rs_line_lits (the one 19// literal harvester the failmodes census already trusts: in-string state, escapes, `//` inside a url) and 20// glued across CONSECUTIVE emitting lines inside one function, so a message built from three literals is one 21// block -- the same unit fc_refusal_shape proved necessary. DECLARED BLIND SPOT: bytes emitted as numeric 22// codes (wc(123) for '{') carry no literal and are not indexed; `find "{}"` therefore cannot name an emitter 23// that composes braces from codes, and says so rather than answering from the nearest literal. 24// THE ARTIFACT knowledge/status/emitmap.tsv (truncate-write via tmp + fsync + rename; ONE writer): 25// E<TAB>file:line<TAB>function<TAB>preview a composed emission block (preview capped, see stamp) 26// C<TAB>file:line<TAB>function<TAB>CONST<TAB>value a *_CAP/*_MAX constant DEFINITION 27// R<TAB>file:line<TAB>function<TAB>CONST a READ of a *_CAP/*_MAX constant 28// last line, anchored BY POSITION: 29// # asof=<epoch> files=N bytes=N blocks=N consts=N reads=N unreadable=N preview_cap=512 previews_cut=N corpus_complete=1 30// EVERY BOUND IS NAMED AND ANNOUNCED: the corpus slot table is the enumerator's REFUSE-never-truncate cap 31// (EM_MAXF, the same figure nx_gateadjudicate declares); the preview cap exists because a block can be a 32// whole HTML template and a query needle is a sentence -- every cut block is counted in the stamp and marked. 33// license_tier: ORIGINAL Read-only over the estate except its one artifact. No hw writes (Rule 26). 34import "nx_syscalls.nx" 35import "nx_gatekit_lib.nx" 36import "nx_refusal_shape_lib.nx" 37 38const EM_OUT: *u8 = "knowledge/status/emitmap.tsv" 39const EM_MAXF: i64 = 32768 // corpus files: gk_corpus_scan REFUSES past this, it never truncates 40const EM_STRIDE: i64 = 256 // bytes per corpus path slot (gk_dirscan refuses a path that does not fit) 41const EM_PREVIEW: i64 = 512 // bytes of a block kept for matching; a cut is counted and marked 42const EM_ROW_FIXED: i64 = 64 // tabs, kind, the line number and the newline of one row 43const EM_FUNC_CAP: i64 = 128 // a function name slot (a longer name is cut and announced in the row) 44const EM_IDENT_CAP: i64 = 128 // a constant name slot 45const EM_TAB: i64 = 9 46const EM_NL: i64 = 10 47const EM_SP: i64 = 32 48const EM_QUOTE: i64 = 34 49const EM_LPAREN: i64 = 40 50const EM_COLON: i64 = 58 51const EM_EQ: i64 = 61 52const EM_USCORE: i64 = 95 53const EM_RBRACE: i64 = 125 54const EM_SLASH: i64 = 47 55const EM_DOT: i64 = 46 56const EM_EXIT_NONE: i64 = 1 57const EM_EXIT_ABSENT: i64 = 3 58 59func em_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 60func em_putn(v: i64) -> i64 { let b: *u8 = sys_mmap(32); let n: i64 = gk_catn(b, 0, v); sys_write(1, b, n); sys_munmap(b, 32); return 0 } 61func em_is_ident(c: i64) -> i64 { 62 if c >= 48 { if c <= 57 { return 1 } } 63 if c >= 65 { if c <= 90 { return 1 } } 64 if c >= 97 { if c <= 122 { return 1 } } 65 if c == EM_USCORE { return 1 } 66 return 0 67} 68// does the identifier buf[s..e) end with _CAP or _MAX? 69func em_is_bound_name(buf: *u8, s: i64, e: i64) -> i64 { 70 if e - s < 5 { return 0 } 71 if (buf[e-4] as i64) == EM_USCORE { 72 if (buf[e-3] as i64) == 67 { if (buf[e-2] as i64) == 65 { if (buf[e-1] as i64) == 80 { return 1 } } } 73 if (buf[e-3] as i64) == 77 { if (buf[e-2] as i64) == 65 { if (buf[e-1] as i64) == 88 { return 1 } } } 74 } 75 return 0 76} 77// the estate-relative spelling of a corpus path: from "buildroot/" onward when present 78func em_relpath(p: *u8) -> *u8 { 79 let pre: *u8 = "buildroot/" as *u8 80 let pl: i64 = gk_len(pre) 81 var i: i64 = 0 82 while p[i] != (0 as u8) { 83 var k: i64 = 0 84 var same: i64 = 1 85 while k < pl { if p[i + k] != pre[k] { same = 0; k = pl } else { k = k + 1 } } 86 if same == 1 { return (p as i64 + i) as *u8 } 87 i = i + 1 88 } 89 return p 90} 91// first non-blank byte of [p, eol) 92func em_skip_ws(buf: *u8, p: i64, eol: i64) -> i64 { 93 var f: i64 = p 94 var ws: i64 = 1 95 while ws == 1 { 96 if f >= eol { ws = 0 } else { 97 let c: i64 = buf[f] as i64 98 if c == EM_SP { f = f + 1 } else { if c == EM_TAB { f = f + 1 } else { ws = 0 } } 99 } 100 } 101 return f 102} 103// end (exclusive) of the identifier starting at i 104func em_ident_end(buf: *u8, i: i64, eol: i64) -> i64 { 105 var e: i64 = i 106 var run: i64 = 1 107 while run == 1 { if e >= eol { run = 0 } else { if em_is_ident(buf[e] as i64) == 1 { e = e + 1 } else { run = 0 } } } 108 return e 109} 110// copy the value text of a const line: after the first '=', front-trimmed, a trailing // comment dropped 111func em_const_value(buf: *u8, from: i64, eol: i64, out: *u8, o0: i64) -> i64 { 112 var v: i64 = from 113 var found: i64 = 0 114 var seek: i64 = 1 115 while seek == 1 { 116 if v >= eol { seek = 0 } else { 117 if (buf[v] as i64) == EM_EQ { found = 1; seek = 0 } 118 v = v + 1 119 } 120 } 121 if found == 0 { return o0 } 122 v = em_skip_ws(buf, v, eol) 123 var o: i64 = o0 124 var go: i64 = 1 125 while go == 1 { 126 if v >= eol { go = 0 } else { 127 let c: i64 = buf[v] as i64 128 if c == EM_SLASH { if v + 1 < eol { if (buf[v + 1] as i64) == EM_SLASH { go = 0 } } } 129 if go == 1 { out[o] = buf[v]; o = o + 1; v = v + 1 } 130 } 131 } 132 // drop trailing blanks before the comment 133 while o > o0 { if out[o - 1] == (EM_SP as u8) { o = o - 1 } else { if out[o - 1] == (EM_TAB as u8) { o = o - 1 } else { return o } } } 134 return o 135} 136// start offset of TAB-separated field f (0-based) within [p, eol); -1 when the row is shorter 137func em_field_start(b: *u8, p: i64, eol: i64, f: i64) -> i64 { 138 if f == 0 { return p } 139 var tabs: i64 = 0 140 var q: i64 = p 141 while q < eol { 142 if (b[q] as i64) == EM_TAB { tabs = tabs + 1; if tabs == f { return q + 1 } } 143 q = q + 1 144 } 145 return 0 - 1 146} 147// end (exclusive) of the field starting at s: the next TAB or eol 148func em_field_end(b: *u8, s: i64, eol: i64) -> i64 { 149 var e: i64 = s 150 while e < eol { if (b[e] as i64) == EM_TAB { return e } e = e + 1 } 151 return eol 152} 153// append a row head "<kind>\t<relpath>:<line>\t<func>\t" ; returns the new offset 154func em_row_head(o0: i64, out: *u8, kind: i64, rel: *u8, line: i64, fn: *u8) -> i64 { 155 var o: i64 = o0 156 out[o] = kind as u8; o = o + 1 157 out[o] = EM_TAB as u8; o = o + 1 158 o = gk_cat(out, o, rel) 159 out[o] = EM_COLON as u8; o = o + 1 160 o = gk_catn(out, o, line) 161 out[o] = EM_TAB as u8; o = o + 1 162 o = gk_cat(out, o, fn) 163 out[o] = EM_TAB as u8; o = o + 1 164 return o 165} 166// flush one composed block as an E row (preview-capped, control bytes dotted); st[4] counts cut previews 167func em_block_row(out: *u8, o0: i64, rel: *u8, bline: i64, fn: *u8, blk: *u8, bo: i64, st: *i64) -> i64 { 168 var o: i64 = em_row_head(o0, out, 69, rel, bline, fn) 169 var pe: i64 = bo 170 if pe > EM_PREVIEW { pe = EM_PREVIEW; st[4] = st[4] + 1 } 171 var q: i64 = 0 172 while q < pe { 173 let cb: i64 = blk[q] as i64 174 if cb < EM_SP { out[o] = EM_DOT as u8 } else { out[o] = blk[q] } 175 o = o + 1 176 q = q + 1 177 } 178 if pe < bo { o = gk_cat(out, o, "...[CUT]" as *u8) } 179 out[o] = EM_NL as u8; o = o + 1 180 st[1] = st[1] + 1 181 return o 182} 183// scan ONE source file; appends rows to the artifact fd; st: 0 files 1 blocks 2 consts 3 reads 4 previews_cut 5 unreadable 6 bytes 184func em_file_scan(path: *u8, fd: i64, st: *i64) -> i64 { 185 let flen: *i64 = sys_mmap(16) as *i64 186 let buf: *u8 = sys_read_file(path, flen) 187 let n: i64 = flen[0] 188 if (buf as i64) == 0 { st[5] = st[5] + 1; return 0 } 189 if n <= 0 { st[5] = st[5] + 1; return 0 } 190 st[0] = st[0] + 1 191 st[6] = st[6] + n 192 let rel: *u8 = em_relpath(path) 193 // output sized from the FILE: one row per line at most, each bounded by the row skeleton + path + func 194 // + preview; the block text itself is a subset of the file's bytes 195 var lines: i64 = 1 196 var ci: i64 = 0 197 while ci < n { if buf[ci] == (EM_NL as u8) { lines = lines + 1 } ci = ci + 1 } 198 let ocap: i64 = lines * (EM_ROW_FIXED + gk_len(rel) + EM_FUNC_CAP + EM_PREVIEW + EM_IDENT_CAP + 16) + n 199 let out: *u8 = sys_mmap(ocap) 200 var o: i64 = 0 201 let blkcap: i64 = n + 64 202 let blk: *u8 = sys_mmap(blkcap) 203 var bo: i64 = 0 204 var bline: i64 = 0 205 let fn: *u8 = sys_mmap(EM_FUNC_CAP) 206 fn[0] = 45 as u8; fn[1] = 0 as u8 // "-" until the first func line: top-level consts live here 207 var line: i64 = 1 208 var p: i64 = 0 209 while p < n { 210 let eol: i64 = gk_eol(buf, p, n) 211 let f: i64 = em_skip_ws(buf, p, eol) 212 var hard: i64 = 0 213 var iscomment: i64 = 0 214 var toplevel_close: i64 = 0 215 if f >= eol { hard = 1 } else { 216 if (buf[f] as i64) == EM_RBRACE { hard = 1; if f == p { toplevel_close = 1 } } 217 if (buf[f] as i64) == EM_SLASH { if f + 1 < eol { if (buf[f + 1] as i64) == EM_SLASH { hard = 1; iscomment = 1 } } } 218 // a top-level `func NAME(` line names the function every following row belongs to 219 if f == p { if eol - f > 5 { if buf[f] == (102 as u8) { if buf[f+1] == (117 as u8) { if buf[f+2] == (110 as u8) { if buf[f+3] == (99 as u8) { if buf[f+4] == (EM_SP as u8) { 220 hard = 1 221 var q: i64 = f + 5 222 var fo: i64 = 0 223 while q < eol { if (buf[q] as i64) == EM_LPAREN { q = eol } else { if fo < EM_FUNC_CAP - 1 { fn[fo] = buf[q]; fo = fo + 1 } q = q + 1 } } 224 fn[fo] = 0 as u8 225 } } } } } } } 226 } 227 // a block ends on a hard line; the row is written BEFORE a new function name replaces fn 228 if hard == 1 { if bo > 0 { o = em_block_row(out, o, rel, bline, fn, blk, bo, st); bo = 0; bline = 0 } } 229 // a column-0 `}` closes the function: what follows is top level again ("-"), never the last name 230 if toplevel_close == 1 { fn[0] = 45 as u8; fn[1] = 0 as u8 } 231 if hard == 0 { 232 let before: i64 = bo 233 bo = rs_line_lits(buf, f, eol, blk, bo, blkcap) 234 if bo > before { if bline == 0 { bline = line } } else { 235 // a non-emitting code line closes the block: consecutive emitting lines are one emission 236 if bo > 0 { o = em_block_row(out, o, rel, bline, fn, blk, bo, st); bo = 0; bline = 0 } 237 } 238 } 239 // constants: a `const NAME: i64 = value` line whose NAME ends _CAP/_MAX is a C row; any other line 240 // that mentions such a name is an R row per mention (comments excluded: a scanner that does not skip 241 // comments measures the documentation) 242 if iscomment == 0 { if f < eol { 243 var isconst: i64 = 0 244 if eol - f > 6 { if buf[f] == (99 as u8) { if buf[f+1] == (111 as u8) { if buf[f+2] == (110 as u8) { if buf[f+3] == (115 as u8) { if buf[f+4] == (116 as u8) { if buf[f+5] == (EM_SP as u8) { isconst = 1 } } } } } } } 245 var i: i64 = f 246 var instr: i64 = 0 247 while i < eol { 248 let c: i64 = buf[i] as i64 249 if c == EM_QUOTE { instr = 1 - instr; i = i + 1 } else { 250 if instr == 1 { i = i + 1 } else { 251 if c == EM_SLASH { if i + 1 < eol { if (buf[i+1] as i64) == EM_SLASH { i = eol } else { i = i + 1 } } else { i = i + 1 } } else { 252 if em_is_ident(c) == 1 { 253 let e2: i64 = em_ident_end(buf, i, eol) 254 if em_is_bound_name(buf, i, e2) == 1 { 255 var kind: i64 = 82 256 if isconst == 1 { if i == f + 6 { kind = 67 } } 257 o = em_row_head(o, out, kind, rel, line, fn) 258 var k: i64 = i 259 while k < e2 { out[o] = buf[k]; o = o + 1; k = k + 1 } 260 if kind == 67 { 261 out[o] = EM_TAB as u8; o = o + 1 262 o = em_const_value(buf, e2, eol, out, o) 263 st[2] = st[2] + 1 264 } else { st[3] = st[3] + 1 } 265 out[o] = EM_NL as u8; o = o + 1 266 } 267 i = e2 268 } else { i = i + 1 } } } } 269 } 270 } } 271 line = line + 1 272 p = eol + 1 273 } 274 if bo > 0 { o = em_block_row(out, o, rel, bline, fn, blk, bo, st) } 275 gk_write_all(fd, out, o) 276 sys_munmap(out, ocap) 277 sys_munmap(blk, blkcap) 278 sys_munmap(fn, EM_FUNC_CAP) 279 sys_free_file(buf, n) 280 sys_munmap(flen as *u8, 16) 281 return 0 282} 283 284func em_census(outp: *u8) -> i64 { 285 let names: *u8 = sys_mmap(EM_MAXF * EM_STRIDE) 286 let nf: i64 = gk_corpus_scan(names, EM_STRIDE, EM_MAXF) 287 if nf < 0 { 288 em_puts("NX-EMITMAP REFUSED: corpus enumeration returned " as *u8); em_putn(nf) 289 em_puts(" (-1 root unopenable, -2 more than EM_MAXF files -- raise the declared slot table deliberately, -3 a path exceeds EM_STRIDE). Nothing written: a truncated census is not a census.\n" as *u8) 290 return 1 291 } 292 let tmp: *u8 = sys_mmap(gk_len(outp) + 8) 293 var to: i64 = gk_cat(tmp, 0, outp); to = gk_cat(tmp, to, ".tmp" as *u8); tmp[to] = 0 as u8 294 let fd: i64 = sys_openat_wr(tmp, MODE_0644) 295 if fd < 0 { em_puts("NX-EMITMAP WRITE-FAILED: cannot open " as *u8); em_puts(tmp); em_puts("\n" as *u8); return 4 } 296 let st: *i64 = sys_mmap(8 * 8) as *i64 297 var z: i64 = 0 298 while z < 8 { st[z] = 0; z = z + 1 } 299 var i: i64 = 0 300 while i < nf { 301 em_file_scan(((names as i64) + i * EM_STRIDE) as *u8, fd, st) 302 i = i + 1 303 } 304 let asof: i64 = sys_now_realtime_sec() 305 let stamp: *u8 = sys_mmap(512) 306 var so: i64 = gk_cat(stamp, 0, "# asof=" as *u8); so = gk_catn(stamp, so, asof) 307 so = gk_cat(stamp, so, " files=" as *u8); so = gk_catn(stamp, so, st[0]) 308 so = gk_cat(stamp, so, " bytes=" as *u8); so = gk_catn(stamp, so, st[6]) 309 so = gk_cat(stamp, so, " blocks=" as *u8); so = gk_catn(stamp, so, st[1]) 310 so = gk_cat(stamp, so, " consts=" as *u8); so = gk_catn(stamp, so, st[2]) 311 so = gk_cat(stamp, so, " reads=" as *u8); so = gk_catn(stamp, so, st[3]) 312 so = gk_cat(stamp, so, " unreadable=" as *u8); so = gk_catn(stamp, so, st[5]) 313 so = gk_cat(stamp, so, " preview_cap=" as *u8); so = gk_catn(stamp, so, EM_PREVIEW) 314 so = gk_cat(stamp, so, " previews_cut=" as *u8); so = gk_catn(stamp, so, st[4]) 315 so = gk_cat(stamp, so, " enumerated=" as *u8); so = gk_catn(stamp, so, nf) 316 so = gk_cat(stamp, so, " corpus_complete=1 blind_spot=byte-code-emissions-not-indexed\n" as *u8) 317 gk_write_all(fd, stamp, so) 318 sys_fsync(fd) 319 sys_close(fd) 320 if sys_renameat(tmp, outp) != 0 { em_puts("NX-EMITMAP WRITE-FAILED: rename\n" as *u8); return 4 } 321 em_puts("NX-EMITMAP census files=" as *u8); em_putn(st[0]); em_puts(" of enumerated=" as *u8); em_putn(nf) 322 em_puts(" unreadable=" as *u8); em_putn(st[5]); em_puts(" (files+unreadable=" as *u8); em_putn(st[0] + st[5]); em_puts(")" as *u8) 323 em_puts(" blocks=" as *u8); em_putn(st[1]); em_puts(" consts=" as *u8); em_putn(st[2]); em_puts(" reads=" as *u8); em_putn(st[3]) 324 em_puts(" previews_cut=" as *u8); em_putn(st[4]); em_puts(" asof=" as *u8); em_putn(asof); em_puts(" of=" as *u8); em_puts(outp); em_puts("\n" as *u8) 325 return 0 326} 327 328// print every row of kind `kind` whose matching field contains `needle` (E: the preview; R/C: the CONST field 329// equals needle exactly). Returns the number printed. 330func em_query(artp: *u8, verb: i64, needle: *u8) -> i64 { 331 let lp: *i64 = sys_mmap(16) as *i64 332 let b: *u8 = sys_read_file(artp, lp) 333 let n: i64 = lp[0] 334 if (b as i64) == 0 { em_puts("NX-EMITMAP ABSENT: no artifact at " as *u8); em_puts(artp); em_puts(" -- run `nx_emitmap census` first\n" as *u8); return 0 - 1 } 335 if n <= 0 { em_puts("NX-EMITMAP ABSENT: empty artifact at " as *u8); em_puts(artp); em_puts("\n" as *u8); return 0 - 1 } 336 let nl: i64 = gk_len(needle) 337 var hits: i64 = 0 338 var p: i64 = 0 339 while p < n { 340 let eol: i64 = gk_eol(b, p, n) 341 if eol - p > 2 { 342 let kind: i64 = b[p] as i64 343 var want: i64 = 0 344 if verb == 1 { if kind == 69 { want = 1 } } 345 if verb == 2 { if kind == 67 { want = 1 } if kind == 82 { want = 1 } } 346 if want == 1 { 347 let f3: i64 = em_field_start(b, p, eol, 3) 348 if f3 >= 0 { 349 var fe: i64 = eol 350 if verb == 2 { fe = em_field_end(b, f3, eol) } 351 var ok: i64 = 0 352 if verb == 2 { 353 if fe - f3 == nl { var k: i64 = 0; ok = 1; while k < nl { if b[f3 + k] != needle[k] { ok = 0; k = nl } else { k = k + 1 } } } 354 } else { 355 if fe - f3 >= nl { if nl > 0 { 356 var s: i64 = f3 357 while s + nl <= fe { var k2: i64 = 0; var same: i64 = 1; while k2 < nl { if b[s + k2] != needle[k2] { same = 0; k2 = nl } else { k2 = k2 + 1 } } if same == 1 { ok = 1; s = fe } else { s = s + 1 } } 358 } } 359 } 360 if ok == 1 { hits = hits + 1; sys_write(1, (b as i64 + p) as *u8, eol - p); sys_write(1, "\n" as *u8, 1) } 361 } 362 } 363 } 364 p = eol + 1 365 } 366 return hits 367} 368 369func main(argc: i64, argv: *i64) -> i64 { 370 if argc < 2 { 371 em_puts("usage: nx_emitmap census [artifact] | nx_emitmap find <text> [artifact] | nx_emitmap bound <CONST> [artifact]\n" as *u8) 372 em_puts(" artifact default knowledge/status/emitmap.tsv; exit 0 found/written, 1 none/refused, 3 artifact absent\n" as *u8) 373 return 2 374 } 375 let verb: *u8 = argv[1] as *u8 376 if gk_streq(verb, "census" as *u8) == 1 { 377 var outp: *u8 = EM_OUT 378 if argc > 2 { outp = argv[2] as *u8 } 379 return em_census(outp) 380 } 381 if argc < 3 { em_puts("usage: nx_emitmap find <text> [artifact] | bound <CONST> [artifact]\n" as *u8); return 2 } 382 var artp: *u8 = EM_OUT 383 if argc > 3 { artp = argv[3] as *u8 } 384 var v: i64 = 0 385 if gk_streq(verb, "find" as *u8) == 1 { v = 1 } 386 if gk_streq(verb, "bound" as *u8) == 1 { v = 2 } 387 if v == 0 { em_puts("usage: verb must be census | find | bound\n" as *u8); return 2 } 388 let hits: i64 = em_query(artp, v, argv[2] as *u8) 389 if hits < 0 { return EM_EXIT_ABSENT } 390 em_puts("NX-EMITMAP " as *u8); em_puts(verb); em_puts(" sites=" as *u8); em_putn(hits); em_puts(" needle=" as *u8); em_puts(argv[2] as *u8); em_puts(" artifact=" as *u8); em_puts(artp) 391 if v == 1 { em_puts(" (composed literal emissions only: byte-code emissions such as wc(123) are a declared blind spot)" as *u8) } 392 em_puts("\n" as *u8) 393 if hits == 0 { return EM_EXIT_NONE } 394 return 0 395}