IC: compilerprocs are handled correctly (#17265)
* IC: compilerprocs are handled correctly * IC: special logic for .exportC'ed procs * IC: 'hello world' compiles for the first round (2nd round fails) * IC: hello world seems to work
This commit is contained in:
parent
761ec2ccc8
commit
6cb26d8010
8 changed files with 120 additions and 39 deletions
|
|
@ -11,7 +11,7 @@ import std / [hashes, tables, intsets, sha1]
|
|||
import packed_ast, bitabs, rodfiles
|
||||
import ".." / [ast, idents, lineinfos, msgs, ropes, options,
|
||||
pathutils, condsyms]
|
||||
|
||||
#import ".." / [renderer, astalgo]
|
||||
from std / os import removeFile, isAbsolute
|
||||
|
||||
type
|
||||
|
|
@ -57,6 +57,9 @@ type
|
|||
symMarker*: IntSet #Table[ItemId, SymId] # ItemId.item -> SymId
|
||||
config*: ConfigRef
|
||||
|
||||
proc isActive*(e: PackedEncoder): bool = e.config != nil
|
||||
proc disable*(e: var PackedEncoder) = e.config = nil
|
||||
|
||||
template primConfigFields(fn: untyped) {.dirty.} =
|
||||
fn backend
|
||||
fn selectedGC
|
||||
|
|
@ -216,7 +219,8 @@ proc addMissing(c: var PackedEncoder; p: PSym) =
|
|||
## consider queuing a symbol for later addition to the packed tree
|
||||
if p != nil and p.itemId.module == c.thisModule:
|
||||
if p.itemId.item notin c.symMarker:
|
||||
c.pendingSyms.add p
|
||||
if not (sfForward in p.flags and p.kind in routineKinds):
|
||||
c.pendingSyms.add p
|
||||
|
||||
proc addMissing(c: var PackedEncoder; p: PType) =
|
||||
## consider queuing a type for later addition to the packed tree
|
||||
|
|
@ -332,6 +336,8 @@ proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
|||
if s.itemId.item >= m.sh.syms.len:
|
||||
setLen m.sh.syms, s.itemId.item+1
|
||||
|
||||
assert sfForward notin s.flags
|
||||
|
||||
var p = PackedSym(kind: s.kind, flags: s.flags, info: s.info.toPackedInfo(c, m), magic: s.magic,
|
||||
position: s.position, offset: s.offset, options: s.options,
|
||||
name: s.name.s.toLitId(m))
|
||||
|
|
@ -418,28 +424,40 @@ proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var Pa
|
|||
toPackedNode(n[i], ir, c, m)
|
||||
ir.patch patchPos
|
||||
|
||||
proc storeInstantiation*(c: var PackedEncoder; m: var PackedModule; s: PSym; i: PInstantiation) =
|
||||
var t = newSeq[PackedItemId](i.concreteTypes.len)
|
||||
for j in 0..high(i.concreteTypes):
|
||||
t[j] = storeTypeLater(i.concreteTypes[j], c, m)
|
||||
m.procInstCache.add PackedInstantiation(key: storeSymLater(s, c, m),
|
||||
sym: storeSymLater(i.sym, c, m),
|
||||
concreteTypes: t)
|
||||
|
||||
proc storeTypeInst*(c: var PackedEncoder; m: var PackedModule; s: PSym; inst: PType) =
|
||||
m.typeInstCache.add (storeSymLater(s, c, m), storeTypeLater(inst, c, m))
|
||||
|
||||
proc addPragmaComputation*(c: var PackedEncoder; m: var PackedModule; n: PNode) =
|
||||
toPackedNode(n, m.toReplay, c, m)
|
||||
|
||||
proc toPackedProcDef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
||||
let info = toPackedInfo(n.info, c, m)
|
||||
let patchPos = ir.prepare(n.kind, n.flags,
|
||||
storeTypeLater(n.typ, c, m), info)
|
||||
for i in 0..<n.len:
|
||||
if i != bodyPos:
|
||||
toPackedNode(n[i], ir, c, m)
|
||||
else:
|
||||
# do not serialize the body of the proc, it's unnecessary since
|
||||
# n[0].sym.ast has the sem'checked variant of it which is what
|
||||
# everybody should use instead.
|
||||
ir.nodes.add PackedNode(kind: nkEmpty, flags: {}, operand: 0,
|
||||
typeId: nilItemId, info: info)
|
||||
ir.patch patchPos
|
||||
|
||||
proc toPackedNodeIgnoreProcDefs(n: PNode, encoder: var PackedEncoder; m: var PackedModule) =
|
||||
case n.kind
|
||||
of routineDefs:
|
||||
# we serialize n[namePos].sym instead
|
||||
if n[namePos].kind == nkSym:
|
||||
discard storeSym(n[namePos].sym, encoder, m)
|
||||
else:
|
||||
toPackedNode(n, m.topLevel, encoder, m)
|
||||
toPackedProcDef(n, m.topLevel, encoder, m)
|
||||
when false:
|
||||
# we serialize n[namePos].sym instead
|
||||
if n[namePos].kind == nkSym:
|
||||
let s = n[namePos].sym
|
||||
discard storeSym(s, encoder, m)
|
||||
if s.flags * {sfExportc, sfCompilerProc, sfCompileTime} == {sfExportc}:
|
||||
m.exportCProcs.add(s.itemId.item)
|
||||
else:
|
||||
toPackedNode(n, m.topLevel, encoder, m)
|
||||
of nkStmtList, nkStmtListExpr:
|
||||
for it in n:
|
||||
toPackedNodeIgnoreProcDefs(it, encoder, m)
|
||||
|
|
@ -450,6 +468,24 @@ proc toPackedNodeTopLevel*(n: PNode, encoder: var PackedEncoder; m: var PackedMo
|
|||
toPackedNodeIgnoreProcDefs(n, encoder, m)
|
||||
flush encoder, m
|
||||
|
||||
proc toPackedGeneratedProcDef*(s: PSym, encoder: var PackedEncoder; m: var PackedModule) =
|
||||
## Generic procs and generated `=hook`'s need explicit top-level entries so
|
||||
## that the code generator can work without having to special case these. These
|
||||
## entries will also be useful for other tools and are the cleanest design
|
||||
## I can come up with.
|
||||
assert s.kind in routineKinds
|
||||
toPackedProcDef(s.ast, m.topLevel, encoder, m)
|
||||
#flush encoder, m
|
||||
|
||||
proc storeInstantiation*(c: var PackedEncoder; m: var PackedModule; s: PSym; i: PInstantiation) =
|
||||
var t = newSeq[PackedItemId](i.concreteTypes.len)
|
||||
for j in 0..high(i.concreteTypes):
|
||||
t[j] = storeTypeLater(i.concreteTypes[j], c, m)
|
||||
m.procInstCache.add PackedInstantiation(key: storeSymLater(s, c, m),
|
||||
sym: storeSymLater(i.sym, c, m),
|
||||
concreteTypes: t)
|
||||
toPackedGeneratedProcDef(i.sym, c, m)
|
||||
|
||||
proc loadError(err: RodFileError; filename: AbsoluteFile) =
|
||||
echo "Error: ", $err, " loading file: ", filename.string
|
||||
|
||||
|
|
@ -520,6 +556,7 @@ proc storeError(err: RodFileError; filename: AbsoluteFile) =
|
|||
removeFile(filename.string)
|
||||
|
||||
proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var PackedModule) =
|
||||
flush encoder, m
|
||||
#rememberConfig(encoder, encoder.config)
|
||||
|
||||
var f = rodfiles.create(filename.string)
|
||||
|
|
@ -572,6 +609,7 @@ proc saveRodFile*(filename: AbsoluteFile; encoder: var PackedEncoder; m: var Pac
|
|||
storeSeqSection enumToStringProcsSection, m.enumToStringProcs
|
||||
|
||||
close(f)
|
||||
encoder.disable()
|
||||
if f.err != ok:
|
||||
storeError(f.err, filename)
|
||||
|
||||
|
|
@ -848,6 +886,8 @@ proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
|
|||
info: newLineInfo(fileIdx, 1, 1),
|
||||
position: int(fileIdx))
|
||||
m.module.owner = newPackage(conf, cache, fileIdx)
|
||||
if fileIdx == conf.projectMainIdx2:
|
||||
m.module.flags.incl sfMainModule
|
||||
|
||||
proc loadToReplayNodes(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||
fileIdx: FileIndex; m: var LoadedModule) =
|
||||
|
|
@ -895,6 +935,7 @@ proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache
|
|||
loadError(err, rod)
|
||||
g[m].status = outdated
|
||||
result = true
|
||||
when false: loadError(err, rod)
|
||||
of loading, loaded:
|
||||
# For loading: Assume no recompile is required.
|
||||
result = false
|
||||
|
|
@ -1061,6 +1102,13 @@ proc idgenFromLoadedModule*(m: LoadedModule): IdGenerator =
|
|||
IdGenerator(module: m.module.itemId.module, symId: int32 m.fromDisk.sh.syms.len,
|
||||
typeId: int32 m.fromDisk.sh.types.len)
|
||||
|
||||
proc searchForCompilerproc*(m: LoadedModule; name: string): int32 =
|
||||
# slow, linear search, but the results are cached:
|
||||
for it in items(m.fromDisk.compilerProcs):
|
||||
if m.fromDisk.sh.strings[it[0]] == name:
|
||||
return it[1]
|
||||
return -1
|
||||
|
||||
# ------------------------- .rod file viewer ---------------------------------
|
||||
|
||||
proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
|
||||
|
|
@ -1081,6 +1129,11 @@ proc rodViewer*(rodfile: AbsoluteFile; config: ConfigRef, cache: IdentCache) =
|
|||
for ex in m.reexports:
|
||||
echo " ", m.sh.strings[ex[0]]
|
||||
# reexports*: seq[(LitId, PackedItemId)]
|
||||
|
||||
echo "all symbols"
|
||||
for i in 0..high(m.sh.syms):
|
||||
echo " ", m.sh.strings[m.sh.syms[i].name], " local ID: ", i
|
||||
|
||||
echo "symbols: ", m.sh.syms.len, " types: ", m.sh.types.len,
|
||||
" top level nodes: ", m.topLevel.nodes.len, " other nodes: ", m.bodies.nodes.len,
|
||||
" strings: ", m.sh.strings.len, " integers: ", m.sh.integers.len,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue