fixes #23556; typeinfo.extendSeq generates random values in ORC (#23557)

fixes #23556

It should somehow handle default fields in the future
This commit is contained in:
ringabout
2024-05-03 22:29:56 +08:00
committed by GitHub
parent d772186b2d
commit 36bf3fa47b
3 changed files with 28 additions and 2 deletions

View File

@@ -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)[]

View File

@@ -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.}:

View File

@@ -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()