summary refs log tree commit diff stats
path: root/compiler/rodimpl.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rodimpl.nim')
-rw-r--r--compiler/rodimpl.nim59
1 files changed, 47 insertions, 12 deletions
diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim
index 839a9c6ca..730328642 100644
--- a/compiler/rodimpl.nim
+++ b/compiler/rodimpl.nim
@@ -321,6 +321,9 @@ proc encodeSym(g: ModuleGraph, s: PSym, result: var string) =
       result.add('\16')
       encodeVInt(s.gcUnsafetyReason.id, result)
       pushSym(w, s.gcUnsafetyReason)
+    if s.transformedBody != nil:
+      result.add('\24')
+      encodeNode(g, s.info, s.transformedBody, result)
   of skModule, skPackage:
     encodeInstantiations(g, s.usedGenerics, result)
     # we don't serialize:
@@ -363,13 +366,7 @@ proc storeType(g: ModuleGraph; t: PType) =
   db.exec(sql"insert into types(nimid, module, data) values (?, ?, ?)",
     t.id, mid, buf)
 
-proc storeNode*(g: ModuleGraph; module: PSym; n: PNode) =
-  if g.config.symbolFiles == disabledSf: return
-  var buf = newStringOfCap(160)
-  encodeNode(g, module.info, n, buf)
-  db.exec(sql"insert into toplevelstmts(module, position, data) values (?, ?, ?)",
-    abs(module.id), module.offset, buf)
-  inc module.offset
+proc transitiveClosure(g: ModuleGraph) =
   var i = 0
   while true:
     if i > 10_000:
@@ -388,9 +385,25 @@ proc storeNode*(g: ModuleGraph; module: PSym; n: PNode) =
       break
     inc i
 
+proc storeNode*(g: ModuleGraph; module: PSym; n: PNode) =
+  if g.config.symbolFiles == disabledSf: return
+  var buf = newStringOfCap(160)
+  encodeNode(g, module.info, n, buf)
+  db.exec(sql"insert into toplevelstmts(module, position, data) values (?, ?, ?)",
+    abs(module.id), module.offset, buf)
+  inc module.offset
+  transitiveClosure(g)
+
 proc recordStmt*(g: ModuleGraph; module: PSym; n: PNode) =
   storeNode(g, module, n)
 
+proc storeFilename(g: ModuleGraph; fullpath: AbsoluteFile; fileIdx: FileIndex) =
+  let id = db.getValue(sql"select id from filenames where fullpath = ?", fullpath.string)
+  if id.len == 0:
+    let fullhash = hashFileCached(g.config, fileIdx, fullpath)
+    db.exec(sql"insert into filenames(nimid, fullpath, fullhash) values (?, ?, ?)",
+        int(fileIdx), fullpath.string, fullhash)
+
 proc storeRemaining*(g: ModuleGraph; module: PSym) =
   if g.config.symbolFiles == disabledSf: return
   var stillForwarded: seq[PSym] = @[]
@@ -400,6 +413,13 @@ proc storeRemaining*(g: ModuleGraph; module: PSym) =
     else:
       stillForwarded.add s
   swap w.forwardedSyms, stillForwarded
+  transitiveClosure(g)
+  var nimid = 0
+  for x in items(g.config.m.fileInfos):
+    # don't store the "command line" entry:
+    if nimid != 0:
+      storeFilename(g, x.fullPath, FileIndex(nimid))
+    inc nimid
 
 # ---------------- decoder -----------------------------------
 
@@ -725,6 +745,9 @@ proc loadSymFromBlob(g; b; info: TLineInfo): PSym =
     if b.s[b.pos] == '\16':
       inc(b.pos)
       result.gcUnsafetyReason = loadSym(g, decodeVInt(b.s, b.pos), result.info)
+    if b.s[b.pos] == '\24':
+      inc b.pos
+      result.transformedBody = decodeNode(g, b, result.info)
   of skModule, skPackage:
     decodeInstantiations(g, b, result.info, result.usedGenerics)
   of skLet, skVar, skField, skForVar:
@@ -752,6 +775,9 @@ proc loadSym(g; id: int; info: TLineInfo): PSym =
   result = loadSymFromBlob(g, b, info)
   doAssert id == result.id, "symbol ID is not consistent!"
 
+proc registerModule*(g; module: PSym) =
+  g.incr.r.syms.add(abs module.id, module)
+
 proc loadModuleSymTab(g; module: PSym) =
   ## goal: fill  module.tab
   g.incr.r.syms.add(module.id, module)
@@ -765,7 +791,8 @@ proc loadModuleSymTab(g; module: PSym) =
       b.s.add '\0'
       s = loadSymFromBlob(g, b, module.info)
     assert s != nil
-    strTableAdd(module.tab, s)
+    if s.kind != skField:
+      strTableAdd(module.tab, s)
   if sfSystemModule in module.flags:
     g.systemModule = module
 
@@ -843,8 +870,9 @@ proc replay(g: ModuleGraph; module: PSym; n: PNode) =
         internalAssert g.config, false
   of nkImportStmt:
     for x in n:
-      internalAssert g.config, x.kind == nkStrLit
-      let imported = g.importModuleCallback(g, module, fileInfoIdx(g.config, AbsoluteFile n[0].strVal))
+      internalAssert g.config, x.kind == nkSym
+      let modpath = AbsoluteFile toFullPath(g.config, x.sym.info)
+      let imported = g.importModuleCallback(g, module, fileInfoIdx(g.config, modpath))
       internalAssert g.config, imported.id < 0
   of nkStmtList, nkStmtListExpr:
     for x in n: replay(g, module, x)
@@ -868,16 +896,23 @@ proc setupModuleCache*(g: ModuleGraph) =
   let dbfile = getNimcacheDir(g.config) / RelativeFile"rodfiles.db"
   if g.config.symbolFiles == writeOnlySf:
     removeFile(dbfile)
+  createDir getNimcacheDir(g.config)
+  let ec = encodeConfig(g)
   if not fileExists(dbfile):
     db = open(connection=string dbfile, user="nim", password="",
               database="nim")
     createDb(db)
-    db.exec(sql"insert into config(config) values (?)", encodeConfig(g))
+    db.exec(sql"insert into config(config) values (?)", ec)
   else:
     db = open(connection=string dbfile, user="nim", password="",
               database="nim")
     let oldConfig = db.getValue(sql"select config from config")
-    g.incr.configChanged = oldConfig != encodeConfig(g)
+    g.incr.configChanged = oldConfig != ec
+    # ensure the filename IDs stay consistent:
+    for row in db.rows(sql"select fullpath, nimid from filenames order by nimid"):
+      let id = fileInfoIdx(g.config, AbsoluteFile row[0])
+      doAssert id.int == parseInt(row[1])
+    db.exec(sql"update config set config = ?", ec)
   db.exec(sql"pragma journal_mode=off")
   # This MUST be turned off, otherwise it's way too slow even for testing purposes:
   db.exec(sql"pragma SYNCHRONOUS=off")