mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
* 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>
(cherry picked from commit d4c2e2c53f)
This commit is contained in:
@@ -247,6 +247,8 @@ proc freeTemp(c: PCtx; r: TRegister) =
|
||||
proc getTempRange(cc: PCtx; n: int; kind: TSlotKind): TRegister =
|
||||
# if register pressure is high, we re-use more aggressively:
|
||||
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):
|
||||
for i in 0..c.maxSlots-n:
|
||||
if not c.slots[i].inUse:
|
||||
@@ -1508,14 +1510,14 @@ proc genAsgn(c: PCtx; le, ri: PNode; requiresCopy: bool) =
|
||||
let tmp = c.genx(ri)
|
||||
c.preventFalseAlias(le[0], opcWrObj, objR, idx, tmp)
|
||||
c.freeTemp(tmp)
|
||||
c.freeTemp(idx)
|
||||
# c.freeTemp(idx) # BUGFIX, see nkDotExpr
|
||||
c.freeTemp(objR)
|
||||
of nkDotExpr:
|
||||
let dest = c.genx(le[0], {gfNode})
|
||||
let idx = genField(c, le[1])
|
||||
let tmp = c.genx(ri)
|
||||
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(dest)
|
||||
of nkDerefExpr, nkHiddenDeref:
|
||||
|
||||
@@ -281,3 +281,133 @@ block: # bug #8007
|
||||
# OK with seq & object variants
|
||||
const d = @[Cost(kind: Fixed, cost: 999), Cost(kind: Dynamic, handler: foo)]
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user