rework wasMoved, move on the JS backend (#23577)

`reset`, `wasMoved` and `move` doesn't support primitive types, which
generate `null` for these types. It is now produce `x = default(...)` in
the backend. Ideally it should be done by ast2ir in the future
This commit is contained in:
ringabout
2024-05-08 23:11:46 +08:00
committed by GitHub
parent 1ad4e80060
commit e662043fd1
9 changed files with 35 additions and 69 deletions

View File

@@ -504,7 +504,7 @@ type
mSwap, mIsNil, mArrToSeq, mOpenArrayToSeq,
mNewString, mNewStringOfCap, mParseBiggestFloat,
mMove, mEnsureMove, mWasMoved, mDup, mDestroy, mTrace,
mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField, mReset,
mDefault, mUnown, mFinished, mIsolate, mAccessEnv, mAccessTypeField,
mArray, mOpenArray, mRange, mSet, mSeq, mVarargs,
mRef, mPtr, mVar, mDistinct, mVoid, mTuple,
mOrdinal, mIterableType,

View File

@@ -357,7 +357,7 @@ proc getPotentialWrites(n: PNode; mutate: bool; result: var seq[PNode]) =
of nkCallKinds:
case n.getMagic:
of mIncl, mExcl, mInc, mDec, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
mAddr, mNew, mNewFinalize, mWasMoved, mDestroy, mReset:
mAddr, mNew, mNewFinalize, mWasMoved, mDestroy:
getPotentialWrites(n[1], true, result)
for i in 2..<n.len:
getPotentialWrites(n[i], mutate, result)

View File

@@ -1352,14 +1352,6 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) =
genAssignment(p, dest, b, {needToCopy})
gcUsage(p.config, e)
proc genReset(p: BProc, n: PNode) =
var a: TLoc = initLocExpr(p, n[1])
specializeReset(p, a)
when false:
linefmt(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
[addrLoc(p.config, a),
genTypeInfoV1(p.module, skipTypes(a.t, {tyVar}), n.info)])
proc genDefault(p: BProc; n: PNode; d: var TLoc) =
if d.k == locNone: d = getTemp(p, n.typ, needsInit=true)
else: resetLoc(p, d)
@@ -2562,7 +2554,6 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
[mangleDynLibProc(prc), getTypeDesc(p.module, prc.loc.t), getModuleDllPath(p.module, prc)])
genCall(p, e, d)
of mDefault, mZeroDefault: genDefault(p, e, d)
of mReset: genReset(p, e)
of mEcho: genEcho(p, e[1].skipConv)
of mArrToSeq: genArrToSeq(p, e, d)
of mNLen..mNError, mSlurp..mQuoteAst:

View File

@@ -2212,16 +2212,17 @@ proc genDefault(p: PProc, n: PNode; r: var TCompRes) =
r.res = createVar(p, n.typ, indirect = false)
r.kind = resExpr
proc genReset(p: PProc, n: PNode) =
proc genWasMoved(p: PProc, n: PNode) =
# TODO: it should be done by nir
var x: TCompRes = default(TCompRes)
useMagic(p, "genericReset")
gen(p, n[1], x)
if x.typ == etyBaseIndex:
lineF(p, "$1 = null, $2 = 0;$n", [x.address, x.res])
else:
let (a, tmp) = maybeMakeTempAssignable(p, n[1], x)
lineF(p, "$1 = genericReset($3, $2);$n", [a,
genTypeInfo(p, n[1].typ), tmp])
var y: TCompRes = default(TCompRes)
genDefault(p, n[1], y)
let (a, _) = maybeMakeTempAssignable(p, n[1], x)
lineF(p, "$1 = $2;$n", [a, y.rdLoc])
proc genMove(p: PProc; n: PNode; r: var TCompRes) =
var a: TCompRes = default(TCompRes)
@@ -2229,7 +2230,7 @@ proc genMove(p: PProc; n: PNode; r: var TCompRes) =
r.res = p.getTemp()
gen(p, n[1], a)
lineF(p, "$1 = $2;$n", [r.rdLoc, a.rdLoc])
genReset(p, n)
genWasMoved(p, n)
#lineF(p, "$1 = $2;$n", [dest.rdLoc, src.rdLoc])
proc genDup(p: PProc; n: PNode; r: var TCompRes) =
@@ -2410,7 +2411,7 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
of mNewSeqOfCap: unaryExpr(p, n, r, "", "[]")
of mOf: genOf(p, n, r)
of mDefault, mZeroDefault: genDefault(p, n, r)
of mReset, mWasMoved: genReset(p, n)
of mWasMoved: genWasMoved(p, n)
of mEcho: genEcho(p, n, r)
of mNLen..mNError, mSlurp, mStaticExec:
localError(p.config, n.info, errXMustBeCompileTime % n[0].sym.name.s)

View File

@@ -1896,7 +1896,7 @@ proc genMagic(c: var ProcCon; n: PNode; d: var Value; m: TMagic) =
of mDefault, mZeroDefault:
genDefault c, n, d
of mMove: genMove(c, n, d)
of mWasMoved, mReset:
of mWasMoved:
unused(c, n, d)
genWasMoved(c, n)
of mDestroy: genDestroy(c, n)

View File

@@ -815,7 +815,7 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode, isConverter = false) =
const
FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl,
mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap,
mAppendSeqElem, mNewSeq, mReset, mShallowCopy, mDeepCopy, mMove,
mAppendSeqElem, mNewSeq, mShallowCopy, mDeepCopy, mMove,
mWasMoved}
template checkIfConverterCalled(c: PContext, n: PNode) =

View File

@@ -1229,13 +1229,6 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
c.freeTemp(tmp1)
c.genAsgnPatch(d2AsNode, d2)
c.freeTemp(d2)
of mReset:
unused(c, n, dest)
var d = c.genx(n[1])
# XXX use ldNullOpcode() here?
c.gABx(n, opcLdNull, d, c.genType(n[1].typ))
c.gABC(n, opcNodeToReg, d, d)
c.genAsgnPatch(n[1], d)
of mDefault, mZeroDefault:
if dest < 0: dest = c.getTemp(n.typ)
c.gABx(n, ldNullOpcode(n.typ), dest, c.genType(n.typ))

View File

@@ -622,37 +622,6 @@ proc nimCopy(dest, src: JSRef, ti: PNimType): JSRef =
else:
result = src
proc genericReset(x: JSRef, ti: PNimType): JSRef {.compilerproc.} =
{.emit: "`result` = null;".}
case ti.kind
of tyPtr, tyRef, tyVar, tyNil:
if isFatPointer(ti):
{.emit: """
`result` = [null, 0];
""".}
of tySet:
{.emit: """
`result` = {};
""".}
of tyTuple, tyObject:
if ti.kind == tyObject:
{.emit: "`result` = {m_type: `ti`};".}
else:
{.emit: "`result` = {};".}
of tySequence, tyOpenArray, tyString:
{.emit: """
`result` = [];
""".}
of tyArrayConstr, tyArray:
{.emit: """
`result` = new Array(`x`.length);
for (var i = 0; i < `x`.length; ++i) {
`result`[i] = genericReset(`x`[i], `ti`.base);
}
""".}
else:
discard
proc arrayConstr(len: int, value: JSRef, typ: PNimType): JSRef {.
asmNoStackFrame, compilerproc.} =
# types are fake

View File

@@ -83,24 +83,36 @@ block:
X = object
a: string
b: set[char]
c: int
d: float
e: int64
var y = X(b: {'a'})
var x = X(b: {'a'}, e: 10)
var y = move x
doAssert x.a == ""
doAssert x.b == {}
doAssert x.c == 0
doAssert x.d == 0.0
doAssert x.e == 0
reset(y)
doAssert y.a == ""
doAssert y.b == {}
doAssert y.c == 0
doAssert y.d == 0.0
doAssert y.e == 0
block:
type
X = object
a: string
b: int
var y = X(b: 1314)
reset(y)
doAssert y.b == 0
var x = 2
var y = move x
doAssert y == 2
doAssert x == 0
reset y
doAssert y == 0
block:
type