This commit is contained in:
Araq
2025-12-16 09:31:46 +01:00
parent 0c12cd7435
commit c39a624165
4 changed files with 35 additions and 24 deletions

View File

@@ -698,8 +698,10 @@ proc writeNifModule*(config: ConfigRef; thisModule: int32; n: PNode;
for action in replayActions:
writeNode(w, content, action)
content.addParRi()
# Only write ops that belong to this module
for op in opsLog:
writeOp(w, content, op)
if op.module == thisModule.int:
writeOp(w, content, op)
w.writeToplevelNode content, n
@@ -1422,8 +1424,9 @@ proc resolveSym(c: var DecodeContext; symAsStr: string; alsoConsiderPrivate: boo
proc resolveHookSym*(c: var DecodeContext; symId: nifstreams.SymId): PSym =
## Resolves a hook SymId to PSym.
## Hook symbols are often private (generated =destroy, =wasMoved, etc.)
let symAsStr = pool.syms[symId]
result = resolveSym(c, symAsStr, false)
result = resolveSym(c, symAsStr, true)
proc tryResolveCompilerProc*(c: var DecodeContext; name: string; moduleFileIdx: FileIndex): PSym =
## Tries to resolve a compiler proc from a module by checking the NIF index.
@@ -1432,7 +1435,7 @@ proc tryResolveCompilerProc*(c: var DecodeContext; name: string; moduleFileIdx:
let symName = name & ".0." & suffix
result = resolveSym(c, symName, true)
proc loadLogOp(c: var DecodeContext; logOps: var seq[LogEntry]; s: var Stream; kind: LogEntryKind; op: TTypeAttachedOp): PackedToken =
proc loadLogOp(c: var DecodeContext; logOps: var seq[LogEntry]; s: var Stream; kind: LogEntryKind; op: TTypeAttachedOp; module: int): PackedToken =
result = next(s)
var key = ""
if result.kind == StringLit:
@@ -1443,9 +1446,8 @@ proc loadLogOp(c: var DecodeContext; logOps: var seq[LogEntry]; s: var Stream; k
if result.kind == Symbol:
let sym = resolveHookSym(c, result.symId)
if sym != nil:
logOps.add LogEntry(kind: kind, op: op, key: key, sym: sym)
else:
raiseAssert "symbol not found: " & pool.syms[result.symId]
logOps.add LogEntry(kind: kind, op: op, module: module, key: key, sym: sym)
# else: symbol not indexed, skip this hook entry
result = next(s)
if result.kind == ParRi:
result = next(s)
@@ -1479,7 +1481,7 @@ proc nextSubtree(r: var Stream; dest: var TokenBuf; tok: var PackedToken) =
dec nested
if nested == 0: break
proc processTopLevel(c: var DecodeContext; s: var Stream; loadFullAst: bool; suffix: string; logOps: var seq[LogEntry]): PNode =
proc processTopLevel(c: var DecodeContext; s: var Stream; loadFullAst: bool; suffix: string; logOps: var seq[LogEntry]; module: int): PNode =
result = newNode(nkStmtList)
var localSyms = initTable[string, PSym]()
@@ -1504,27 +1506,27 @@ proc processTopLevel(c: var DecodeContext; s: var Stream; loadFullAst: bool; suf
else:
raiseAssert "expected ParRi but got " & $t.kind
elif t.tagId == repConverterTag:
t = loadLogOp(c, logOps, s, ConverterEntry, attachedTrace)
t = loadLogOp(c, logOps, s, ConverterEntry, attachedTrace, module)
elif t.tagId == repDestroyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDestructor)
t = loadLogOp(c, logOps, s, HookEntry, attachedDestructor, module)
elif t.tagId == repWasMovedTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedWasMoved)
t = loadLogOp(c, logOps, s, HookEntry, attachedWasMoved, module)
elif t.tagId == repCopyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedAsgn)
t = loadLogOp(c, logOps, s, HookEntry, attachedAsgn, module)
elif t.tagId == repSinkTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedSink)
t = loadLogOp(c, logOps, s, HookEntry, attachedSink, module)
elif t.tagId == repDupTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDup)
t = loadLogOp(c, logOps, s, HookEntry, attachedDup, module)
elif t.tagId == repTraceTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedTrace)
t = loadLogOp(c, logOps, s, HookEntry, attachedTrace, module)
elif t.tagId == repDeepCopyTag:
t = loadLogOp(c, logOps, s, HookEntry, attachedDeepCopy)
t = loadLogOp(c, logOps, s, HookEntry, attachedDeepCopy, module)
elif t.tagId == repEnumToStrTag:
t = loadLogOp(c, logOps, s, EnumToStrEntry, attachedTrace)
t = loadLogOp(c, logOps, s, EnumToStrEntry, attachedTrace, module)
elif t.tagId == repMethodTag:
t = loadLogOp(c, logOps, s, MethodEntry, attachedTrace)
t = loadLogOp(c, logOps, s, MethodEntry, attachedTrace, module)
#elif t.tagId == repClassTag:
# t = loadLogOp(c, logOps, s, ClassEntry, attachedTrace)
# t = loadLogOp(c, logOps, s, ClassEntry, attachedTrace, module)
elif t.tagId == includeTag or t.tagId == importTag:
t = skipTree(s)
elif loadFullAst:
@@ -1560,7 +1562,7 @@ proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: va
if t.kind == ParLe and pool.tags[t.tagId] == toNifTag(nkStmtList):
t = next(s[]) # skip (stmts
t = next(s[]) # skip flags
result = processTopLevel(c, s[], loadFullAst, suffix, logOps)
result = processTopLevel(c, s[], loadFullAst, suffix, logOps, f.int)
else:
result = newNode(nkStmtList)

View File

@@ -1001,6 +1001,7 @@ type
kind*: LogEntryKind
op*: TTypeAttachedOp
isGeneric*: bool
module*: int # Which module this entry belongs to
key*: string
sym*: PSym

View File

@@ -369,7 +369,10 @@ proc getAttachedOp*(g: ModuleGraph; t: PType; op: TTypeAttachedOp): PSym =
if g.attachedOps[op].contains(t.itemId):
result = resolveAttachedOp(g, g.attachedOps[op][t.itemId])
else:
result = nil
# Fall back to key-based lookup for NIF-loaded hooks
let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback)
result = g.loadedOps[op].getOrDefault(key)
#echo "fallback ", key, " ", op, " ", result
proc setAttachedOp*(g: ModuleGraph; module: int; t: PType; op: TTypeAttachedOp; value: PSym) =
## we also need to record this to the packed module.
@@ -378,7 +381,10 @@ proc setAttachedOp*(g: ModuleGraph; module: int; t: PType; op: TTypeAttachedOp;
# Use key-based deduplication for opsLog because different type objects
# (e.g. canon vs orig) can have different itemIds but same structural key
if key notin g.loadedOps[op]:
g.opsLog.add LogEntry(kind: HookEntry, op: op, key: key, sym: value)
# Hooks should be written to the module where the type is defined,
# not the module that triggered the registration
let ownerModule = if t.sym != nil: t.sym.itemId.module.int else: module
g.opsLog.add LogEntry(kind: HookEntry, op: op, module: ownerModule, key: key, sym: value)
g.loadedOps[op][key] = value
g.attachedOps[op][t.itemId] = LazySym(sym: value)
@@ -429,7 +435,8 @@ proc getToStringProc*(g: ModuleGraph; t: PType): PSym =
proc setToStringProc*(g: ModuleGraph; t: PType; value: PSym) =
g.enumToStringProcs[t.itemId] = LazySym(sym: value)
let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback)
g.opsLog.add LogEntry(kind: EnumToStrEntry, key: key, sym: value)
let ownerModule = if t.sym != nil: t.sym.itemId.module.int else: value.itemId.module.int
g.opsLog.add LogEntry(kind: EnumToStrEntry, module: ownerModule, key: key, sym: value)
iterator methodsForGeneric*(g: ModuleGraph; t: PType): (int, PSym) =
if g.methodsPerGenericType.contains(t.itemId):
@@ -439,7 +446,8 @@ iterator methodsForGeneric*(g: ModuleGraph; t: PType): (int, PSym) =
proc addMethodToGeneric*(g: ModuleGraph; module: int; t: PType; col: int; m: PSym) =
g.methodsPerGenericType.mgetOrPut(t.itemId, @[]).add (col, LazySym(sym: m))
let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback)
g.opsLog.add LogEntry(kind: MethodEntry, key: key, sym: m)
let ownerModule = if t.sym != nil: t.sym.itemId.module.int else: module
g.opsLog.add LogEntry(kind: MethodEntry, module: ownerModule, key: key, sym: m)
proc hasDisabledAsgn*(g: ModuleGraph; t: PType): bool =
let op = getAttachedOp(g, t, attachedAsgn)

View File

@@ -255,7 +255,7 @@ proc processPipelineModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator
if m == module:
replayActions.add n
writeNifModule(graph.config, module.position.int32, topLevelStmts, move(graph.opsLog), replayActions)
writeNifModule(graph.config, module.position.int32, topLevelStmts, graph.opsLog, 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.