ast2nif

Search:
Group by:
Source   Edit  

AST to NIF bridge.

Types

DecodeContext = object
Source   Edit  
LoadFlag = enum
  LoadFullAst, AlwaysLoadInterface
Source   Edit  
ModuleSuffix = distinct string
Source   Edit  
ParsedSymName = object
  name*: string
  module*: string
  count*: int
Source   Edit  
PrecompiledModule = object
  topLevel*: PNode
  deps*: seq[ModuleSuffix]
  logOps*: seq[LogEntry]
  module*: PSym
  reexportedModules*: seq[(string, string)]
  genericOffers*: seq[tuple[generic, inst: PSym, concreteTypes: seq[PType],
                            genericParamsCount: int]] ## generic instances this module created; modulegraphs.nim rebuilds
                                                      ## `procInstCache` from them so a consumer reuses the instance instead of
                                                      ## re-instantiating it in its own (operator-blind) module scope.
Source   Edit  

Consts

SysModuleSuffix = "@sys"
Reserved module-suffix sentinel for module-less magic singleton types — the nil type is created via newSysType with the graph idgen, whose module can be -1 (e.g. during VM const-eval before a real module is current), so its uniqueId.module is unresolvable. Such a type has no fields and an identity that is fully captured by its kind, so we serialize it with this sentinel and reconstruct it on load (see createTypeStub) without ever touching a .nif file. A real moduleSuffix never starts with '@'. Source   Edit  

Procs

proc createDecodeContext(config: ConfigRef; cache: IdentCache): DecodeContext {.
    ...raises: [], tags: [], forbids: [].}
Supposed to be a global variable Source   Edit  
proc firstSon(n: Cursor): Cursor {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc getMainModuleSuffix(c: DecodeContext): string {.inline, ...raises: [],
    tags: [], forbids: [].}
Source   Edit  
proc globalName(sym: PSym; config: ConfigRef): string {....raises: [],
    tags: [RootEffect], forbids: [].}
Source   Edit  
proc icNifTypeName(typ: PType; config: ConfigRef): string {....raises: [],
    tags: [RootEffect], forbids: [].}
The serialized NIF name of a type, recorded next to RTTI data definitions in the cnif artifact so a later run can re-demand the typeinfo when a reused TU still references it (the def-retention check). Backend-minted types have no NIF name. Source   Edit  
proc isStub(s: PSym): bool {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc isStub(t: PType): bool {.inline, ...raises: [], tags: [], forbids: [].}
Source   Edit  
proc loadNifModule(c: var DecodeContext; f: FileIndex;
                   interf, interfHidden: var TStrTable;
                   flags: set[LoadFlag] = {}): PrecompiledModule {.
    ...raises: [OSError, ValueError, KeyError, Exception],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc loadNifModule(c: var DecodeContext; suffix: ModuleSuffix;
                   interf, interfHidden: var TStrTable;
                   flags: set[LoadFlag] = {}): PrecompiledModule {.
    ...raises: [OSError, ValueError, KeyError, Exception],
    tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect, RootEffect], forbids: [].}
Source   Edit  
proc loadSym(c: var DecodeContext; s: PSym) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc loadType(c: var DecodeContext; t: PType) {.
    ...raises: [KeyError, ValueError, Exception, OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Source   Edit  
proc moduleSymbolStubs(c: var DecodeContext; module: FileIndex): seq[PSym] {.
    ...raises: [KeyError, OSError, ValueError],
    tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect, RootEffect], forbids: [].}

Stubs for every non-type symbol serialized in module's NIF index. The per-module backend uses this to emit the routines a module OWNS: procs are serialized as (sd ...) symbol-defs and loaded lazily, never as nkProcDef statements in the top-level stmt list, so genTopLevelStmt alone never reaches them — without this, a routine called only from other modules would be emitted by nobody once the demanding module merely prototypes it.

Returns lazy stubs: the index table is moved out while iterating (loading a symbol can register new modules and invalidate the iterator), so the caller forces full load (.kind, .ast) and filters AFTER this returns, with the index back in place.

Source   Edit  
proc parseSymName(s: string): ParsedSymName {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc registerNifAstTags() {....raises: [], tags: [], forbids: [].}
(Re)registers ast2nif's NIF tags explicitly. The top-level registerTag initializers above depend on nifstreams.pool having been initialized FIRST (pool = createLiterals(TagData) in nifstreams' module init) — an inter-module init-order requirement. The IC-built compiler currently emits module init calls in a different order, so the initializers registered into a pool that was subsequently replaced: the tag ids then denoted builtin tags (replay came out as deref, repdestroy as pat, ...) and every written NIF was silently corrupted. Called from nim.nim before any command runs; idempotent (getOrIncl by name). Source   Edit  
proc resolveHookSym(c: var DecodeContext; symId: nifstreams.SymId): PSym {.
    ...raises: [OSError, ValueError, KeyError],
    tags: [ReadEnvEffect, ReadIOEffect, ReadDirEffect, RootEffect], forbids: [].}
Resolves a hook SymId to PSym. Hook symbols are often private (generated =destroy, =wasMoved, etc.) Source   Edit  
proc setMainModule(c: var DecodeContext; fileIdx: FileIndex) {....raises: [],
    tags: [RootEffect], forbids: [].}
Records the module that is being compiled fresh so that re-exports of its own symbols by dependencies are not turned into duplicate stubs. Source   Edit  
proc toClassSymId(config: ConfigRef; typeId: ItemId): nifstreams.SymId {.
    ...raises: [], tags: [RootEffect], forbids: [].}
Converts a type ItemId to its SymId for the class index. Source   Edit  
proc toConverterIndexEntry(config: ConfigRef; converterSym: PSym): (
    nifstreams.SymId, nifstreams.SymId) {....raises: [], tags: [RootEffect],
    forbids: [].}
Converts a converter symbol to an index entry (destType, converterSym). Returns the destination type's SymId and the converter's SymId. Source   Edit  
proc toHookIndexEntry(config: ConfigRef; typeId: ItemId; hookSym: PSym): HookIndexEntry {.
    ...raises: [], tags: [RootEffect], forbids: [].}
Converts a type ItemId and hook symbol to a HookIndexEntry for the NIF index. Source   Edit  
proc toMethodIndexEntry(config: ConfigRef; methodSym: PSym; signature: string): (
    nifstreams.SymId, nifstreams.StrId) {....raises: [], tags: [RootEffect],
    forbids: [].}
Converts a method symbol/signature to a method index entry. Source   Edit  
proc toNifFilename(conf: ConfigRef; f: FileIndex): string {....raises: [OSError],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect], forbids: [].}
Source   Edit  
proc tryResolveCompilerProc(c: var DecodeContext; name: string;
                            moduleFileIdx: FileIndex): PSym {.
    ...raises: [OSError, ValueError, KeyError, Exception],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect, ReadDirEffect], forbids: [].}
Tries to resolve a compiler proc from a module by checking the NIF index. Returns nil if the symbol doesn't exist. The NIF disamb is mint order, so name.0. can be any of the overloads sharing the name — for newSeq it is the generic magic, not the RTL proc (a refc build then demands codegen of the generic and dies on seq[T]): enumerate the index entries with this basename and pick the one that carries sfCompilerProc. Source   Edit  
proc writeNifModule(config: ConfigRef; thisModule: int32; n: PNode;
                    opsLog: seq[LogEntry]; replayActions: seq[PNode] = @[];
                    implDeps: seq[int] = @[];
                    reexportedModules: seq[(string, string)] = @[];
    genericOffers: seq[tuple[generic, inst: PSym, concreteTypes: seq[PType],
                             genericParamsCount: int]] = @[];
                    resolvedImportDeps: seq[FileIndex] = @[]) {.
    ...raises: [KeyError, Exception, OSError, IOError, ValueError], tags: [
    RootEffect, ReadEnvEffect, ReadIOEffect, WriteDirEffect, ReadDirEffect],
    forbids: [].}
Source   Edit  
proc writeSemDeps(config: ConfigRef; thisModule: int32; importPaths: seq[string]) {.
    ...raises: [OSError, Exception],
    tags: [RootEffect, ReadEnvEffect, ReadIOEffect], forbids: [].}
The module's REAL direct imports as nim m sem resolved them — static plus any a macro generated — recorded as full source paths. nim ic reads this .s.deps.nif to re-derive the build graph: imports the static scanner missed become new nodes (replacing the old build-failure discovery loop), and when false imports the scanner over-included are pruned. Always written so it is current after every successful sem (like .edges). Source   Edit