mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-11 22:08:54 +00:00
Fixed state optimizer. It did not replace deleted states in `excLandingState`.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user