diff --git a/compiler/vm.nim b/compiler/vm.nim index 0c2c23987b..7f5e0d1c53 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -138,6 +138,9 @@ proc createStrKeepNode(x: var TFullReg) = template createStr(x) = x.node = newNode(nkStrLit) +template createSet(x) = + x.node = newNode(nkCurly) + proc moveConst(x: var TFullReg, y: TFullReg) = if x.kind != y.kind: myreset(x) @@ -722,18 +725,22 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].intVal = ord(containsSets(a, b) and not equalSets(a, b)) of opcMulSet: decodeBC(rkNode) + createSet(regs[ra]) move(regs[ra].node.sons, nimsets.intersectSets(regs[rb].node, regs[rc].node).sons) of opcPlusSet: decodeBC(rkNode) + createSet(regs[ra]) move(regs[ra].node.sons, nimsets.unionSets(regs[rb].node, regs[rc].node).sons) of opcMinusSet: decodeBC(rkNode) + createSet(regs[ra]) move(regs[ra].node.sons, nimsets.diffSets(regs[rb].node, regs[rc].node).sons) of opcSymdiffSet: decodeBC(rkNode) + createSet(regs[ra]) move(regs[ra].node.sons, nimsets.symdiffSets(regs[rb].node, regs[rc].node).sons) of opcConcatStr: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 3819bed98a..28e0a8fd6e 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -14,7 +14,12 @@ # assignments ('x = y'). For simple data types that fit into a register # this doesn't matter. However it matters for strings and other complex # types that use the 'node' field; the reason is that slots are -# re-used in a register based VM. XXX Come up with an example. +# re-used in a register based VM. Example: +# +# .. code-block:: nimrod +# let s = a & b # no matter what, create fresh node +# s = a & b # no matter what, keep the node +# import unsigned, strutils, ast, astalgo, types, msgs, renderer, vmdef, @@ -1335,6 +1340,8 @@ proc genVarSection(c: PCtx; n: PNode) = if a.sons[2].kind == nkEmpty: c.gABx(a, ldNullOpcode(s.typ), s.position, c.genType(s.typ)) else: + if not fitsRegister(s.typ): + c.gABx(a, ldNullOpcode(s.typ), s.position, c.genType(s.typ)) gen(c, a.sons[2], s.position.TRegister) else: # assign to a.sons[0]; happens for closures diff --git a/tests/vm/teval1.nim b/tests/vm/teval1.nim index a02f26592f..cdb4ad8e2b 100644 --- a/tests/vm/teval1.nim +++ b/tests/vm/teval1.nim @@ -16,4 +16,9 @@ const echo "##", x, "##" +# bug #1310 +static: + var i, j: set[int8] = {} + var k = i + j +