encodes/decodes itemId.module

This commit is contained in:
demotomohiro
2025-10-27 15:40:11 +09:00
parent e9127b2567
commit 25ca7ccc79
4 changed files with 72 additions and 27 deletions

View File

@@ -6,3 +6,5 @@ let
typeIdTag* = registerTag("typeId")
typeTag* = registerTag("t")
sonsTag* = registerTag("sons")
modIdTag* = registerTag("modId")

View File

@@ -8,6 +8,7 @@ type
graph: ModuleGraph
symbols: Table[int, PSym]
types: Table[int, PType]
modules: Table[int, FileIndex] # maps module id in NIF to FileIndex of the module
proc nodeKind(n: Cursor): TNodeKind {.inline.} =
assert n.kind == ParLe
@@ -58,6 +59,23 @@ when false:
else:
expectTag(n, id)
proc fromNifModuleId(c: var DecodeContext; n: var Cursor): FileIndex =
if n.kind == ParLe:
expectTag n, modIdTag
incExpect n, IntLit
let id = pool.integers[n.intId]
incExpect n, StringLit
let path = pool.strings[n.litId].AbsoluteFile
result = fileInfoIdx(c.graph.config, path)
assert id notin c.modules
c.modules[id] = result
inc n
skipParRi n
elif n.kind == IntLit:
let id = pool.integers[n.intId]
result = c.modules[id]
inc n
proc fromNifSymbol(c: var DecodeContext; n: var Cursor): PSym
proc fromNifType(c: var DecodeContext; n: var Cursor): PType
proc fromNif(c: var DecodeContext; n: var Cursor): PNode
@@ -68,7 +86,9 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
let id = pool.integers[n.intId]
incExpect n, Ident
let ident = c.graph.cache.getIdent(pool.strings[n.litId])
incExpect n, IntLit
inc n
let itemIdModule = c.fromNifModuleId(n).int32
expect n, IntLit
let itemId = pool.integers[n.intId].int32
incExpect n, ParLe
let kind = parseSymKind(pool.tags[n.tagId])
@@ -79,17 +99,17 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
let flags = if n.kind == Ident: pool.strings[n.litId].parseSymFlags else: {}
inc n
var position = if kind == skModule:
expect n, StringLit
let path = pool.strings[n.litId].AbsoluteFile
fileInfoIdx(c.graph.config, path).int
c.fromNifModuleId(n).int
else:
expect n, IntLit
pool.integers[n.intId]
incExpect n, IntLit
let p = pool.integers[n.intId]
inc n
p
expect n, IntLit
let disamb = pool.integers[n.intId].int32
inc n
result = PSym(itemId: ItemId(module: 0, item: itemId),
result = PSym(itemId: ItemId(module: itemIdModule, item: itemId),
kind: kind,
name: ident,
flags: flags,
@@ -116,7 +136,9 @@ proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
expectTag n, typeIdTag
incExpect n, IntLit
let id = pool.integers[n.intId]
incExpect n, IntLit
inc n
let itemIdModule = c.fromNifModuleId(n).int32
expect n, IntLit
let itemId = pool.integers[n.intId].int32
incExpect n, Ident
let kind = parseTypeKind(pool.strings[n.litId])
@@ -124,7 +146,7 @@ proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
let flags = if n.kind == Ident: pool.strings[n.litId].parseTypeFlags else: {}
inc n
result = PType(itemId: ItemId(module: 0, item: itemId),
result = PType(itemId: ItemId(module: itemIdModule, item: itemId),
kind: kind,
flags: flags)
assert id notin c.types

View File

@@ -8,6 +8,7 @@ type
conf: ConfigRef
decodedSyms: HashSet[PSym]
decodedTypes: HashSet[PType]
decodedFileIndices: HashSet[FileIndex]
dest: TokenBuf
proc initEncodeContext(conf: ConfigRef): EncodeContext =
@@ -30,6 +31,18 @@ proc writeFlags[E](dest: var TokenBuf; flags: set[E]) =
else:
dest.addDotToken
proc toNifModuleId(c: var EncodeContext; moduleId: int) =
# `ItemId.module` in PType and PSym (and `PSym.position` when it is skModule) are module's FileIndex
# but it cannot be directly encoded as the uniqueness of it can broke
# if any import/include statements are changed.
if not c.decodedFileIndices.containsOrIncl(moduleId.FileIndex):
c.dest.buildTree modIdTag:
c.dest.addIntLit moduleId
let path = toFullPath(c.conf, moduleId.FileIndex)
c.dest.addStrLit path
else:
c.dest.addIntLit moduleId
proc toNif(c: var EncodeContext; sym: PSym)
proc toNif(c: var EncodeContext; typ: PType)
proc toNif(c: var EncodeContext; n: PNode)
@@ -38,17 +51,14 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
c.dest.buildTree symIdTag:
c.dest.addIntLit sym.id
c.dest.addIdent sym.name.s
c.toNifModuleId sym.itemId.module
c.dest.addIntLit sym.itemId.item
c.dest.buildTree sym.kind.toNifTag:
# TODO: add kind specific data
discard
c.dest.writeFlags sym.flags
if sym.kind == skModule:
# position is module's FileIndex but it cannot be directly encoded
# as the uniqueness of it can broke
# if any import/include statements are changed.
let path = toFullPath(c.conf, sym.position.FileIndex)
c.dest.addStrLit path
c.toNifModuleId sym.position
else:
c.dest.addIntLit sym.position
c.dest.addIntLit sym.disamb
@@ -60,6 +70,7 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
proc toNifDef(c: var EncodeContext; typ: PType) =
c.dest.buildTree typeIdTag:
c.dest.addIntLit typ.id
c.toNifModuleId typ.itemId.module
c.dest.addIntLit typ.itemId.item
c.dest.addIdent toNifTag(typ.kind)
c.dest.writeFlags typ.flags
@@ -75,8 +86,6 @@ proc toNifDef(c: var EncodeContext; typ: PType) =
c.toNif typ.owner
c.toNif typ.sym
#include nifencodertypes
proc toNif(c: var EncodeContext; sym: PSym) =
if sym == nil:
c.dest.addDotToken()

View File

@@ -81,21 +81,33 @@ proc eql(x, y: TLoc): bool =
else:
result = true
proc eqlFileIndex(x, y: int; c: EqlContext): bool =
let xpath = c.confX.toFullPath(x.FileIndex)
let ypath = c.confY.toFullPath(y.FileIndex)
if xpath != ypath:
echo "file index mismatch: ", xpath, "/", ypath
result = false
else:
result = true
proc eqlSymPos(x, y: PSym; c: EqlContext): bool =
if x.kind == skModule:
let xpath = c.confX.toFullPath(x.position.FileIndex)
let ypath = c.confY.toFullPath(y.position.FileIndex)
if xpath != ypath:
echo "symbol position mismatch: ", xpath, "/", ypath
result = false
else:
result = true
result = eqlFileIndex(x.position, y.position, c)
elif x.position != y.position:
echo "symbol position mismatch: ", x.position, "/", y.position
result = false
else:
result = true
proc eqlItemId(x, y: ItemId; c: EqlContext): bool =
if x.item != y.item:
echo "itemId.item mismatch: ", x.item, "/", y.item
result = false
elif not eqlFileIndex(x.module, y.module, c):
result = false
else:
result = true
proc eql(x, y: PSym; c: var EqlContext): bool =
if x == nil and y == nil:
result = true
@@ -105,8 +117,8 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
elif x.name.s != y.name.s:
echo "symbol name mismatch: ", x.name.s, "/", y.name.s
result = false
elif x.itemId.item != y.itemId.item:
echo "symbol itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
elif not eqlItemId(x.itemId, y.itemId, c):
echo "symbol itemId mismatch"
result = false
elif x.kind != y.kind:
echo "symbol kind mismatch: ", x.kind, "/", y.kind
@@ -146,8 +158,8 @@ proc eql(x, y: PType; c: var EqlContext): bool =
elif x == nil or y == nil:
echo "type is missing"
result = false
elif x.itemId.item != y.itemId.item:
echo "type itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
elif not eqlItemId(x.itemId, y.itemId, c):
echo "type itemId mismatch"
result = false
elif x.kind != y.kind:
echo "type kind mismatch: ", x.kind, "/", y.kind