.cursor implementation (#12637)

* cursors: first implementation
* added currently failing test
* .cursor works for doubly linked lists
* make -d:useMalloc work again
* added code to nil out refs in a destructor
* it's now called --gc:arc
* renderer.nim: render nkBreakState properly
* make simple closure iterators work without leaking
This commit is contained in:
Andreas Rumpf 2019-11-12 15:05:36 +01:00 • committed by GitHub
commit dfb020b174
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 106 additions and 36 deletions

View file

@ -52,11 +52,24 @@ proc dotField(x: PNode, f: PSym): PNode =
result.sons[1] = newSymNode(f, x.info)
result.typ = f.typ
proc newAsgnStmt(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
if c.kind != attachedDestructor:
body.add newAsgnStmt(x, y)
proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
case n.kind
of nkSym:
let f = n.sym
fillBody(c, f.typ, body, x.dotField(f), y.dotField(f))
if sfCursor in f.flags and f.typ.skipTypes(abstractInst).kind in {tyRef, tyProc} and
c.g.config.selectedGC == gcDestructors:
defaultOp(c, f.typ, body, x.dotField(f), y.dotField(f))
else:
fillBody(c, f.typ, body, x.dotField(f), y.dotField(f))
of nkNilLit: discard
of nkRecCase:
if c.kind in {attachedSink, attachedAsgn, attachedDeepCopy}:
@ -113,11 +126,6 @@ proc newAsgnCall(g: ModuleGraph; op: PSym; x, y: PNode): PNode =
result.add genAddr(g, x)
result.add y
proc newAsgnStmt(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
proc newOpCall(op: PSym; x: PNode): PNode =
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
result.add(newSymNode(op))
@ -236,10 +244,6 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
body.add newDeepCopyCall(op, x, y)
result = true
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
if c.kind != attachedDestructor:
body.add newAsgnStmt(x, y)
proc addVar(father, v, value: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = v
@ -393,6 +397,9 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
when false:
# XXX investigate if this is necessary:
actions.add newAsgnStmt(x, newNodeIT(nkNilLit, body.info, t))
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")
@ -419,6 +426,9 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
body.add genIf(c, cond, actions)
body.add newAsgnStmt(x, y)
of attachedDestructor:
when false:
# XXX investigate if this is necessary:
actions.add newAsgnStmt(xenv, newNodeIT(nkNilLit, body.info, xenv.typ))
body.add genIf(c, cond, actions)
of attachedDeepCopy: assert(false, "cannot happen")