Skip to content

Commit ec607ec

Browse files
committed
big progress
1 parent 189b960 commit ec607ec

File tree

1 file changed

+50
-42
lines changed

1 file changed

+50
-42
lines changed

compiler/ast2nif.nim

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
305308
proc 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) =
316319
proc 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

471471
proc 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

476476
proc 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

618614
proc 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

10041021
proc 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

10261034
when isMainModule:
10271035
import std / syncio

0 commit comments

Comments
 (0)