summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-07-27 18:21:32 +0200
committerAndreas Rumpf <rumpf_a@web.de>2018-07-27 18:21:32 +0200
commit700448f359fcaa397793d314eff7cf3aa2b13d18 (patch)
tree50ae48f8fbc453251e4ed2f0b186da8904fbd70b
parentef4b755183f6564cc0f35cdf01794626c4e5fe2f (diff)
downloadNim-700448f359fcaa397793d314eff7cf3aa2b13d18.tar.gz
destroyer pass: adaptations for the new destructor based runtime
-rw-r--r--compiler/destroyer.nim6
-rw-r--r--compiler/semasgn.nim28
2 files changed, 27 insertions, 7 deletions
diff --git a/compiler/destroyer.nim b/compiler/destroyer.nim
index c2a74edb1..bd735560a 100644
--- a/compiler/destroyer.nim
+++ b/compiler/destroyer.nim
@@ -258,8 +258,10 @@ proc registerDropBit(c: var Con; s: PSym) =
   c.toDropBit[s.id] = result
   # generate:
   #  if not sinkParam_AliveBit: `=destroy`(sinkParam)
-  c.destroys.add newTree(nkIfStmt,
-    newTree(nkElifBranch, newSymNode result, genDestroy(c, s.typ, newSymNode s)))
+  let t = s.typ.skipTypes({tyGenericInst, tyAlias, tySink})
+  if t.destructor != nil:
+    c.destroys.add newTree(nkIfStmt,
+      newTree(nkElifBranch, newSymNode result, genDestroy(c, t, newSymNode s)))
 
 proc p(n: PNode; c: var Con): PNode
 
diff --git a/compiler/semasgn.nim b/compiler/semasgn.nim
index a05ef7a28..8b2e20efc 100644
--- a/compiler/semasgn.nim
+++ b/compiler/semasgn.nim
@@ -197,13 +197,10 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   case t.kind
   of tyNone, tyEmpty, tyVoid: discard
   of tyPointer, tySet, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString,
-      tyPtr, tyString, tyRef, tyOpt:
+      tyPtr, tyRef, tyOpt:
     defaultOp(c, t, body, x, y)
-  of tyArray, tySequence:
+  of tyArray:
     if {tfHasAsgn, tfUncheckedArray} * t.flags == {tfHasAsgn}:
-      if t.kind == tySequence:
-        # XXX add 'nil' handling here
-        body.add newSeqCall(c.c, x, y)
       let i = declareCounter(c, body, firstOrd(c.c.config, t))
       let whileLoop = genWhileLoop(c, i, x)
       let elemType = t.lastSon
@@ -213,6 +210,27 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
       body.add whileLoop
     else:
       defaultOp(c, t, body, x, y)
+  of tySequence:
+    # note that tfHasAsgn is propagated so we need the check on
+    # 'selectedGC' here to determine if we have the new runtime.
+    if c.c.config.selectedGC == gcDestructors:
+      discard considerOverloadedOp(c, t, body, x, y)
+    elif tfHasAsgn in t.flags:
+      body.add newSeqCall(c.c, x, y)
+      let i = declareCounter(c, body, firstOrd(c.c.config, t))
+      let whileLoop = genWhileLoop(c, i, x)
+      let elemType = t.lastSon
+      liftBodyAux(c, elemType, whileLoop.sons[1], x.at(i, elemType),
+                                                  y.at(i, elemType))
+      addIncStmt(c, whileLoop.sons[1], i)
+      body.add whileLoop
+    else:
+      defaultOp(c, t, body, x, y)
+  of tyString:
+    if tfHasAsgn in t.flags:
+      discard considerOverloadedOp(c, t, body, x, y)
+    else:
+      defaultOp(c, t, body, x, y)
   of tyObject, tyDistinct:
     if not considerOverloadedOp(c, t, body, x, y):
       if t.sons[0] != nil: