fixes #3731
This commit is contained in:
parent
0acdaea334
commit
cbcdf12d2c
3 changed files with 27 additions and 4 deletions
|
|
@ -545,7 +545,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
if regs[rb].node.kind == nkRefTy:
|
if regs[rb].node.kind == nkRefTy:
|
||||||
regs[ra].node = regs[rb].node.sons[0]
|
regs[ra].node = regs[rb].node.sons[0]
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errGenerated, "limited VM support for 'ref'")
|
stackTrace(c, tos, pc, errGenerated, "limited VM support for pointers")
|
||||||
else:
|
else:
|
||||||
stackTrace(c, tos, pc, errNilAccess)
|
stackTrace(c, tos, pc, errNilAccess)
|
||||||
of opcWrDeref:
|
of opcWrDeref:
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
|
||||||
(b.uint32 shl 16'u32) or
|
(b.uint32 shl 16'u32) or
|
||||||
(c.uint32 shl 24'u32)).TInstr
|
(c.uint32 shl 24'u32)).TInstr
|
||||||
when false:
|
when false:
|
||||||
if ctx.code.len == 72:
|
if ctx.code.len == 43:
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
echo "generating ", opc
|
echo "generating ", opc
|
||||||
ctx.code.add(ins)
|
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) =
|
proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
|
||||||
# Applies `opc` to `bx` and stores it into register `a`
|
# Applies `opc` to `bx` and stores it into register `a`
|
||||||
# `bx` must be signed and in the range [-32768, 32767]
|
# `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:
|
if bx >= -32768 and bx <= 32767:
|
||||||
let ins = (opc.uint32 or a.uint32 shl 8'u32 or
|
let ins = (opc.uint32 or a.uint32 shl 8'u32 or
|
||||||
(bx+wordExcess).uint32 shl 16'u32).TInstr
|
(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):
|
if isAddr and (let m = canElimAddr(n); m != nil):
|
||||||
gen(c, m, dest, flags)
|
gen(c, m, dest, flags)
|
||||||
return
|
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:
|
# consider:
|
||||||
# proc foo(f: var ref int) =
|
# proc foo(f: var ref int) =
|
||||||
# f = new(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):
|
if gfAddrOf notin flags and fitsRegister(n.typ):
|
||||||
c.gABC(n, opcNodeToReg, dest, dest)
|
c.gABC(n, opcNodeToReg, dest, dest)
|
||||||
elif isAddr and isGlobal(n.sons[0]):
|
elif isAddr and isGlobal(n.sons[0]):
|
||||||
gen(c, n.sons[0], dest, flags+{gfAddrOf})
|
gen(c, n.sons[0], dest, flags+af)
|
||||||
else:
|
else:
|
||||||
let tmp = c.genx(n.sons[0], newflags)
|
let tmp = c.genx(n.sons[0], newflags)
|
||||||
if dest < 0: dest = c.getTemp(n.typ)
|
if dest < 0: dest = c.getTemp(n.typ)
|
||||||
|
|
|
||||||
15
tests/vm/tmitems.nim
Normal file
15
tests/vm/tmitems.nim
Normal file
|
|
@ -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()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue