From a78dd184ecea8e94b2299caf2317983e42b63328 Mon Sep 17 00:00:00 2001 From: araq Date: Sun, 14 Dec 2025 09:19:01 +0100 Subject: [PATCH] wip --- compiler/ast2nif.nim | 36 +++++++++++++++++++++--------------- compiler/astdef.nim | 1 + compiler/modulegraphs.nim | 7 ++++++- compiler/pipelines.nim | 20 +------------------- lib/system.nim | 14 +++++++------- 5 files changed, 36 insertions(+), 42 deletions(-) diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index 2eb23d03fa..a4c939bd8e 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -664,11 +664,26 @@ proc buildExportBuf(w: var Writer): TokenBuf = result.add identToken(pool.strings.getOrIncl(name), NoLineInfo) result.addParRi() +proc translateOpsLog(w: var Writer; opsLog: seq[LogEntry]): IndexSections = + result = IndexSections(hooks: default array[AttachedOp, seq[HookIndexEntry]], converters: @[], classes: @[]) + for entry in opsLog: + let key = pool.syms.getOrIncl(entry.typ.typeKey(w.infos.config)) + let sym = pool.syms.getOrIncl(w.toNifSymName(entry.sym)) + case entry.kind + of HookEntry: + result.hooks[toAttachedOp(entry.op)].add HookIndexEntry(isGeneric: entry.isGeneric, typ: key, hook: sym) + of ConverterEntry: + result.converters.add (key, sym) + of MethodEntry: + discard "to implement" + of EnumToStrEntry: + discard "to implement" + + let replayTag = registerTag("replay") proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode; - hooks: array[AttachedOp, seq[HookIndexEntry]]; - converters: seq[(nifstreams.SymId, nifstreams.SymId)]; + opsLog: seq[LogEntry]; classes: seq[ClassIndexEntry]; replayActions: seq[PNode] = @[]) = var w = Writer(infos: LineInfoWriter(config: config), currentModule: thisModule) @@ -702,17 +717,9 @@ proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode; # Build index with export, hook, converter, and method information let exportBuf = buildExportBuf(w) - createIndex(d, dest[0].info, false, - IndexSections(hooks: hooks, converters: converters, classes: classes, exportBuf: exportBuf)) - - # 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) + var sections = translateOpsLog(w, opsLog) + sections.exportBuf = exportBuf + createIndex(d, dest[0].info, false, sections) # --------------------------- Loader (lazy!) ----------------------------------------------- @@ -1443,8 +1450,7 @@ proc tryResolveCompilerProc*(c: var DecodeContext; name: string; moduleFileIdx: result = resolveSym(c, symName, true) proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: var TStrTable; - hooks: var Table[nifstreams.SymId, HooksPerType]; - converters: var seq[(string, string)]; + logOps: var seq[LogEntry]; classes: var seq[ClassIndexEntry]; loadFullAst: bool = false): PNode = let suffix = moduleSuffix(c.infos.config, f) diff --git a/compiler/astdef.nim b/compiler/astdef.nim index d0c4586681..35c7c7ed1b 100644 --- a/compiler/astdef.nim +++ b/compiler/astdef.nim @@ -1000,6 +1000,7 @@ type LogEntry* = object kind*: LogEntryKind op*: TTypeAttachedOp + isGeneric*: bool typ*: PType sym*: PSym diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index fdc9da184b..5c5b35223d 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -367,8 +367,9 @@ proc getAttachedOp*(g: ModuleGraph; t: PType; op: TTypeAttachedOp): PSym = proc setAttachedOp*(g: ModuleGraph; module: int; t: PType; op: TTypeAttachedOp; value: PSym) = ## we also need to record this to the packed module. + if not g.attachedOps[op].contains(t.itemId): + g.opsLog.add LogEntry(kind: HookEntry, op: op, typ: t, sym: value) g.attachedOps[op][t.itemId] = LazySym(sym: value) - g.opsLog.add LogEntry(kind: HookEntry, op: op, typ: t, sym: value) proc setAttachedOp*(g: ModuleGraph; module: int; typeId: ItemId; op: TTypeAttachedOp; value: PSym) = ## Overload that takes ItemId directly, useful for registering hooks from NIF index. @@ -780,6 +781,10 @@ proc moduleFromRodFile*(g: ModuleGraph; fileIdx: FileIndex; else: result = nil +proc processLogOps*(g: ModuleGraph; logOps: seq[LogEntry]) = + for x in logOps: + discard + when not defined(nimKochBootstrap): proc moduleFromNifFile*(g: ModuleGraph; fileIdx: FileIndex; cachedModules: var seq[FileIndex]; diff --git a/compiler/pipelines.nim b/compiler/pipelines.nim index 1c17bae0ba..adf10f00de 100644 --- a/compiler/pipelines.nim +++ b/compiler/pipelines.nim @@ -254,24 +254,6 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator for (m, n) in PCtx(graph.vm).vmstateDiff: if m == module: replayActions.add n - # Collect hooks from the module graph for the current module - var hooks = default array[AttachedOp, seq[HookIndexEntry]] - for op in TTypeAttachedOp: - if op == attachedDeepCopy: continue # Not supported in nimony - let nimonyOp = toAttachedOp(op) - for typeId, lazySym in graph.attachedOps[op]: - if typeId.module == module.position.int32: - let sym = lazySym.sym - if sym != nil: - hooks[nimonyOp].add toHookIndexEntry(graph.config, typeId, sym) - # Collect converters from the module's interface - var converters: seq[(nifstreams.SymId, nifstreams.SymId)] = @[] - for lazySym in graph.ifaces[module.position].converters: - let sym = lazySym.sym - if sym != nil: - let entry = toConverterIndexEntry(graph.config, sym) - if entry[0] != nifstreams.SymId(0): - converters.add entry # Collect methods per type for classes var classes: seq[ClassIndexEntry] = @[] for typeId, methodList in graph.methodsPerType: @@ -288,7 +270,7 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator cls: toClassSymId(graph.config, typeId), methods: methods ) - writeNifModule(graph.config, module.position.int32, topLevelStmts, hooks, converters, classes, replayActions) + writeNifModule(graph.config, module.position.int32, topLevelStmts, move(graph.opsLog), classes, replayActions) 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. diff --git a/lib/system.nim b/lib/system.nim index ecc14b2ea7..5ac510dad5 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -390,15 +390,15 @@ else: ## Generic `destructor`:idx: implementation that can be overridden. discard - when defined(nimAllowNonVarDestructor) and arcLikeMem: - proc `=destroy`*(x: string) {.inline, magic: "Destroy", enforceNoRaises.} = - discard +when defined(nimAllowNonVarDestructor) and arcLikeMem: + proc `=destroy`*(x: string) {.inline, magic: "Destroy", enforceNoRaises.} = + discard - proc `=destroy`*[T](x: seq[T]) {.inline, magic: "Destroy".} = - discard + proc `=destroy`*[T](x: seq[T]) {.inline, magic: "Destroy".} = + discard - proc `=destroy`*[T](x: ref T) {.inline, magic: "Destroy".} = - discard + proc `=destroy`*[T](x: ref T) {.inline, magic: "Destroy".} = + discard when defined(nimHasDup): proc `=dup`*[T](x: T): T {.inline, magic: "Dup".} =