diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-04-04 10:16:15 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-04-04 10:16:15 +0200 |
commit | cbcdf12d2c78de352d3f5149882cca2b0b72522d (patch) | |
tree | f940df0fdf1c3b60481d39a9dd9a8c246ffe33fb | |
parent | 0acdaea3342e13317ac9956add08e606208b2986 (diff) | |
download | Nim-cbcdf12d2c78de352d3f5149882cca2b0b72522d.tar.gz |
fixes #3731
-rw-r--r-- | compiler/vm.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 14 | ||||
-rw-r--r-- | tests/vm/tmitems.nim | 15 |
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() |