Fixed state optimizer. It did not replace deleted states in
`excLandingState`.
This commit is contained in:
Yuriy Glukhov
2025-12-05 15:27:38 +01:00
committed by GitHub
parent 0ea5f2625c
commit 8f8814b495
2 changed files with 60 additions and 10 deletions

View File

@@ -1307,16 +1307,15 @@ proc countStateOccurences(ctx: var Ctx, n: PNode, stateOccurences: var openArray
proc replaceDeletedStates(ctx: var Ctx, n: PNode): PNode =
result = n
for i in 0 ..< n.safeLen:
let c = n[i]
if c.kind == nkIntLit:
let idx = c.intVal
if idx >= 0 and idx < ctx.states.len and ctx.states[idx].label == c and ctx.states[idx].deletable:
let gt = ctx.replaceDeletedStates(skipStmtList(ctx.states[idx].body))
assert(gt.kind == nkGotoState)
n[i] = gt[0]
else:
n[i] = ctx.replaceDeletedStates(c)
if n.kind == nkIntLit:
let idx = n.intVal
if idx >= 0 and idx < ctx.states.len and ctx.states[idx].label == n and ctx.states[idx].deletable:
let gt = ctx.replaceDeletedStates(skipStmtList(ctx.states[idx].body))
assert(gt.kind == nkGotoState)
result = gt[0]
else:
for i in 0 ..< n.safeLen:
n[i] = ctx.replaceDeletedStates(n[i])
proc replaceInlinedStates(ctx: var Ctx, n: PNode): PNode =
## Find all nkGotoState(stateIdx) nodes that do not follow nkYield.
@@ -1347,6 +1346,7 @@ proc optimizeStates(ctx: var Ctx) =
# Replace deletable state labels to labels of respective non-empty states
for i in 0 .. ctx.states.high:
ctx.states[i].body = ctx.replaceDeletedStates(ctx.states[i].body)
ctx.states[i].excLandingState = ctx.replaceDeletedStates(ctx.states[i].excLandingState)
# Remove deletable states
var i = 0

View File

@@ -17,9 +17,12 @@ proc testClosureIterAux(it: iterator(): int, exceptionExpected: bool, expectedRe
var exceptionCaught = false
var maxIterations = 10000
try:
for i in it():
closureIterResult.add(i)
dec maxIterations
doAssert(maxIterations > 0, "Too many iterations in test. Infinite loop?")
except TestError:
exceptionCaught = true
@@ -847,3 +850,50 @@ block:
doAssert(w() == 123)
doAssert(getCurrentExceptionMsg() == "Outer error")
doAssert(getCurrentExceptionMsg() == "")
block: #25330 (v1)
iterator count1(): int {.closure.} =
yield 1
raiseTestError()
iterator count0(): int {.closure.} =
try:
var count = count1
while true:
yield count()
if finished(count): break
finally:
try:
checkpoint(2)
var count2 = count1
while true:
yield count2()
if finished(count2): break
discard # removing this outputs "raise"
except:
checkpoint(3)
raise
testExc(count0, 1, 2, 1, 3)
block: #25330 (v2)
iterator count1(): int {.closure.} =
yield 1
raiseTestError()
iterator count0(): int {.closure.} =
try:
var count = count1
for x in 0 .. 10:
yield count()
finally:
try:
checkpoint(2)
var count2 = count1
for x in 0 .. 10:
yield count2()
except:
checkpoint(3)
raise
testExc(count0, 1, 2, 1, 3)