compilation cache: fixed recently introduced bug (lazy loading of bodies)

This commit is contained in:
Araq
2011-11-06 01:11:38 +01:00
parent dc08a033d9
commit 089e287c6e
7 changed files with 63 additions and 19 deletions

View File

@@ -18,5 +18,5 @@ const
VersionPatch* = 13
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
RodFileVersion* = "1031" # modify this if the rod-format changes!
RodFileVersion* = "1032" # modify this if the rod-format changes!

View File

@@ -83,7 +83,7 @@
#
# The data section MUST be the last section of the file, because processing
# stops immediately after ``DATA(`` and the rest is only loaded on demand
# by using mem'mapped a file.
# by using a mem'mapped file.
#
import
@@ -91,8 +91,8 @@ import
ropes, idents, crc, idgen, rodutils, memfiles
type
TReasonForRecompile* = enum
rrEmpty, # used by moddeps module
TReasonForRecompile* = enum ## all the reasons that can trigger recompilation
rrEmpty, # dependencies not yet computed
rrNone, # no need to recompile
rrRodDoesNotExist, # rod file does not exist
rrRodInvalid, # rod file is invalid
@@ -146,10 +146,11 @@ var rodCompilerprocs*: TStrTable
proc handleSymbolFile*(module: PSym, filename: string): PRodReader
# global because this is needed by magicsys
proc loadInitSection*(r: PRodReader): PNode
proc loadStub*(s: PSym)
# implementation
proc rawLoadStub(s: PSym)
var gTypeTable: TIdTable
proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym
@@ -241,9 +242,9 @@ proc decodeNodeLazyBody(r: PRodReader, fInfo: TLineInfo,
addSonNilAllowed(result, decodeNodeLazyBody(r, result.info, nil))
inc i
if r.s[r.pos] == ')': inc(r.pos)
else: internalError(result.info, "decodeNode")
else:
InternalError(fInfo, "decodeNode " & r.s[r.pos])
else: internalError(result.info, "decodeNode: ')' missing")
else:
InternalError(fInfo, "decodeNode: '(' missing " & $r.pos)
proc decodeNode(r: PRodReader, fInfo: TLineInfo): PNode =
result = decodeNodeLazyBody(r, fInfo, nil)
@@ -408,7 +409,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
result.position = decodeVInt(r.s, r.pos)
elif result.kind notin routineKinds:
result.position = 0
# BUGFIX: this may have been misused as reader index! But we still
# this may have been misused as reader index! But we still
# need it for routines as the body is loaded lazily.
if r.s[r.pos] == '`':
inc(r.pos)
@@ -420,6 +421,9 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
if r.s[r.pos] == '(':
if result.kind in routineKinds:
result.ast = decodeNodeLazyBody(r, result.info, result)
# since we load the body lazily, we need to set the reader to
# be able to reload:
result.position = r.readerIndex
else:
result.ast = decodeNode(r, result.info)
#echo "decoded: ", ident.s, "}"
@@ -637,7 +641,7 @@ proc newRodReader(modfilename: string, crc: TCrc32,
except EOS:
return nil
# we terminate the file explicitely with ``\0``, so the cast to `cstring`
# is save:
# is safe:
r.s = cast[cstring](r.memFile.mem)
if startsWith(r.s, "NIM:"):
initIITable(r.index.tab)
@@ -649,7 +653,7 @@ proc newRodReader(modfilename: string, crc: TCrc32,
inc(r.pos)
if r.s[r.pos] == '\x0A': inc(r.pos)
if version == RodFileVersion:
# since ROD files are only for caching, no backwarts compatibility is
# since ROD files are only for caching, no backwards compatibility is
# needed
processRodFile(r, crc)
else:
@@ -729,7 +733,7 @@ proc rrGetSym(r: PRodReader, id: int, info: TLineInfo): PSym =
else:
# own symbol:
result = decodeSymSafePos(r, d, info)
if result != nil and result.kind == skStub: loadStub(result)
if result != nil and result.kind == skStub: rawLoadStub(result)
proc loadInitSection(r: PRodReader): PNode =
if r.initIdx == 0 or r.dataIdx == 0: InternalError("loadInitSection")
@@ -835,7 +839,7 @@ proc GetCRC*(filename: string): TCrc32 =
var idx = getModuleIdx(filename)
result = gMods[idx].crc
proc loadStub(s: PSym) =
proc rawLoadStub(s: PSym) =
if s.kind != skStub: InternalError("loadStub")
var rd = gMods[s.position].rd
var theId = s.id # used for later check
@@ -848,6 +852,17 @@ proc loadStub(s: PSym) =
InternalError(rs.info, "loadStub: wrong ID")
#MessageOut('loaded stub: ' + s.name.s);
proc LoadStub*(s: PSym) =
## loads the stub symbol `s`.
# deactivate the GC here because we do a deep recursion and generate no
# garbage when restoring parts of the object graph anyway.
# Since we die with internal errors if this fails, so no try-finally is
# necessary.
GC_disable()
rawLoadStub(s)
GC_enable()
proc getBody*(s: PSym): PNode =
## retrieves the AST's body of `s`. If `s` has been loaded from a rod-file
## it may perform an expensive reload operation. Otherwise it's a simple

View File

@@ -518,12 +518,12 @@ proc process(c: PPassContext, n: PNode): PNode =
if c == nil: return
var w = PRodWriter(c)
case n.kind
of nkStmtList:
of nkStmtList:
for i in countup(0, sonsLen(n) - 1): discard process(c, n.sons[i])
of nkTemplateDef, nkMacroDef:
var s = n.sons[namePos].sym
addInterfaceSym(w, s)
of nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef:
#var s = n.sons[namePos].sym
#addInterfaceSym(w, s)
of nkProcDef, nkMethodDef, nkIteratorDef, nkConverterDef,
nkTemplateDef, nkMacroDef:
var s = n.sons[namePos].sym
if s == nil: InternalError(n.info, "rodwrite.process")
if n.sons[bodyPos] == nil:

View File

@@ -0,0 +1,13 @@
discard """
output: "abcd"
"""
import tables
var x = initTable[int, string]()
x[2] = "ab"
x[5] = "cd"
echo x[2], x[5]

View File

@@ -0,0 +1,13 @@
discard """
output: "abef"
"""
import tables
var x = initTable[int, string]()
x[2] = "ab"
x[5] = "ef"
echo x[2], x[5]

View File

@@ -309,6 +309,10 @@ proc runRodFiles(r: var TResults, options: string) =
test "bmethods2.nim"
delNimCache()
# test generics:
test "tgeneric1.nim"
test "tgeneric2.nim"
delNimCache()
proc compileRodFiles(r: var TResults, options: string) =
template test(filename: expr): stmt =

View File

@@ -7,7 +7,6 @@ Version 0.8.14
- fix actors.nim; test with different thread var implementations
- dead code elim for JS backend
version 0.9.0
=============