summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2019-04-06 17:32:33 +0200
committerAraq <rumpf_a@web.de>2019-04-06 17:32:53 +0200
commit6e6a9a721fc039c88851650e4ab989aeff04fc9f (patch)
tree1cbcab26559355e7b7ee4dee87454956661dc5da /compiler
parentfab75fbaf1a2dd94cedfc0b41173edf49b581c6e (diff)
downloadNim-6e6a9a721fc039c88851650e4ab989aeff04fc9f.tar.gz
destructors: we are cooking now
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim3
-rw-r--r--compiler/commands.nim13
-rw-r--r--compiler/injectdestructors.nim18
-rw-r--r--compiler/liftdestructors.nim14
-rw-r--r--compiler/transf.nim2
5 files changed, 37 insertions, 13 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index a21d9f738..0aeb94bb5 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1808,3 +1808,6 @@ template getBody*(s: PSym): PNode = s.ast[bodyPos]
 
 template detailedInfo*(sym: PSym): string =
   sym.name.s
+
+proc isInlineIterator*(s: PSym): bool {.inline.} =
+  s.kind == skIterator and s.typ.callConv != ccClosure
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 0c574a079..6935e7747 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -745,12 +745,13 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
       conf.cppDefine(arg)
   of "newruntime":
     expectNoArg(conf, switch, arg, pass, info)
-    doAssert(conf != nil)
-    incl(conf.features, destructor)
-    incl(conf.globalOptions, optNimV2)
-    defineSymbol(conf.symbols, "nimV2")
-    conf.selectedGC = gcDestructors
-    defineSymbol(conf.symbols, "gcdestructors")
+    if pass in {passCmd2, passPP}:
+      doAssert(conf != nil)
+      incl(conf.features, destructor)
+      incl(conf.globalOptions, optNimV2)
+      defineSymbol(conf.symbols, "nimV2")
+      conf.selectedGC = gcDestructors
+      defineSymbol(conf.symbols, "gcdestructors")
   of "stylecheck":
     case arg.normalize
     of "off": conf.globalOptions = conf.globalOptions - {optStyleHint, optStyleError}
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim
index f1bda866b..350fd9c8d 100644
--- a/compiler/injectdestructors.nim
+++ b/compiler/injectdestructors.nim
@@ -456,7 +456,7 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
       result.add arg[0]
       for i in 1..<arg.len:
         result.add pArg(arg[i], c, i < L and parameters[i].kind == tySink)
-    elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkBracket, nkCharLit..nkFloat128Lit}:
+    elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkBracket, nkCharLit..nkTripleStrLit}:
       discard "object construction to sink parameter: nothing to do"
       result = arg
     elif arg.kind == nkSym and isSinkParam(arg.sym):
@@ -616,7 +616,21 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
     else:
       result = genCopy(c, dest.typ, dest, ri)
       result.add p(ri, c)
+  of nkHiddenSubConv, nkHiddenStdConv:
+    let harmless = ri[1].kind in (nkCallKinds + {nkSym, nkTupleConstr, nkObjConstr,
+                                                 nkBracket, nkBracketExpr, nkNilLit})
+    if harmless:
+      result = moveOrCopy(dest, ri[1], c)
+      var b = newNodeIT(ri.kind, ri.info, ri.typ)
+      b.add ri[0] # add empty node
+      let L = result.len-1
+      b.add result[L]
+      result[L] = b
+    else:
+      result = genCopy(c, dest.typ, dest, ri)
+      result.add p(ri, c)
   else:
+    # XXX At least string literals can be moved?
     result = genCopy(c, dest.typ, dest, ri)
     result.add p(ri, c)
 
@@ -725,7 +739,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
   when defined(nimDebugDestroys):
     if owner.name.s == "main":
       echo "injecting into ", n
-  if sfGeneratedOp in owner.flags: return n
+  if sfGeneratedOp in owner.flags or isInlineIterator(owner): return n
   var c: Con
   c.owner = owner
   c.destroys = newNodeI(nkStmtList, n.info)
diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim
index dba09b4ef..cfab1e221 100644
--- a/compiler/liftdestructors.nim
+++ b/compiler/liftdestructors.nim
@@ -309,13 +309,14 @@ proc seqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
 proc strOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
   case c.kind
   of attachedAsgn, attachedDeepCopy:
+    body.add callCodegenProc(c.graph, "nimAsgnStrV2", c.info, genAddr(c.graph, x), y)
     # we generate:
     # setLen(dest, y.len)
     # var i = 0
     # while i < y.len: dest[i] = y[i]; inc(i)
     # This is usually more efficient than a destroy/create pair.
-    body.add setLenStrCall(c.graph, x, y)
-    forallElements(c, t, body, x, y)
+    #body.add setLenStrCall(c.graph, x, y)
+    #forallElements(c, t, body, x, y)
   of attachedSink:
     let moveCall = genBuiltin(c.graph, mMove, "move", x)
     moveCall.add y
@@ -473,8 +474,11 @@ proc liftBodyAux(c: var TLiftCtx; t: PType; body, x, y: PNode) =
      tyTypeDesc, tyGenericInvocation, tyForward:
     #internalError(c.graph.config, c.info, "assignment requested for type: " & typeToString(t))
     discard
+  of tyVar, tyLent:
+    if c.kind != attachedDestructor:
+      liftBodyAux(c, lastSon(t), body, x, y)
   of tyOrdinal, tyRange, tyInferred,
-     tyGenericInst, tyStatic, tyVar, tyLent, tyAlias, tySink:
+     tyGenericInst, tyStatic, tyAlias, tySink:
     liftBodyAux(c, lastSon(t), body, x, y)
 
 proc newProcType(info: TLineInfo; owner: PSym): PType =
@@ -650,7 +654,7 @@ proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
     orig.assignment = canon.assignment
     orig.sink = canon.sink
 
-  #if not isTrival(orig.destructor):
+  if not isTrival(orig.destructor):
     #or not isTrival(orig.assignment) or
     # not isTrival(orig.sink):
-  #  orig.flags.incl tfHasAsgn
+    orig.flags.incl tfHasAsgn
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 640ed1136..a597123de 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -772,6 +772,8 @@ proc transformCall(c: PTransf, n: PNode): PTransNode =
   elif magic == mProcCall:
     # but do not change to its dispatcher:
     result = transformSons(c, n[1])
+  elif magic == mStrToStr:
+    result = transform(c, n[1])
   else:
     let s = transformSons(c, n).PNode
     # bugfix: check after 'transformSons' if it's still a method call: