mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-18 18:47:16 +00:00
IC: compilerprocs mechanism
This commit is contained in:
@@ -1420,10 +1420,32 @@ proc resolveHookSym*(c: var DecodeContext; symId: nifstreams.SymId): PSym =
|
||||
disamb: sn.count.int32, state: Partial)
|
||||
c.syms[id] = (result, offs)
|
||||
|
||||
proc tryResolveCompilerProc*(c: var DecodeContext; name: string; moduleFileIdx: FileIndex): PSym =
|
||||
## Tries to resolve a compiler proc from a module by checking the NIF index.
|
||||
## Returns nil if the symbol doesn't exist.
|
||||
let suffix = moduleSuffix(c.infos.config, moduleFileIdx)
|
||||
let symName = name & ".0." & suffix
|
||||
|
||||
# Check if module index is loaded, if not load it
|
||||
let module = moduleId(c, suffix)
|
||||
|
||||
# Check if symbol exists in the index (check both public and private)
|
||||
var offs = c.mods[module].index.public.getOrDefault(symName)
|
||||
if offs.offset == 0:
|
||||
offs = c.mods[module].index.private.getOrDefault(symName)
|
||||
if offs.offset == 0:
|
||||
return nil
|
||||
|
||||
# Get or create the SymId for this symbol name
|
||||
let symId = pool.syms.getOrIncl(symName)
|
||||
# Now resolve it - this will create the PSym stub
|
||||
result = resolveHookSym(c, symId)
|
||||
|
||||
proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: var TStrTable;
|
||||
hooks: var Table[nifstreams.SymId, HooksPerType];
|
||||
converters: var seq[(string, string)];
|
||||
classes: var seq[ClassIndexEntry]): PNode =
|
||||
classes: var seq[ClassIndexEntry];
|
||||
loadFullAst: bool = false): PNode =
|
||||
let suffix = moduleSuffix(c.infos.config, f)
|
||||
|
||||
# Ensure module index is loaded - moduleId returns the FileIndex for this suffix
|
||||
|
||||
@@ -447,6 +447,7 @@ proc mainCommand*(graph: ModuleGraph) =
|
||||
of cmdNifC:
|
||||
# Generate C code from NIF files
|
||||
wantMainModule(conf)
|
||||
setOutFile(conf)
|
||||
commandNifC(graph)
|
||||
of cmdDeps:
|
||||
# Generate .build.nif for nifmake
|
||||
|
||||
@@ -435,7 +435,30 @@ proc copyTypeProps*(g: ModuleGraph; module: int; dest, src: PType) =
|
||||
|
||||
proc loadCompilerProc*(g: ModuleGraph; name: string): PSym =
|
||||
result = nil
|
||||
if g.config.symbolFiles == disabledSf: return nil
|
||||
if g.config.symbolFiles == disabledSf:
|
||||
# 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:
|
||||
# First try system module (most compilerprocs are there)
|
||||
let systemFileIdx = g.config.m.systemFileIdx
|
||||
if systemFileIdx != InvalidFileIdx:
|
||||
result = tryResolveCompilerProc(ast.program, name, systemFileIdx)
|
||||
if result != nil:
|
||||
strTableAdd(g.compilerprocs, result)
|
||||
return result
|
||||
|
||||
# Try threadpool module (some compilerprocs like FlowVar are there)
|
||||
# Find threadpool module by searching loaded modules
|
||||
for moduleIdx in 0..<g.ifaces.len:
|
||||
let module = g.ifaces[moduleIdx].module
|
||||
if module != nil and module.name.s == "threadpool":
|
||||
let threadpoolFileIdx = module.position.FileIndex
|
||||
result = tryResolveCompilerProc(ast.program, name, threadpoolFileIdx)
|
||||
if result != nil:
|
||||
strTableAdd(g.compilerprocs, result)
|
||||
return result
|
||||
return nil
|
||||
|
||||
# slow, linear search, but the results are cached:
|
||||
for module in 0..<len(g.packed):
|
||||
@@ -755,9 +778,11 @@ proc moduleFromRodFile*(g: ModuleGraph; fileIdx: FileIndex;
|
||||
|
||||
when not defined(nimKochBootstrap):
|
||||
proc moduleFromNifFile*(g: ModuleGraph; fileIdx: FileIndex;
|
||||
cachedModules: var seq[FileIndex]): PSym =
|
||||
cachedModules: var seq[FileIndex];
|
||||
loadFullAst: bool = false): PSym =
|
||||
## Returns 'nil' if the module needs to be recompiled.
|
||||
## Loads module from NIF file when optCompress is enabled.
|
||||
## When loadFullAst is true, loads the complete module AST for code generation.
|
||||
|
||||
if not fileExists(toNifFilename(g.config, fileIdx)):
|
||||
return nil
|
||||
@@ -779,7 +804,7 @@ when not defined(nimKochBootstrap):
|
||||
var converters: seq[(string, string)] = @[]
|
||||
var classes: seq[ClassIndexEntry] = @[]
|
||||
result.astImpl = loadNifModule(ast.program, fileIdx, g.ifaces[fileIdx.int].interf,
|
||||
g.ifaces[fileIdx.int].interfHidden, hooks, converters, classes)
|
||||
g.ifaces[fileIdx.int].interfHidden, hooks, converters, classes, loadFullAst)
|
||||
# Register hooks from NIF index with the module graph
|
||||
for typSymId, hooksPerType in hooks:
|
||||
let typeItemId = parseTypeSymIdToItemId(ast.program, typSymId)
|
||||
|
||||
@@ -39,8 +39,9 @@ proc loadModuleDependencies(g: ModuleGraph; mainFileIdx: FileIndex): seq[PSym] =
|
||||
if visited.containsOrIncl(int(fileIdx)):
|
||||
continue
|
||||
|
||||
# Load module from NIF
|
||||
let module = moduleFromNifFile(g, fileIdx, cachedModules)
|
||||
# Only load full AST for main module; others are loaded lazily by codegen
|
||||
let isMainModule = fileIdx == mainFileIdx
|
||||
let module = moduleFromNifFile(g, fileIdx, cachedModules, loadFullAst=isMainModule)
|
||||
if module == nil:
|
||||
continue
|
||||
|
||||
@@ -71,8 +72,10 @@ proc generateCodeForModule(g: ModuleGraph; module: PSym) =
|
||||
if module.ast != nil:
|
||||
cgen.genTopLevelStmt(bmod, module.ast)
|
||||
|
||||
# Finalize the module
|
||||
finalCodegenActions(g, bmod, newNodeI(nkStmtList, module.info))
|
||||
# Finalize the module (this adds it to modulesClosed)
|
||||
# Create an empty stmt list as the init body - genInitCode in writeModule will set it up properly
|
||||
let initStmt = newNodeI(nkStmtList, module.info)
|
||||
finalCodegenActions(g, bmod, initStmt)
|
||||
|
||||
# Generate dispatcher methods
|
||||
for disp in getDispatchers(g):
|
||||
@@ -92,11 +95,12 @@ proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
|
||||
"Cannot load NIF file for main module: " & toFullPath(g.config, mainFileIdx))
|
||||
return
|
||||
|
||||
# Set up backend modules
|
||||
# Set up backend modules for all modules that need code generation
|
||||
for module in modules:
|
||||
discard setupNifBackendModule(g, module)
|
||||
|
||||
# Generate code for all modules except main (main goes last)
|
||||
# This ensures all modules are added to modulesClosed
|
||||
let mainModule = g.getModule(mainFileIdx)
|
||||
for module in modules:
|
||||
if module != mainModule:
|
||||
@@ -106,6 +110,13 @@ proc generateCode*(g: ModuleGraph; mainFileIdx: FileIndex) =
|
||||
if mainModule != nil:
|
||||
generateCodeForModule(g, mainModule)
|
||||
|
||||
# Also ensure system module is set up and generated if it exists
|
||||
if g.systemModule != nil and g.systemModule != mainModule:
|
||||
let systemBmod = BModuleList(g.backend).modules[g.systemModule.position]
|
||||
if systemBmod == nil:
|
||||
discard setupNifBackendModule(g, g.systemModule)
|
||||
generateCodeForModule(g, g.systemModule)
|
||||
|
||||
# Write C files
|
||||
if g.backend != nil:
|
||||
cgenWriteModules(g.backend, g.config)
|
||||
|
||||
Reference in New Issue
Block a user