summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ccgexprs.nim8
-rw-r--r--compiler/ccgtypes.nim9
-rw-r--r--compiler/sighashes.nim29
-rw-r--r--lib/system/gc.nim1
-rw-r--r--tests/generics/tgeneric_closure.nim2
5 files changed, 24 insertions, 25 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index d68e26ec3..fc6b33e4b 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -1059,15 +1059,17 @@ proc genReset(p: BProc, n: PNode) =
 
 proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) =
   var sizeExpr = sizeExpr
-  let refType = a.t
+  let typ = a.t
   var b: TLoc
   initLoc(b, locExpr, a.t, OnHeap)
+  let refType = typ.skipTypes(abstractInst)
+  assert refType.kind == tyRef
   let bt = refType.lastSon
   if sizeExpr.isNil:
     sizeExpr = "sizeof($1)" %
         [getTypeDesc(p.module, bt)]
-  let args = [getTypeDesc(p.module, refType),
-              genTypeInfo(p.module, refType),
+  let args = [getTypeDesc(p.module, typ),
+              genTypeInfo(p.module, typ),
               sizeExpr]
   if a.s == OnHeap and usesNativeGC():
     # use newObjRC1 as an optimization
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 5c13d8186..f236a8a50 100644
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -287,8 +287,9 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
   else: result = nil
 
   if result != nil and typ.isImportedType():
-    if cacheGetType(m.typeCache, typ) == nil:
-      idTablePut(m.typeCache, typ, result)
+    let sig = hashType typ
+    if cacheGetType(m.typeCache, sig) == nil:
+      m.typeCache[sig] = result
       addAbiCheck(m, typ, result)
 
 proc pushType(m: BModule, typ: PType) =
@@ -861,8 +862,8 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; name, base: Rope) =
 
 proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope) =
   var base: Rope
-  if sonsLen(typ) > 0 and typ.sons[0] != nil:
-    var x = typ.sons[0]
+  if sonsLen(typ) > 0 and typ.lastSon != nil:
+    var x = typ.lastSon
     if typ.kind == tyObject: x = x.skipTypes(skipPtrs)
     base = genTypeInfo(m, x)
   else:
diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim
index 6918b28a2..d1175cb5e 100644
--- a/compiler/sighashes.nim
+++ b/compiler/sighashes.nim
@@ -68,6 +68,8 @@ else:
     toBase64a(cast[cstring](unsafeAddr u), sizeof(u))
   proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len)
   proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1)
+  proc `&=`(c: var MD5Context, i: BiggestInt) =
+    md5Update(c, cast[cstring](unsafeAddr i), sizeof(i))
 
   template lowlevel(v) =
     md5Update(c, cast[cstring](unsafeAddr(v)), sizeof(v))
@@ -127,15 +129,6 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
     return
 
   case t.kind
-  of tyGenericInst:
-    var x = t.lastSon
-    if x.kind == tyGenericBody: x = x.lastSon
-    if x.kind == tyTuple:
-      c.hashType x, flags
-      return
-    for i in countup(0, sonsLen(t) - 2):
-      c.hashType t.sons[i], flags
-    return
   of tyGenericInvocation:
     for i in countup(0, sonsLen(t) - 1):
       c.hashType t.sons[i], flags
@@ -146,16 +139,19 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
     else:
       c.hashSym(t.sym)
     return
-  of tyAlias:
+  of tyAlias, tyGenericInst:
     c.hashType t.lastSon, flags
     return
   else:
     discard
 
   c &= char(t.kind)
-
   case t.kind
   of tyObject, tyEnum:
+    if t.typeInst != nil:
+      assert t.typeInst.kind == tyGenericInst
+      for i in countup(1, sonsLen(t.typeInst) - 2):
+        c.hashType t.typeInst.sons[i], flags
     # Every cyclic type in Nim need to be constructed via some 't.sym', so this
     # is actually safe without an infinite recursion check:
     if t.sym != nil:
@@ -163,13 +159,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
       #  writeStackTrace()
       #  echo "yes ", t.sym.name.s
       #  #quit 1
-      if t.typeInst != nil:
-        assert t.typeInst.kind == tyGenericInst
-        for i in countup(1, sonsLen(t.typeInst) - 2):
-          c.hashType t.typeInst.sons[i], flags
       c.hashSym(t.sym)
     else:
-      lowlevel(t.id)
+      c &= t.id
   of tyRef, tyPtr, tyGenericBody:
     c.hashType t.lastSon, flags
   of tyUserTypeClass:
@@ -247,7 +239,10 @@ proc hashProc*(s: PSym): SigHash =
   c &= p.name.s
   c &= "."
   c &= m.name.s
-
+  # so that createThread[void]() (aka generic specialization) gets a unique
+  # hash, we also hash the line information. This is pretty bad, but the best
+  # solution for now:
+  c &= s.info.line
   md5Final c, result.Md5Digest
 
 proc hashOwner*(s: PSym): SigHash =
diff --git a/lib/system/gc.nim b/lib/system/gc.nim
index 7fb4c7ac7..5e9be6246 100644
--- a/lib/system/gc.nim
+++ b/lib/system/gc.nim
@@ -461,6 +461,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
   gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
   collectCT(gch)
   var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
+  gcAssert typ.kind == tyString or size >= typ.base.size, "size too small"
   gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
   # now it is buffered in the ZCT
   res.typ = typ
diff --git a/tests/generics/tgeneric_closure.nim b/tests/generics/tgeneric_closure.nim
index 7198dce96..8dcd677fd 100644
--- a/tests/generics/tgeneric_closure.nim
+++ b/tests/generics/tgeneric_closure.nim
@@ -8,7 +8,7 @@ type
   TEventHandler[T] = proc (e: var TEventArgs, data: T) {.closure.}
   TEvent*[T] = object
     #handlers: seq[TEventHandler[T]] # Does not work
-    handlers: seq[proc (e: var TEventArgs, data: T) {.closure.}] # works
+    handlers: seq[proc (e: var TEventArgs, d: T) {.closure.}] # works
 
   TData = object
     x: int