nx_intern.nx
buildroot/runtime/nx_intern.nx
about
nx_intern.nx -- string interning pool.
Maps a (bytes, len) -> stable i64 id. Same string content always
gets the same id; ids are dense from 0. Foundation for:
* Symbol table dedup in nxld + nxasm
* Identifier interning in lex (turns strcmp into ==)
* Section name interning across the .shstrtab + .strtab
* Type-name dedup in opt
Internally:
* nx_hash for FNV-1a key -> id lookup
* Backing byte buffer holding the actual string content,
each entry NUL-terminated (so nx_intern_at returns a *u8
directly usable as a C-string)
* Side-array of (offset, length) pairs indexed by id
API:
nx_intern_new(bytes_cap, ids_cap)
nx_intern_get(t, bytes, len) -- returns id (creates if new)
nx_intern_at(t, id, out_len) -- returns *u8 + length
nx_intern_count(t) -- total ids assigned
Performance: O(1) average for get + at; backing buffer never
re-allocates so all returned *u8 stay valid for the table's
lifetime (a critical invariant for symbol-table users).
dependencies 2 imports · 4 importers
imports: syscalls.nxnx_hash.nx
imported by: nx_bpe.nxnx_dwarf_str.nxnx_f32_bpe_load.nxnx_f32_bpe_load_test.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 38 | struct NxIntern |
consts
| 36 | const NX_MAGIC_1024: i64 = 1024 |
| 49 | const NX_INTERN_BYTES: i64 = 64 |
functions
| 52 | func nx_intern_next_pow2(n: i64) -> i64 called by 1: nx_intern_new |
| 58 | func nx_intern_new(bytes_cap: i64, ids_cap: i64) -> *NxIntern |
| 76 | func nx_intern_bytes_eq(t: *NxIntern, off: i64, other: *u8, len: i64) -> i64 |
| 86 | func nx_intern_get(t: *NxIntern, bytes: *u8, len: i64) -> i64 |
| 132 | func nx_intern_lookup(t: *NxIntern, bytes: *u8, len: i64) -> i64 |
| 145 | func nx_intern_at(t: *NxIntern, id: i64, out_len: *i64) -> *u8 |
| 153 | func nx_intern_count(t: *NxIntern) -> i64 { return t.n_ids } |
| 157 | func main() -> i64 |