From 2fcc1637465df3ccc04394ee4703330cc51ee493 Mon Sep 17 00:00:00 2001 From: Araq Date: Tue, 20 Feb 2018 01:15:43 +0100 Subject: symbol files: more progress --- compiler/modules.nim | 16 ++++++----- compiler/passes.nim | 42 ++++++++++++++++++++++++----- compiler/rod.nim | 2 +- compiler/rodimpl.nim | 76 ++++++++++++++++++++++++++++++++++++++++------------ compiler/sem.nim | 3 ++- 5 files changed, 107 insertions(+), 32 deletions(-) diff --git a/compiler/modules.nim b/compiler/modules.nim index ab384311e..ede10a0f4 100644 --- a/compiler/modules.nim +++ b/compiler/modules.nim @@ -169,13 +169,15 @@ proc compileModule*(graph: ModuleGraph; fileIdx: int32; cache: IdentCache, flags if sfMainModule in result.flags: gMainPackageId = result.owner.id - if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCheck, cmdIdeTools}: - rd = handleSymbolFile(result, cache) - if result.id < 0: - internalError("handleSymbolFile should have set the module's ID") - return - else: - result.id = getModuleId(toFullPath(fileIdx)) + when false: + if gCmd in {cmdCompileToC, cmdCompileToCpp, cmdCheck, cmdIdeTools}: + rd = handleSymbolFile(result, cache) + if result.id < 0: + internalError("handleSymbolFile should have set the module's ID") + return + else: + discard + result.id = getModuleId(toFullPath(fileIdx)) discard processModule(graph, result, if sfMainModule in flags and gProjectIsStdin: stdin.llStreamOpen else: nil, rd, cache) diff --git a/compiler/passes.nim b/compiler/passes.nim index 29b27627d..1b4cd6fec 100644 --- a/compiler/passes.nim +++ b/compiler/passes.nim @@ -7,13 +7,13 @@ # distribution, for details about the copyright. # -# This module implements the passes functionality. A pass must implement the -# `TPass` interface. +## This module implements the passes functionality. A pass must implement the +## `TPass` interface. import strutils, options, ast, astalgo, llstream, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, - nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder + nimsets, syntaxes, times, rodread, idgen, modulegraphs, reorder, rod type @@ -29,7 +29,8 @@ type TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.} TPass* = tuple[open: TPassOpen, openCached: TPassOpenCached, - process: TPassProcess, close: TPassClose] + process: TPassProcess, close: TPassClose, + isFrontend: bool] TPassData* = tuple[input: PNode, closeOutput: PNode] TPasses* = openArray[TPass] @@ -41,11 +42,13 @@ type proc makePass*(open: TPassOpen = nil, openCached: TPassOpenCached = nil, process: TPassProcess = nil, - close: TPassClose = nil): TPass = + close: TPassClose = nil, + isFrontend = false): TPass = result.open = open result.openCached = openCached result.close = close result.process = process + result.isFrontend = isFrontend # the semantic checker needs these: var @@ -178,7 +181,34 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream, a: TPassContextArray s: PLLStream fileIdx = module.fileIdx - if rd == nil: + if module.id < 0: + # new module caching mechanism: + for i in 0.. 0, "cannot find file name for DB ID " & $dbId + result = fileInfoIdx(fullpath) + proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, result: var string) = if n == nil: @@ -91,7 +104,7 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, result.add(',') encodeVInt(n.info.line, result) result.add(',') - encodeVInt(n.info.fileIndex, result) + encodeVInt(toDbFileId(n.info.toFullPath), result) elif fInfo.line != n.info.line: result.add('?') encodeVInt(n.info.col, result) @@ -269,7 +282,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) = result.add(',') if s.info.line != -1'i16: encodeVInt(s.info.line, result) result.add(',') - encodeVInt(s.info.fileIndex, result) + encodeVInt(toDbFileId(s.info.toFullPath), result) if s.owner != nil: result.add('*') encodeVInt(s.owner.id, result) @@ -331,8 +344,8 @@ proc storeSym(w: PRodWriter; s: PSym) = encodeSym(w, s, buf) # XXX only store the name for exported symbols in order to speed up lookup # times once we enable the skStub logic. - db.exec(sql"insert into syms(nimid, module, name, data) values (?, ?, ?, ?)", - s.id, abs(w.module.id), s.name.s, buf) + db.exec(sql"insert into syms(nimid, module, name, data, exported) values (?, ?, ?, ?, ?)", + s.id, abs(w.module.id), s.name.s, buf, ord(sfExported in s.flags)) proc storeType(w: PRodWriter; t: PType) = var buf = newStringOfCap(160) @@ -410,7 +423,7 @@ proc decodeLineInfo(r; b; info: var TLineInfo) = else: info.line = int16(decodeVInt(b.s, b.pos)) if b.s[b.pos] == ',': inc(b.pos) - info.fileIndex = int32(decodeVInt(b.s, b.pos)) + info.fileIndex = fromDbFileId(decodeVInt(b.s, b.pos)) proc skipNode(b) = assert b.s[b.pos] == '(' @@ -569,7 +582,7 @@ proc loadType(r; id: int; info: TLineInfo): PType = inc(b.pos) result.size = decodeVInt(b.s, b.pos) else: - result.size = - 1 + result.size = -1 if b.s[b.pos] == '=': inc(b.pos) result.align = decodeVInt(b.s, b.pos).int16 @@ -642,25 +655,21 @@ proc decodeInstantiations(r; b; info: TLineInfo; ii.compilesId = decodeVInt(b.s, b.pos) s.safeAdd ii -proc loadSym(r; id: int; info: TLineInfo): PSym = - var - id: int - ident: PIdent - result = r.syms.getOrDefault(id) - if result != nil: return result - var b = loadBlob(sql"select data from syms where nimid = ?", id) +proc loadSymFromBlob(r; b; info: TLineInfo): PSym = if b.s[b.pos] == '{': inc(b.pos) if b.s[b.pos] == '}': inc(b.pos) return # nil sym var k = TSymKind(decodeVInt(b.s, b.pos)) + var id: int if b.s[b.pos] == '+': inc(b.pos) id = decodeVInt(b.s, b.pos) setId(id) else: internalError(info, "decodeSym: no id") + var ident: PIdent if b.s[b.pos] == '&': inc(b.pos) ident = r.cache.getIdent(decodeStr(b.s, b.pos)) @@ -729,9 +738,34 @@ proc loadSym(r; id: int; info: TLineInfo): PSym = # result.ast = decodeNodeLazyBody(b, result.info, result) #else: result.ast = decodeNode(r, b, result.info) + if sfCompilerProc in result.flags: + registerCompilerProc(result) + +proc loadSym(r; id: int; info: TLineInfo): PSym = + result = r.syms.getOrDefault(id) + if result != nil: return result + var b = loadBlob(sql"select data from syms where nimid = ?", id) + result = loadSymFromBlob(r, b, info) + doAssert id == result.id, "symbol ID is not consistent!" + +proc loadModuleSymTab(r; module: PSym) = + ## goal: fill module.tab + gr.syms[module.id] = module + for row in db.fastRows(sql"select nimid, data from syms where module = ? and exported = 1", abs(module.id)): + let id = parseInt(row[0]) + var s = r.syms.getOrDefault(id) + if s == nil: + var b = BlobReader(pos: 0) + shallowCopy(b.s, row[1]) + s = loadSymFromBlob(r, b, module.info) + assert s != nil + strTableAdd(module.tab, s) + if sfSystemModule in module.flags: + magicsys.systemModule = module proc loadNode*(module: PSym; index: var int): PNode = if index == 0: + loadModuleSymTab(gr, module) index = parseInt db.getValue( sql"select min(id) from toplevelstmts where module = ?", abs module.id) var b = BlobReader(pos: 0) @@ -749,6 +783,14 @@ proc createDb() = ); """) + db.exec(sql""" + create table if not exists filenames( + id integer primary key, + fullpath varchar(8000) not null + ); + """) + db.exec sql"create index if not exists FilenameIx on filenames(fullpath);" + db.exec(sql""" create table if not exists modules( id integer primary key, @@ -779,6 +821,7 @@ proc createDb() = module integer not null, name varchar(256) not null, data blob not null, + exported int not null, foreign key (module) references module(id) ); """) @@ -798,7 +841,6 @@ proc createDb() = """) db.exec sql"create index TopLevelStmtByModuleIdx on toplevelstmts(module);" - db.exec(sql""" create table if not exists statics( id integer primary key, diff --git a/compiler/sem.nim b/compiler/sem.nim index 053e739d3..12e77affc 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -621,4 +621,5 @@ proc myClose(graph: ModuleGraph; context: PPassContext, n: PNode): PNode = popProcCon(c) if c.runnableExamples != nil: testExamples(c) -const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose) +const semPass* = makePass(myOpen, myOpenCached, myProcess, myClose, + isFrontend = true) -- cgit 1.4.1-2-gfad0