Skip to content

Commit be50e4f

Browse files
committed
encodes/decodes itemId.module
1 parent 4bd7a93 commit be50e4f

File tree

4 files changed

+72
-27
lines changed

4 files changed

+72
-27
lines changed

compiler/icnif/icniftags.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ let
66
typeIdTag* = registerTag("typeId")
77
typeTag* = registerTag("t")
88
sonsTag* = registerTag("sons")
9+
10+
modIdTag* = registerTag("modId")

compiler/icnif/nifdecoder.nim

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type
88
graph: ModuleGraph
99
symbols: Table[int, PSym]
1010
types: Table[int, PType]
11+
modules: Table[int, FileIndex] # maps module id in NIF to FileIndex of the module
1112

1213
proc nodeKind(n: Cursor): TNodeKind {.inline.} =
1314
assert n.kind == ParLe
@@ -58,6 +59,23 @@ when false:
5859
else:
5960
expectTag(n, id)
6061

62+
proc fromNifModuleId(c: var DecodeContext; n: var Cursor): FileIndex =
63+
if n.kind == ParLe:
64+
expectTag n, modIdTag
65+
incExpect n, IntLit
66+
let id = pool.integers[n.intId]
67+
incExpect n, StringLit
68+
let path = pool.strings[n.litId].AbsoluteFile
69+
result = fileInfoIdx(c.graph.config, path)
70+
assert id notin c.modules
71+
c.modules[id] = result
72+
inc n
73+
skipParRi n
74+
elif n.kind == IntLit:
75+
let id = pool.integers[n.intId]
76+
result = c.modules[id]
77+
inc n
78+
6179
proc fromNifSymbol(c: var DecodeContext; n: var Cursor): PSym
6280
proc fromNifType(c: var DecodeContext; n: var Cursor): PType
6381
proc fromNif(c: var DecodeContext; n: var Cursor): PNode
@@ -68,7 +86,9 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
6886
let id = pool.integers[n.intId]
6987
incExpect n, Ident
7088
let ident = c.graph.cache.getIdent(pool.strings[n.litId])
71-
incExpect n, IntLit
89+
inc n
90+
let itemIdModule = c.fromNifModuleId(n).int32
91+
expect n, IntLit
7292
let itemId = pool.integers[n.intId].int32
7393
incExpect n, ParLe
7494
let kind = parseSymKind(pool.tags[n.tagId])
@@ -79,17 +99,17 @@ proc fromNifSymDef(c: var DecodeContext; n: var Cursor): PSym =
7999
let flags = if n.kind == Ident: pool.strings[n.litId].parseSymFlags else: {}
80100
inc n
81101
var position = if kind == skModule:
82-
expect n, StringLit
83-
let path = pool.strings[n.litId].AbsoluteFile
84-
fileInfoIdx(c.graph.config, path).int
102+
c.fromNifModuleId(n).int
85103
else:
86104
expect n, IntLit
87-
pool.integers[n.intId]
88-
incExpect n, IntLit
105+
let p = pool.integers[n.intId]
106+
inc n
107+
p
108+
expect n, IntLit
89109
let disamb = pool.integers[n.intId].int32
90110
inc n
91111

92-
result = PSym(itemId: ItemId(module: 0, item: itemId),
112+
result = PSym(itemId: ItemId(module: itemIdModule, item: itemId),
93113
kind: kind,
94114
name: ident,
95115
flags: flags,
@@ -116,15 +136,17 @@ proc fromNifTypeDef(c: var DecodeContext; n: var Cursor): PType =
116136
expectTag n, typeIdTag
117137
incExpect n, IntLit
118138
let id = pool.integers[n.intId]
119-
incExpect n, IntLit
139+
inc n
140+
let itemIdModule = c.fromNifModuleId(n).int32
141+
expect n, IntLit
120142
let itemId = pool.integers[n.intId].int32
121143
incExpect n, Ident
122144
let kind = parseTypeKind(pool.strings[n.litId])
123145
incExpect n, {Ident, DotToken}
124146
let flags = if n.kind == Ident: pool.strings[n.litId].parseTypeFlags else: {}
125147
inc n
126148

127-
result = PType(itemId: ItemId(module: 0, item: itemId),
149+
result = PType(itemId: ItemId(module: itemIdModule, item: itemId),
128150
kind: kind,
129151
flags: flags)
130152
assert id notin c.types

compiler/icnif/nifencoder.nim

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type
88
conf: ConfigRef
99
decodedSyms: HashSet[PSym]
1010
decodedTypes: HashSet[PType]
11+
decodedFileIndices: HashSet[FileIndex]
1112
dest: TokenBuf
1213

1314
proc initEncodeContext(conf: ConfigRef): EncodeContext =
@@ -30,6 +31,18 @@ proc writeFlags[E](dest: var TokenBuf; flags: set[E]) =
3031
else:
3132
dest.addDotToken
3233

34+
proc toNifModuleId(c: var EncodeContext; moduleId: int) =
35+
# `ItemId.module` in PType and PSym (and `PSym.position` when it is skModule) are module's FileIndex
36+
# but it cannot be directly encoded as the uniqueness of it can broke
37+
# if any import/include statements are changed.
38+
if not c.decodedFileIndices.containsOrIncl(moduleId.FileIndex):
39+
c.dest.buildTree modIdTag:
40+
c.dest.addIntLit moduleId
41+
let path = toFullPath(c.conf, moduleId.FileIndex)
42+
c.dest.addStrLit path
43+
else:
44+
c.dest.addIntLit moduleId
45+
3346
proc toNif(c: var EncodeContext; sym: PSym)
3447
proc toNif(c: var EncodeContext; typ: PType)
3548
proc toNif(c: var EncodeContext; n: PNode)
@@ -38,17 +51,14 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
3851
c.dest.buildTree symIdTag:
3952
c.dest.addIntLit sym.id
4053
c.dest.addIdent sym.name.s
54+
c.toNifModuleId sym.itemId.module
4155
c.dest.addIntLit sym.itemId.item
4256
c.dest.buildTree sym.kind.toNifTag:
4357
# TODO: add kind specific data
4458
discard
4559
c.dest.writeFlags sym.flags
4660
if sym.kind == skModule:
47-
# position is module's FileIndex but it cannot be directly encoded
48-
# as the uniqueness of it can broke
49-
# if any import/include statements are changed.
50-
let path = toFullPath(c.conf, sym.position.FileIndex)
51-
c.dest.addStrLit path
61+
c.toNifModuleId sym.position
5262
else:
5363
c.dest.addIntLit sym.position
5464
c.dest.addIntLit sym.disamb
@@ -60,6 +70,7 @@ proc toNifDef(c: var EncodeContext; sym: PSym) =
6070
proc toNifDef(c: var EncodeContext; typ: PType) =
6171
c.dest.buildTree typeIdTag:
6272
c.dest.addIntLit typ.id
73+
c.toNifModuleId typ.itemId.module
6374
c.dest.addIntLit typ.itemId.item
6475
c.dest.addIdent toNifTag(typ.kind)
6576
c.dest.writeFlags typ.flags
@@ -75,8 +86,6 @@ proc toNifDef(c: var EncodeContext; typ: PType) =
7586
c.toNif typ.owner
7687
c.toNif typ.sym
7788

78-
#include nifencodertypes
79-
8089
proc toNif(c: var EncodeContext; sym: PSym) =
8190
if sym == nil:
8291
c.dest.addDotToken()

tests/icnif/tencode_node2node.nim

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,33 @@ proc eql(x, y: TLoc): bool =
8181
else:
8282
result = true
8383

84+
proc eqlFileIndex(x, y: int; c: EqlContext): bool =
85+
let xpath = c.confX.toFullPath(x.FileIndex)
86+
let ypath = c.confY.toFullPath(y.FileIndex)
87+
if xpath != ypath:
88+
echo "file index mismatch: ", xpath, "/", ypath
89+
result = false
90+
else:
91+
result = true
92+
8493
proc eqlSymPos(x, y: PSym; c: EqlContext): bool =
8594
if x.kind == skModule:
86-
let xpath = c.confX.toFullPath(x.position.FileIndex)
87-
let ypath = c.confY.toFullPath(y.position.FileIndex)
88-
if xpath != ypath:
89-
echo "symbol position mismatch: ", xpath, "/", ypath
90-
result = false
91-
else:
92-
result = true
95+
result = eqlFileIndex(x.position, y.position, c)
9396
elif x.position != y.position:
9497
echo "symbol position mismatch: ", x.position, "/", y.position
9598
result = false
9699
else:
97100
result = true
98101

102+
proc eqlItemId(x, y: ItemId; c: EqlContext): bool =
103+
if x.item != y.item:
104+
echo "itemId.item mismatch: ", x.item, "/", y.item
105+
result = false
106+
elif not eqlFileIndex(x.module, y.module, c):
107+
result = false
108+
else:
109+
result = true
110+
99111
proc eql(x, y: PSym; c: var EqlContext): bool =
100112
if x == nil and y == nil:
101113
result = true
@@ -105,8 +117,8 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
105117
elif x.name.s != y.name.s:
106118
echo "symbol name mismatch: ", x.name.s, "/", y.name.s
107119
result = false
108-
elif x.itemId.item != y.itemId.item:
109-
echo "symbol itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
120+
elif not eqlItemId(x.itemId, y.itemId, c):
121+
echo "symbol itemId mismatch"
110122
result = false
111123
elif x.kind != y.kind:
112124
echo "symbol kind mismatch: ", x.kind, "/", y.kind
@@ -146,8 +158,8 @@ proc eql(x, y: PType; c: var EqlContext): bool =
146158
elif x == nil or y == nil:
147159
echo "type is missing"
148160
result = false
149-
elif x.itemId.item != y.itemId.item:
150-
echo "type itemId.item mismatch: ", x.itemId.item, "/", y.itemId.item
161+
elif not eqlItemId(x.itemId, y.itemId, c):
162+
echo "type itemId mismatch"
151163
result = false
152164
elif x.kind != y.kind:
153165
echo "type kind mismatch: ", x.kind, "/", y.kind

0 commit comments

Comments
 (0)