code wiki / (root) / nx_linemap.nx

nx_linemap.nx

buildroot/runtime/nx_linemap.nx

21534 B465 linesdepth 0pulls 0 transitivereach 291 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_linemap.nx -- OUT-OF-BAND expanded-line -> (file, source-line) map. WHY THIS EXISTS nx_cc compiles PRE-EXPANDED source: nx_import.nx splices every imported file inline into ONE flat buffer, so every line number the lexer produces is a line in that flat stream. Consequences, both measured: * a diagnostic can say WHERE the compiler was but never WHICH FILE the author must open (nx_parse.nx says so in-source: "Mapping back to per-file lines is a separate rung"; the /compare/lang matrix scores the 5W+H voice 24/25 and names the missing point as the file name); * nx_dwarf_line.nx -- a complete DWARF v5 .debug_line builder -- has no file table to emit, so it sits built and unwired along with 11 sibling organs. This module is the substrate both of those need. It is NOT itself the fix to either; it is the thing they were both missing. DESIGN DECISION -- a SPAN TABLE, not C's `#line` directives The C toolchain solves this IN BAND: cpp injects `#line N "file"` into the expanded text and the compiler's lexer understands them. We reject that, and the reasons are worth stating because the in-band design is the older and more familiar one: 1. EVERY consumer of the expanded buffer must then understand a second syntax that is not NishiLang -- the lexer, and anything that ever reads the buffer for any other purpose. One producer's convenience becomes every reader's obligation. 2. It is FORGEABLE FROM ORDINARY SOURCE. The expanded buffer carries string literals verbatim; a literal containing a newline followed by `#line 1 "victim.nx"` would relabel the real code after it. Diagnostics -- and later, debug info a debugger trusts -- could be made to point at an innocent file BY WRITING A STRING. Putting metadata in a channel that also carries attacker-writable text is a confusion of layers, and the estate has already paid for that class once (the in-STRING `}` that closed a brace skip mid-body, nx_import.nx skip_func_main, debt 1785894599). 3. It perturbs the very bytes nx_diag_caret prints, so the snippet machinery would have to learn to skip directives to avoid showing them to the author. Clang (SourceManager) and rustc (SourceMap) both keep this mapping OUT of the text, beside it. We match that known good. THE COST WE ACCEPT, STATED PLAINLY: an out-of-band map is a parallel structure that can DESYNC from the buffer it describes -- it is only as true as its producer. In-band directives cannot desync, because they ARE the buffer. That is

dependencies 0 imports · 6 importers

nx_linemap.nx nx_import.nx nx_ir.nx nx_lsp.nx nx_parse.nx nx_parse_field_candidate_t280.nx nx_x86_64_ctx.nx

imports: none

imported by: nx_import.nxnx_ir.nxnx_lsp.nxnx_parse.nxnx_parse_field_candidate_t280.nxnx_x86_64_ctx.nx

structs

86struct LineMap

consts

80const NX_LM_MAX_SPANS: i64 = 8192
81const NX_LM_MAX_FILES: i64 = 512
82const NX_LM_PATH_LEN: i64 = 1024
83const NX_LM_MAX_FUNCS: i64 = 4096
84const NX_LM_FNAME_LEN: i64 = 128
253const NX_LM_STMT_SLOTS: i64 = 262144

functions

61func lm_ovf_puts(s: *u8) -> i64
called by 1: lm_add_span
67func lm_ovf_putn(v: i64) -> i64
called by 1: lm_add_span
106func lm_new() -> *LineMap
133func lm_slen(s: *u8) -> i64
139func lm_at(p: *u8, d: i64) -> *u8
144func lm_seq(a: *u8, b: *u8) -> i64
called by 1: lm_intern_file
154func lm_copy(dst: *u8, src: *u8, n: i64) -> i64
166func lm_intern_file(lm: *LineMap, path: *u8) -> i64
188func lm_file_path(lm: *LineMap, id: i64) -> *u8
198func lm_basename(p: *u8) -> *u8
called by 2: nx_diag_locnx_diag_loc calls 2: lm_slenlm_at
229func lm_set_debug(v: i64) -> i64
called by 2: mainmain
234func lm_debug_on() -> i64
called by 1: alloc_instr
260func lm_stmt_init() -> i64
called by 1: lm_stmt_stamp
273func lm_stmt_set_cur(line: i64) -> i64 { lm_stmt_cur_line = line; return 0 }
274func lm_stmt_cur() -> i64 { return lm_stmt_cur_line }
275func lm_stmt_count() -> i64 { return lm_stmt_n }
276func lm_stmt_overflowed() -> i64 { return lm_stmt_full }
278func lm_stmt_slot(p: i64) -> i64 { return (p >> 8) & (NX_LM_STMT_SLOTS - 1) }
280func lm_stmt_stamp(p: i64) -> i64
306func lm_stmt_lookup(p: i64) -> i64
calls 1: lm_stmt_slot
321func lm_set_active(lm: *LineMap) -> i64
326func lm_get_active() -> *LineMap
335func lm_fn_record(lm: *LineMap, name: *u8, nlen: i64, out_line: i64) -> i64
calls 2: lm_atlm_copy
353func lm_fn_lookup(lm: *LineMap, name: *u8, nlen: i64) -> i64
calls 1: lm_at
375func lm_add_span(lm: *LineMap, out_line: i64, file_id: i64, src_line: i64) -> i64
439func lm_lookup(lm: *LineMap, out_line: i64, o_file: *i64, o_src: *i64) -> i64