This commit is contained in:
Araq
2015-09-18 11:24:16 +02:00
parent eb7f514933
commit 5b2f54ffa1
4 changed files with 15 additions and 6 deletions

View File

@@ -738,6 +738,8 @@ type
name*: Rope
path*: PNode # can be a string literal!
CompilesId* = int ## id that is used for the caching logic within
## ``system.compiles``. See the seminst module.
TInstantiation* = object
sym*: PSym
concreteTypes*: seq[PType]
@@ -745,6 +747,7 @@ type
# needed in caas mode for purging the cache
# XXX: it's possible to switch to a
# simple ref count here
compilesId*: CompilesId
PInstantiation* = ref TInstantiation

View File

@@ -72,6 +72,7 @@ type
inGenericContext*: int # > 0 if we are in a generic type
inUnrolledContext*: int # > 0 if we are unrolling a loop
inCompilesContext*: int # > 0 if we are in a ``compiles`` magic
compilesContextIdGenerator*: int
inGenericInst*: int # > 0 if we are instantiating a generic
converters*: TSymSeq # sequence of converters
patterns*: TSymSeq # sequence of pattern matchers

View File

@@ -1636,7 +1636,9 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
# watch out, hacks ahead:
let oldErrorCount = msgs.gErrorCounter
let oldErrorMax = msgs.gErrorMax
inc c.inCompilesContext
let oldCompilesId = c.inCompilesContext
inc c.compilesContextIdGenerator
c.inCompilesContext = c.compilesContextIdGenerator
# do not halt after first error:
msgs.gErrorMax = high(int)
@@ -1660,6 +1662,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
except ERecoverableError:
discard
# undo symbol table changes (as far as it's possible):
c.inCompilesContext = oldCompilesId
c.generics = oldGenerics
c.inGenericContext = oldInGenericContext
c.inUnrolledContext = oldInUnrolledContext
@@ -1668,7 +1671,6 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
msgs.setInfoContextLen(oldContextLen)
setLen(gOwners, oldOwnerLen)
c.currentScope = oldScope
dec c.inCompilesContext
errorOutputs = oldErrorOutputs
msgs.gErrorCounter = oldErrorCount
msgs.gErrorMax = oldErrorMax

View File

@@ -47,10 +47,11 @@ proc sameInstantiation(a, b: TInstantiation): bool =
flags = {ExactTypeDescValues}): return
result = true
proc genericCacheGet(genericSym: PSym, entry: TInstantiation): PSym =
proc genericCacheGet(genericSym: PSym, entry: TInstantiation;
id: CompilesId): PSym =
if genericSym.procInstCache != nil:
for inst in genericSym.procInstCache:
if sameInstantiation(entry, inst[]):
if inst.compilesId == id and sameInstantiation(entry, inst[]):
return inst.sym
proc removeDefaultParamValues(n: PNode) =
@@ -249,13 +250,15 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
if tfTriggersCompileTime in result.typ.flags:
incl(result.flags, sfCompileTime)
n.sons[genericParamsPos] = ast.emptyNode
var oldPrc = genericCacheGet(fn, entry[])
var oldPrc = genericCacheGet(fn, entry[], c.inCompilesContext)
if oldPrc == nil:
# we MUST not add potentially wrong instantiations to the caching mechanism.
# This means recursive instantiations behave differently when in
# a ``compiles`` context but this is the lesser evil. See
# bug #1055 (tevilcompiles).
if c.inCompilesContext == 0: fn.procInstCache.safeAdd(entry)
#if c.inCompilesContext == 0:
entry.compilesId = c.inCompilesContext
fn.procInstCache.safeAdd(entry)
c.generics.add(makeInstPair(fn, entry))
if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)