Skip to content

Commit 611b8bb

Browse files
authored
fixes #25007; implements setLenUninit for refc (#25022)
fixes #25007 ```nim proc setLengthSeqUninit(s: PGenericSeq, typ: PNimType, newLen: int, isTrivial: bool): PGenericSeq {. compilerRtl.} = ``` In this added function, only the line `zeroMem(dataPointer(result, elemAlign, elemSize, newLen), (result.len-%newLen) *% elemSize)` is removed from `proc setLengthSeqV2` when enlarging a sequence. JS and VM versions simply use `setLen`.
1 parent 7e2df41 commit 611b8bb

File tree

13 files changed

+79
-7
lines changed

13 files changed

+79
-7
lines changed

changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ errors.
3333
- `strutils.multiReplace` overload for character set replacements in a single pass.
3434
Useful for string sanitation. Follows existing multiReplace semantics.
3535

36+
- `system.setLenUninit` now supports refc, JS and VM backends.
37+
3638
[//]: # "Changes:"
3739

3840
- `std/math` The `^` symbol now supports floating-point as exponent in addition to the Natural type.

compiler/ast.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,7 @@ type
500500
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
501501
mInSet, mRepr, mExit,
502502
mSetLengthStr, mSetLengthSeq,
503+
mSetLengthSeqUninit,
503504
mIsPartOf, mAstToStr, mParallel,
504505
mSwap, mIsNil, mArrToSeq, mOpenArrayToSeq,
505506
mNewString, mNewStringOfCap, mParseBiggestFloat,

compiler/ccgexprs.nim

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,7 +2214,7 @@ proc isTrivialTypesToSnippet(t: PType): Snippet =
22142214
else:
22152215
result = NimTrue
22162216

2217-
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
2217+
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc, noinit = false) =
22182218
if optSeqDestructors in p.config.globalOptions:
22192219
e[1] = makeAddr(e[1], p.module.idgen)
22202220
genCall(p, e, d)
@@ -2236,7 +2236,9 @@ proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
22362236
pExpr = cIfExpr(ra, cAddr(derefField(ra, "Sup")), NimNil)
22372237
else:
22382238
pExpr = ra
2239-
call.snippet = cCast(rt, cgCall(p, "setLengthSeqV2", pExpr, rti, rb,
2239+
2240+
let name = if noinit: "setLengthSeqUninit" else: "setLengthSeqV2"
2241+
call.snippet = cCast(rt, cgCall(p, name, pExpr, rti, rb,
22402242
isTrivialTypesToSnippet(t.skipTypes(abstractInst)[0])))
22412243

22422244
genAssignment(p, a, call, {})
@@ -2975,6 +2977,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
29752977
p.s(cpsStmts).addCallStmt(cgsymValue(p.module, "nimGCunref"), ra)
29762978
of mSetLengthStr: genSetLengthStr(p, e, d)
29772979
of mSetLengthSeq: genSetLengthSeq(p, e, d)
2980+
of mSetLengthSeqUninit: genSetLengthSeq(p, e, d, noinit = true)
29782981
of mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet,
29792982
mInSet, mXorSet:
29802983
genSetOp(p, e, d, op)

compiler/condsyms.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,5 @@ proc initDefines*(symbols: StringTableRef) =
172172
defineSymbol("nimHasDefaultFloatRoundtrip")
173173
defineSymbol("nimHasXorSet")
174174

175+
defineSymbol("nimHasSetLengthSeqUninitMagic")
176+

compiler/jsgen.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2434,7 +2434,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
24342434
binaryExpr(p, n, r, "mnewString",
24352435
"""if ($1.length < $2) { for (var i = $3.length; i < $4; ++i) $3.push(0); }
24362436
else {$3.length = $4; }""")
2437-
of mSetLengthSeq:
2437+
of mSetLengthSeq, mSetLengthSeqUninit:
24382438
var x, y: TCompRes = default(TCompRes)
24392439
gen(p, n[1], x)
24402440
gen(p, n[2], y)

compiler/nifgen.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ proc magicToNifTag(s: TMagic): (string, int) =
358358
of mExit: ("exit", NoMagic)
359359
of mSetLengthStr: ("setlenstr", NoMagic)
360360
of mSetLengthSeq: ("setlenseq", NoMagic)
361+
of mSetLengthSeqUninit: ("setlensequninit", NoMagic)
361362
of mIsPartOf: ("ispartof", NoMagic)
362363
of mAstToStr: ("asttostr", NoMagic)
363364
of mParallel: ("parallel", NoMagic)

compiler/semdata.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ proc analyseIfAddressTakenInCall*(c: PContext, n: PNode, isConverter = false) =
710710
return
711711
const
712712
FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
713-
mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
713+
mSetLengthStr, mSetLengthSeq, mSetLengthSeqUninit, mAppendStrCh, mAppendStrStr, mSwap,
714714
mAppendSeqElem, mNewSeq, mShallowCopy, mDeepCopy, mMove, mWasMoved}
715715

716716
template checkIfConverterCalled(c: PContext, n: PNode) =

compiler/semmagic.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
667667
result = semQuantifier(c, n)
668668
of mOld:
669669
result = semOld(c, n)
670-
of mSetLengthSeq:
670+
of mSetLengthSeq, mSetLengthSeqUninit:
671671
result = n
672672
let seqType = result[1].typ.skipTypes({tyPtr, tyRef, # in case we had auto-dereferencing
673673
tyVar, tyGenericInst, tyOwned, tySink,

compiler/vmgen.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}, m: TMag
12211221
var tmp = c.genx(n[1])
12221222
c.gABC(n, opcQuit, tmp)
12231223
c.freeTemp(tmp)
1224-
of mSetLengthStr, mSetLengthSeq:
1224+
of mSetLengthStr, mSetLengthSeq, mSetLengthSeqUninit:
12251225
unused(c, n, dest)
12261226
var d = c.genx(n[1])
12271227
var tmp = c.genx(n[2])

lib/system.nim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,22 @@ proc setLen*[T](s: var seq[T], newlen: Natural) {.
955955
## assert x == @[10]
956956
## ```
957957

958+
when defined(nimHasSetLengthSeqUninitMagic):
959+
func setLenUninit*[T](s: var seq[T], newlen: Natural) {.magic: "SetLengthSeqUninit", nodestroy.} =
960+
## Sets the length of seq `s` to `newlen`. `T` may be any sequence type.
961+
## New slots will not be initialized.
962+
##
963+
## If the current length is greater than the new length,
964+
## `s` will be truncated.
965+
## ```nim
966+
## var x = @[10, 20]
967+
## x.setLenUninit(5)
968+
## x[4] = 50
969+
## assert x[4] == 50Add commentMore actions
970+
## x.setLenUninit(1)
971+
## assert x == @[10]
972+
## ```
973+
958974
proc setLen*(s: var string, newlen: Natural) {.
959975
magic: "SetLengthStr", noSideEffect.}
960976
## Sets the length of string `s` to `newlen`.

0 commit comments

Comments
 (0)