* fix #15704 #15597 wrong VM register was freed * same treatment for nkCheckedFieldExpr * note concerning HighRegisterPressure * bump NimPatch * Update lib/system.nim Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
b56a037183
commit
d4c2e2c53f
2 changed files with 134 additions and 2 deletions
|
|
@ -247,6 +247,8 @@ proc freeTemp(c: PCtx; r: TRegister) =
|
||||||
proc getTempRange(cc: PCtx; n: int; kind: TSlotKind): TRegister =
|
proc getTempRange(cc: PCtx; n: int; kind: TSlotKind): TRegister =
|
||||||
# if register pressure is high, we re-use more aggressively:
|
# if register pressure is high, we re-use more aggressively:
|
||||||
let c = cc.prc
|
let c = cc.prc
|
||||||
|
# we could also customize via the following (with proper caching in ConfigRef):
|
||||||
|
# let highRegisterPressure = cc.config.getConfigVar("vm.highRegisterPressure", "40").parseInt
|
||||||
if c.maxSlots >= HighRegisterPressure or c.maxSlots+n >= high(TRegister):
|
if c.maxSlots >= HighRegisterPressure or c.maxSlots+n >= high(TRegister):
|
||||||
for i in 0..c.maxSlots-n:
|
for i in 0..c.maxSlots-n:
|
||||||
if not c.slots[i].inUse:
|
if not c.slots[i].inUse:
|
||||||
|
|
@ -1508,14 +1510,14 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
|
||||||
let tmp = c.genx(ri)
|
let tmp = c.genx(ri)
|
||||||
c.preventFalseAlias(le[0], opcWrObj, objR, idx, tmp)
|
c.preventFalseAlias(le[0], opcWrObj, objR, idx, tmp)
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
c.freeTemp(idx)
|
# c.freeTemp(idx) # BUGFIX, see nkDotExpr
|
||||||
c.freeTemp(objR)
|
c.freeTemp(objR)
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
let dest = c.genx(le[0], {gfNode})
|
let dest = c.genx(le[0], {gfNode})
|
||||||
let idx = genField(c, le[1])
|
let idx = genField(c, le[1])
|
||||||
let tmp = c.genx(ri)
|
let tmp = c.genx(ri)
|
||||||
c.preventFalseAlias(le, opcWrObj, dest, idx, tmp)
|
c.preventFalseAlias(le, opcWrObj, dest, idx, tmp)
|
||||||
c.freeTemp(idx)
|
# c.freeTemp(idx) # BUGFIX: idx is an immediate (field position), not a register
|
||||||
c.freeTemp(tmp)
|
c.freeTemp(tmp)
|
||||||
c.freeTemp(dest)
|
c.freeTemp(dest)
|
||||||
of nkDerefExpr, nkHiddenDeref:
|
of nkDerefExpr, nkHiddenDeref:
|
||||||
|
|
|
||||||
|
|
@ -281,3 +281,133 @@ block: # bug #8007
|
||||||
# OK with seq & object variants
|
# OK with seq & object variants
|
||||||
const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
|
const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
|
||||||
doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
|
doAssert $d == "@[(kind: Fixed, cost: 999), (kind: Dynamic, handler: ...)]"
|
||||||
|
|
||||||
|
block: # VM wrong register free causes errors in unrelated code
|
||||||
|
block: # bug #15597
|
||||||
|
#[
|
||||||
|
Error: unhandled exception: 'sym' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect]
|
||||||
|
in /Users/timothee/git_clone/nim/Nim_prs/compiler/vm.nim(1176) rawExecute
|
||||||
|
in opcIndCall
|
||||||
|
in let prc = if not isClosure: bb.sym else: bb[0].sym
|
||||||
|
]#
|
||||||
|
proc bar2(head: string): string = "asdf"
|
||||||
|
proc gook(u1: int) = discard
|
||||||
|
|
||||||
|
type PathEntry = object
|
||||||
|
kind: int
|
||||||
|
path: string
|
||||||
|
|
||||||
|
iterator globOpt(): int =
|
||||||
|
var u1: int
|
||||||
|
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
gook(u1)
|
||||||
|
|
||||||
|
var entry = PathEntry()
|
||||||
|
entry.path = bar2("")
|
||||||
|
if false:
|
||||||
|
echo "here2"
|
||||||
|
|
||||||
|
proc processAux(a: float) = discard
|
||||||
|
|
||||||
|
template bar(iter: untyped): untyped =
|
||||||
|
var ret: float
|
||||||
|
for x in iter: break
|
||||||
|
ret
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
processAux(bar(globOpt()))
|
||||||
|
static: main()
|
||||||
|
|
||||||
|
block: # ditto
|
||||||
|
# D20201024T133245
|
||||||
|
type Deque = object
|
||||||
|
proc initDeque2(initialSize: int = 4): Deque = Deque()
|
||||||
|
proc len2(a: Deque): int = 2
|
||||||
|
proc baz(dir: string): bool = true
|
||||||
|
proc bar2(head: string): string = "asdf"
|
||||||
|
proc bar3(path: var string) = path = path
|
||||||
|
|
||||||
|
type PathEntry = object
|
||||||
|
kind: int
|
||||||
|
path: string
|
||||||
|
|
||||||
|
proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string = dir
|
||||||
|
|
||||||
|
iterator globOpt(dir: string): int =
|
||||||
|
var stack = initDeque2()
|
||||||
|
doAssert baz("")
|
||||||
|
let z = stack.len2
|
||||||
|
if stack.len2 >= 0:
|
||||||
|
var entry = PathEntry()
|
||||||
|
let current = if true: stack.len2 else: stack.len2
|
||||||
|
entry.path = bar2("")
|
||||||
|
bar3(entry.path)
|
||||||
|
if false:
|
||||||
|
echo "here2" # comment here => you get same error as https://github.com/nim-lang/Nim/issues/15704
|
||||||
|
|
||||||
|
proc processAux(a: float) = discard
|
||||||
|
|
||||||
|
template bar(iter: untyped): untyped =
|
||||||
|
var ret: float
|
||||||
|
for x in iter: break
|
||||||
|
ret
|
||||||
|
proc main() =
|
||||||
|
processAux(bar(globOpt(initGlobOpt("."))))
|
||||||
|
static: main()
|
||||||
|
|
||||||
|
block: # bug #15704
|
||||||
|
#[
|
||||||
|
Error: attempt to access a nil address kind: rkFloat
|
||||||
|
]#
|
||||||
|
type Deque = object
|
||||||
|
proc initDeque2(initialSize: int = 4): Deque = Deque()
|
||||||
|
proc len2(a: Deque): int = 2
|
||||||
|
|
||||||
|
proc baz(dir: string): bool = true
|
||||||
|
proc bar2(head: string): string = "asdf"
|
||||||
|
proc bar3(path: var string) = path = path
|
||||||
|
|
||||||
|
type PathEntry = object
|
||||||
|
kind: int
|
||||||
|
path: string
|
||||||
|
depth: int
|
||||||
|
|
||||||
|
proc initGlobOpt(dir: string, a1=false,a2=false,a3=false,a4=false): string =
|
||||||
|
dir
|
||||||
|
|
||||||
|
iterator globOpt(dir: string): int =
|
||||||
|
var stack = initDeque2()
|
||||||
|
doAssert baz("")
|
||||||
|
let z = stack.len2
|
||||||
|
var a5: int
|
||||||
|
if stack.len2 >= 0:
|
||||||
|
var entry = PathEntry()
|
||||||
|
if false:
|
||||||
|
echo "here"
|
||||||
|
let current = if true: stack.len2 else: stack.len2
|
||||||
|
entry.depth = 1
|
||||||
|
entry.path = bar2("")
|
||||||
|
bar3(entry.path)
|
||||||
|
proc processAux(a: float) = discard
|
||||||
|
template bar(iter: untyped): untyped =
|
||||||
|
var ret: float
|
||||||
|
for x in iter:
|
||||||
|
break
|
||||||
|
ret
|
||||||
|
const dir = "."
|
||||||
|
proc main() =
|
||||||
|
processAux(bar(globOpt(initGlobOpt(dir))))
|
||||||
|
static: main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue