summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2013-01-27 21:28:34 +0200
committerZahary Karadjov <zahary@gmail.com>2013-01-27 21:28:34 +0200
commit55f8ed2452cf6e9b2bc0024940a99c3d9ae31d77 (patch)
treef9de41e5820b02b56c373338f9f9cc3369135308
parent5d9153d4207aaa04adb6e304e76f598fc3b9a107 (diff)
downloadNim-55f8ed2452cf6e9b2bc0024940a99c3d9ae31d77.tar.gz
remove any traces of the old global generics cache
-rwxr-xr-xcompiler/main.nim3
-rwxr-xr-xcompiler/sem.nim14
-rwxr-xr-xcompiler/semdata.nim32
-rwxr-xr-xcompiler/semexprs.nim2
-rwxr-xr-xcompiler/seminst.nim8
-rwxr-xr-xcompiler/semtypinst.nim115
6 files changed, 65 insertions, 109 deletions
diff --git a/compiler/main.nim b/compiler/main.nim
index 06d16ed08..4767c1537 100755
--- a/compiler/main.nim
+++ b/compiler/main.nim
@@ -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
diff --git a/compiler/sem.nim b/compiler/sem.nim
index b136cc035..9844d71b0 100755
--- a/compiler/sem.nim
+++ b/compiler/sem.nim
@@ -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: 
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index 54662111b..f5d5a9604 100755
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -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) =
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index e1d69c0bc..e6123b1bc 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -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
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 0533d62ad..5a818103d 100755
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -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]):
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 03b6e3961..26341525c 100755
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -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