ic refactoring (#17778)
* minor IC documentation update * IC: refactoring: removed the 'shared' type and fields, these were a leftover from an earlier design
This commit is contained in:
parent
83fa0fc843
commit
4b0b536419
7 changed files with 146 additions and 159 deletions
|
|
@ -27,7 +27,7 @@ type
|
||||||
proc isExportedToC(c: var AliveContext; g: PackedModuleGraph; symId: int32): bool =
|
proc isExportedToC(c: var AliveContext; g: PackedModuleGraph; symId: int32): bool =
|
||||||
## "Exported to C" procs are special (these are marked with '.exportc') because these
|
## "Exported to C" procs are special (these are marked with '.exportc') because these
|
||||||
## must not be optimized away!
|
## must not be optimized away!
|
||||||
let symPtr = addr g[c.thisModule].fromDisk.sh.syms[symId]
|
let symPtr = unsafeAddr g[c.thisModule].fromDisk.syms[symId]
|
||||||
let flags = symPtr.flags
|
let flags = symPtr.flags
|
||||||
# due to a bug/limitation in the lambda lifting, unused inner procs
|
# due to a bug/limitation in the lambda lifting, unused inner procs
|
||||||
# are not transformed correctly; issue (#411). However, the whole purpose here
|
# are not transformed correctly; issue (#411). However, the whole purpose here
|
||||||
|
|
@ -39,7 +39,7 @@ proc isExportedToC(c: var AliveContext; g: PackedModuleGraph; symId: int32): boo
|
||||||
# XXX: This used to be a condition to:
|
# XXX: This used to be a condition to:
|
||||||
# (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
# (sfExportc in prc.flags and lfExportLib in prc.loc.flags) or
|
||||||
if sfCompilerProc in flags:
|
if sfCompilerProc in flags:
|
||||||
c.compilerProcs[g[c.thisModule].fromDisk.sh.strings[symPtr.name]] = (c.thisModule, symId)
|
c.compilerProcs[g[c.thisModule].fromDisk.strings[symPtr.name]] = (c.thisModule, symId)
|
||||||
|
|
||||||
template isNotGeneric(n: NodePos): bool = ithSon(tree, n, genericParamsPos).kind == nkEmpty
|
template isNotGeneric(n: NodePos): bool = ithSon(tree, n, genericParamsPos).kind == nkEmpty
|
||||||
|
|
||||||
|
|
@ -47,17 +47,17 @@ proc followLater(c: var AliveContext; g: PackedModuleGraph; module: int; item: i
|
||||||
## Marks a symbol 'item' as used and later in 'followNow' the symbol's body will
|
## Marks a symbol 'item' as used and later in 'followNow' the symbol's body will
|
||||||
## be analysed.
|
## be analysed.
|
||||||
if not c.alive[module].containsOrIncl(item):
|
if not c.alive[module].containsOrIncl(item):
|
||||||
var body = g[module].fromDisk.sh.syms[item].ast
|
var body = g[module].fromDisk.syms[item].ast
|
||||||
if body != emptyNodeId:
|
if body != emptyNodeId:
|
||||||
let opt = g[module].fromDisk.sh.syms[item].options
|
let opt = g[module].fromDisk.syms[item].options
|
||||||
if g[module].fromDisk.sh.syms[item].kind in routineKinds:
|
if g[module].fromDisk.syms[item].kind in routineKinds:
|
||||||
body = NodeId ithSon(g[module].fromDisk.bodies, NodePos body, bodyPos)
|
body = NodeId ithSon(g[module].fromDisk.bodies, NodePos body, bodyPos)
|
||||||
c.stack.add((module, opt, NodePos(body)))
|
c.stack.add((module, opt, NodePos(body)))
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
let nid = g[module].fromDisk.sh.syms[item].name
|
let nid = g[module].fromDisk.syms[item].name
|
||||||
if nid != LitId(0):
|
if nid != LitId(0):
|
||||||
let name = g[module].fromDisk.sh.strings[nid]
|
let name = g[module].fromDisk.strings[nid]
|
||||||
if name in ["nimFrame", "callDepthLimitReached"]:
|
if name in ["nimFrame", "callDepthLimitReached"]:
|
||||||
echo "I was called! ", name, " body exists: ", body != emptyNodeId, " ", module, " ", item
|
echo "I was called! ", name, " body exists: ", body != emptyNodeId, " ", module, " ", item
|
||||||
|
|
||||||
|
|
@ -66,12 +66,12 @@ proc requestCompilerProc(c: var AliveContext; g: PackedModuleGraph; name: string
|
||||||
followLater(c, g, module, item)
|
followLater(c, g, module, item)
|
||||||
|
|
||||||
proc loadTypeKind(t: PackedItemId; c: AliveContext; g: PackedModuleGraph; toSkip: set[TTypeKind]): TTypeKind =
|
proc loadTypeKind(t: PackedItemId; c: AliveContext; g: PackedModuleGraph; toSkip: set[TTypeKind]): TTypeKind =
|
||||||
template kind(t: ItemId): TTypeKind = g[t.module].fromDisk.sh.types[t.item].kind
|
template kind(t: ItemId): TTypeKind = g[t.module].fromDisk.types[t.item].kind
|
||||||
|
|
||||||
var t2 = translateId(t, g, c.thisModule, c.decoder.config)
|
var t2 = translateId(t, g, c.thisModule, c.decoder.config)
|
||||||
result = t2.kind
|
result = t2.kind
|
||||||
while result in toSkip:
|
while result in toSkip:
|
||||||
t2 = translateId(g[t2.module].fromDisk.sh.types[t2.item].types[^1], g, t2.module, c.decoder.config)
|
t2 = translateId(g[t2.module].fromDisk.types[t2.item].types[^1], g, t2.module, c.decoder.config)
|
||||||
result = t2.kind
|
result = t2.kind
|
||||||
|
|
||||||
proc rangeCheckAnalysis(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: NodePos) =
|
proc rangeCheckAnalysis(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: NodePos) =
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,8 @@ The frontend produces a set of `.rod` files. Every `.nim` module
|
||||||
produces its own `.rod` file.
|
produces its own `.rod` file.
|
||||||
|
|
||||||
- The IR must be a faithful representation of the AST in memory.
|
- The IR must be a faithful representation of the AST in memory.
|
||||||
- The backend can do its own caching but doesn't have to.
|
- The backend can do its own caching but doesn't have to. In the
|
||||||
- We know by comparing 'nim check compiler/nim' against 'nim c compiler/nim'
|
current implementation the backend also caches its results.
|
||||||
that 2/3 of the compiler's runtime is spent in the frontend. Hence we
|
|
||||||
implement IC for the frontend first and only later for the backend. The
|
|
||||||
backend will recompile everything until we implement its own caching
|
|
||||||
mechanisms.
|
|
||||||
|
|
||||||
Advantage of the "set of files" vs the previous global database:
|
Advantage of the "set of files" vs the previous global database:
|
||||||
- By construction, we either read from the `.rod` file or from the
|
- By construction, we either read from the `.rod` file or from the
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,12 @@ type
|
||||||
emittedTypeInfo*: seq[string]
|
emittedTypeInfo*: seq[string]
|
||||||
backendFlags*: set[ModuleBackendFlag]
|
backendFlags*: set[ModuleBackendFlag]
|
||||||
|
|
||||||
sh*: Shared
|
syms*: seq[PackedSym]
|
||||||
|
types*: seq[PackedType]
|
||||||
|
strings*: BiTable[string] # we could share these between modules.
|
||||||
|
numbers*: BiTable[BiggestInt] # we also store floats in here so
|
||||||
|
# that we can assure that every bit is kept
|
||||||
|
|
||||||
cfg: PackedConfig
|
cfg: PackedConfig
|
||||||
|
|
||||||
PackedEncoder* = object
|
PackedEncoder* = object
|
||||||
|
|
@ -66,6 +71,50 @@ type
|
||||||
symMarker*: IntSet #Table[ItemId, SymId] # ItemId.item -> SymId
|
symMarker*: IntSet #Table[ItemId, SymId] # ItemId.item -> SymId
|
||||||
config*: ConfigRef
|
config*: ConfigRef
|
||||||
|
|
||||||
|
proc toString*(tree: PackedTree; n: NodePos; m: PackedModule; nesting: int;
|
||||||
|
result: var string) =
|
||||||
|
let pos = n.int
|
||||||
|
if result.len > 0 and result[^1] notin {' ', '\n'}:
|
||||||
|
result.add ' '
|
||||||
|
|
||||||
|
result.add $tree[pos].kind
|
||||||
|
case tree.nodes[pos].kind
|
||||||
|
of nkNone, nkEmpty, nkNilLit, nkType: discard
|
||||||
|
of nkIdent, nkStrLit..nkTripleStrLit:
|
||||||
|
result.add " "
|
||||||
|
result.add m.strings[LitId tree.nodes[pos].operand]
|
||||||
|
of nkSym:
|
||||||
|
result.add " "
|
||||||
|
result.add m.strings[m.syms[tree.nodes[pos].operand].name]
|
||||||
|
of directIntLit:
|
||||||
|
result.add " "
|
||||||
|
result.addInt tree.nodes[pos].operand
|
||||||
|
of externSIntLit:
|
||||||
|
result.add " "
|
||||||
|
result.addInt m.numbers[LitId tree.nodes[pos].operand]
|
||||||
|
of externUIntLit:
|
||||||
|
result.add " "
|
||||||
|
result.add $cast[uint64](m.numbers[LitId tree.nodes[pos].operand])
|
||||||
|
of nkFloatLit..nkFloat128Lit:
|
||||||
|
result.add " "
|
||||||
|
result.add $cast[BiggestFloat](m.numbers[LitId tree.nodes[pos].operand])
|
||||||
|
else:
|
||||||
|
result.add "(\n"
|
||||||
|
for i in 1..(nesting+1)*2: result.add ' '
|
||||||
|
for child in sonsReadonly(tree, n):
|
||||||
|
toString(tree, child, m, nesting + 1, result)
|
||||||
|
result.add "\n"
|
||||||
|
for i in 1..nesting*2: result.add ' '
|
||||||
|
result.add ")"
|
||||||
|
#for i in 1..nesting*2: result.add ' '
|
||||||
|
|
||||||
|
proc toString*(tree: PackedTree; n: NodePos; m: PackedModule): string =
|
||||||
|
result = ""
|
||||||
|
toString(tree, n, m, 0, result)
|
||||||
|
|
||||||
|
proc debug*(tree: PackedTree; m: PackedModule) =
|
||||||
|
stdout.write toString(tree, NodePos 0, m)
|
||||||
|
|
||||||
proc isActive*(e: PackedEncoder): bool = e.config != nil
|
proc isActive*(e: PackedEncoder): bool = e.config != nil
|
||||||
proc disable(e: var PackedEncoder) = e.config = nil
|
proc disable(e: var PackedEncoder) = e.config = nil
|
||||||
|
|
||||||
|
|
@ -134,14 +183,14 @@ proc toLitId(x: FileIndex; c: var PackedEncoder; m: var PackedModule): LitId =
|
||||||
result = c.filenames.getOrDefault(x)
|
result = c.filenames.getOrDefault(x)
|
||||||
if result == LitId(0):
|
if result == LitId(0):
|
||||||
let p = msgs.toFullPath(c.config, x)
|
let p = msgs.toFullPath(c.config, x)
|
||||||
result = getOrIncl(m.sh.strings, p)
|
result = getOrIncl(m.strings, p)
|
||||||
c.filenames[x] = result
|
c.filenames[x] = result
|
||||||
c.lastFile = x
|
c.lastFile = x
|
||||||
c.lastLit = result
|
c.lastLit = result
|
||||||
assert result != LitId(0)
|
assert result != LitId(0)
|
||||||
|
|
||||||
proc toFileIndex*(x: LitId; m: PackedModule; config: ConfigRef): FileIndex =
|
proc toFileIndex*(x: LitId; m: PackedModule; config: ConfigRef): FileIndex =
|
||||||
result = msgs.fileInfoIdx(config, AbsoluteFile m.sh.strings[x])
|
result = msgs.fileInfoIdx(config, AbsoluteFile m.strings[x])
|
||||||
|
|
||||||
proc includesIdentical(m: var PackedModule; config: ConfigRef): bool =
|
proc includesIdentical(m: var PackedModule; config: ConfigRef): bool =
|
||||||
for it in mitems(m.includes):
|
for it in mitems(m.includes):
|
||||||
|
|
@ -151,7 +200,6 @@ proc includesIdentical(m: var PackedModule; config: ConfigRef): bool =
|
||||||
|
|
||||||
proc initEncoder*(c: var PackedEncoder; m: var PackedModule; moduleSym: PSym; config: ConfigRef; pc: PackedConfig) =
|
proc initEncoder*(c: var PackedEncoder; m: var PackedModule; moduleSym: PSym; config: ConfigRef; pc: PackedConfig) =
|
||||||
## setup a context for serializing to packed ast
|
## setup a context for serializing to packed ast
|
||||||
m.sh = Shared()
|
|
||||||
c.thisModule = moduleSym.itemId.module
|
c.thisModule = moduleSym.itemId.module
|
||||||
c.config = config
|
c.config = config
|
||||||
m.moduleFlags = moduleSym.flags
|
m.moduleFlags = moduleSym.flags
|
||||||
|
|
@ -179,11 +227,11 @@ proc addImportFileDep*(c: var PackedEncoder; m: var PackedModule; f: FileIndex)
|
||||||
m.imports.add toLitId(f, c, m)
|
m.imports.add toLitId(f, c, m)
|
||||||
|
|
||||||
proc addHidden*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
proc addHidden*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
let nameId = getOrIncl(m.sh.strings, s.name.s)
|
let nameId = getOrIncl(m.strings, s.name.s)
|
||||||
m.hidden.add((nameId, s.itemId.item))
|
m.hidden.add((nameId, s.itemId.item))
|
||||||
|
|
||||||
proc addExported*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
proc addExported*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
let nameId = getOrIncl(m.sh.strings, s.name.s)
|
let nameId = getOrIncl(m.strings, s.name.s)
|
||||||
m.exports.add((nameId, s.itemId.item))
|
m.exports.add((nameId, s.itemId.item))
|
||||||
|
|
||||||
proc addConverter*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
proc addConverter*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
|
|
@ -201,12 +249,12 @@ proc addMethod*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
m.methods.add s.itemId.item
|
m.methods.add s.itemId.item
|
||||||
|
|
||||||
proc addReexport*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
proc addReexport*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
let nameId = getOrIncl(m.sh.strings, s.name.s)
|
let nameId = getOrIncl(m.strings, s.name.s)
|
||||||
m.reexports.add((nameId, PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m),
|
m.reexports.add((nameId, PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m),
|
||||||
item: s.itemId.item)))
|
item: s.itemId.item)))
|
||||||
|
|
||||||
proc addCompilerProc*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
proc addCompilerProc*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
let nameId = getOrIncl(m.sh.strings, s.name.s)
|
let nameId = getOrIncl(m.strings, s.name.s)
|
||||||
m.compilerProcs.add((nameId, s.itemId.item))
|
m.compilerProcs.add((nameId, s.itemId.item))
|
||||||
|
|
||||||
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule)
|
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule)
|
||||||
|
|
@ -225,11 +273,11 @@ proc flush(c: var PackedEncoder; m: var PackedModule) =
|
||||||
|
|
||||||
proc toLitId(x: string; m: var PackedModule): LitId =
|
proc toLitId(x: string; m: var PackedModule): LitId =
|
||||||
## store a string as a literal
|
## store a string as a literal
|
||||||
result = getOrIncl(m.sh.strings, x)
|
result = getOrIncl(m.strings, x)
|
||||||
|
|
||||||
proc toLitId(x: BiggestInt; m: var PackedModule): LitId =
|
proc toLitId(x: BiggestInt; m: var PackedModule): LitId =
|
||||||
## store an integer as a literal
|
## store an integer as a literal
|
||||||
result = getOrIncl(m.sh.numbers, x)
|
result = getOrIncl(m.numbers, x)
|
||||||
|
|
||||||
proc toPackedInfo(x: TLineInfo; c: var PackedEncoder; m: var PackedModule): PackedLineInfo =
|
proc toPackedInfo(x: TLineInfo; c: var PackedEncoder; m: var PackedModule): PackedLineInfo =
|
||||||
PackedLineInfo(line: x.line, col: x.col, file: toLitId(x.fileIndex, c, m))
|
PackedLineInfo(line: x.line, col: x.col, file: toLitId(x.fileIndex, c, m))
|
||||||
|
|
@ -299,8 +347,8 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
|
||||||
result = PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
|
result = PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
|
||||||
|
|
||||||
if t.uniqueId.module == c.thisModule and not c.typeMarker.containsOrIncl(t.uniqueId.item):
|
if t.uniqueId.module == c.thisModule and not c.typeMarker.containsOrIncl(t.uniqueId.item):
|
||||||
if t.uniqueId.item >= m.sh.types.len:
|
if t.uniqueId.item >= m.types.len:
|
||||||
setLen m.sh.types, t.uniqueId.item+1
|
setLen m.types, t.uniqueId.item+1
|
||||||
|
|
||||||
var p = PackedType(kind: t.kind, flags: t.flags, callConv: t.callConv,
|
var p = PackedType(kind: t.kind, flags: t.flags, callConv: t.callConv,
|
||||||
size: t.size, align: t.align, nonUniqueId: t.itemId.item,
|
size: t.size, align: t.align, nonUniqueId: t.itemId.item,
|
||||||
|
|
@ -315,7 +363,7 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
|
||||||
p.owner = t.owner.safeItemId(c, m)
|
p.owner = t.owner.safeItemId(c, m)
|
||||||
|
|
||||||
# fill the reserved slot, nothing else:
|
# fill the reserved slot, nothing else:
|
||||||
m.sh.types[t.uniqueId.item] = p
|
m.types[t.uniqueId.item] = p
|
||||||
|
|
||||||
proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
|
proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
|
||||||
## the plib hangs off the psym via the .annex field
|
## the plib hangs off the psym via the .annex field
|
||||||
|
|
@ -334,8 +382,8 @@ proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
||||||
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
||||||
|
|
||||||
if s.itemId.module == c.thisModule and not c.symMarker.containsOrIncl(s.itemId.item):
|
if s.itemId.module == c.thisModule and not c.symMarker.containsOrIncl(s.itemId.item):
|
||||||
if s.itemId.item >= m.sh.syms.len:
|
if s.itemId.item >= m.syms.len:
|
||||||
setLen m.sh.syms, s.itemId.item+1
|
setLen m.syms, s.itemId.item+1
|
||||||
|
|
||||||
assert sfForward notin s.flags
|
assert sfForward notin s.flags
|
||||||
|
|
||||||
|
|
@ -363,7 +411,7 @@ proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
||||||
p.cname = toLitId(s.cname, m)
|
p.cname = toLitId(s.cname, m)
|
||||||
|
|
||||||
# fill the reserved slot, nothing else:
|
# fill the reserved slot, nothing else:
|
||||||
m.sh.syms[s.itemId.item] = p
|
m.syms[s.itemId.item] = p
|
||||||
|
|
||||||
proc addModuleRef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
proc addModuleRef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
||||||
## add a remote symbol reference to the tree
|
## add a remote symbol reference to the tree
|
||||||
|
|
@ -387,7 +435,7 @@ proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var Pa
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.strings, n.ident.s),
|
operand: int32 getOrIncl(m.strings, n.ident.s),
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if n.sym.itemId.module == c.thisModule:
|
if n.sym.itemId.module == c.thisModule:
|
||||||
|
|
@ -405,15 +453,15 @@ proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var Pa
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of externIntLit:
|
of externIntLit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.numbers, n.intVal),
|
operand: int32 getOrIncl(m.numbers, n.intVal),
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.strings, n.strVal),
|
operand: int32 getOrIncl(m.strings, n.strVal),
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkFloatLit..nkFloat128Lit:
|
of nkFloatLit..nkFloat128Lit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.numbers, cast[BiggestInt](n.floatVal)),
|
operand: int32 getOrIncl(m.numbers, cast[BiggestInt](n.floatVal)),
|
||||||
typeId: storeTypeLater(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
else:
|
else:
|
||||||
let patchPos = ir.prepare(n.kind, n.flags,
|
let patchPos = ir.prepare(n.kind, n.flags,
|
||||||
|
|
@ -499,7 +547,6 @@ proc loadError(err: RodFileError; filename: AbsoluteFile; config: ConfigRef;) =
|
||||||
|
|
||||||
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
|
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
|
||||||
ignoreConfig = false): RodFileError =
|
ignoreConfig = false): RodFileError =
|
||||||
m.sh = Shared()
|
|
||||||
var f = rodfiles.open(filename.string)
|
var f = rodfiles.open(filename.string)
|
||||||
f.loadHeader()
|
f.loadHeader()
|
||||||
f.loadSection configSection
|
f.loadSection configSection
|
||||||
|
|
@ -519,7 +566,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
|
||||||
f.loadSection section
|
f.loadSection section
|
||||||
f.load data
|
f.load data
|
||||||
|
|
||||||
loadTabSection stringsSection, m.sh.strings
|
loadTabSection stringsSection, m.strings
|
||||||
|
|
||||||
loadSeqSection checkSumsSection, m.includes
|
loadSeqSection checkSumsSection, m.includes
|
||||||
if not includesIdentical(m, config):
|
if not includesIdentical(m, config):
|
||||||
|
|
@ -527,7 +574,7 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
|
||||||
|
|
||||||
loadSeqSection depsSection, m.imports
|
loadSeqSection depsSection, m.imports
|
||||||
|
|
||||||
loadTabSection numbersSection, m.sh.numbers
|
loadTabSection numbersSection, m.numbers
|
||||||
|
|
||||||
loadSeqSection exportsSection, m.exports
|
loadSeqSection exportsSection, m.exports
|
||||||
loadSeqSection hiddenSection, m.hidden
|
loadSeqSection hiddenSection, m.hidden
|
||||||
|
|
@ -545,8 +592,8 @@ proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef
|
||||||
loadSeqSection toReplaySection, m.toReplay.nodes
|
loadSeqSection toReplaySection, m.toReplay.nodes
|
||||||
loadSeqSection topLevelSection, m.topLevel.nodes
|
loadSeqSection topLevelSection, m.topLevel.nodes
|
||||||
loadSeqSection bodiesSection, m.bodies.nodes
|
loadSeqSection bodiesSection, m.bodies.nodes
|
||||||
loadSeqSection symsSection, m.sh.syms
|
loadSeqSection symsSection, m.syms
|
||||||
loadSeqSection typesSection, m.sh.types
|
loadSeqSection typesSection, m.types
|
||||||
|
|
||||||
loadSeqSection typeInstCacheSection, m.typeInstCache
|
loadSeqSection typeInstCacheSection, m.typeInstCache
|
||||||
loadSeqSection procInstCacheSection, m.procInstCache
|
loadSeqSection procInstCacheSection, m.procInstCache
|
||||||
|
|
@ -586,13 +633,13 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
|
||||||
f.storeSection section
|
f.storeSection section
|
||||||
f.store data
|
f.store data
|
||||||
|
|
||||||
storeTabSection stringsSection, m.sh.strings
|
storeTabSection stringsSection, m.strings
|
||||||
|
|
||||||
storeSeqSection checkSumsSection, m.includes
|
storeSeqSection checkSumsSection, m.includes
|
||||||
|
|
||||||
storeSeqSection depsSection, m.imports
|
storeSeqSection depsSection, m.imports
|
||||||
|
|
||||||
storeTabSection numbersSection, m.sh.numbers
|
storeTabSection numbersSection, m.numbers
|
||||||
|
|
||||||
storeSeqSection exportsSection, m.exports
|
storeSeqSection exportsSection, m.exports
|
||||||
storeSeqSection hiddenSection, m.hidden
|
storeSeqSection hiddenSection, m.hidden
|
||||||
|
|
@ -610,9 +657,9 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
|
||||||
storeSeqSection topLevelSection, m.topLevel.nodes
|
storeSeqSection topLevelSection, m.topLevel.nodes
|
||||||
|
|
||||||
storeSeqSection bodiesSection, m.bodies.nodes
|
storeSeqSection bodiesSection, m.bodies.nodes
|
||||||
storeSeqSection symsSection, m.sh.syms
|
storeSeqSection symsSection, m.syms
|
||||||
|
|
||||||
storeSeqSection typesSection, m.sh.types
|
storeSeqSection typesSection, m.types
|
||||||
|
|
||||||
storeSeqSection typeInstCacheSection, m.typeInstCache
|
storeSeqSection typeInstCacheSection, m.typeInstCache
|
||||||
storeSeqSection procInstCacheSection, m.procInstCache
|
storeSeqSection procInstCacheSection, m.procInstCache
|
||||||
|
|
@ -700,17 +747,17 @@ proc loadNodes*(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
||||||
of nkEmpty, nkNilLit, nkType:
|
of nkEmpty, nkNilLit, nkType:
|
||||||
discard
|
discard
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
result.ident = getIdent(c.cache, g[thisModule].fromDisk.sh.strings[n.litId])
|
result.ident = getIdent(c.cache, g[thisModule].fromDisk.strings[n.litId])
|
||||||
of nkSym:
|
of nkSym:
|
||||||
result.sym = loadSym(c, g, thisModule, PackedItemId(module: LitId(0), item: tree.nodes[n.int].operand))
|
result.sym = loadSym(c, g, thisModule, PackedItemId(module: LitId(0), item: tree.nodes[n.int].operand))
|
||||||
of directIntLit:
|
of directIntLit:
|
||||||
result.intVal = tree.nodes[n.int].operand
|
result.intVal = tree.nodes[n.int].operand
|
||||||
of externIntLit:
|
of externIntLit:
|
||||||
result.intVal = g[thisModule].fromDisk.sh.numbers[n.litId]
|
result.intVal = g[thisModule].fromDisk.numbers[n.litId]
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
result.strVal = g[thisModule].fromDisk.sh.strings[n.litId]
|
result.strVal = g[thisModule].fromDisk.strings[n.litId]
|
||||||
of nkFloatLit..nkFloat128Lit:
|
of nkFloatLit..nkFloat128Lit:
|
||||||
result.floatVal = cast[BiggestFloat](g[thisModule].fromDisk.sh.numbers[n.litId])
|
result.floatVal = cast[BiggestFloat](g[thisModule].fromDisk.numbers[n.litId])
|
||||||
of nkModuleRef:
|
of nkModuleRef:
|
||||||
let (n1, n2) = sons2(tree, n)
|
let (n1, n2) = sons2(tree, n)
|
||||||
assert n1.kind == nkInt32Lit
|
assert n1.kind == nkInt32Lit
|
||||||
|
|
@ -767,7 +814,7 @@ proc symHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
options: s.options,
|
options: s.options,
|
||||||
position: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
|
position: if s.kind in {skForVar, skVar, skLet, skTemp}: 0 else: s.position,
|
||||||
offset: if s.kind in routineKinds: defaultOffset else: s.offset,
|
offset: if s.kind in routineKinds: defaultOffset else: s.offset,
|
||||||
name: getIdent(c.cache, g[si].fromDisk.sh.strings[s.name])
|
name: getIdent(c.cache, g[si].fromDisk.strings[s.name])
|
||||||
)
|
)
|
||||||
|
|
||||||
template loadAstBody(p, field) =
|
template loadAstBody(p, field) =
|
||||||
|
|
@ -785,7 +832,7 @@ proc loadLib(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
result = nil
|
result = nil
|
||||||
else:
|
else:
|
||||||
result = PLib(generated: l.generated, isOverriden: l.isOverriden,
|
result = PLib(generated: l.generated, isOverriden: l.isOverriden,
|
||||||
kind: l.kind, name: rope g[si].fromDisk.sh.strings[l.name])
|
kind: l.kind, name: rope g[si].fromDisk.strings[l.name])
|
||||||
loadAstBody(l, path)
|
loadAstBody(l, path)
|
||||||
|
|
||||||
proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
|
|
@ -798,14 +845,14 @@ proc symBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
loadAstBody(s, ast)
|
loadAstBody(s, ast)
|
||||||
result.annex = loadLib(c, g, si, item, s.annex)
|
result.annex = loadLib(c, g, si, item, s.annex)
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
result.cname = g[si].fromDisk.sh.strings[s.cname]
|
result.cname = g[si].fromDisk.strings[s.cname]
|
||||||
|
|
||||||
if s.kind in {skLet, skVar, skField, skForVar}:
|
if s.kind in {skLet, skVar, skField, skForVar}:
|
||||||
result.guard = loadSym(c, g, si, s.guard)
|
result.guard = loadSym(c, g, si, s.guard)
|
||||||
result.bitsize = s.bitsize
|
result.bitsize = s.bitsize
|
||||||
result.alignment = s.alignment
|
result.alignment = s.alignment
|
||||||
result.owner = loadSym(c, g, si, s.owner)
|
result.owner = loadSym(c, g, si, s.owner)
|
||||||
let externalName = g[si].fromDisk.sh.strings[s.externalName]
|
let externalName = g[si].fromDisk.strings[s.externalName]
|
||||||
if externalName != "":
|
if externalName != "":
|
||||||
result.loc.r = rope externalName
|
result.loc.r = rope externalName
|
||||||
result.loc.flags = s.locFlags
|
result.loc.flags = s.locFlags
|
||||||
|
|
@ -818,14 +865,14 @@ proc loadSym(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; s:
|
||||||
assert g[si].status in {loaded, storing, stored}
|
assert g[si].status in {loaded, storing, stored}
|
||||||
if not g[si].symsInit:
|
if not g[si].symsInit:
|
||||||
g[si].symsInit = true
|
g[si].symsInit = true
|
||||||
setLen g[si].syms, g[si].fromDisk.sh.syms.len
|
setLen g[si].syms, g[si].fromDisk.syms.len
|
||||||
|
|
||||||
if g[si].syms[s.item] == nil:
|
if g[si].syms[s.item] == nil:
|
||||||
if g[si].fromDisk.sh.syms[s.item].kind != skModule:
|
if g[si].fromDisk.syms[s.item].kind != skModule:
|
||||||
result = symHeaderFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item)
|
result = symHeaderFromPacked(c, g, g[si].fromDisk.syms[s.item], si, s.item)
|
||||||
# store it here early on, so that recursions work properly:
|
# store it here early on, so that recursions work properly:
|
||||||
g[si].syms[s.item] = result
|
g[si].syms[s.item] = result
|
||||||
symBodyFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item, result)
|
symBodyFromPacked(c, g, g[si].fromDisk.syms[s.item], si, s.item, result)
|
||||||
else:
|
else:
|
||||||
result = g[si].module
|
result = g[si].module
|
||||||
assert result != nil
|
assert result != nil
|
||||||
|
|
@ -866,13 +913,13 @@ proc loadType(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; t
|
||||||
|
|
||||||
if not g[si].typesInit:
|
if not g[si].typesInit:
|
||||||
g[si].typesInit = true
|
g[si].typesInit = true
|
||||||
setLen g[si].types, g[si].fromDisk.sh.types.len
|
setLen g[si].types, g[si].fromDisk.types.len
|
||||||
|
|
||||||
if g[si].types[t.item] == nil:
|
if g[si].types[t.item] == nil:
|
||||||
result = typeHeaderFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item)
|
result = typeHeaderFromPacked(c, g, g[si].fromDisk.types[t.item], si, t.item)
|
||||||
# store it here early on, so that recursions work properly:
|
# store it here early on, so that recursions work properly:
|
||||||
g[si].types[t.item] = result
|
g[si].types[t.item] = result
|
||||||
typeBodyFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item, result)
|
typeBodyFromPacked(c, g, g[si].fromDisk.types[t.item], si, t.item, result)
|
||||||
else:
|
else:
|
||||||
result = g[si].types[t.item]
|
result = g[si].types[t.item]
|
||||||
assert result.itemId.item > 0
|
assert result.itemId.item > 0
|
||||||
|
|
@ -897,7 +944,7 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
|
||||||
let e2 =
|
let e2 =
|
||||||
when e[1] is PackedItemId: e[1]
|
when e[1] is PackedItemId: e[1]
|
||||||
else: PackedItemId(module: LitId(0), item: e[1])
|
else: PackedItemId(module: LitId(0), item: e[1])
|
||||||
iface.mgetOrPut(cache.getIdent(m.fromDisk.sh.strings[nameLit]), @[]).add(e2)
|
iface.mgetOrPut(cache.getIdent(m.fromDisk.strings[nameLit]), @[]).add(e2)
|
||||||
|
|
||||||
for e in m.fromDisk.exports:
|
for e in m.fromDisk.exports:
|
||||||
m.iface.impl(e)
|
m.iface.impl(e)
|
||||||
|
|
@ -1000,7 +1047,7 @@ proc loadProcBody*(config: ConfigRef, cache: IdentCache;
|
||||||
lastFile: FileIndex(-1),
|
lastFile: FileIndex(-1),
|
||||||
config: config,
|
config: config,
|
||||||
cache: cache)
|
cache: cache)
|
||||||
let pos = g[mId].fromDisk.sh.syms[s.itemId.item].ast
|
let pos = g[mId].fromDisk.syms[s.itemId.item].ast
|
||||||
assert pos != emptyNodeId
|
assert pos != emptyNodeId
|
||||||
result = loadProcBody(decoder, g, mId, g[mId].fromDisk.bodies, NodePos pos)
|
result = loadProcBody(decoder, g, mId, g[mId].fromDisk.bodies, NodePos pos)
|
||||||
|
|
||||||
|
|
@ -1042,15 +1089,15 @@ proc translateId*(id: PackedItemId; g: PackedModuleGraph; thisModule: int; confi
|
||||||
|
|
||||||
proc checkForHoles(m: PackedModule; config: ConfigRef; moduleId: int) =
|
proc checkForHoles(m: PackedModule; config: ConfigRef; moduleId: int) =
|
||||||
var bugs = 0
|
var bugs = 0
|
||||||
for i in 1 .. high(m.sh.syms):
|
for i in 1 .. high(m.syms):
|
||||||
if m.sh.syms[i].kind == skUnknown:
|
if m.syms[i].kind == skUnknown:
|
||||||
echo "EMPTY ID ", i, " module ", moduleId, " ", toFullPath(config, FileIndex(moduleId))
|
echo "EMPTY ID ", i, " module ", moduleId, " ", toFullPath(config, FileIndex(moduleId))
|
||||||
inc bugs
|
inc bugs
|
||||||
assert bugs == 0
|
assert bugs == 0
|
||||||
when false:
|
when false:
|
||||||
var nones = 0
|
var nones = 0
|
||||||
for i in 1 .. high(m.sh.types):
|
for i in 1 .. high(m.types):
|
||||||
inc nones, m.sh.types[i].kind == tyNone
|
inc nones, m.types[i].kind == tyNone
|
||||||
assert nones < 1
|
assert nones < 1
|
||||||
|
|
||||||
proc simulateLoadedModule*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
proc simulateLoadedModule*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||||
|
|
@ -1133,13 +1180,13 @@ proc interfaceSymbol*(config: ConfigRef, cache: IdentCache;
|
||||||
result = loadSym(decoder, g, int(module), values[0])
|
result = loadSym(decoder, g, int(module), values[0])
|
||||||
|
|
||||||
proc idgenFromLoadedModule*(m: LoadedModule): IdGenerator =
|
proc idgenFromLoadedModule*(m: LoadedModule): IdGenerator =
|
||||||
IdGenerator(module: m.module.itemId.module, symId: int32 m.fromDisk.sh.syms.len,
|
IdGenerator(module: m.module.itemId.module, symId: int32 m.fromDisk.syms.len,
|
||||||
typeId: int32 m.fromDisk.sh.types.len)
|
typeId: int32 m.fromDisk.types.len)
|
||||||
|
|
||||||
proc searchForCompilerproc*(m: LoadedModule; name: string): int32 =
|
proc searchForCompilerproc*(m: LoadedModule; name: string): int32 =
|
||||||
# slow, linear search, but the results are cached:
|
# slow, linear search, but the results are cached:
|
||||||
for it in items(m.fromDisk.compilerProcs):
|
for it in items(m.fromDisk.compilerProcs):
|
||||||
if m.fromDisk.sh.strings[it[0]] == name:
|
if m.fromDisk.strings[it[0]] == name:
|
||||||
return it[1]
|
return it[1]
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
|
@ -1149,31 +1196,31 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
|
||||||
var m: PackedModule
|
var m: PackedModule
|
||||||
let err = loadRodFile(rodfile, m, config, ignoreConfig=true)
|
let err = loadRodFile(rodfile, m, config, ignoreConfig=true)
|
||||||
if err != ok:
|
if err != ok:
|
||||||
config.quitOrRaise "Error: could not load: " & $rodfile.string & " reason: " & $err
|
config.quitOrRaise "Error: could not load: " & $rodfile.string & " reason: " & $err
|
||||||
|
|
||||||
when true:
|
when true:
|
||||||
echo "exports:"
|
echo "exports:"
|
||||||
for ex in m.exports:
|
for ex in m.exports:
|
||||||
echo " ", m.sh.strings[ex[0]], " local ID: ", ex[1]
|
echo " ", m.strings[ex[0]], " local ID: ", ex[1]
|
||||||
assert ex[0] == m.sh.syms[ex[1]].name
|
assert ex[0] == m.syms[ex[1]].name
|
||||||
# ex[1] int32
|
# ex[1] int32
|
||||||
|
|
||||||
echo "reexports:"
|
echo "reexports:"
|
||||||
for ex in m.reexports:
|
for ex in m.reexports:
|
||||||
echo " ", m.sh.strings[ex[0]]
|
echo " ", m.strings[ex[0]]
|
||||||
# reexports*: seq[(LitId, PackedItemId)]
|
# reexports*: seq[(LitId, PackedItemId)]
|
||||||
|
|
||||||
echo "hidden: " & $m.hidden.len
|
echo "hidden: " & $m.hidden.len
|
||||||
for ex in m.hidden:
|
for ex in m.hidden:
|
||||||
echo " ", m.sh.strings[ex[0]], " local ID: ", ex[1]
|
echo " ", m.strings[ex[0]], " local ID: ", ex[1]
|
||||||
|
|
||||||
echo "all symbols"
|
echo "all symbols"
|
||||||
for i in 0..high(m.sh.syms):
|
for i in 0..high(m.syms):
|
||||||
if m.sh.syms[i].name != LitId(0):
|
if m.syms[i].name != LitId(0):
|
||||||
echo " ", m.sh.strings[m.sh.syms[i].name], " local ID: ", i, " kind ", m.sh.syms[i].kind
|
echo " ", m.strings[m.syms[i].name], " local ID: ", i, " kind ", m.syms[i].kind
|
||||||
else:
|
else:
|
||||||
echo " <anon symbol?> local ID: ", i, " kind ", m.sh.syms[i].kind
|
echo " <anon symbol?> local ID: ", i, " kind ", m.syms[i].kind
|
||||||
|
|
||||||
echo "symbols: ", m.sh.syms.len, " types: ", m.sh.types.len,
|
echo "symbols: ", m.syms.len, " types: ", m.types.len,
|
||||||
" top level nodes: ", m.topLevel.nodes.len, " other nodes: ", m.bodies.nodes.len,
|
" top level nodes: ", m.topLevel.nodes.len, " other nodes: ", m.bodies.nodes.len,
|
||||||
" strings: ", m.sh.strings.len, " numbers: ", m.sh.numbers.len
|
" strings: ", m.strings.len, " numbers: ", m.numbers.len
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,12 @@ proc checkType(c: var CheckedContext; typeId: PackedItemId) =
|
||||||
if not c.checkedTypes.containsOrIncl(itemId):
|
if not c.checkedTypes.containsOrIncl(itemId):
|
||||||
let oldThisModule = c.thisModule
|
let oldThisModule = c.thisModule
|
||||||
c.thisModule = itemId.module
|
c.thisModule = itemId.module
|
||||||
checkTypeObj c, c.g.packed[itemId.module].fromDisk.sh.types[itemId.item]
|
checkTypeObj c, c.g.packed[itemId.module].fromDisk.types[itemId.item]
|
||||||
c.thisModule = oldThisModule
|
c.thisModule = oldThisModule
|
||||||
|
|
||||||
proc checkSym(c: var CheckedContext; s: PackedSym) =
|
proc checkSym(c: var CheckedContext; s: PackedSym) =
|
||||||
if s.name != LitId(0):
|
if s.name != LitId(0):
|
||||||
assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId s.name
|
assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId s.name
|
||||||
checkType c, s.typ
|
checkType c, s.typ
|
||||||
if s.ast != emptyNodeId:
|
if s.ast != emptyNodeId:
|
||||||
checkNode(c, c.g.packed[c.thisModule].fromDisk.bodies, NodePos s.ast)
|
checkNode(c, c.g.packed[c.thisModule].fromDisk.bodies, NodePos s.ast)
|
||||||
|
|
@ -57,14 +57,14 @@ proc checkSym(c: var CheckedContext; s: PackedSym) =
|
||||||
proc checkLocalSym(c: var CheckedContext; item: int32) =
|
proc checkLocalSym(c: var CheckedContext; item: int32) =
|
||||||
let itemId = ItemId(module: c.thisModule, item: item)
|
let itemId = ItemId(module: c.thisModule, item: item)
|
||||||
if not c.checkedSyms.containsOrIncl(itemId):
|
if not c.checkedSyms.containsOrIncl(itemId):
|
||||||
checkSym c, c.g.packed[c.thisModule].fromDisk.sh.syms[item]
|
checkSym c, c.g.packed[c.thisModule].fromDisk.syms[item]
|
||||||
|
|
||||||
proc checkForeignSym(c: var CheckedContext; symId: PackedItemId) =
|
proc checkForeignSym(c: var CheckedContext; symId: PackedItemId) =
|
||||||
let itemId = translateId(symId, c.g.packed, c.thisModule, c.g.config)
|
let itemId = translateId(symId, c.g.packed, c.thisModule, c.g.config)
|
||||||
if not c.checkedSyms.containsOrIncl(itemId):
|
if not c.checkedSyms.containsOrIncl(itemId):
|
||||||
let oldThisModule = c.thisModule
|
let oldThisModule = c.thisModule
|
||||||
c.thisModule = itemId.module
|
c.thisModule = itemId.module
|
||||||
checkSym c, c.g.packed[itemId.module].fromDisk.sh.syms[itemId.item]
|
checkSym c, c.g.packed[itemId.module].fromDisk.syms[itemId.item]
|
||||||
c.thisModule = oldThisModule
|
c.thisModule = oldThisModule
|
||||||
|
|
||||||
proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
|
proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
|
||||||
|
|
@ -74,15 +74,15 @@ proc checkNode(c: var CheckedContext; tree: PackedTree; n: NodePos) =
|
||||||
of nkEmpty, nkNilLit, nkType, nkNilRodNode:
|
of nkEmpty, nkNilLit, nkType, nkNilRodNode:
|
||||||
discard
|
discard
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId n.litId
|
assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
|
||||||
of nkSym:
|
of nkSym:
|
||||||
checkLocalSym(c, tree.nodes[n.int].operand)
|
checkLocalSym(c, tree.nodes[n.int].operand)
|
||||||
of directIntLit:
|
of directIntLit:
|
||||||
discard
|
discard
|
||||||
of externIntLit, nkFloatLit..nkFloat128Lit:
|
of externIntLit, nkFloatLit..nkFloat128Lit:
|
||||||
assert c.g.packed[c.thisModule].fromDisk.sh.numbers.hasLitId n.litId
|
assert c.g.packed[c.thisModule].fromDisk.numbers.hasLitId n.litId
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
assert c.g.packed[c.thisModule].fromDisk.sh.strings.hasLitId n.litId
|
assert c.g.packed[c.thisModule].fromDisk.strings.hasLitId n.litId
|
||||||
of nkModuleRef:
|
of nkModuleRef:
|
||||||
let (n1, n2) = sons2(tree, n)
|
let (n1, n2) = sons2(tree, n)
|
||||||
assert n1.kind == nkInt32Lit
|
assert n1.kind == nkInt32Lit
|
||||||
|
|
@ -97,25 +97,25 @@ proc checkTree(c: var CheckedContext; t: PackedTree) =
|
||||||
|
|
||||||
proc checkLocalSymIds(c: var CheckedContext; m: PackedModule; symIds: seq[int32]) =
|
proc checkLocalSymIds(c: var CheckedContext; m: PackedModule; symIds: seq[int32]) =
|
||||||
for symId in symIds:
|
for symId in symIds:
|
||||||
assert symId >= 0 and symId < m.sh.syms.len, $symId & " " & $m.sh.syms.len
|
assert symId >= 0 and symId < m.syms.len, $symId & " " & $m.syms.len
|
||||||
|
|
||||||
proc checkModule(c: var CheckedContext; m: PackedModule) =
|
proc checkModule(c: var CheckedContext; m: PackedModule) =
|
||||||
# We check that:
|
# We check that:
|
||||||
# - Every symbol references existing types and symbols.
|
# - Every symbol references existing types and symbols.
|
||||||
# - Every tree node references existing types and symbols.
|
# - Every tree node references existing types and symbols.
|
||||||
for i in 0..high(m.sh.syms):
|
for i in 0..high(m.syms):
|
||||||
checkLocalSym c, int32(i)
|
checkLocalSym c, int32(i)
|
||||||
|
|
||||||
checkTree c, m.toReplay
|
checkTree c, m.toReplay
|
||||||
checkTree c, m.topLevel
|
checkTree c, m.topLevel
|
||||||
|
|
||||||
for e in m.exports:
|
for e in m.exports:
|
||||||
assert e[1] >= 0 and e[1] < m.sh.syms.len
|
assert e[1] >= 0 and e[1] < m.syms.len
|
||||||
assert e[0] == m.sh.syms[e[1]].name
|
assert e[0] == m.syms[e[1]].name
|
||||||
|
|
||||||
for e in m.compilerProcs:
|
for e in m.compilerProcs:
|
||||||
assert e[1] >= 0 and e[1] < m.sh.syms.len
|
assert e[1] >= 0 and e[1] < m.syms.len
|
||||||
assert e[0] == m.sh.syms[e[1]].name
|
assert e[0] == m.syms[e[1]].name
|
||||||
|
|
||||||
checkLocalSymIds c, m, m.converters
|
checkLocalSymIds c, m, m.converters
|
||||||
checkLocalSymIds c, m, m.methods
|
checkLocalSymIds c, m, m.methods
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,12 @@ proc isTracked(current, trackPos: PackedLineInfo, tokenLen: int): bool =
|
||||||
|
|
||||||
proc searchLocalSym(c: var NavContext; s: PackedSym; info: PackedLineInfo): bool =
|
proc searchLocalSym(c: var NavContext; s: PackedSym; info: PackedLineInfo): bool =
|
||||||
result = s.name != LitId(0) and
|
result = s.name != LitId(0) and
|
||||||
isTracked(info, c.trackPos, c.g.packed[c.thisModule].fromDisk.sh.strings[s.name].len)
|
isTracked(info, c.trackPos, c.g.packed[c.thisModule].fromDisk.strings[s.name].len)
|
||||||
|
|
||||||
proc searchForeignSym(c: var NavContext; s: ItemId; info: PackedLineInfo): bool =
|
proc searchForeignSym(c: var NavContext; s: ItemId; info: PackedLineInfo): bool =
|
||||||
let name = c.g.packed[s.module].fromDisk.sh.syms[s.item].name
|
let name = c.g.packed[s.module].fromDisk.syms[s.item].name
|
||||||
result = name != LitId(0) and
|
result = name != LitId(0) and
|
||||||
isTracked(info, c.trackPos, c.g.packed[s.module].fromDisk.sh.strings[name].len)
|
isTracked(info, c.trackPos, c.g.packed[s.module].fromDisk.strings[name].len)
|
||||||
|
|
||||||
const
|
const
|
||||||
EmptyItemId = ItemId(module: -1'i32, item: -1'i32)
|
EmptyItemId = ItemId(module: -1'i32, item: -1'i32)
|
||||||
|
|
@ -51,7 +51,7 @@ proc search(c: var NavContext; tree: PackedTree): ItemId =
|
||||||
case tree.nodes[i].kind
|
case tree.nodes[i].kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
let item = tree.nodes[i].operand
|
let item = tree.nodes[i].operand
|
||||||
if searchLocalSym(c, c.g.packed[c.thisModule].fromDisk.sh.syms[item], tree.nodes[i].info):
|
if searchLocalSym(c, c.g.packed[c.thisModule].fromDisk.syms[item], tree.nodes[i].info):
|
||||||
return ItemId(module: c.thisModule, item: item)
|
return ItemId(module: c.thisModule, item: item)
|
||||||
of nkModuleRef:
|
of nkModuleRef:
|
||||||
if tree.nodes[i].info.line == c.trackPos.line and tree.nodes[i].info.file == c.trackPos.file:
|
if tree.nodes[i].info.line == c.trackPos.line and tree.nodes[i].info.file == c.trackPos.file:
|
||||||
|
|
@ -74,7 +74,7 @@ proc isDecl(tree: PackedTree; n: NodePos): bool =
|
||||||
|
|
||||||
proc usage(c: var NavContext; info: PackedLineInfo; isDecl: bool) =
|
proc usage(c: var NavContext; info: PackedLineInfo; isDecl: bool) =
|
||||||
var m = ""
|
var m = ""
|
||||||
var file = c.g.packed[c.thisModule].fromDisk.sh.strings[info.file]
|
var file = c.g.packed[c.thisModule].fromDisk.strings[info.file]
|
||||||
if c.outputSep == ' ':
|
if c.outputSep == ' ':
|
||||||
file = os.extractFilename file
|
file = os.extractFilename file
|
||||||
toLocation(m, file, info.line.int, info.col.int + ColOffset)
|
toLocation(m, file, info.line.int, info.col.int + ColOffset)
|
||||||
|
|
@ -102,7 +102,7 @@ proc nav(g: ModuleGraph) =
|
||||||
# translate the track position to a packed position:
|
# translate the track position to a packed position:
|
||||||
let unpacked = g.config.m.trackPos
|
let unpacked = g.config.m.trackPos
|
||||||
let mid = unpacked.fileIndex
|
let mid = unpacked.fileIndex
|
||||||
let fileId = g.packed[int32 mid].fromDisk.sh.strings.getKeyId(toFullPath(g.config, mid))
|
let fileId = g.packed[int32 mid].fromDisk.strings.getKeyId(toFullPath(g.config, mid))
|
||||||
|
|
||||||
if fileId == LitId(0):
|
if fileId == LitId(0):
|
||||||
internalError(g.config, unpacked, "cannot find a valid file ID")
|
internalError(g.config, unpacked, "cannot find a valid file ID")
|
||||||
|
|
|
||||||
|
|
@ -98,17 +98,6 @@ type
|
||||||
|
|
||||||
PackedTree* = object ## usually represents a full Nim module
|
PackedTree* = object ## usually represents a full Nim module
|
||||||
nodes*: seq[PackedNode]
|
nodes*: seq[PackedNode]
|
||||||
#sh*: Shared
|
|
||||||
|
|
||||||
Shared* = ref object # shared between different versions of 'Module'.
|
|
||||||
# (though there is always exactly one valid
|
|
||||||
# version of a module)
|
|
||||||
syms*: seq[PackedSym]
|
|
||||||
types*: seq[PackedType]
|
|
||||||
strings*: BiTable[string] # we could share these between modules.
|
|
||||||
numbers*: BiTable[BiggestInt] # we also store floats in here so
|
|
||||||
# that we can assure that every bit is kept
|
|
||||||
#config*: ConfigRef
|
|
||||||
|
|
||||||
PackedInstantiation* = object
|
PackedInstantiation* = object
|
||||||
key*, sym*: PackedItemId
|
key*, sym*: PackedItemId
|
||||||
|
|
@ -374,51 +363,6 @@ const
|
||||||
externUIntLit* = {nkUIntLit, nkUInt8Lit, nkUInt16Lit, nkUInt32Lit, nkUInt64Lit}
|
externUIntLit* = {nkUIntLit, nkUInt8Lit, nkUInt16Lit, nkUInt32Lit, nkUInt64Lit}
|
||||||
directIntLit* = nkInt32Lit
|
directIntLit* = nkInt32Lit
|
||||||
|
|
||||||
proc toString*(tree: PackedTree; n: NodePos; sh: Shared; nesting: int;
|
|
||||||
result: var string) =
|
|
||||||
let pos = n.int
|
|
||||||
if result.len > 0 and result[^1] notin {' ', '\n'}:
|
|
||||||
result.add ' '
|
|
||||||
|
|
||||||
result.add $tree[pos].kind
|
|
||||||
case tree.nodes[pos].kind
|
|
||||||
of nkNone, nkEmpty, nkNilLit, nkType: discard
|
|
||||||
of nkIdent, nkStrLit..nkTripleStrLit:
|
|
||||||
result.add " "
|
|
||||||
result.add sh.strings[LitId tree.nodes[pos].operand]
|
|
||||||
of nkSym:
|
|
||||||
result.add " "
|
|
||||||
result.add sh.strings[sh.syms[tree.nodes[pos].operand].name]
|
|
||||||
of directIntLit:
|
|
||||||
result.add " "
|
|
||||||
result.addInt tree.nodes[pos].operand
|
|
||||||
of externSIntLit:
|
|
||||||
result.add " "
|
|
||||||
result.addInt sh.numbers[LitId tree.nodes[pos].operand]
|
|
||||||
of externUIntLit:
|
|
||||||
result.add " "
|
|
||||||
result.add $cast[uint64](sh.numbers[LitId tree.nodes[pos].operand])
|
|
||||||
of nkFloatLit..nkFloat128Lit:
|
|
||||||
result.add " "
|
|
||||||
result.add $cast[BiggestFloat](sh.numbers[LitId tree.nodes[pos].operand])
|
|
||||||
else:
|
|
||||||
result.add "(\n"
|
|
||||||
for i in 1..(nesting+1)*2: result.add ' '
|
|
||||||
for child in sonsReadonly(tree, n):
|
|
||||||
toString(tree, child, sh, nesting + 1, result)
|
|
||||||
result.add "\n"
|
|
||||||
for i in 1..nesting*2: result.add ' '
|
|
||||||
result.add ")"
|
|
||||||
#for i in 1..nesting*2: result.add ' '
|
|
||||||
|
|
||||||
|
|
||||||
proc toString*(tree: PackedTree; n: NodePos; sh: Shared): string =
|
|
||||||
result = ""
|
|
||||||
toString(tree, n, sh, 0, result)
|
|
||||||
|
|
||||||
proc debug*(tree: PackedTree; sh: Shared) =
|
|
||||||
stdout.write toString(tree, NodePos 0, sh)
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
proc identIdImpl(tree: PackedTree; n: NodePos): LitId =
|
proc identIdImpl(tree: PackedTree; n: NodePos): LitId =
|
||||||
if n.kind == nkIdent:
|
if n.kind == nkIdent:
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ from typetraits import supportsCopyMem
|
||||||
## (`RodFileError`). The file format broken up into sections (`RodSection`)
|
## (`RodFileError`). The file format broken up into sections (`RodSection`)
|
||||||
## and preceeded by a header (see: `cookie`). The precise layout, section
|
## and preceeded by a header (see: `cookie`). The precise layout, section
|
||||||
## ordering and data following the section are determined by the user. See
|
## ordering and data following the section are determined by the user. See
|
||||||
## `ic.loadRoadFile`.
|
## `ic.loadRodFile`.
|
||||||
##
|
##
|
||||||
## A basic but "wrong" example of the lifecycle:
|
## A basic but "wrong" example of the lifecycle:
|
||||||
## ---------------------------------------------
|
## ---------------------------------------------
|
||||||
## 1. `create` or `open` - create a new one or open an existing
|
## 1. `create` or `open` - create a new one or open an existing
|
||||||
|
|
@ -45,10 +45,10 @@ from typetraits import supportsCopyMem
|
||||||
## The API is centered around IO and prone to error, each operation checks or
|
## The API is centered around IO and prone to error, each operation checks or
|
||||||
## sets the `RodFile.err` field. A user of this API needs to handle these
|
## sets the `RodFile.err` field. A user of this API needs to handle these
|
||||||
## appropriately.
|
## appropriately.
|
||||||
##
|
##
|
||||||
## API Notes
|
## API Notes
|
||||||
## =========
|
## =========
|
||||||
##
|
##
|
||||||
## Valid inputs for Rod files
|
## Valid inputs for Rod files
|
||||||
## --------------------------
|
## --------------------------
|
||||||
## ASTs, hopes, dreams, and anything as long as it and any children it may have
|
## ASTs, hopes, dreams, and anything as long as it and any children it may have
|
||||||
|
|
@ -61,7 +61,7 @@ from typetraits import supportsCopyMem
|
||||||
## ----------------------------
|
## ----------------------------
|
||||||
## A flag based approach is used where operations no-op in case of a
|
## A flag based approach is used where operations no-op in case of a
|
||||||
## preexisting error and set the flag if they encounter one.
|
## preexisting error and set the flag if they encounter one.
|
||||||
##
|
##
|
||||||
## Misc
|
## Misc
|
||||||
## ----
|
## ----
|
||||||
## * 'Prim' is short for 'primitive', as in a non-sequence type
|
## * 'Prim' is short for 'primitive', as in a non-sequence type
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue