remove any traces of the old global generics cache
This commit is contained in:
parent
5d9153d420
commit
55f8ed2452
6 changed files with 65 additions and 109 deletions
|
|
@ -282,7 +282,6 @@ proc CommandCompileToC =
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# !! semdata.gGenericsCache
|
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
# suggest.usageSym
|
# suggest.usageSym
|
||||||
|
|
@ -397,7 +396,6 @@ proc resetMemory =
|
||||||
ResetAllModules()
|
ResetAllModules()
|
||||||
resetRopeCache()
|
resetRopeCache()
|
||||||
resetSysTypes()
|
resetSysTypes()
|
||||||
gGenericsCache = nil
|
|
||||||
gOwners = @[]
|
gOwners = @[]
|
||||||
rangeDestructorProc = nil
|
rangeDestructorProc = nil
|
||||||
for i in low(buckets)..high(buckets):
|
for i in low(buckets)..high(buckets):
|
||||||
|
|
@ -421,7 +419,6 @@ proc resetMemory =
|
||||||
# rodread.gMods
|
# rodread.gMods
|
||||||
|
|
||||||
# !! ropes.cache
|
# !! ropes.cache
|
||||||
# !! semdata.gGenericsCache
|
|
||||||
# semthreads.computed?
|
# semthreads.computed?
|
||||||
#
|
#
|
||||||
# suggest.usageSym
|
# suggest.usageSym
|
||||||
|
|
|
||||||
|
|
@ -189,14 +189,14 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||||
include semtypes, semtempl, semgnrc, semstmts, semexprs
|
include semtypes, semtempl, semgnrc, semstmts, semexprs
|
||||||
|
|
||||||
proc addCodeForGenerics(c: PContext, n: PNode) =
|
proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
for i in countup(c.generics.lastGenericIdx, Len(c.generics.generics) - 1):
|
for i in countup(c.lastGenericIdx, c.generics.len - 1):
|
||||||
var prc = c.generics.generics[i].inst.sym
|
var prc = c.generics[i].inst.sym
|
||||||
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
||||||
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
||||||
InternalError(prc.info, "no code for " & prc.name.s)
|
InternalError(prc.info, "no code for " & prc.name.s)
|
||||||
else:
|
else:
|
||||||
addSon(n, prc.ast)
|
addSon(n, prc.ast)
|
||||||
c.generics.lastGenericIdx = Len(c.generics.generics)
|
c.lastGenericIdx = c.generics.len
|
||||||
|
|
||||||
proc semExprNoFlags(c: PContext, n: PNode): PNode {.procvar.} =
|
proc semExprNoFlags(c: PContext, n: PNode): PNode {.procvar.} =
|
||||||
result = semExpr(c, n, {})
|
result = semExpr(c, n, {})
|
||||||
|
|
@ -229,7 +229,7 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
||||||
proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||||
result = semStmt(c, n)
|
result = semStmt(c, n)
|
||||||
# BUGFIX: process newly generated generics here, not at the end!
|
# BUGFIX: process newly generated generics here, not at the end!
|
||||||
if c.generics.lastGenericIdx < Len(c.generics.generics):
|
if c.lastGenericIdx < c.generics.len:
|
||||||
var a = newNodeI(nkStmtList, n.info)
|
var a = newNodeI(nkStmtList, n.info)
|
||||||
addCodeForGenerics(c, a)
|
addCodeForGenerics(c, a)
|
||||||
if sonsLen(a) > 0:
|
if sonsLen(a) > 0:
|
||||||
|
|
|
||||||
|
|
@ -40,20 +40,10 @@ type
|
||||||
genericSym*: PSym
|
genericSym*: PSym
|
||||||
inst*: PInstantiation
|
inst*: PInstantiation
|
||||||
|
|
||||||
# If we generate an instance of a generic, we'd like to re-use that
|
|
||||||
# instance if possible across module boundaries. However, this is not
|
|
||||||
# possible if the compilation cache is enabled. So we give up then and use
|
|
||||||
# the caching of generics only per module, not per project.
|
|
||||||
TGenericsCache* {.final.} = object
|
|
||||||
generics*: seq[TInstantiationPair] # a list of the things to compile
|
|
||||||
lastGenericIdx*: int # used for the generics stack
|
|
||||||
|
|
||||||
PGenericsCache* = ref TGenericsCache
|
|
||||||
PContext* = ref TContext
|
PContext* = ref TContext
|
||||||
TContext* = object of TPassContext # a context represents a module
|
TContext* = object of TPassContext # a context represents a module
|
||||||
module*: PSym # the module sym belonging to the context
|
module*: PSym # the module sym belonging to the context
|
||||||
p*: PProcCon # procedure context
|
p*: PProcCon # procedure context
|
||||||
generics*: PGenericsCache # may point to a global or module-local structure
|
|
||||||
friendModule*: PSym # current friend module; may access private data;
|
friendModule*: PSym # current friend module; may access private data;
|
||||||
# this is used so that generic instantiations
|
# this is used so that generic instantiations
|
||||||
# can access private object fields
|
# can access private object fields
|
||||||
|
|
@ -84,9 +74,9 @@ type
|
||||||
evalContext*: PEvalContext
|
evalContext*: PEvalContext
|
||||||
UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent
|
UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent
|
||||||
# naming it multiple times
|
# naming it multiple times
|
||||||
|
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
|
||||||
|
lastGenericIdx*: int # used for the generics stack
|
||||||
|
|
||||||
var
|
|
||||||
gGenericsCache*: PGenericsCache # save for modularity
|
|
||||||
|
|
||||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||||
result.genericSym = s
|
result.genericSym = s
|
||||||
|
|
@ -96,10 +86,6 @@ proc filename*(c: PContext): string =
|
||||||
# the module's filename
|
# the module's filename
|
||||||
return c.module.filename
|
return c.module.filename
|
||||||
|
|
||||||
proc newGenericsCache*(): PGenericsCache =
|
|
||||||
new(result)
|
|
||||||
result.generics = @[]
|
|
||||||
|
|
||||||
proc newContext*(module: PSym): PContext
|
proc newContext*(module: PSym): PContext
|
||||||
|
|
||||||
proc lastOptionEntry*(c: PContext): POptionEntry
|
proc lastOptionEntry*(c: PContext): POptionEntry
|
||||||
|
|
@ -171,15 +157,7 @@ proc newContext(module: PSym): PContext =
|
||||||
result.patterns = @[]
|
result.patterns = @[]
|
||||||
result.includedFiles = initIntSet()
|
result.includedFiles = initIntSet()
|
||||||
initStrTable(result.userPragmas)
|
initStrTable(result.userPragmas)
|
||||||
if optSymbolFiles notin gGlobalOptions:
|
result.generics = @[]
|
||||||
# re-usage of generic instantiations across module boundaries is
|
|
||||||
# very nice for code size:
|
|
||||||
if gGenericsCache == nil: gGenericsCache = newGenericsCache()
|
|
||||||
result.generics = gGenericsCache
|
|
||||||
else:
|
|
||||||
# we have to give up and use a per-module cache for generic instantiations:
|
|
||||||
result.generics = newGenericsCache()
|
|
||||||
assert gGenericsCache == nil
|
|
||||||
result.UnknownIdents = initIntSet()
|
result.UnknownIdents = initIntSet()
|
||||||
|
|
||||||
proc inclSym(sq: var TSymSeq, s: PSym) =
|
proc inclSym(sq: var TSymSeq, s: PSym) =
|
||||||
|
|
|
||||||
|
|
@ -1359,7 +1359,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
let oldInUnrolledContext = c.InUnrolledContext
|
let oldInUnrolledContext = c.InUnrolledContext
|
||||||
let oldInGenericInst = c.InGenericInst
|
let oldInGenericInst = c.InGenericInst
|
||||||
let oldProcCon = c.p
|
let oldProcCon = c.p
|
||||||
c.generics = newGenericsCache()
|
c.generics = @[]
|
||||||
try:
|
try:
|
||||||
result = semExpr(c, n, flags)
|
result = semExpr(c, n, flags)
|
||||||
if msgs.gErrorCounter != oldErrorCount: result = nil
|
if msgs.gErrorCounter != oldErrorCount: result = nil
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,9 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
|
||||||
popProcCon(c)
|
popProcCon(c)
|
||||||
|
|
||||||
proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
||||||
for i in countup(0, Len(c.generics.generics) - 1):
|
for i in countup(0, c.generics.len - 1):
|
||||||
if c.generics.generics[i].genericSym.id == s.id:
|
if c.generics[i].genericSym.id == s.id:
|
||||||
var oldPrc = c.generics.generics[i].inst.sym
|
var oldPrc = c.generics[i].inst.sym
|
||||||
pushInfoContext(oldPrc.info)
|
pushInfoContext(oldPrc.info)
|
||||||
openScope(c.tab)
|
openScope(c.tab)
|
||||||
var n = oldPrc.ast
|
var n = oldPrc.ast
|
||||||
|
|
@ -166,7 +166,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||||
var oldPrc = GenericCacheGet(fn, entry[])
|
var oldPrc = GenericCacheGet(fn, entry[])
|
||||||
if oldPrc == nil:
|
if oldPrc == nil:
|
||||||
fn.procInstCache.safeAdd(entry)
|
fn.procInstCache.safeAdd(entry)
|
||||||
c.generics.generics.add(makeInstPair(fn, entry))
|
c.generics.add(makeInstPair(fn, entry))
|
||||||
if n.sons[pragmasPos].kind != nkEmpty:
|
if n.sons[pragmasPos].kind != nkEmpty:
|
||||||
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
||||||
if isNil(n.sons[bodyPos]):
|
if isNil(n.sons[bodyPos]):
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ proc searchInstTypes(key: PType): PType =
|
||||||
|
|
||||||
for inst in genericTyp.sym.typeInstCache:
|
for inst in genericTyp.sym.typeInstCache:
|
||||||
if inst.id == key.id: return inst
|
if inst.id == key.id: return inst
|
||||||
|
if inst.sons.len < key.sons.len:
|
||||||
|
# XXX: This happens for prematurely cached
|
||||||
|
# types such as TChannel[empty]. Why?
|
||||||
|
# See the notes for PActor in handleGenericInvokation
|
||||||
|
return
|
||||||
block MatchType:
|
block MatchType:
|
||||||
for j in 1 .. high(key.sons):
|
for j in 1 .. high(key.sons):
|
||||||
# XXX sameType is not really correct for nested generics?
|
# XXX sameType is not really correct for nested generics?
|
||||||
|
|
@ -138,7 +143,6 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
var body = t.sons[0]
|
var body = t.sons[0]
|
||||||
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
||||||
var header: PType = nil
|
var header: PType = nil
|
||||||
when true:
|
|
||||||
# search for some instantiation here:
|
# search for some instantiation here:
|
||||||
result = searchInstTypes(t)
|
result = searchInstTypes(t)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
|
|
@ -184,29 +188,6 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
||||||
rawAddSon(result, newbody)
|
rawAddSon(result, newbody)
|
||||||
checkPartialConstructedType(cl.info, newbody)
|
checkPartialConstructedType(cl.info, newbody)
|
||||||
else:
|
|
||||||
for i in countup(1, sonsLen(t) - 1):
|
|
||||||
if PType(idTableGet(cl.typeMap, t.sons[i])) == nil: debug(t)
|
|
||||||
var x = replaceTypeVarsT(cl, t.sons[i])
|
|
||||||
if t.sons[i].kind == tyGenericParam:
|
|
||||||
if header == nil: header = copyType(t, t.owner, false)
|
|
||||||
header.sons[i] = x
|
|
||||||
assert x.kind != tyGenericInvokation
|
|
||||||
idTablePut(cl.typeMap, body.sons[i-1], x)
|
|
||||||
if header == nil: header = t
|
|
||||||
result = searchInstTypes(cl.c.generics.InstTypes, header)
|
|
||||||
if result != nil: return
|
|
||||||
result = newType(tyGenericInst, t.sons[0].owner)
|
|
||||||
for i in countup(0, sonsLen(t) - 1):
|
|
||||||
# if one of the params is not concrete, we cannot do anything
|
|
||||||
# but we already raised an error!
|
|
||||||
addSon(result, header.sons[i])
|
|
||||||
idTablePut(cl.c.generics.InstTypes, header, result)
|
|
||||||
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
|
||||||
newbody.flags = newbody.flags + t.flags + body.flags
|
|
||||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
|
||||||
addSon(result, newbody)
|
|
||||||
checkPartialConstructedType(cl.info, newbody)
|
|
||||||
|
|
||||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||||
result = t
|
result = t
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue