@@ -302,10 +302,13 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) =
302302 # do not unload modules
303303 w.writtenSyms.add sym
304304
305+ proc shouldWriteSymDef (w: Writer ; sym: PSym ): bool {.inline .} =
306+ result = sym.itemId.module == w.currentModule and sym.state == Complete
307+
305308proc writeSym (w: var Writer ; dest: var TokenBuf ; sym: PSym ) =
306309 if sym == nil :
307310 dest.addDotToken ()
308- elif sym.itemId.module == w.currentModule and sym.state == Complete :
311+ elif shouldWriteSymDef (w, sym) :
309312 sym.state = Sealed
310313 writeSymDef (w, dest, sym)
311314 else :
@@ -316,7 +319,7 @@ proc writeSym(w: var Writer; dest: var TokenBuf; sym: PSym) =
316319proc writeSymNode (w: var Writer ; dest: var TokenBuf ; n: PNode ; sym: PSym ) =
317320 if sym == nil :
318321 dest.addDotToken ()
319- elif sym.itemId.module == w.currentModule and sym.state == Complete :
322+ elif shouldWriteSymDef (w, sym) :
320323 sym.state = Sealed
321324 if n.typField != n.sym.typImpl:
322325 dest.buildTree hiddenTypeTag, trLineInfo (w, n.info):
@@ -429,11 +432,13 @@ proc writeNode(w: var Writer; dest: var TokenBuf; n: PNode) =
429432 writeNode (w, dest, n[i])
430433 of nkFormalParams:
431434 # Track parameters (first child is return type, rest are parameters)
435+ inc w.inProc
432436 w.withNode dest, n:
433437 for i in 0 ..< n.len:
434438 if i > 0 : # Skip return type
435439 addLocalSyms (w, n[i])
436440 writeNode (w, dest, n[i])
441+ dec w.inProc
437442 of nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkLambda, nkDo, nkMacroDef:
438443 inc w.inProc
439444 # Entering a proc/function body - parameters are local
@@ -456,17 +461,12 @@ proc writeNode(w: var Writer; dest: var TokenBuf; n: PNode) =
456461 for i in 0 ..< n.len:
457462 writeNode (w, dest, n[i])
458463
459- proc writeToplevelNode (w: var Writer ; outer, inner : var TokenBuf ; n: PNode ) =
464+ proc writeToplevelNode (w: var Writer ; dest : var TokenBuf ; n: PNode ) =
460465 case n.kind
461466 of nkStmtList, nkStmtListExpr:
462- for son in n: writeToplevelNode (w, outer, inner, son)
463- of nkProcDef, nkFuncDef, nkMethodDef, nkIteratorDef, nkConverterDef, nkLambda, nkDo, nkMacroDef:
464- # Delegate to `w.topLevel`!
465- writeNode w, inner, n
466- of nkConstSection, nkTypeSection, nkTypeDef:
467- writeNode w, inner, n
467+ for son in n: writeToplevelNode (w, dest, son)
468468 else :
469- writeNode w, outer , n
469+ writeNode w, dest , n
470470
471471proc createStmtList (buf: var TokenBuf ; info: PackedLineInfo ) {.inline .} =
472472 buf.addParLe pool.tags.getOrIncl (toNifTag (nkStmtList)), info
@@ -475,17 +475,14 @@ proc createStmtList(buf: var TokenBuf; info: PackedLineInfo) {.inline.} =
475475
476476proc writeNifModule * (config: ConfigRef ; thisModule: int32 ; n: PNode ) =
477477 var w = Writer (infos: LineInfoWriter (config: config), currentModule: thisModule)
478- var outer = createTokenBuf (300 )
479- var inner = createTokenBuf (300 )
478+ var content = createTokenBuf (300 )
480479
481480 let rootInfo = trLineInfo (w, n.info)
482- createStmtList (outer, rootInfo)
483- createStmtList (inner, rootInfo)
481+ createStmtList (content, rootInfo)
484482
485- w.writeToplevelNode outer, inner , n
483+ w.writeToplevelNode content , n
486484
487- outer.addParRi ()
488- inner.addParRi ()
485+ content.addParRi ()
489486
490487 let m = modname (w.moduleToNifSuffix, w.currentModule, w.infos.config)
491488 let nifFilename = AbsoluteFile (m).changeFileExt (" .nif" )
@@ -494,8 +491,7 @@ proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode) =
494491 var dest = createTokenBuf (600 )
495492 createStmtList (dest, rootInfo)
496493 dest.add w.deps
497- dest.add outer
498- dest.add inner
494+ dest.add content
499495 dest.addParRi ()
500496
501497 writeFile (dest, d)
@@ -587,7 +583,6 @@ proc cursorFromIndexEntry(c: var DecodeContext; module: FileIndex; entry: NifInd
587583 buf: var TokenBuf ): Cursor =
588584 let s = addr c.mods[module.int32 ].stream
589585 s.r.jumpTo entry.offset
590- var buf = createTokenBuf (30 )
591586 nifcursors.parse (s[], buf, entry.info)
592587 result = cursorAt (buf, 0 )
593588
@@ -613,7 +608,8 @@ proc getOffset(c: var DecodeContext; module: FileIndex; nifName: string): NifInd
613608 if result .offset == 0 :
614609 raiseAssert " symbol has no offset: " & nifName
615610
616- proc loadNode (c: var DecodeContext ; n: var Cursor ; thisModule: string ): PNode
611+ proc loadNode (c: var DecodeContext ; n: var Cursor ; thisModule: string ;
612+ localSyms: var Table [string , PSym ]): PNode
617613
618614proc loadTypeStub (c: var DecodeContext ; t: SymId ): PType =
619615 let name = pool.syms[t]
@@ -745,7 +741,8 @@ proc loadType*(c: var DecodeContext; t: PType) =
745741 loadField t.itemId.item # nonUniqueId
746742
747743 t.typeInstImpl = loadTypeStub (c, n)
748- t.nImpl = loadNode (c, n, typesModule)
744+ var emptyLocalSyms = initTable [string , PSym ]()
745+ t.nImpl = loadNode (c, n, typesModule, emptyLocalSyms)
749746 t.ownerFieldImpl = loadSymStub (c, n, typesModule)
750747 t.symImpl = loadSymStub (c, n, typesModule)
751748 loadLoc c, n, t.locImpl
@@ -755,7 +752,7 @@ proc loadType*(c: var DecodeContext; t: PType) =
755752
756753 skipParRi n
757754
758- proc loadAnnex (c: var DecodeContext ; n: var Cursor ; thisModule: string ): PLib =
755+ proc loadAnnex (c: var DecodeContext ; n: var Cursor ; thisModule: string ; localSyms: var Table [ string , PSym ] ): PLib =
759756 if n.kind == DotToken :
760757 result = nil
761758 inc n
@@ -767,7 +764,7 @@ proc loadAnnex(c: var DecodeContext; n: var Cursor; thisModule: string): PLib =
767764 expect n, StringLit
768765 result .name = pool.strings[n.litId]
769766 inc n
770- result .path = loadNode (c, n, thisModule)
767+ result .path = loadNode (c, n, thisModule, localSyms )
771768 skipParRi n
772769 else :
773770 raiseAssert " `lib/annex` information expected"
@@ -817,7 +814,8 @@ proc loadSymFromCursor(c: var DecodeContext; s: PSym; n: var Cursor; thisModule:
817814 # We do not store `sym.ast` here but instead set it in the deserializer
818815 # writeNode(w, sym.ast)
819816 loadLoc c, n, s.locImpl
820- s.constraintImpl = loadNode (c, n, thisModule)
817+ var emptyLocalSyms = initTable [string , PSym ]()
818+ s.constraintImpl = loadNode (c, n, thisModule, emptyLocalSyms)
821819 s.instantiatedFromImpl = loadSymStub (c, n, thisModule)
822820 skipParRi n
823821
@@ -845,12 +843,20 @@ template withNode(c: var DecodeContext; n: var Cursor; result: PNode; kind: TNod
845843 body
846844 skipParRi n
847845
848- proc loadNode (c: var DecodeContext ; n: var Cursor ; thisModule: string ): PNode =
846+ proc loadNode (c: var DecodeContext ; n: var Cursor ; thisModule: string ;
847+ localSyms: var Table [string , PSym ]): PNode =
849848 result = nil
850849 case n.kind
851850 of Symbol :
852851 let info = c.infos.oldLineInfo (n.info)
853- result = newSymNode (c.loadSymStub (n, thisModule), info)
852+ let symName = pool.syms[n.symId]
853+ # Check local symbols first
854+ let localSym = localSyms.getOrDefault (symName)
855+ if localSym != nil :
856+ result = newSymNode (localSym, info)
857+ inc n
858+ else :
859+ result = newSymNode (c.loadSymStub (n, thisModule), info)
854860 of DotToken :
855861 result = nil
856862 inc n
@@ -874,14 +880,25 @@ proc loadNode(c: var DecodeContext; n: var Cursor; thisModule: string): PNode =
874880 let info = c.infos.oldLineInfo (n.info)
875881 let name = n.firstSon
876882 assert name.kind == SymbolDef
883+ let symName = pool.syms[name.symId]
877884 # Check if this is a local symbol (no module suffix in name)
878- let isLocal = parseSymName (pool.syms[name.symId]).module.len == 0
879- let sym = c.loadSymStub (name.symId, thisModule)
885+ let sn = parseSymName (symName)
886+ let isLocal = sn.module.len == 0
887+ var sym: PSym
880888 if isLocal:
889+ # Create local symbol directly - it's not in the index
890+ let module = moduleId (c, thisModule)
891+ let val = addr c.mods[module.int32 ].symCounter
892+ inc val[]
893+ let id = ItemId (module: module.int32 , item: val[])
894+ sym = PSym (itemId: id, kindImpl: skStub, name: c.cache.getIdent (sn.name),
895+ disamb: sn.count.int32 , state: Complete )
896+ localSyms[symName] = sym # register for later references
881897 inc n # skip `sd` tag
882898 loadSymFromCursor (c, sym, n, thisModule)
883899 sym.state = Sealed # mark as fully loaded
884900 else :
901+ sym = c.loadSymStub (name.symId, thisModule)
885902 skip n # skip the entire sdef for indexed symbols
886903 result = newSymNode (sym, info)
887904 of typeDefTagName:
@@ -957,7 +974,7 @@ proc loadNode(c: var DecodeContext; n: var Cursor; thisModule: string): PNode =
957974 else :
958975 c.withNode n, result , kind:
959976 while n.kind != ParRi :
960- result .sons.add c.loadNode (n, thisModule)
977+ result .sons.add c.loadNode (n, thisModule, localSyms )
961978 else :
962979 raiseAssert " expected string literal but got " & $ n.kind
963980
@@ -1003,25 +1020,16 @@ proc toNifIndexFilename*(conf: ConfigRef; f: FileIndex): string =
10031020
10041021proc loadNifModule * (c: var DecodeContext ; f: FileIndex ; interf, interfHidden: var TStrTable ): PNode =
10051022 let suffix = moduleSuffix (c.infos.config, f)
1006- let modFile = toGeneratedFile (c.infos.config, AbsoluteFile (suffix), " .nif" ).string
10071023
10081024 # Ensure module index is loaded - moduleId returns the FileIndex for this suffix
10091025 let module = moduleId (c, suffix)
10101026
10111027 # Populate interface tables from the NIF index structure
1012- # Use the FileIndex returned by moduleId to ensure we access the correct index
1028+ # Symbols are created as stubs (Partial state) and will be loaded lazily via loadSym
10131029 populateInterfaceTablesFromIndex (c, module, interf, interfHidden, suffix)
10141030
1015- var buf = createTokenBuf (300 )
1016- var s = nifstreams.open (modFile)
1017- discard processDirectives (s.r)
1018- # XXX We can optimize this here and only load the top level entries!
1019- try :
1020- nifcursors.parse (s, buf, NoLineInfo )
1021- finally :
1022- nifstreams.close (s)
1023- var n = cursorAt (buf, 0 )
1024- result = loadNode (c, n, suffix)
1031+ # Return empty statement list - actual content is loaded lazily via the index
1032+ result = newNode (nkStmtList)
10251033
10261034when isMainModule :
10271035 import std / syncio
0 commit comments