Skip to content

Commit c985e81

Browse files
committed
support ic
1 parent 96455d4 commit c985e81

File tree

7 files changed

+93
-23
lines changed

7 files changed

+93
-23
lines changed

compiler/ic/ic.nim

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type
3636
bodies*: PackedTree # other trees. Referenced from typ.n and sym.ast by their position.
3737
#producedGenerics*: Table[GenericKey, SymId]
3838
exports*: seq[(LitId, int32)]
39+
hidden*: seq[(LitId, int32)]
3940
reexports*: seq[(LitId, PackedItemId)]
4041
compilerProcs*: seq[(LitId, int32)]
4142
converters*, methods*, trmacros*, pureEnums*: seq[int32]
@@ -177,6 +178,10 @@ proc addIncludeFileDep*(c: var PackedEncoder; m: var PackedModule; f: FileIndex)
177178
proc addImportFileDep*(c: var PackedEncoder; m: var PackedModule; f: FileIndex) =
178179
m.imports.add toLitId(f, c, m)
179180

181+
proc addHidden*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
182+
let nameId = getOrIncl(m.sh.strings, s.name.s)
183+
m.hidden.add((nameId, s.itemId.item))
184+
180185
proc addExported*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
181186
let nameId = getOrIncl(m.sh.strings, s.name.s)
182187
m.exports.add((nameId, s.itemId.item))
@@ -524,7 +529,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
524529
loadTabSection numbersSection, m.sh.numbers
525530

526531
loadSeqSection exportsSection, m.exports
527-
532+
loadSeqSection hiddenSection, m.hidden
528533
loadSeqSection reexportsSection, m.reexports
529534

530535
loadSeqSection compilerProcsSection, m.compilerProcs
@@ -589,7 +594,7 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
589594
storeTabSection numbersSection, m.sh.numbers
590595

591596
storeSeqSection exportsSection, m.exports
592-
597+
storeSeqSection hiddenSection, m.hidden
593598
storeSeqSection reexportsSection, m.reexports
594599

595600
storeSeqSection compilerProcsSection, m.compilerProcs
@@ -655,7 +660,9 @@ type
655660
syms: seq[PSym] # indexed by itemId
656661
types: seq[PType]
657662
module*: PSym # the one true module symbol.
658-
iface: Table[PIdent, seq[PackedItemId]] # PackedItemId so that it works with reexported symbols too
663+
iface, ifaceHidden: Table[PIdent, seq[PackedItemId]]
664+
# PackedItemId so that it works with reexported symbols too
665+
# ifaceHidden includes private symbols
659666

660667
PackedModuleGraph* = seq[LoadedModule] # indexed by FileIndex
661668

@@ -882,12 +889,18 @@ proc newPackage(config: ConfigRef; cache: IdentCache; fileIdx: FileIndex): PSym
882889
proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
883890
fileIdx: FileIndex; m: var LoadedModule) =
884891
m.iface = initTable[PIdent, seq[PackedItemId]]()
892+
m.ifaceHidden = initTable[PIdent, seq[PackedItemId]]()
885893
for e in m.fromDisk.exports:
886894
let nameLit = e[0]
887895
m.iface.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(PackedItemId(module: LitId(0), item: e[1]))
888896
for re in m.fromDisk.reexports:
889897
let nameLit = re[0]
890898
m.iface.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(re[1])
899+
m.ifaceHidden.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(re[1])
900+
901+
for e in m.fromDisk.hidden:
902+
let nameLit = e[0]
903+
m.ifaceHidden.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(PackedItemId(module: LitId(0), item: e[1]))
891904

892905
let filename = AbsoluteFile toFullPath(conf, fileIdx)
893906
# We cannot call ``newSym`` here, because we have to circumvent the ID
@@ -1053,24 +1066,29 @@ type
10531066
values: seq[PackedItemId]
10541067
i, module: int
10551068

1069+
template interfSelect(a: LoadedModule, importHidden: bool): auto =
1070+
var ret = a.iface.addr
1071+
if importHidden: ret = a.ifaceHidden.addr
1072+
ret[]
1073+
10561074
proc initRodIter*(it: var RodIter; config: ConfigRef, cache: IdentCache;
10571075
g: var PackedModuleGraph; module: FileIndex;
1058-
name: PIdent): PSym =
1076+
name: PIdent, importHidden: bool): PSym =
10591077
it.decoder = PackedDecoder(
10601078
lastModule: int32(-1),
10611079
lastLit: LitId(0),
10621080
lastFile: FileIndex(-1),
10631081
config: config,
10641082
cache: cache)
1065-
it.values = g[int module].iface.getOrDefault(name)
1083+
it.values = g[int module].interfSelect(importHidden).getOrDefault(name)
10661084
it.i = 0
10671085
it.module = int(module)
10681086
if it.i < it.values.len:
10691087
result = loadSym(it.decoder, g, int(module), it.values[it.i])
10701088
inc it.i
10711089

10721090
proc initRodIterAllSyms*(it: var RodIter; config: ConfigRef, cache: IdentCache;
1073-
g: var PackedModuleGraph; module: FileIndex): PSym =
1091+
g: var PackedModuleGraph; module: FileIndex, importHidden: bool): PSym =
10741092
it.decoder = PackedDecoder(
10751093
lastModule: int32(-1),
10761094
lastLit: LitId(0),
@@ -1079,7 +1097,7 @@ proc initRodIterAllSyms*(it: var RodIter; config: ConfigRef, cache: IdentCache;
10791097
cache: cache)
10801098
it.values = @[]
10811099
it.module = int(module)
1082-
for v in g[int module].iface.values:
1100+
for v in g[int module].interfSelect(importHidden).values:
10831101
it.values.add v
10841102
it.i = 0
10851103
if it.i < it.values.len:
@@ -1093,19 +1111,19 @@ proc nextRodIter*(it: var RodIter; g: var PackedModuleGraph): PSym =
10931111

10941112
iterator interfaceSymbols*(config: ConfigRef, cache: IdentCache;
10951113
g: var PackedModuleGraph; module: FileIndex;
1096-
name: PIdent): PSym =
1114+
name: PIdent, importHidden: bool): PSym =
10971115
setupDecoder()
1098-
let values = g[int module].iface.getOrDefault(name)
1116+
let values = g[int module].interfSelect(importHidden).getOrDefault(name)
10991117
for pid in values:
11001118
let s = loadSym(decoder, g, int(module), pid)
11011119
assert s != nil
11021120
yield s
11031121

11041122
proc interfaceSymbol*(config: ConfigRef, cache: IdentCache;
11051123
g: var PackedModuleGraph; module: FileIndex;
1106-
name: PIdent): PSym =
1124+
name: PIdent, importHidden: bool): PSym =
11071125
setupDecoder()
1108-
let values = g[int module].iface.getOrDefault(name)
1126+
let values = g[int module].interfSelect(importHidden).getOrDefault(name)
11091127
result = loadSym(decoder, g, int(module), values[0])
11101128

11111129
proc idgenFromLoadedModule*(m: LoadedModule): IdGenerator =
@@ -1126,7 +1144,7 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
11261144
let err = loadRodFile(rodfile, m, config, ignoreConfig=true)
11271145
if err != ok:
11281146
echo "Error: could not load: ", rodfile.string, " reason: ", err
1129-
quit 1
1147+
doAssert false # quit would prevent getting a stacktrace
11301148

11311149
when true:
11321150
echo "exports:"
@@ -1140,6 +1158,10 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
11401158
echo " ", m.sh.strings[ex[0]]
11411159
# reexports*: seq[(LitId, PackedItemId)]
11421160

1161+
echo "hidden: " & $m.hidden.len
1162+
for ex in m.hidden:
1163+
echo " ", m.sh.strings[ex[0]], " local ID: ", ex[1]
1164+
11431165
echo "all symbols"
11441166
for i in 0..high(m.sh.syms):
11451167
if m.sh.syms[i].name != LitId(0):

compiler/ic/rodfiles.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type
1818
depsSection
1919
numbersSection
2020
exportsSection
21+
hiddenSection
2122
reexportsSection
2223
compilerProcsSection
2324
trmacrosSection

compiler/modulegraphs.nim

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type
2929
patterns*: seq[LazySym]
3030
pureEnums*: seq[LazySym]
3131
interf: TStrTable
32-
interfAll: TStrTable
32+
interfHidden: TStrTable
3333
uniqueName*: Rope
3434

3535
Operators* = object
@@ -162,16 +162,15 @@ proc toBase64a(s: cstring, len: int): string =
162162
result.add cb64[(a and 3) shl 4]
163163

164164
template interfSelect(iface: Iface, importHidden: bool): TStrTable =
165-
var ret: ptr TStrTable # without intermediate ptr, it creates a copy and compiler becomes 15x slower!
166-
if importHidden: ret = iface.interfAll.addr
167-
else: ret = iface.interf.addr
165+
var ret = iface.interf.addr # without intermediate ptr, it creates a copy and compiler becomes 15x slower!
166+
if importHidden: ret = iface.interfHidden.addr
168167
ret[]
169168

170169
template semtab(g: ModuleGraph, m: PSym): TStrTable =
171170
g.ifaces[m.position].interf
172171

173172
template semtabAll*(g: ModuleGraph, m: PSym): TStrTable =
174-
g.ifaces[m.position].interfAll
173+
g.ifaces[m.position].interfHidden
175174

176175
proc initStrTables*(g: ModuleGraph, m: PSym) =
177176
initStrTable(semtab(g, m))
@@ -213,7 +212,7 @@ proc initModuleIter*(mi: var ModuleIter; g: ModuleGraph; m: PSym; name: PIdent):
213212
mi.fromRod = isCachedModule(g, mi.modIndex)
214213
mi.importHidden = optImportHidden in m.options
215214
if mi.fromRod:
216-
result = initRodIter(mi.rodIt, g.config, g.cache, g.packed, FileIndex mi.modIndex, name)
215+
result = initRodIter(mi.rodIt, g.config, g.cache, g.packed, FileIndex mi.modIndex, name, mi.importHidden)
217216
else:
218217
result = initIdentIter(mi.ti, g.ifaces[mi.modIndex].interfSelect(mi.importHidden), name)
219218

@@ -224,22 +223,24 @@ proc nextModuleIter*(mi: var ModuleIter; g: ModuleGraph): PSym =
224223
result = nextIdentIter(mi.ti, g.ifaces[mi.modIndex].interfSelect(mi.importHidden))
225224

226225
iterator allSyms*(g: ModuleGraph; m: PSym): PSym =
226+
let importHidden = optImportHidden in m.options
227227
if isCachedModule(g, m):
228228
var rodIt: RodIter
229-
var r = initRodIterAllSyms(rodIt, g.config, g.cache, g.packed, FileIndex m.position)
229+
var r = initRodIterAllSyms(rodIt, g.config, g.cache, g.packed, FileIndex m.position, importHidden)
230230
while r != nil:
231231
yield r
232232
r = nextRodIter(rodIt, g.packed)
233233
else:
234-
for s in g.ifaces[m.position].interfSelect(optImportHidden in m.options).data:
234+
for s in g.ifaces[m.position].interfSelect(importHidden).data:
235235
if s != nil:
236236
yield s
237237

238238
proc someSym*(g: ModuleGraph; m: PSym; name: PIdent): PSym =
239+
let importHidden = optImportHidden in m.options
239240
if isCachedModule(g, m):
240-
result = interfaceSymbol(g.config, g.cache, g.packed, FileIndex(m.position), name)
241+
result = interfaceSymbol(g.config, g.cache, g.packed, FileIndex(m.position), name, importHidden)
241242
else:
242-
result = strTableGet(g.ifaces[m.position].interfSelect(optImportHidden in m.options), name)
243+
result = strTableGet(g.ifaces[m.position].interfSelect(importHidden), name)
243244

244245
proc systemModuleSym*(g: ModuleGraph; name: PIdent): PSym =
245246
result = someSym(g, g.systemModule, name)
@@ -376,7 +377,10 @@ template onDefAux(info: TLineInfo; s0: PSym, c0: untyped, isFwd: bool) =
376377
# unfortunately, can't use `c.isTopLevel` because the scope isn't closed yet
377378
top = c.currentScope.depthLevel <= 3
378379
else: top = c.currentScope.depthLevel <= 2
379-
if top and c.module != nil: strTableAdd(semtabAll(c.graph, c.module), s0)
380+
if top and c.module != nil:
381+
strTableAdd(semtabAll(c.graph, c.module), s0)
382+
if c.config.symbolFiles != disabledSf:
383+
addHidden(c.encoder, c.packedRepr, s0)
380384

381385
when defined(nimfind):
382386
template onUse*(info: TLineInfo; s: PSym) =

testament/categories.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ proc icTests(r: var TResults; testsDir: string, cat: Category, options: string)
500500

501501
const tempExt = "_temp.nim"
502502
for it in walkDirRec(testsDir / "ic"):
503+
# for it in ["tests/ic/timports.nim"]: # debugging: to try a specific test
503504
if isTestFile(it) and not it.endsWith(tempExt):
504505
let nimcache = nimcacheDir(it, options, getTestSpecTarget())
505506
removeDir(nimcache)

tests/ic/mimports.nim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from mimportsb {.all.} import fnb1, hfnb3
2+
3+
proc fn1*(): int = 1
4+
proc fn2*(): int = 2
5+
proc hfn3(): int = 3
6+
proc hfn4(): int = 4
7+
proc hfn5(): int = 5
8+
9+
export mimportsb.fnb2, hfnb3

tests/ic/mimportsb.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
proc fnb1*(): int = 1
2+
proc fnb2*(): int = 2
3+
proc hfnb3(): int = 3
4+
proc hfnb4(): int = 4

tests/ic/timports.nim

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import mimports
2+
doAssert fn1() == 1
3+
doAssert not declared(hfn3)
4+
5+
#!EDIT!#
6+
7+
import mimports {.all.}
8+
doAssert fn1() == 1
9+
doAssert declared(hfn3)
10+
doAssert hfn3() == 3
11+
doAssert mimports.hfn4() == 4
12+
13+
# reexports
14+
doAssert not declared(fnb1)
15+
doAssert not declared(hfnb4)
16+
doAssert fnb2() == 2
17+
doAssert hfnb3() == 3
18+
19+
#!EDIT!#
20+
21+
from mimports {.all.} import hfn3
22+
doAssert not declared(fn1)
23+
from mimports {.all.} as bar import fn1
24+
doAssert fn1() == 1
25+
doAssert hfn3() == 3
26+
doAssert not declared(hfn4)
27+
doAssert declared(mimports.hfn4)
28+
doAssert mimports.hfn4() == 4
29+
doAssert bar.hfn4() == 4

0 commit comments

Comments
 (0)