mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-30 20:28:00 +00:00
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:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user