mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
IC: remember which modules are from the NIF cache (#25443)
This commit is contained in:
@@ -345,6 +345,8 @@ proc writeSymDef(w: var Writer; dest: var TokenBuf; sym: PSym) =
|
||||
|
||||
if sym.kindImpl == skModule:
|
||||
dest.addDotToken() # position will be set by the loader!
|
||||
elif sym.kindImpl in {skVar, skLet, skForVar, skResult}:
|
||||
dest.addIntLit 0 # hack for the VM which uses this field to store information
|
||||
else:
|
||||
dest.addIntLit sym.positionImpl
|
||||
|
||||
@@ -879,7 +881,11 @@ proc readEmbeddedIndex(s: var Stream): Table[string, NifIndexEntry] =
|
||||
proc moduleId(c: var DecodeContext; suffix: string; flags: set[LoadFlag] = {}): FileIndex =
|
||||
var isKnownFile = false
|
||||
result = c.infos.config.registerNifSuffix(suffix, isKnownFile)
|
||||
if not isKnownFile or AlwaysLoadInterface in flags:
|
||||
# Always load the module's index if it's not already in c.mods
|
||||
# This is needed when resolving symbols from modules that were registered elsewhere
|
||||
# but haven't had their NIF index loaded yet
|
||||
let hasEntry = c.mods.hasKey(result)
|
||||
if not hasEntry or AlwaysLoadInterface in flags:
|
||||
let modFile = (getNimcacheDir(c.infos.config) / RelativeFile(suffix & ".nif")).string
|
||||
if not fileExists(modFile):
|
||||
raiseAssert "NIF file not found for module suffix '" & suffix & "': " & modFile &
|
||||
@@ -1438,7 +1444,13 @@ proc resolveSym(c: var DecodeContext; symAsStr: string; alsoConsiderPrivate: boo
|
||||
return nil # Local symbols shouldn't be hooks
|
||||
let module = moduleId(c, sn.module)
|
||||
# Look up the symbol in the module's index
|
||||
# Try both formats: with module suffix (e.g., "foo.0.modulename") and without (e.g., "foo.0.")
|
||||
# NIF spec allows local symbols to be stored without module suffix
|
||||
var offs = c.mods[module].index.getOrDefault(symAsStr)
|
||||
if offs.offset == 0:
|
||||
# Try the format without module suffix
|
||||
let localKey = sn.name & "." & $sn.count & "."
|
||||
offs = c.mods[module].index.getOrDefault(localKey)
|
||||
if offs.offset == 0:
|
||||
return nil
|
||||
if not alsoConsiderPrivate and offs.vis == Hidden:
|
||||
|
||||
@@ -32,6 +32,7 @@ type
|
||||
nodes: seq[Node]
|
||||
processedModules: Table[string, int] # modname -> node index
|
||||
includeStack: seq[string]
|
||||
systemNodeId: int # ID of the system.nim node
|
||||
|
||||
proc toPair(c: DepContext; f: string): FilePair =
|
||||
FilePair(nimFile: f, modname: moduleSuffix(f, cast[seq[string]](c.config.searchPaths)))
|
||||
@@ -128,6 +129,9 @@ proc processImport(c: var DepContext; importPath: string; current: Node) =
|
||||
# New module - create node and process it
|
||||
let newNode = Node(files: @[pair], id: c.nodes.len)
|
||||
current.deps.add newNode.id
|
||||
# Every module depends on system.nim
|
||||
if c.systemNodeId >= 0:
|
||||
newNode.deps.add c.systemNodeId
|
||||
c.processedModules[pair.modname] = newNode.id
|
||||
c.nodes.add newNode
|
||||
traverseDeps(c, pair, newNode)
|
||||
@@ -223,9 +227,9 @@ proc traverseDeps(c: var DepContext; pair: FilePair; current: Node) =
|
||||
|
||||
proc generateBuildFile(c: DepContext): string =
|
||||
## Generate the .build.nif file for nifmake
|
||||
createDir("nifcache")
|
||||
result = "nifcache" / c.nodes[0].files[0].modname & ".build.nif"
|
||||
#getNimcacheDir(c.config).string / c.nodes[0].files[0].modname & ".build.nif"
|
||||
let nimcache = getNimcacheDir(c.config).string
|
||||
createDir(nimcache)
|
||||
result = nimcache / c.nodes[0].files[0].modname & ".build.nif"
|
||||
|
||||
var b = nifbuilder.open(result)
|
||||
defer: b.close()
|
||||
@@ -250,7 +254,7 @@ proc generateBuildFile(c: DepContext): string =
|
||||
b.addSymbolDef "nim_m"
|
||||
b.addStrLit getAppFilename()
|
||||
b.addStrLit "m"
|
||||
b.addStrLit "--nimcache:nifcache"
|
||||
b.addStrLit "--nimcache:" & nimcache
|
||||
# Add search paths
|
||||
for p in c.config.searchPaths:
|
||||
b.addStrLit "--path:" & p.string
|
||||
@@ -265,7 +269,7 @@ proc generateBuildFile(c: DepContext): string =
|
||||
b.addSymbolDef "nim_nifc"
|
||||
b.addStrLit getAppFilename()
|
||||
b.addStrLit "nifc"
|
||||
b.addStrLit "--nimcache:nifcache"
|
||||
b.addStrLit "--nimcache:" & nimcache
|
||||
# Add search paths
|
||||
for p in c.config.searchPaths:
|
||||
b.addStrLit "--path:" & p.string
|
||||
@@ -354,7 +358,8 @@ proc commandIc*(conf: ConfigRef) =
|
||||
nifler: nifler,
|
||||
nodes: @[],
|
||||
processedModules: initTable[string, int](),
|
||||
includeStack: @[]
|
||||
includeStack: @[],
|
||||
systemNodeId: -1
|
||||
)
|
||||
|
||||
# Create root node for main project file
|
||||
@@ -366,6 +371,7 @@ proc commandIc*(conf: ConfigRef) =
|
||||
# model the system.nim dependency:
|
||||
let sysNode = Node(files: @[toPair(c, (conf.libpath / RelativeFile"system.nim").string)], id: 1)
|
||||
c.nodes.add sysNode
|
||||
c.systemNodeId = sysNode.id
|
||||
rootNode.deps.add sysNode.id
|
||||
|
||||
# Process dependencies
|
||||
|
||||
@@ -289,9 +289,8 @@ proc myImportModule(c: PContext, n: var PNode, importStmtResult: PNode): PSym =
|
||||
c.recursiveDep = err
|
||||
|
||||
let trackUnusedImport = warnUnusedImportX in c.config.notes
|
||||
var realModule: PSym
|
||||
discard pushOptionEntry(c)
|
||||
realModule = c.graph.importModuleCallback(c.graph, c.module, f)
|
||||
let realModule = c.graph.importModuleCallback(c.graph, c.module, f)
|
||||
result = importModuleAs(c, n, realModule, transf.importHidden, trackUnusedImport)
|
||||
popOptionEntry(c)
|
||||
|
||||
|
||||
@@ -375,11 +375,12 @@ proc loadCompilerProc*(g: ModuleGraph; name: string): PSym =
|
||||
if g.config.symbolFiles == disabledSf and optWithinConfigSystem notin g.config.globalOptions:
|
||||
# For NIF-based compilation, search in loaded NIF modules
|
||||
when not defined(nimKochBootstrap):
|
||||
# Only try to resolve from NIF if we're actually using NIF files (cmdNifC)
|
||||
if g.config.cmd == cmdNifC:
|
||||
# Try to resolve from NIF for both cmdNifC and cmdM (which uses NIF files)
|
||||
if g.config.cmd in {cmdNifC, cmdM}:
|
||||
# First try system module (most compilerprocs are there)
|
||||
let systemFileIdx = g.config.m.systemFileIdx
|
||||
if systemFileIdx != InvalidFileIdx:
|
||||
if systemFileIdx != InvalidFileIdx and not g.withinSystem:
|
||||
# Only try to load from NIF if the file exists (it may not during initial ic build)
|
||||
result = tryResolveCompilerProc(ast.program, name, systemFileIdx)
|
||||
if result != nil:
|
||||
strTableAdd(g.compilerprocs, result)
|
||||
@@ -536,6 +537,7 @@ proc initModuleGraphFields(result: ModuleGraph) =
|
||||
result.operators = initOperators(result)
|
||||
result.emittedTypeInfo = initTable[string, FileIndex]()
|
||||
result.cachedFiles = newStringTable()
|
||||
result.cachedMods = initIntSet()
|
||||
|
||||
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||
result = ModuleGraph()
|
||||
@@ -677,6 +679,9 @@ when not defined(nimKochBootstrap):
|
||||
g.ifaces[fileIdx.int].interfHidden, flags)
|
||||
result.module = m
|
||||
|
||||
# Mark module as cached
|
||||
g.cachedMods.incl fileIdx.int
|
||||
|
||||
# Register hooks from NIF index with the module graph
|
||||
for x in result.logOps:
|
||||
case x.kind
|
||||
|
||||
@@ -1586,7 +1586,6 @@ proc genAsgn(c: PCtx; dest: TDest; ri: PNode; requiresCopy: bool) =
|
||||
proc setSlot(c: PCtx; v: PSym) =
|
||||
# XXX generate type initialization here?
|
||||
if v.position == 0:
|
||||
# IC: review this solution again later
|
||||
v.positionImpl = getFreeRegister(c, if v.kind == skLet: slotFixedLet else: slotFixedVar, start = 1)
|
||||
|
||||
template cannotEval(c: PCtx; n: PNode) =
|
||||
|
||||
4
tests/ic/myimp.nim
Normal file
4
tests/ic/myimp.nim
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
proc foo*(x: var int) =
|
||||
inc x
|
||||
|
||||
10
tests/ic/timp.nim
Normal file
10
tests/ic/timp.nim
Normal file
@@ -0,0 +1,10 @@
|
||||
discard """
|
||||
output: "hi 1"
|
||||
"""
|
||||
|
||||
import myimp
|
||||
|
||||
var x = 0
|
||||
foo(x)
|
||||
|
||||
echo "hi ", x
|
||||
Reference in New Issue
Block a user