mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
fixes #23556 It should somehow handle default fields in the future
This commit is contained in:
@@ -129,7 +129,9 @@ when not defined(gcDestructors):
|
||||
else:
|
||||
proc nimNewObj(size, align: int): pointer {.importCompilerProc.}
|
||||
proc newSeqPayload(cap, elemSize, elemAlign: int): pointer {.importCompilerProc.}
|
||||
proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize, elemAlign: int): pointer {.
|
||||
proc prepareSeqAddUninit(len: int; p: pointer; addlen, elemSize, elemAlign: int): pointer {.
|
||||
importCompilerProc.}
|
||||
proc zeroNewElements(len: int; p: pointer; addlen, elemSize, elemAlign: int) {.
|
||||
importCompilerProc.}
|
||||
|
||||
template `+!!`(a, b): untyped = cast[pointer](cast[int](a) + b)
|
||||
@@ -221,7 +223,8 @@ proc extendSeq*(x: Any) =
|
||||
var s = cast[ptr NimSeqV2Reimpl](x.value)
|
||||
let elem = x.rawType.base
|
||||
if s.p == nil or s.p.cap < s.len+1:
|
||||
s.p = cast[ptr NimSeqPayloadReimpl](prepareSeqAdd(s.len, s.p, 1, elem.size, elem.align))
|
||||
s.p = cast[ptr NimSeqPayloadReimpl](prepareSeqAddUninit(s.len, s.p, 1, elem.size, elem.align))
|
||||
zeroNewElements(s.len, s.p, 1, elem.size, elem.align)
|
||||
inc s.len
|
||||
else:
|
||||
var y = cast[ptr PGenSeq](x.value)[]
|
||||
|
||||
@@ -90,6 +90,12 @@ proc prepareSeqAdd(len: int; p: pointer; addlen, elemSize, elemAlign: int): poin
|
||||
q.cap = newCap
|
||||
result = q
|
||||
|
||||
proc zeroNewElements(len: int; q: pointer; addlen, elemSize, elemAlign: int) {.
|
||||
noSideEffect, tags: [], raises: [], compilerRtl.} =
|
||||
{.noSideEffect.}:
|
||||
let headerSize = align(sizeof(NimSeqPayloadBase), elemAlign)
|
||||
zeroMem(q +! headerSize +! len * elemSize, addlen * elemSize)
|
||||
|
||||
proc prepareSeqAddUninit(len: int; p: pointer; addlen, elemSize, elemAlign: int): pointer {.
|
||||
noSideEffect, tags: [], raises: [], compilerRtl.} =
|
||||
{.noSideEffect.}:
|
||||
|
||||
@@ -74,3 +74,20 @@ block:
|
||||
|
||||
doAssert getEnumOrdinal(y, "Hello") == 0
|
||||
doAssert getEnumOrdinal(y, "hello") == 1
|
||||
|
||||
block: # bug #23556
|
||||
proc test =
|
||||
var
|
||||
t: seq[int]
|
||||
aseq = toAny(t)
|
||||
|
||||
invokeNewSeq(aseq, 0)
|
||||
|
||||
# Got random value only when loop 8 times.
|
||||
for i in 1 .. 8:
|
||||
extendSeq(aseq)
|
||||
|
||||
doAssert t == @[0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
for i in 1 .. 7:
|
||||
test()
|
||||
|
||||
Reference in New Issue
Block a user