From 8e10fb388265d5f2591dde4ddbf019850a7ffdae Mon Sep 17 00:00:00 2001 From: araq Date: Wed, 21 Jan 2026 11:25:49 +0100 Subject: [PATCH] much progress --- compiler/ast2nif.nim | 14 +++++++++++++- compiler/modulegraphs.nim | 4 ++-- compiler/vmgen.nim | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index 935637a94b..97e6343da0 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -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: diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 8f13e4d516..dda7f8a379 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -375,8 +375,8 @@ 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: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index ddcc834c7e..9576fd3a99 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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) =