mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-25 12:25:08 +00:00
remove any traces of the old global generics cache
This commit is contained in:
@@ -282,7 +282,6 @@ proc CommandCompileToC =
|
||||
# rodread.gMods
|
||||
|
||||
# !! ropes.cache
|
||||
# !! semdata.gGenericsCache
|
||||
# semthreads.computed?
|
||||
#
|
||||
# suggest.usageSym
|
||||
@@ -397,7 +396,6 @@ proc resetMemory =
|
||||
ResetAllModules()
|
||||
resetRopeCache()
|
||||
resetSysTypes()
|
||||
gGenericsCache = nil
|
||||
gOwners = @[]
|
||||
rangeDestructorProc = nil
|
||||
for i in low(buckets)..high(buckets):
|
||||
@@ -421,7 +419,6 @@ proc resetMemory =
|
||||
# rodread.gMods
|
||||
|
||||
# !! ropes.cache
|
||||
# !! semdata.gGenericsCache
|
||||
# semthreads.computed?
|
||||
#
|
||||
# suggest.usageSym
|
||||
|
||||
@@ -188,15 +188,15 @@ proc semConstBoolExpr(c: PContext, n: PNode): PNode =
|
||||
|
||||
include semtypes, semtempl, semgnrc, semstmts, semexprs
|
||||
|
||||
proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||
for i in countup(c.generics.lastGenericIdx, Len(c.generics.generics) - 1):
|
||||
var prc = c.generics.generics[i].inst.sym
|
||||
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
||||
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
||||
proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||
for i in countup(c.lastGenericIdx, c.generics.len - 1):
|
||||
var prc = c.generics[i].inst.sym
|
||||
if prc.kind in {skProc, skMethod, skConverter} and prc.magic == mNone:
|
||||
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
|
||||
InternalError(prc.info, "no code for " & prc.name.s)
|
||||
else:
|
||||
addSon(n, prc.ast)
|
||||
c.generics.lastGenericIdx = Len(c.generics.generics)
|
||||
c.lastGenericIdx = c.generics.len
|
||||
|
||||
proc semExprNoFlags(c: PContext, n: PNode): PNode {.procvar.} =
|
||||
result = semExpr(c, n, {})
|
||||
@@ -229,7 +229,7 @@ proc myOpenCached(module: PSym, rd: PRodReader): PPassContext =
|
||||
proc SemStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
|
||||
result = semStmt(c, n)
|
||||
# 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)
|
||||
addCodeForGenerics(c, a)
|
||||
if sonsLen(a) > 0:
|
||||
|
||||
@@ -39,21 +39,11 @@ type
|
||||
TInstantiationPair* = object
|
||||
genericSym*: PSym
|
||||
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
|
||||
TContext* = object of TPassContext # a context represents a module
|
||||
module*: PSym # the module sym belonging to the 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;
|
||||
# this is used so that generic instantiations
|
||||
# can access private object fields
|
||||
@@ -84,9 +74,9 @@ type
|
||||
evalContext*: PEvalContext
|
||||
UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent
|
||||
# naming it multiple times
|
||||
|
||||
var
|
||||
gGenericsCache*: PGenericsCache # save for modularity
|
||||
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
|
||||
lastGenericIdx*: int # used for the generics stack
|
||||
|
||||
|
||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||
result.genericSym = s
|
||||
@@ -96,10 +86,6 @@ proc filename*(c: PContext): string =
|
||||
# the module's filename
|
||||
return c.module.filename
|
||||
|
||||
proc newGenericsCache*(): PGenericsCache =
|
||||
new(result)
|
||||
result.generics = @[]
|
||||
|
||||
proc newContext*(module: PSym): PContext
|
||||
|
||||
proc lastOptionEntry*(c: PContext): POptionEntry
|
||||
@@ -171,15 +157,7 @@ proc newContext(module: PSym): PContext =
|
||||
result.patterns = @[]
|
||||
result.includedFiles = initIntSet()
|
||||
initStrTable(result.userPragmas)
|
||||
if optSymbolFiles notin gGlobalOptions:
|
||||
# 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.generics = @[]
|
||||
result.UnknownIdents = initIntSet()
|
||||
|
||||
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 oldInGenericInst = c.InGenericInst
|
||||
let oldProcCon = c.p
|
||||
c.generics = newGenericsCache()
|
||||
c.generics = @[]
|
||||
try:
|
||||
result = semExpr(c, n, flags)
|
||||
if msgs.gErrorCounter != oldErrorCount: result = nil
|
||||
|
||||
@@ -104,9 +104,9 @@ proc instantiateBody(c: PContext, n: PNode, result: PSym) =
|
||||
popProcCon(c)
|
||||
|
||||
proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
|
||||
for i in countup(0, Len(c.generics.generics) - 1):
|
||||
if c.generics.generics[i].genericSym.id == s.id:
|
||||
var oldPrc = c.generics.generics[i].inst.sym
|
||||
for i in countup(0, c.generics.len - 1):
|
||||
if c.generics[i].genericSym.id == s.id:
|
||||
var oldPrc = c.generics[i].inst.sym
|
||||
pushInfoContext(oldPrc.info)
|
||||
openScope(c.tab)
|
||||
var n = oldPrc.ast
|
||||
@@ -166,7 +166,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
||||
var oldPrc = GenericCacheGet(fn, entry[])
|
||||
if oldPrc == nil:
|
||||
fn.procInstCache.safeAdd(entry)
|
||||
c.generics.generics.add(makeInstPair(fn, entry))
|
||||
c.generics.add(makeInstPair(fn, entry))
|
||||
if n.sons[pragmasPos].kind != nkEmpty:
|
||||
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
|
||||
if isNil(n.sons[bodyPos]):
|
||||
|
||||
@@ -42,6 +42,11 @@ proc searchInstTypes(key: PType): PType =
|
||||
|
||||
for inst in genericTyp.sym.typeInstCache:
|
||||
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:
|
||||
for j in 1 .. high(key.sons):
|
||||
# XXX sameType is not really correct for nested generics?
|
||||
@@ -138,75 +143,51 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
|
||||
var body = t.sons[0]
|
||||
if body.kind != tyGenericBody: InternalError(cl.info, "no generic body")
|
||||
var header: PType = nil
|
||||
when true:
|
||||
# search for some instantiation here:
|
||||
result = searchInstTypes(t)
|
||||
if result != nil: return
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
var x = t.sons[i]
|
||||
if x.kind == tyGenericParam:
|
||||
x = lookupTypeVar(cl, x)
|
||||
if header == nil: header = copyType(t, t.owner, false)
|
||||
header.sons[i] = x
|
||||
#idTablePut(cl.typeMap, body.sons[i-1], x)
|
||||
if header != nil:
|
||||
# search again after first pass:
|
||||
result = searchInstTypes(header)
|
||||
if result != nil: return
|
||||
else:
|
||||
header = copyType(t, t.owner, false)
|
||||
# ugh need another pass for deeply recursive generic types (e.g. PActor)
|
||||
# we need to add the candidate here, before it's fully instantiated for
|
||||
# recursive instantions:
|
||||
result = newType(tyGenericInst, t.sons[0].owner)
|
||||
result.rawAddSon(header.sons[0])
|
||||
cacheTypeInst(result)
|
||||
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
var x = replaceTypeVarsT(cl, t.sons[i])
|
||||
assert x.kind != tyGenericInvokation
|
||||
# search for some instantiation here:
|
||||
result = searchInstTypes(t)
|
||||
if result != nil: return
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
var x = t.sons[i]
|
||||
if x.kind == tyGenericParam:
|
||||
x = lookupTypeVar(cl, x)
|
||||
if header == nil: header = copyType(t, t.owner, false)
|
||||
header.sons[i] = x
|
||||
idTablePut(cl.typeMap, body.sons[i-1], x)
|
||||
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
# if one of the params is not concrete, we cannot do anything
|
||||
# but we already raised an error!
|
||||
rawAddSon(result, header.sons[i])
|
||||
|
||||
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
||||
newbody.flags = newbody.flags + t.flags + body.flags
|
||||
result.flags = result.flags + newbody.flags
|
||||
newbody.callConv = body.callConv
|
||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
||||
# This type may be a generic alias and we want to resolve it here.
|
||||
# One step is enough, because the recursive nature of
|
||||
# handleGenericInvokation will handle the alias-to-alias-to-alias case
|
||||
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
||||
rawAddSon(result, newbody)
|
||||
checkPartialConstructedType(cl.info, newbody)
|
||||
#idTablePut(cl.typeMap, body.sons[i-1], x)
|
||||
if header != nil:
|
||||
# search again after first pass:
|
||||
result = searchInstTypes(header)
|
||||
if result != nil: return
|
||||
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)
|
||||
header = copyType(t, t.owner, false)
|
||||
# ugh need another pass for deeply recursive generic types (e.g. PActor)
|
||||
# we need to add the candidate here, before it's fully instantiated for
|
||||
# recursive instantions:
|
||||
result = newType(tyGenericInst, t.sons[0].owner)
|
||||
result.rawAddSon(header.sons[0])
|
||||
cacheTypeInst(result)
|
||||
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
var x = replaceTypeVarsT(cl, t.sons[i])
|
||||
assert x.kind != tyGenericInvokation
|
||||
header.sons[i] = x
|
||||
idTablePut(cl.typeMap, body.sons[i-1], x)
|
||||
|
||||
for i in countup(1, sonsLen(t) - 1):
|
||||
# if one of the params is not concrete, we cannot do anything
|
||||
# but we already raised an error!
|
||||
rawAddSon(result, header.sons[i])
|
||||
|
||||
var newbody = ReplaceTypeVarsT(cl, lastSon(body))
|
||||
newbody.flags = newbody.flags + t.flags + body.flags
|
||||
result.flags = result.flags + newbody.flags
|
||||
newbody.callConv = body.callConv
|
||||
newbody.n = ReplaceTypeVarsN(cl, lastSon(body).n)
|
||||
# This type may be a generic alias and we want to resolve it here.
|
||||
# One step is enough, because the recursive nature of
|
||||
# handleGenericInvokation will handle the alias-to-alias-to-alias case
|
||||
if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
|
||||
rawAddSon(result, newbody)
|
||||
checkPartialConstructedType(cl.info, newbody)
|
||||
|
||||
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
|
||||
result = t
|
||||
|
||||
Reference in New Issue
Block a user