icnifcore

Search:
Group by:
Source   Edit  

nifcore-based IC serialization helpers — Stage 1 of porting the IC backend from the old nifstreams/nifcursors NIF stack to nifcore (see doc/ic_nifcore_port.md).

It hosts:

  • the process-wide shared Pool/TagPool that stands in for the old global nifstreams.pool,
  • writeFileStable, the content-stable file writer mirroring nifcursors.writeFile(..., OnlyIfChanged),
  • the first ported writer (writeSemDeps), used as the migration spike.

No nifstreams/nifcursors types cross this module's boundary: callers pass plain Nim values (config, ids, string lists), so it can coexist with the still-old-API ast2nif.nim during the migration.

Types

CookieKind = enum
  ckParLe, ckParRi, ckSym, ckSymDef, ckIdent, ckStr, ckInt, ckUInt, ckFloat,
  ckChar, ckDot
Source   Edit  
CookieTok = object
  kind*: CookieKind
  tag*: string
  name*: string
  sym*: uint32
  str*: string
  ival*: int64
  uval*: uint64
  fval*: float64
  cval*: uint32
Source   Edit  
IcBuilder = object
  buf*: TokenBuf
A thin nifcore TokenBuf builder whose surface is primitive types only (strings/ints/floats). It lets the still-old-API ast2nif.nim drive a nifcore buffer without any nifcore type crossing the module boundary — the bridge that routes IC output onto the nifcore serializer (Stage 2). Source   Edit  

Lets

icPool = newPool()
Source   Edit  
icTags = newTagPool()
Source   Edit  

Procs

proc addAll(dest: var IcBuilder; src: var IcBuilder) {....raises: [], tags: [],
    forbids: [].}
Append every top-level subtree of src into dest — the nifcore analogue of the old dest.add wholeBuffer splice. Source   Edit  
proc addCharLit(b: var IcBuilder; c: char) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addDotToken(b: var IcBuilder) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc addFloatLit(b: var IcBuilder; v: float64) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addIdent(b: var IcBuilder; s: string) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addIntLit(b: var IcBuilder; v: int64) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addStmtsBody(dest: var IcBuilder; src: var IcBuilder) {....raises: [],
    tags: [], forbids: [].}
Append the BODY of a (stmts . . <body> ) builder into dest, dropping the wrapper tag and its two leading dot slots (flags/type) — the nifcore analogue of the old for i in 3 ..< content.len-1: dest.add content[i]. Source   Edit  
proc addStrLit(b: var IcBuilder; s: string) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addSymDef(b: var IcBuilder; s: string) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addSymUse(b: var IcBuilder; s: string) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc addUIntLit(b: var IcBuilder; v: uint64) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc closeTag(b: var IcBuilder) {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc collectBifStrLits(path: string): seq[string] {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Read a small (tag "s" "s" …) bif sidecar (semdeps/edges) and return every string literal it holds, in order — the binary analogue of the old nifstreams scan that collected StrLits. Keeps nifcore types out of deps.nim, which only needs the recorded string list. Source   Edit  
proc createIcBuf(cap = 16): TokenBuf {.inline, ...raises: [], tags: [], forbids: [].}
A TokenBuf bound to the shared IC pools. Source   Edit  
proc cursorPool(c: Cursor): Pool {.inline, ...raises: [], tags: [], forbids: [].}
The literals pool the cursor's buffer was built against. ast2nif.nim imports nifcore with except pool (to keep nifstreams' global pool var the writer uses), so the reader reaches a cursor's pool through here — needed once bif-loaded buffers carry their OWN fresh pool rather than the shared icPool. Source   Edit  
proc flattenForCookie(b: var IcBuilder): seq[CookieTok] {....raises: [], tags: [],
    forbids: [].}
Flatten the nifcore module buffer to the cookie hashers' flat token list. Source   Edit  
proc lineInfo(b: var IcBuilder; file: string; line, col: int32; comment = "") {.
    ...raises: [], tags: [], forbids: [].}
Attach line info (+ optional #comment#) to the head just emitted. No-op when file is empty (matches the old "emit only when info is valid"). Strings are interned in the shared pools; the file/comment ids reproduce the old pool.files/pool.strings entries by string value. Source   Edit  
proc newIcBuilder(cap = 16): IcBuilder {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc openTag(b: var IcBuilder; tag: string) {.inline, ...raises: [], tags: [],
    forbids: [].}
Source   Edit  
proc storeBif(b: var IcBuilder; path: string; dottedSuffix: string) {.
    ...raises: [IOError], tags: [WriteIOEffect], forbids: [].}
Persist the buffer as a compact, self-contained binary NIF (.bif). Source   Edit  
proc storeBifStable(b: var IcBuilder; path: string; dottedSuffix: string) {.
    ...raises: [IOError, OSError, Exception],
    tags: [WriteIOEffect, ReadIOEffect, WriteDirEffect, ReadDirEffect],
    forbids: [].}
Content-stable bif write — the binary analogue of writeFileStable's onlyIfChanged: only replace path when the encoded bytes differ, so an unchanged sidecar keeps its mtime and nifmake prunes the dependent rebuild cascade. Used for the iface/impl cookies + dep sidecars whose byte-stability gates incremental builds. (bif encoding is deterministic for a given buffer under fresh pools, so equal content ⇒ equal bytes.) Source   Edit  
proc tagId(s: string): TagId {.inline, ...raises: [], tags: [], forbids: [].}
Intern a tag name in the shared tag pool. Source   Edit  
proc writeFileStable(b: var TokenBuf; path: string; onlyIfChanged = false) {.
    ...raises: [Exception, IOError],
    tags: [RootEffect, ReadIOEffect, WriteIOEffect], forbids: [].}
Serialize b to canonical module NIF text and write it. Mirrors nifcursors.writeFile: the module suffix is derived from path ("." & extractModuleSuffix), and onlyIfChanged skips the write when the on-disk bytes already match — the content-stability nifmake's incremental rebuild depends on. Source   Edit  
proc writeSemDeps(config: ConfigRef; thisModule: int32; importPaths: seq[string]) {.
    ...raises: [OSError, IOError, Exception], tags: [RootEffect, ReadEnvEffect,
    ReadIOEffect, WriteIOEffect, WriteDirEffect, ReadDirEffect], forbids: [].}
Stage 1 spike: the nifcore port of ast2nif.writeSemDeps. Serializes the module's resolved direct imports as (semdeps "path" ...). Byte-identical to the old writer (verified), so nim ic build graphs are unaffected. Source   Edit  
proc writeStable(b: var IcBuilder; path: string; onlyIfChanged = false) {.
    inline, ...raises: [Exception, IOError],
    tags: [RootEffect, ReadIOEffect, WriteIOEffect], forbids: [].}
Source   Edit