diff options
author | ringabout <43030857+ringabout@users.noreply.github.com> | 2023-05-12 21:24:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-12 15:24:14 +0200 |
commit | ddce5559981ac5dedd3a5dfb210eb25296e69307 (patch) | |
tree | c65eaaba45022b9587b41fa857d97c95c9ccc0f9 | |
parent | 871e4af6ef384ef27c9357dab24ab727a2006eae (diff) | |
download | Nim-ddce5559981ac5dedd3a5dfb210eb25296e69307.tar.gz |
improve `wasMoved` hooks; allow reset to use the overridden `wasMoved` hook (#21831)
* improve `wasMoved` hooks * Because `wasMoved` is lifted
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/liftdestructors.nim | 37 | ||||
-rw-r--r-- | compiler/optimizer.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 9 | ||||
-rw-r--r-- | lib/system.nim | 13 |
5 files changed, 43 insertions, 20 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 7183aac4e..56ca8f605 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -381,7 +381,7 @@ proc genWasMoved(c: var Con, n: PNode): PNode = result = genOp(c, op, n) else: result = newNodeI(nkCall, n.info) - result.add(newSymNode(createMagic(c.graph, c.idgen, "wasMoved", mWasMoved))) + result.add(newSymNode(createMagic(c.graph, c.idgen, "`=wasMoved`", mWasMoved))) result.add copyTree(n) #mWasMoved does not take the address #if n.kind != nkSym: # message(c.graph.config, n.info, warnUser, "wasMoved(" & $n & ")") diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 43e5baf08..e8db14569 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -89,7 +89,7 @@ proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = call.typ = t body.add newAsgnStmt(x, call) elif c.kind == attachedWasMoved: - body.add genBuiltin(c, mWasMoved, "wasMoved", x) + body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) proc genAddr(c: var TLiftCtx; x: PNode): PNode = if x.kind == nkHiddenDeref: @@ -143,7 +143,7 @@ proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode = if sfNeverRaises notin op.flags: c.canRaise = true if c.addMemReset: - result = newTree(nkStmtList, destroy, genBuiltin(c, mWasMoved, "wasMoved", x)) + result = newTree(nkStmtList, destroy, genBuiltin(c, mWasMoved, "`=wasMoved`", x)) else: result = destroy @@ -262,7 +262,7 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) = #body.add newAsgnStmt(blob, x) var wasMovedCall = newNodeI(nkCall, c.info) - wasMovedCall.add(newSymNode(createMagic(c.g, c.idgen, "wasMoved", mWasMoved))) + wasMovedCall.add(newSymNode(createMagic(c.g, c.idgen, "`=wasMoved`", mWasMoved))) wasMovedCall.add x # mWasMoved does not take the address body.add wasMovedCall @@ -548,7 +548,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = if canFormAcycle(c.g, t.elemType): # follow all elements: forallElements(c, t, body, x, y) - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -588,7 +588,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = if op == nil: return # protect from recursion body.add newHookCall(c, op, x, y) - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -606,7 +606,7 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add genBuiltin(c, mDestroy, "destroy", x) of attachedTrace: discard "strings are atomic and have no inner elements that are to trace" - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -707,7 +707,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = # If the ref is polymorphic we have to account for this body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x, c.idgen), y) #echo "can follow ", elemType, " static ", isFinal(elemType) - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -758,7 +758,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv, c.idgen), y) - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -785,7 +785,7 @@ proc weakrefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.sons.insert(des, 0) of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: discard - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -813,7 +813,7 @@ proc ownedRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add genIf(c, x, actions) of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: discard - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -850,7 +850,7 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.sons.insert(des, 0) of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: discard - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -868,7 +868,7 @@ proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) = body.add genIf(c, xx, actions) of attachedDeepCopy: assert(false, "cannot happen") of attachedTrace: discard - of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "wasMoved", x) + of attachedWasMoved: body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) of attachedDup: assert false, "cannot happen" @@ -934,8 +934,14 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) = defaultOp(c, t, body, x, y) of tyObject: if not considerUserDefinedOp(c, t, body, x, y): - if c.kind in {attachedAsgn, attachedSink} and t.sym != nil and sfImportc in t.sym.flags: - body.add newAsgnStmt(x, y) + if t.sym != nil and sfImportc in t.sym.flags: + case c.kind + of {attachedAsgn, attachedSink}: + body.add newAsgnStmt(x, y) + of attachedWasMoved: + body.add genBuiltin(c, mWasMoved, "`=wasMoved`", x) + else: + fillBodyObjT(c, t, body, x, y) else: fillBodyObjT(c, t, body, x, y) of tyDistinct: @@ -1004,6 +1010,9 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp result.ast = n incl result.flags, sfFromGeneric incl result.flags, sfGeneratedOp + if kind == attachedWasMoved: + incl result.flags, sfNoSideEffect + incl result.typ.flags, tfNoSideEffect proc genTypeFieldCopy(c: var TLiftCtx; t: PType; body, x, y: PNode) = let xx = genBuiltin(c, mAccessTypeField, "accessTypeField", x) diff --git a/compiler/optimizer.nim b/compiler/optimizer.nim index 0b26e8d34..a5cfa5420 100644 --- a/compiler/optimizer.nim +++ b/compiler/optimizer.nim @@ -113,7 +113,7 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = if n[0].kind == nkSym: let s = n[0].sym let name = s.name.s.normalize - if s.magic == mWasMoved or name == "=wasmoved": + if name == "=wasmoved": b.wasMovedLocs.add n special = true elif name == "=destroy": diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 71efcadb1..b47737bee 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -613,6 +613,15 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, let op = getAttachedOp(c.graph, t, attachedTrace) if op != nil: result[0] = newSymNode(op) + of mWasMoved: + result = n + let t = n[1].typ.skipTypes(abstractVar) + let op = getAttachedOp(c.graph, t, attachedWasMoved) + if op != nil: + result[0] = newSymNode(op) + let addrExp = newNodeIT(nkHiddenAddr, result[1].info, makePtrType(c, t)) + addrExp.add result[1] + result[1] = addrExp of mUnown: result = semUnown(c, n) of mExists, mForall: diff --git a/lib/system.nim b/lib/system.nim index e7b6ed7c3..f8523b094 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -137,15 +137,20 @@ proc new*[T](a: var ref T, finalizer: proc (x: ref T) {.nimcall.}) {. ## **Note**: The `finalizer` refers to the type `T`, not to the object! ## This means that for each object of type `T` the finalizer will be called! -proc wasMoved*[T](obj: var T) {.magic: "WasMoved", noSideEffect.} = +proc `=wasMoved`[T](obj: var T) {.magic: "WasMoved", noSideEffect.} = + ## Generic `wasMoved`:idx: implementation that can be overridden. + +proc wasMoved*[T](obj: var T) {.inline, noSideEffect.} = ## Resets an object `obj` to its initial (binary zero) value to signify ## it was "moved" and to signify its destructor should do nothing and ## ideally be optimized away. - discard + {.cast(raises: []), cast(tags: []).}: + `=wasMoved`(obj) proc move*[T](x: var T): T {.magic: "Move", noSideEffect.} = result = x - wasMoved(x) + {.cast(raises: []), cast(tags: []).}: + `=wasMoved`(x) type range*[T]{.magic: "Range".} ## Generic type to construct range types. @@ -912,7 +917,7 @@ proc reset*[T](obj: var T) {.noSideEffect.} = when defined(gcDestructors): {.cast(noSideEffect), cast(raises: []), cast(tags: []).}: `=destroy`(obj) - wasMoved(obj) + `=wasMoved`(obj) else: obj = default(typeof(obj)) |