bring back the 'm' switch for development

This commit is contained in:
araq
2025-12-02 09:25:17 +01:00
parent 91febf1f4c
commit ce4d75cbc2
3 changed files with 36 additions and 14 deletions

View File

@@ -11,6 +11,7 @@
import std / [assertions, tables, sets]
from std / strutils import startsWith
from std / os import fileExists
import astdef, idents, msgs, options
import lineinfos as astli
import pathutils #, modulegraphs
@@ -495,12 +496,14 @@ proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode) =
writeFile(dest, d)
createIndex(d, false, dest[0].info)
# Unload all written types and symbols from memory after the entire module is written
# This handles cyclic references correctly since everything is written before unloading
for typ in w.writtenTypes:
forcePartial(typ)
for sym in w.writtenSyms:
forcePartial(sym)
# Don't unload symbols/types yet - they may be needed by other modules that haven't
# had their NIF files written. For recursive module dependencies (like system.nim),
# we need all NIFs to exist before we can safely unload and reload.
# TODO: Implement deferred unloading at end of compilation for memory savings.
#for typ in w.writtenTypes:
# forcePartial(typ)
#for sym in w.writtenSyms:
# forcePartial(sym)
# --------------------------- Loader (lazy!) -----------------------------------------------
@@ -589,6 +592,10 @@ proc moduleId(c: var DecodeContext; suffix: string): FileIndex =
if not isKnownFile:
let modFile = (getNimcacheDir(c.infos.config) / RelativeFile(suffix & ".nif")).string
let idxFile = (getNimcacheDir(c.infos.config) / RelativeFile(suffix & ".s.idx.nif")).string
if not fileExists(modFile):
raiseAssert "NIF file not found for module suffix '" & suffix & "': " & modFile &
". This can happen when loading a module from NIF that references another module " &
"whose NIF file hasn't been written yet."
if result.int >= c.mods.len:
c.mods.setLen(result.int + 1)
c.mods[result.int] = NifModule(stream: nifstreams.open(modFile), index: readIndex(idxFile))

View File

@@ -510,6 +510,9 @@ proc setCmd*(conf: ConfigRef, cmd: Command) =
of cmdCompileToOC: conf.backend = backendObjc
of cmdCompileToJS: conf.backend = backendJs
of cmdCompileToNif: conf.backend = backendNif
of cmdM:
# cmdM requires optCompress for proper IC handling (include files, etc.)
conf.globalOptions.incl optCompress
else: discard
proc setCommandEarly*(conf: ConfigRef, command: string) =

View File

@@ -160,7 +160,7 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
s = stream
graph.interactive = stream.kind == llsStdIn
var topLevelStmts =
if optCompress in graph.config.globalOptions:
if optCompress in graph.config.globalOptions or graph.config.cmd == cmdM:
newNodeI(nkStmtList, module.info)
else:
nil
@@ -235,14 +235,16 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
raiseAssert "use setPipeLinePass to set a proper PipelinePass"
when not defined(nimKochBootstrap):
if optCompress in graph.config.globalOptions and not graph.config.isDefined("nimscript"):
if (optCompress in graph.config.globalOptions or graph.config.cmd == cmdM) and
not graph.config.isDefined("nimscript"):
topLevelStmts.add finalNode
writeNifModule(graph.config, module.position.int32, topLevelStmts)
if graph.config.backend notin {backendC, backendCpp, backendObjc}:
if graph.config.backend notin {backendC, backendCpp, backendObjc} and graph.config.cmd != cmdM:
# We only write rod files here if no C-like backend is active.
# The C-like backends have been patched to support the IC mechanism.
# They are responsible for closing the rod files. See `cbackend.nim`.
# cmdM uses NIF files only, not ROD files.
closeRodFile(graph, module)
result = true
@@ -261,11 +263,20 @@ proc compilePipelineModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymF
if result == nil:
var cachedModules: seq[FileIndex] = @[]
when not defined(nimKochBootstrap):
# Try loading from NIF file first if optCompress is enabled
if optCompress in graph.config.globalOptions and not graph.config.isDefined("nimscript"):
# For cmdM: load imports from NIF files (but compile the main module from source)
# Skip when withinSystem is true (compiling system.nim itself)
if graph.config.cmd == cmdM and
sfMainModule notin flags and
not graph.withinSystem and
not graph.config.isDefined("nimscript"):
result = moduleFromNifFile(graph, fileIdx, cachedModules)
if result == nil:
# Fall back to ROD file loading
if result == nil:
let nifPath = toNifFilename(graph.config, fileIdx)
localError(graph.config, unknownLineInfo,
"nim m requires precompiled NIF for import: " & toFullPath(graph.config, fileIdx) &
" (expected: " & nifPath & ")")
if result == nil and graph.config.cmd != cmdM:
# Fall back to ROD file loading (not used for cmdM which uses NIF only)
result = moduleFromRodFile(graph, fileIdx, cachedModules)
let path = toFullPath(graph.config, fileIdx)
let filename = AbsoluteFile path
@@ -287,7 +298,8 @@ proc compilePipelineModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymF
partialInitModule(result, graph, fileIdx, filename)
for m in cachedModules:
registerModuleById(graph, m)
if sfMainModule in flags and graph.config.cmd == cmdM:
if graph.config.cmd == cmdM:
# cmdM uses NIF files, not ROD files - skip ROD-specific replay
discard
else:
replayStateChanges(graph.packed.pm[m.int].module, graph)