summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-06-18 15:05:44 +0200
committerAraq <rumpf_a@web.de>2015-06-18 15:06:00 +0200
commit17cace280ca927a97adc21314141947210fe17b5 (patch)
tree016bd219417ed448bd192654dba20a16313523b3 /compiler
parentbd394eaeda9bcd57daae92520d933676dc6573b9 (diff)
downloadNim-17cace280ca927a97adc21314141947210fe17b5.tar.gz
fixes #2297, fixes #2946
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lowerings.nim20
-rw-r--r--compiler/vm.nim12
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim7
4 files changed, 22 insertions, 19 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim
index b6b01d558..b4319b246 100644
--- a/compiler/lowerings.nim
+++ b/compiler/lowerings.nim
@@ -63,6 +63,26 @@ proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode =
     if n.sons[i].kind == nkSym: v.addVar(n.sons[i])
     result.add newAsgnStmt(n.sons[i], newTupleAccess(tempAsNode, i))
 
+proc lowerSwap*(n: PNode; owner: PSym): PNode =
+  result = newNodeI(nkStmtList, n.info)
+  # note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
+  var temp = newSym(skVar, getIdent(genPrefix), owner, n.info)
+  temp.typ = n.sons[1].typ
+  incl(temp.flags, sfFromGeneric)
+
+  var v = newNodeI(nkVarSection, n.info)
+  let tempAsNode = newSymNode(temp)
+
+  var vpart = newNodeI(nkIdentDefs, v.info, 3)
+  vpart.sons[0] = tempAsNode
+  vpart.sons[1] = ast.emptyNode
+  vpart.sons[2] = n[1]
+  addSon(v, vpart)
+
+  result.add(v)
+  result.add newFastAsgnStmt(n[1], n[2])
+  result.add newFastAsgnStmt(n[2], tempAsNode)
+
 proc createObj*(owner: PSym, info: TLineInfo): PType =
   result = newType(tyObject, owner)
   rawAddSon(result, nil)
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 9f0d0bfce..826356c68 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -1051,18 +1051,6 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
           # set to default value:
           for i in oldLen .. <newLen:
             regs[ra].node.sons[i] = newNodeI(nkEmpty, c.debug[pc])
-    of opcSwap:
-      let rb = instr.regB
-      if regs[ra].kind == regs[rb].kind:
-        case regs[ra].kind
-        of rkNone: discard
-        of rkInt: swap regs[ra].intVal, regs[rb].intVal
-        of rkFloat: swap regs[ra].floatVal, regs[rb].floatVal
-        of rkNode: swap regs[ra].node, regs[rb].node
-        of rkRegisterAddr: swap regs[ra].regAddr, regs[rb].regAddr
-        of rkNodeAddr: swap regs[ra].nodeAddr, regs[rb].nodeAddr
-      else:
-        internalError(c.debug[pc], "cannot swap operands")
     of opcReset:
       internalError(c.debug[pc], "too implement")
     of opcNarrowS:
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index 047009f01..2d0272cd7 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -65,7 +65,7 @@ type
     opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet,
     opcMulSet, opcPlusSet, opcMinusSet, opcSymdiffSet, opcConcatStr,
     opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq,
-    opcSwap, opcIsNil, opcOf, opcIs,
+    opcIsNil, opcOf, opcIs,
     opcSubStr, opcParseFloat, opcConv, opcCast,
     opcQuit, opcReset,
     opcNarrowS, opcNarrowU,
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index c68282fde..dc3188c66 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -831,12 +831,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     c.freeTemp(tmp)
   of mSwap:
     unused(n, dest)
-    var
-      d1 = c.genx(n.sons[1])
-      d2 = c.genx(n.sons[2])
-    c.gABC(n, opcSwap, d1, d2)
-    c.genAsgnPatch(n.sons[1], d1)
-    c.genAsgnPatch(n.sons[2], d2)
+    c.gen(lowerSwap(n, if c.prc == nil: c.module else: c.prc.sym))
   of mIsNil: genUnaryABC(c, n, dest, opcIsNil)
   of mCopyStr:
     if dest < 0: dest = c.getTemp(n.typ)