Skip to content

Commit 061f354

Browse files
committed
ok
1 parent ebc6e2c commit 061f354

File tree

2 files changed

+68
-26
lines changed

2 files changed

+68
-26
lines changed

compiler/closureiters.nim

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@
108108
# yield 0
109109
# raise ...
110110
# :finallyPath[LEVEL] = 3 # Exception did not happen. Our finally can continue to state 3
111-
# :state = 2 # And we continue to our finally
111+
# :state = 2 # And we continue to our finally
112112
# break :stateLoop
113113
# of 1: # Except
114+
# inc(:curExcLevel, -1) # Exception is caught
114115
# yield 1
115116
# :tmpResult = 3 # Return
116117
# :finalyPath[LEVEL] = 0 # Configure finally path.
117118
# :state = 2 # Goto Finally
118119
# break :stateLoop
120+
# popCurrentException() # XXX: This is likely wrong, see #25031
119121
# :state = 2 # What would happen should we not return
120122
# break :stateLoop
121123
# of 2: # Finally
@@ -140,8 +142,6 @@ import
140142
renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos,
141143
options
142144

143-
import astalgo
144-
145145
import std/tables
146146

147147
when defined(nimPreviewSlimSystem):
@@ -344,12 +344,10 @@ proc collectExceptState(ctx: var Ctx, n: PNode): PNode {.inline.} =
344344
else:
345345
ifBranch = newNodeI(nkElse, c.info)
346346

347-
ifBranch.add(c[^1])
347+
ifBranch.add(newTreeI(nkStmtList, c.info, ctx.newChangeCurExcLevel(c.info, -1), c[^1]))
348348
ifStmt.add(ifBranch)
349349

350350
if ifStmt.len != 0:
351-
# let setupExc = newTree(nkCall, newSymNode(ctx.g.getCompilerProc("pushCurrentException")), ctx.newCurExcAccess())
352-
# result = newTree(nkStmtList, ctx.newNullifyCurExc(n.info), ifStmt)
353351
result = newTree(nkStmtList, ifStmt)
354352
else:
355353
result = ctx.g.emptyNode
@@ -361,14 +359,24 @@ proc addElseToExcept(ctx: var Ctx, n, gotoOut: PNode) =
361359
if n[0].kind == nkIfStmt and n[0][^1].kind != nkElse:
362360
# Not all cases are covered, which means exception is not handled
363361
# and we should go to parent exception landing state
362+
let action =
363+
if ctx.curFinallyLevel == 0:
364+
# There is no suitable finally around. We must reraise.
365+
newTreeI(nkRaiseStmt, n.info, ctx.g.emptyNode)
366+
else:
367+
# Jump to finally.
368+
newTree(nkGotoState, ctx.curExcLandingState)
369+
364370
n[0].add(newTree(nkElse,
365-
newTreeI(nkStmtList, n.info,
366-
newTree(nkGotoState, ctx.curExcLandingState))))
371+
newTreeI(nkStmtList, n.info, action)))
367372

368373
# Exception is handled
374+
# XXX: This is likely wrong. See #25031. We must clear exception not only here
375+
# at the end of except but also when except flow is interrupted with break or return
376+
# and if there's a raise in except flow, current exception must be replaced with the
377+
# raised one.
369378
n.add newTree(nkCall,
370379
newSymNode(ctx.g.getCompilerProc("popCurrentException")))
371-
n.add(ctx.newChangeCurExcLevel(n.info, -1))
372380
if gotoOut != nil:
373381
# We have a finally node following this except block, and exception is handled
374382
# Configure its path to continue normally
@@ -848,7 +856,6 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
848856
newTree(nkElifBranch, excNilCmp, retStmt),
849857
newTree(nkElse,
850858
newTree(nkStmtList,
851-
# newTreeI(nkCall, info, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode),
852859
newTreeI(nkRaiseStmt, info, ctx.g.emptyNode))))
853860

854861
result = newTree(nkIfStmt,
@@ -1496,7 +1503,7 @@ proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n:
14961503
result = wrapIntoStateLoop(ctx, caseDispatcher)
14971504
result = liftLocals(ctx, result)
14981505

1499-
when true:
1506+
when false:
15001507
echo "TRANSFORM TO STATES:"
15011508
echo renderTree(result)
15021509

tests/iter/tyieldintry.nim

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -182,21 +182,56 @@ block:
182182

183183
test(it, 0, 1, 2, 3)
184184

185-
# block: # Return in except with no finallies around
186-
# iterator it(): int {.closure.} =
187-
# try:
188-
# try:
189-
# yield 0
190-
# raiseTestError()
191-
# finally:
192-
# checkpoint(1)
193-
# except ValueError:
194-
# yield 2
195-
# return
196-
197-
# checkpoint(123)
198-
199-
# test(it, 0, 1, 2)
185+
block: # Wrong except
186+
iterator it(): int {.closure.} =
187+
try:
188+
try:
189+
yield 0
190+
raiseTestError()
191+
except ValueError:
192+
doAssert(false, "Unreachable")
193+
finally:
194+
checkpoint(1)
195+
except ValueError:
196+
yield 123
197+
return
198+
199+
checkpoint(123)
200+
201+
testExc(it, 0, 1)
202+
203+
block: # Nexted except without finally
204+
iterator it(): int {.closure.} =
205+
try:
206+
try:
207+
yield 0
208+
raiseTestError()
209+
except ValueError:
210+
doAssert(false, "Unreachable")
211+
except ValueError:
212+
yield 123
213+
214+
checkpoint(123)
215+
216+
testExc(it, 0)
217+
218+
block: # Return in except with no finallies around
219+
iterator it(): int {.closure.} =
220+
try:
221+
try:
222+
yield 0
223+
raiseTestError()
224+
except ValueError:
225+
doAssert(false, "Unreachable")
226+
finally:
227+
checkpoint(1)
228+
except TestError:
229+
yield 2
230+
return
231+
232+
checkpoint(123)
233+
234+
test(it, 0, 1, 2)
200235

201236
block:
202237
iterator it(): int {.closure.} =

0 commit comments

Comments
 (0)