summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2014-12-28 00:42:24 +0100
committerAraq <rumpf_a@web.de>2014-12-28 00:42:24 +0100
commit41587a533959e4269be29f4f238d524048ac303a (patch)
tree30c53323f16acb2cb0599a0b999f4aaf63ea105a
parent010b8f85c73671782de956c9dcd2cb3e8441041e (diff)
downloadNim-41587a533959e4269be29f4f238d524048ac303a.tar.gz
fixes #1781
-rw-r--r--compiler/vmdef.nim3
-rw-r--r--compiler/vmgen.nim13
-rw-r--r--tests/vm/triangle_array.nim17
3 files changed, 27 insertions, 6 deletions
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index c06606318..3d49cb130 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -164,7 +164,8 @@ type
     slotTempInt,      # some temporary int
     slotTempFloat,    # some temporary float
     slotTempStr,      # some temporary string
-    slotTempComplex   # some complex temporary (s.node field is used)
+    slotTempComplex,  # some complex temporary (s.node field is used)
+    slotTempPerm      # slot is temporary but permanent (hack)
 
   PProc* = ref object
     blocks*: seq[TBlock]    # blocks; temp data structure
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index c4101874c..9a3fc260a 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -16,7 +16,7 @@
 #   types that use the 'node' field; the reason is that slots are
 #   re-used in a register based VM. Example:
 # 
-# .. code-block:: nimrod
+# .. code-block:: nim
 #   let s = a & b  # no matter what, create fresh node
 #   s = a & b  # no matter what, keep the node
 #
@@ -28,7 +28,7 @@
 # this copy depends on the involved types.
 
 import
-  unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, 
+  unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef,
   trees, intsets, rodread, magicsys, options, lowerings
 
 from os import splitFile
@@ -58,6 +58,7 @@ proc codeListing(c: PCtx, result: var string, start=0; last = -1) =
     if i in jumpTargets: result.addf("L$1:\n", i)
     let x = c.code[i]
 
+    result.add($i)
     let opc = opcode(x)
     if opc in {opcConv, opcCast}:
       let y = c.code[i+1]
@@ -188,7 +189,7 @@ proc getTemp(c: PCtx; typ: PType): TRegister =
 
 proc freeTemp(c: PCtx; r: TRegister) =
   let c = c.prc
-  if c.slots[r].kind >= slotSomeTemp: c.slots[r].inUse = false
+  if c.slots[r].kind in {slotSomeTemp..slotTempComplex}: c.slots[r].inUse = false
 
 proc getTempRange(c: PCtx; n: int; kind: TSlotKind): TRegister =
   # if register pressure is high, we re-use more aggressively:
@@ -1074,8 +1075,10 @@ proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode;
         c.gABC(n, opcNodeToReg, dest, dest)
     elif c.prc.slots[tmp].kind >= slotTempUnknown:
       gABC(c, n, opcAddrNode, dest, tmp)
-      # XXX this can still be wrong sometimes; hopefully it's only generated
-      # in call contexts, where it is safe
+      # hack ahead; in order to fix bug #1781 we mark the temporary as
+      # permanent, so that it's not used for anything else:
+      c.prc.slots[tmp].kind = slotTempPerm
+      # XXX this is still a hack
       #message(n.info, warnUser, "suspicious opcode used")
     else:
       gABC(c, n, opcAddrReg, dest, tmp)
diff --git a/tests/vm/triangle_array.nim b/tests/vm/triangle_array.nim
new file mode 100644
index 000000000..054c66f22
--- /dev/null
+++ b/tests/vm/triangle_array.nim
@@ -0,0 +1,17 @@
+discard """
+  output: "56"
+"""
+
+# bug #1781
+
+proc initCombinations: array[11, array[11, int]] =
+  result[0]          = [1,2,3,4,5,6,7,8,9,10,11]
+  result[1][1 .. 10] =   [12,13,14,15,16,17,18,19,20,21]
+  result[2][2 .. 10] =     [22,23,24,25,26,27,28,29,30]
+  result[3][3 .. 10] =       [31,32,33,34,35,36,37,38]
+  result[4][4 .. 10] =         [39,40,41,42,43,44,45]
+  result[5][5 .. 10] =           [46,47,48,49,50,51]
+  result[6][6 .. 10] =             [52,53,54,55,56]
+
+const combinations = initCombinations()
+echo combinations[6][10]