summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/lowerings.nim20
-rw-r--r--compiler/vm.nim12
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim7
-rw-r--r--tests/vm/tconsttable2.nim81
-rw-r--r--tests/vm/tswap.nim24
6 files changed, 127 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)
diff --git a/tests/vm/tconsttable2.nim b/tests/vm/tconsttable2.nim
new file mode 100644
index 000000000..e07734eb5
--- /dev/null
+++ b/tests/vm/tconsttable2.nim
@@ -0,0 +1,81 @@
+discard """
+  msg: '''61'''
+"""
+
+# bug #2297
+
+import tables
+
+proc html5tags*(): TableRef[string, string] =
+  var html5tagsCache: Table[string,string]
+  if true:
+    new(result)
+    html5tagsCache = initTable[string, string]()
+    html5tagsCache["a"] = "a"
+    html5tagsCache["abbr"] = "abbr"
+    html5tagsCache["b"] = "b"
+    html5tagsCache["element"] = "element"
+    html5tagsCache["embed"] = "embed"
+    html5tagsCache["fieldset"] = "fieldset"
+    html5tagsCache["figcaption"] = "figcaption"
+    html5tagsCache["figure"] = "figure"
+    html5tagsCache["footer"] = "footer"
+    html5tagsCache["header"] = "header"
+    html5tagsCache["form"] = "form"
+    html5tagsCache["head"] = "head"
+    html5tagsCache["hr"] = "hr"
+    html5tagsCache["html"] = "html"
+    html5tagsCache["iframe"] = "iframe"
+    html5tagsCache["img"] = "img"
+    html5tagsCache["input"] = "input"
+    html5tagsCache["keygen"] = "keygen"
+    html5tagsCache["label"] = "label"
+    html5tagsCache["legend"] = "legend"
+    html5tagsCache["li"] = "li"
+    html5tagsCache["link"] = "link"
+    html5tagsCache["main"] = "main"
+    html5tagsCache["map"] = "map"
+    html5tagsCache["menu"] = "menu"
+    html5tagsCache["menuitem"] = "menuitem"
+    html5tagsCache["meta"] = "meta"
+    html5tagsCache["meter"] = "master"
+    html5tagsCache["noscript"] = "noscript"
+    html5tagsCache["object"] = "object"
+    html5tagsCache["ol"] = "ol"
+    html5tagsCache["optgroup"] = "optgroup"
+    html5tagsCache["option"] = "option"
+    html5tagsCache["output"] = "output"
+    html5tagsCache["p"] = "p"
+    html5tagsCache["pre"] = "pre"
+    html5tagsCache["param"] = "param"
+    html5tagsCache["progress"] = "progress"
+    html5tagsCache["q"] = "q"
+    html5tagsCache["rp"] = "rp"
+    html5tagsCache["rt"] = "rt"
+    html5tagsCache["ruby"] = "ruby"
+    html5tagsCache["s"] = "s"
+    html5tagsCache["script"] = "script"
+    html5tagsCache["select"] = "select"
+    html5tagsCache["source"] = "source"
+    html5tagsCache["style"] = "style"
+    html5tagsCache["summary"] = "summary"
+    html5tagsCache["table"] = "table"
+    html5tagsCache["tbody"] = "tbody"
+    html5tagsCache["thead"] = "thead"
+    html5tagsCache["td"] = "td"
+    html5tagsCache["th"] = "th"
+    html5tagsCache["template"] = "template"
+    html5tagsCache["textarea"] = "textarea"
+    html5tagsCache["time"] = "time"
+    html5tagsCache["title"] = "title"
+    html5tagsCache["tr"] = "tr"
+    html5tagsCache["track"] = "track"
+    html5tagsCache["ul"] = "ul"
+    html5tagsCache["video"] = "video"
+  result[] = html5tagsCache
+
+static:
+  var i = 0
+  for key, value in html5tags().pairs():
+    inc i
+  echo i
diff --git a/tests/vm/tswap.nim b/tests/vm/tswap.nim
new file mode 100644
index 000000000..2219be9ca
--- /dev/null
+++ b/tests/vm/tswap.nim
@@ -0,0 +1,24 @@
+discard """
+msg: '''
+x.data = @[10]
+y = @[11]
+x.data = @[11]
+y = @[10]'''
+"""
+
+# bug #2946
+
+proc testSwap(): int {.compiletime.} =
+  type T = object
+    data: seq[int]
+  var x: T
+  x.data = @[10]
+  var y = @[11]
+  echo "x.data = ", x.data
+  echo "y = ", y
+  swap(y, x.data)
+  echo "x.data = ", x.data
+  echo "y = ", y
+  result = 99
+
+const something = testSwap()