diff options
-rw-r--r-- | compiler/ccgexprs.nim | 27 | ||||
-rw-r--r-- | lib/system.nim | 2 | ||||
-rw-r--r-- | lib/system/repr.nim | 17 |
3 files changed, 43 insertions, 3 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 8ccca9813..5cf6df847 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2607,6 +2607,28 @@ proc genConstSeq(p: BProc, n: PNode, t: PType): Rope = result = "(($1)&$2)" % [getTypeDesc(p.module, t), result] +proc genConstSeqV2(p: BProc, n: PNode, t: PType): Rope = + var data = rope"{" + for i in countup(0, n.len - 1): + if i > 0: data.addf(",$n", []) + data.add genConstExpr(p, n.sons[i]) + data.add("}") + + result = getTempName(p.module) + let payload = getTempName(p.module) + let base = t.skipTypes(abstractInst).sons[0] + + appcg(p.module, cfsData, + "static const struct {$n" & + " NI cap; void* allocator; $1 data[$2];$n" & + "} $3 = {$2, NIM_NIL, $4};$n" & + "static NIM_CONST struct {$n" & + " NI len;$n" & + " $6 p;$n" & + "} $5 = {$2, ($6)&$3};$n", [ + getTypeDesc(p.module, base), rope(len(n)), payload, data, + result, getTypeDesc(p.module, t)]) + proc genConstExpr(p: BProc, n: PNode): Rope = case n.kind of nkHiddenStdConv, nkHiddenSubConv: @@ -2618,7 +2640,10 @@ proc genConstExpr(p: BProc, n: PNode): Rope = of nkBracket, nkPar, nkTupleConstr, nkClosure: var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: - result = genConstSeq(p, n, n.typ) + if p.config.selectedGc == gcDestructors: + result = genConstSeqV2(p, n, n.typ) + else: + result = genConstSeq(p, n, n.typ) elif t.kind == tyProc and t.callConv == ccClosure and n.len > 1 and n.sons[1].kind == nkNilLit: # Conversion: nimcall -> closure. diff --git a/lib/system.nim b/lib/system.nim index 71d1458fd..df7f5e13b 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -3383,7 +3383,7 @@ when not defined(JS): #and not defined(nimscript): when not defined(nimscript) and hasAlloc: when not defined(gcDestructors): include "system/assign" - include "system/repr" + include "system/repr" when hostOS != "standalone" and not defined(nimscript): proc getCurrentException*(): ref Exception {.compilerRtl, inl, benign.} = diff --git a/lib/system/repr.nim b/lib/system/repr.nim index ff8f92404..68d316b73 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -160,6 +160,21 @@ when not defined(useNimRtl): reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), typ.base, cl) add result, "]" + when defined(gcDestructors): + type + GenericSeq = object + len: int + p: pointer + PGenericSeq = ptr GenericSeq + const payloadOffset = sizeof(int) + sizeof(pointer) + # see seqs.nim: cap: int + # region: Allocator + + template payloadPtr(x: untyped): untyped = cast[PGenericSeq](x).p + else: + const payloadOffset = GenericSeqSize + template payloadPtr(x: untyped): untyped = x + proc reprSequence(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) = if p == nil: @@ -170,7 +185,7 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..cast[PGenericSeq](p).len-1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[ByteAddress](p) + GenericSeqSize + i*bs), + reprAux(result, cast[pointer](cast[ByteAddress](payloadPtr(p)) + payloadOffset + i*bs), typ.base, cl) add result, "]" |