summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-04-04 10:16:15 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-04-04 10:16:15 +0200
commitcbcdf12d2c78de352d3f5149882cca2b0b72522d (patch)
treef940df0fdf1c3b60481d39a9dd9a8c246ffe33fb
parent0acdaea3342e13317ac9956add08e606208b2986 (diff)
downloadNim-cbcdf12d2c78de352d3f5149882cca2b0b72522d.tar.gz
fixes #3731
-rw-r--r--compiler/vm.nim2
-rw-r--r--compiler/vmgen.nim14
-rw-r--r--tests/vm/tmitems.nim15
3 files changed, 27 insertions, 4 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim
index 1235a648d..f799334d6 100644
--- a/compiler/vm.nim
+++ b/compiler/vm.nim
@@ -545,7 +545,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
         if regs[rb].node.kind == nkRefTy:
           regs[ra].node = regs[rb].node.sons[0]
         else:
-          stackTrace(c, tos, pc, errGenerated, "limited VM support for 'ref'")
+          stackTrace(c, tos, pc, errGenerated, "limited VM support for pointers")
       else:
         stackTrace(c, tos, pc, errNilAccess)
     of opcWrDeref:
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 038a07a16..019c79eb3 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -103,7 +103,7 @@ proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
                            (b.uint32 shl 16'u32) or
                            (c.uint32 shl 24'u32)).TInstr
   when false:
-    if ctx.code.len == 72:
+    if ctx.code.len == 43:
       writeStackTrace()
       echo "generating ", opc
   ctx.code.add(ins)
@@ -126,6 +126,11 @@ proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: BiggestInt) =
 proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
   # Applies `opc` to `bx` and stores it into register `a`
   # `bx` must be signed and in the range [-32768, 32767]
+  when false:
+    if c.code.len == 43:
+      writeStackTrace()
+      echo "generating ", opc
+
   if bx >= -32768 and bx <= 32767:
     let ins = (opc.uint32 or a.uint32 shl 8'u32 or
               (bx+wordExcess).uint32 shl 16'u32).TInstr
@@ -1125,7 +1130,10 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
   if isAddr and (let m = canElimAddr(n); m != nil):
     gen(c, m, dest, flags)
     return
-  let newflags = if isAddr: flags+{gfAddrOf} else: flags
+
+  let af = if n[0].kind in {nkBracketExpr, nkDotExpr, nkCheckedFieldExpr}: {gfAddrOf, gfFieldAccess}
+           else: {gfAddrOf}
+  let newflags = if isAddr: flags+af else: flags
   # consider:
   # proc foo(f: var ref int) =
   #   f = new(int)
@@ -1140,7 +1148,7 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
     if gfAddrOf notin flags and fitsRegister(n.typ):
       c.gABC(n, opcNodeToReg, dest, dest)
   elif isAddr and isGlobal(n.sons[0]):
-    gen(c, n.sons[0], dest, flags+{gfAddrOf})
+    gen(c, n.sons[0], dest, flags+af)
   else:
     let tmp = c.genx(n.sons[0], newflags)
     if dest < 0: dest = c.getTemp(n.typ)
diff --git a/tests/vm/tmitems.nim b/tests/vm/tmitems.nim
new file mode 100644
index 000000000..18f5bfa06
--- /dev/null
+++ b/tests/vm/tmitems.nim
@@ -0,0 +1,15 @@
+discard """
+  msg: '''13'''
+"""
+# bug #3731
+var list {.compileTime.} = newSeq[int]()
+
+macro calc*(): stmt {.immediate.} =
+  list.add(1)
+  for c in list.mitems:
+    c = 13
+
+  for c in list:
+    echo c
+
+calc()