From 1f3899ca2959848a2e8d847683a02caeee16f3a8 Mon Sep 17 00:00:00 2001 From: araq Date: Sun, 14 Dec 2025 11:02:29 +0100 Subject: [PATCH] progress --- compiler/ast.nim | 6 ++ compiler/ast2nif.nim | 37 +++++------- compiler/astdef.nim | 2 +- compiler/modulegraphs.nim | 53 +++++++---------- compiler/typekeys.nim | 121 +++++++++++++++++++++----------------- lib/system.nim | 14 ++--- 6 files changed, 120 insertions(+), 113 deletions(-) diff --git a/compiler/ast.nim b/compiler/ast.nim index e8755390d2..ff0e01adc9 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -46,6 +46,12 @@ template loadType(t: PType) = when not defined(nimKochBootstrap): ast2nif.loadType(program, t) +proc loadSymCallback*(s: PSym) {.nimcall.} = + loadSym(s) + +proc loadTypeCallback*(t: PType) {.nimcall.} = + loadType(t) + proc ensureMutable*(s: PSym) {.inline.} = assert s.state != Sealed if s.state == Partial: loadSym(s) diff --git a/compiler/ast2nif.nim b/compiler/ast2nif.nim index a4c939bd8e..eba84db097 100644 --- a/compiler/ast2nif.nim +++ b/compiler/ast2nif.nim @@ -667,7 +667,7 @@ proc buildExportBuf(w: var Writer): TokenBuf = 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 key = pool.syms.getOrIncl(entry.key) let sym = pool.syms.getOrIncl(w.toNifSymName(entry.sym)) case entry.kind of HookEntry: @@ -1393,24 +1393,6 @@ proc toNifIndexFilename*(conf: ConfigRef; f: FileIndex): string = let suffix = moduleSuffix(conf, f) result = toGeneratedFile(conf, AbsoluteFile(suffix), ".s.idx.nif").string -proc parseTypeSymIdToItemId*(c: var DecodeContext; symId: nifstreams.SymId): ItemId = - ## Parses a type SymId (format: `"`tN.modulesuffix"`) to extract ItemId. - let s = pool.syms[symId] - if not s.startsWith("`t"): - return ItemId(module: -1, item: 0) - var i = 2 # skip "`t" - var item = 0'i32 - while i < s.len and s[i] in {'0'..'9'}: - item = item * 10 + int32(ord(s[i]) - ord('0')) - inc i - if i < s.len and s[i] == '.': - inc i - let suffix = s.substr(i) - let module = moduleId(c, suffix) - result = ItemId(module: int32(module), item: item) - else: - result = ItemId(module: -1, item: item) - proc resolveSym(c: var DecodeContext; symAsStr: string; alsoConsiderPrivate: bool): PSym = result = c.syms.getOrDefault(symAsStr)[0] if result != nil: @@ -1463,9 +1445,22 @@ proc loadNifModule*(c: var DecodeContext; f: FileIndex; interf, interfHidden: va populateInterfaceTablesFromIndex(c, module, interf, interfHidden, suffix) # Return hooks from the index - hooks = move c.mods[module].index.hooks + let hooks = move c.mods[module].index.hooks + for typeKey, h in hooks: + for op in AttachedOp: + let (hookSymId, isGeneric) = h.a[op] + let hookSym = resolveHookSym(c, hookSymId) + if hookSym != nil: + logOps.add LogEntry(kind: HookEntry, op: toTTypeAttachedOp(op), + isGeneric: isGeneric, key: pool.syms[typeKey], sym: hookSym) # Return converters from the index - converters = move c.mods[module].index.converters + let converters = move c.mods[module].index.converters + for (destType, convSym) in converters: + let symId = pool.syms.getOrIncl(convSym) + let convPSym = resolveHookSym(c, symId) # reuse hook resolution + if convPSym != nil: + logOps.add LogEntry(kind: ConverterEntry, + isGeneric: false, key: destType, sym: convPSym) # Return classes/methods from the index classes = move c.mods[module].index.classes diff --git a/compiler/astdef.nim b/compiler/astdef.nim index 35c7c7ed1b..27761fd81b 100644 --- a/compiler/astdef.nim +++ b/compiler/astdef.nim @@ -1001,7 +1001,7 @@ type kind*: LogEntryKind op*: TTypeAttachedOp isGeneric*: bool - typ*: PType + key*: string sym*: PSym diff --git a/compiler/modulegraphs.nim b/compiler/modulegraphs.nim index 5c5b35223d..a1118c4f7f 100644 --- a/compiler/modulegraphs.nim +++ b/compiler/modulegraphs.nim @@ -20,6 +20,8 @@ when not defined(nimKochBootstrap): import ast2nif import "../dist/nimony/src/lib" / [nifstreams, bitabs] +import typekeys + when defined(nimPreviewSlimSystem): import std/assertions @@ -79,6 +81,7 @@ type typeInstCache*: Table[ItemId, seq[LazyType]] # A symbol's ItemId. procInstCache*: Table[ItemId, seq[LazyInstantiation]] # A symbol's ItemId. attachedOps*: array[TTypeAttachedOp, Table[ItemId, LazySym]] # Type ID, destructors, etc. + loadedOps: array[TTypeAttachedOp, Table[string, PSym]] # This can later by unified with `attachedOps` once it's stable opsLog*: seq[LogEntry] methodsPerGenericType*: Table[ItemId, seq[(int, LazySym)]] # Type ID, attached methods memberProcsPerType*: Table[ItemId, seq[PSym]] # Type ID, attached member procs (only c++, virtual,member and ctor so far). @@ -368,7 +371,8 @@ 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) + let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback) + g.opsLog.add LogEntry(kind: HookEntry, op: op, key: key, sym: value) g.attachedOps[op][t.itemId] = LazySym(sym: value) proc setAttachedOp*(g: ModuleGraph; module: int; typeId: ItemId; op: TTypeAttachedOp; value: PSym) = @@ -417,7 +421,8 @@ proc getToStringProc*(g: ModuleGraph; t: PType): PSym = proc setToStringProc*(g: ModuleGraph; t: PType; value: PSym) = g.enumToStringProcs[t.itemId] = LazySym(sym: value) - g.opsLog.add LogEntry(kind: EnumToStrEntry, typ: t, sym: value) + let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback) + g.opsLog.add LogEntry(kind: EnumToStrEntry, key: key, sym: value) iterator methodsForGeneric*(g: ModuleGraph; t: PType): (int, PSym) = if g.methodsPerGenericType.contains(t.itemId): @@ -426,7 +431,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)) - g.opsLog.add LogEntry(kind: MethodEntry, typ: t, sym: m) + let key = typeKey(t, g.config, loadTypeCallback, loadSymCallback) + g.opsLog.add LogEntry(kind: MethodEntry, key: key, sym: m) proc hasDisabledAsgn*(g: ModuleGraph; t: PType): bool = let op = getAttachedOp(g, t, attachedAsgn) @@ -809,38 +815,23 @@ when not defined(nimKochBootstrap): # Register module in graph registerModule(g, result) - var hooks = initTable[nifstreams.SymId, HooksPerType]() - var converters: seq[(string, string)] = @[] + var opsLog: seq[LogEntry] = @[] var classes: seq[ClassIndexEntry] = @[] result.astImpl = loadNifModule(ast.program, fileIdx, g.ifaces[fileIdx.int].interf, - g.ifaces[fileIdx.int].interfHidden, hooks, converters, classes, loadFullAst) + g.ifaces[fileIdx.int].interfHidden, opsLog, classes, loadFullAst) # Register hooks from NIF index with the module graph - for typSymId, hooksPerType in hooks: - let typeItemId = parseTypeSymIdToItemId(ast.program, typSymId) - if typeItemId.module >= 0: - for op in AttachedOp: - let (hookSymId, isGeneric) = hooksPerType.a[op] - if hookSymId != nifstreams.SymId(0): - let hookSym = resolveHookSym(ast.program, hookSymId) - if hookSym != nil: - setAttachedOp(g, int(fileIdx), typeItemId, toTTypeAttachedOp(op), hookSym) - # Register converters from NIF index with the module's interface - for (destType, convSym) in converters: - let symId = pool.syms.getOrIncl(convSym) - let convPSym = resolveHookSym(ast.program, symId) # reuse hook resolution - if convPSym != nil: - g.ifaces[fileIdx.int].converters.add LazySym(sym: convPSym) + for x in opsLog: + case x.kind + of HookEntry: + g.loadedOps[x.op][x.key] = x.sym + of ConverterEntry: + g.ifaces[fileIdx.int].converters.add LazySym(sym: x.sym) + of MethodEntry: + discard "todo" + of EnumToStrEntry: + discard "todo" # Register methods per type from NIF index - for classEntry in classes: - let typeItemId = parseTypeSymIdToItemId(ast.program, classEntry.cls) - if typeItemId.module >= 0: - var methodSyms: seq[LazySym] = @[] - for methodEntry in classEntry.methods: - let methodSym = resolveHookSym(ast.program, methodEntry.fn) - if methodSym != nil: - methodSyms.add LazySym(sym: methodSym) - if methodSyms.len > 0: - setMethodsPerType(g, typeItemId, methodSyms) + discard "todo" cachedModules.add fileIdx proc configComplete*(g: ModuleGraph) = diff --git a/compiler/typekeys.nim b/compiler/typekeys.nim index a03f7ffebd..c58a0377ed 100644 --- a/compiler/typekeys.nim +++ b/compiler/typekeys.nim @@ -48,10 +48,20 @@ type CoDistinct CoHashTypeInsideNode -proc typeKey(c: var Mangler, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) -proc symKey(c: var Mangler, s: PSym; conf: ConfigRef) = + TypeLoader* = proc (t: PType) {.nimcall.} + SymLoader* = proc (s: PSym) {.nimcall.} + Context = object + m: Mangler + tl: TypeLoader + sl: SymLoader + +proc typeKey(c: var Context; t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) +proc symKey(c: var Context; s: PSym; conf: ConfigRef) = + if s.state == Partial: + assert c.sl != nil + c.sl(s) if sfAnon in s.flagsImpl or s.kindImpl == skGenericParam: - c.addIdent("´anon") + c.m.addIdent("´anon") else: var name = s.name.s name.add '.' @@ -67,32 +77,32 @@ proc symKey(c: var Mangler, s: PSym; conf: ConfigRef) = if it.kindImpl == skModule: name.add '.' name.add modname(it, conf) - c.addSymbol(name) + c.m.addSymbol(name) -proc treeKey(c: var Mangler, n: PNode; flags: set[ConsiderFlag]; conf: ConfigRef) = +proc treeKey(c: var Context; n: PNode; flags: set[ConsiderFlag]; conf: ConfigRef) = if n == nil: - c.addEmpty() + c.m.addEmpty() return let k = n.kind case k of nkEmpty, nkNilLit, nkType: discard of nkIdent: - c.addIdent(n.ident.s) + c.m.addIdent(n.ident.s) of nkSym: symKey(c, n.sym, conf) if CoHashTypeInsideNode in flags and n.sym.typImpl != nil: typeKey(c, n.sym.typImpl, flags, conf) of nkCharLit..nkUInt64Lit: let v = n.intVal - c.addIntLit v + c.m.addIntLit v of nkFloatLit..nkFloat64Lit: let v = n.floatVal - c.addFloatLit v + c.m.addFloatLit v of nkStrLit..nkTripleStrLit: - c.addStrLit n.strVal + c.m.addStrLit n.strVal else: - withTree c, toNifTag(k): + withTree c.m, toNifTag(k): for i in 0.. 0: c.typeKey(t.sonsImpl[0], flags, conf) - c.addIdent toNifTag(t.callConvImpl) - if tfVarargs in t.flagsImpl: c.addIdent "´varargs" + c.m.addIdent toNifTag(t.callConvImpl) + if tfVarargs in t.flagsImpl: c.m.addIdent "´varargs" of tyArray: - withTree c, toNifTag(t.kind): + withTree c.m, toNifTag(t.kind): c.typeKey(t.sonsImpl[^1], flags-{CoIgnoreRange}, conf) c.typeKey(t.sonsImpl[0], flags-{CoIgnoreRange}, conf) else: - withTree c, toNifTag(t.kind): + withTree c.m, toNifTag(t.kind): for i in 1..