diff options
-rw-r--r-- | compiler/ccgexprs.nim | 8 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 9 | ||||
-rw-r--r-- | compiler/sighashes.nim | 29 | ||||
-rw-r--r-- | lib/system/gc.nim | 1 | ||||
-rw-r--r-- | tests/generics/tgeneric_closure.nim | 2 |
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 |