Skip to content

Commit a7db22d

Browse files
committed
Fixes #21235, fixes #23602, fixes #24978, fixes #25018
1 parent 4263a51 commit a7db22d

File tree

3 files changed

+668
-628
lines changed

3 files changed

+668
-628
lines changed

compiler/closureiters.nim

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ type
159159
fn: PSym
160160
tmpResultSym: PSym # Used when we return, but finally has to interfere
161161
finallyPathSym: PSym
162-
curExcSym: PSym # Current exception
162+
curExcLevelSym: PSym # Current exception
163163

164164
# states: seq[tuple[label: PNode, body: PNode, inlinable: bool]] # The resulting states. Label is int literal.
165165
states: seq[State] # The resulting states. Label is int literal.
@@ -246,10 +246,10 @@ proc newFinallyPathAssign(ctx: var Ctx, level: int, label: PNode, info: TLineInf
246246
let fp = newFinallyPathAccess(ctx, level, info)
247247
result = newTree(nkAsgn, fp, label)
248248

249-
proc newCurExcAccess(ctx: var Ctx): PNode =
250-
if ctx.curExcSym.isNil:
251-
ctx.curExcSym = ctx.newEnvVar(":curExc", ctx.g.callCodegenProc("getCurrentException").typ)
252-
ctx.newEnvVarAccess(ctx.curExcSym)
249+
proc newCurExcLevelAccess(ctx: var Ctx): PNode =
250+
if ctx.curExcLevelSym.isNil:
251+
ctx.curExcLevelSym = ctx.newEnvVar(":curExcLevel", ctx.g.getSysType(ctx.fn.info, tyInt16))
252+
ctx.newEnvVarAccess(ctx.curExcLevelSym)
253253

254254
proc newStateLabel(ctx: Ctx): PNode =
255255
ctx.g.newIntLit(TLineInfo(), 0)
@@ -310,13 +310,24 @@ proc hasYields(n: PNode): bool =
310310
result = true
311311
break
312312

313-
proc newNullifyCurExc(ctx: var Ctx, info: TLineInfo): PNode =
314-
# :curEcx = nil
315-
let curExc = ctx.newCurExcAccess()
313+
proc newNullifyCurExcLevel(ctx: var Ctx, info: TLineInfo, decrement = false): PNode =
314+
# :curEcx = 0
315+
let curExc = ctx.newCurExcLevelAccess()
316316
curExc.info = info
317-
let nilnode = newNodeIT(nkNilLit, info, curExc.typ)
317+
let nilnode = ctx.g.newIntLit(info, 0)
318318
result = newTree(nkAsgn, curExc, nilnode)
319319

320+
proc newChangeCurExcLevel(ctx: var Ctx, info: TLineInfo, by: int): PNode =
321+
# inc :curEcx
322+
let curExc = ctx.newCurExcLevelAccess()
323+
curExc.info = info
324+
# let nilnode = newNodeIT(nkNilLit, info, curExc.typ)
325+
# result = newTree(nkAsgn, curExc, nilnode)
326+
327+
result = newTreeIT(nkCall, info, ctx.g.getSysType(info, tyVoid),
328+
newSymNode(ctx.g.getSysMagic(info, "inc", mInc)), curExc,
329+
ctx.g.newIntLit(info, by))
330+
320331
proc newOr(g: ModuleGraph, a, b: PNode): PNode {.inline.} =
321332
result = newTreeIT(nkCall, a.info, g.getSysType(a.info, tyBool),
322333
newSymNode(g.getSysMagic(a.info, "or", mOr)), a, b)
@@ -389,7 +400,7 @@ proc addElseToExcept(ctx: var Ctx, n, gotoOut: PNode) =
389400

390401
n.add newTree(nkCall,
391402
newSymNode(ctx.g.getCompilerProc("popCurrentException")))
392-
n.add(ctx.newNullifyCurExc(n.info))
403+
n.add(ctx.newChangeCurExcLevel(n.info, -1))
393404
if gotoOut != nil:
394405
n.add(ctx.newFinallyPathAssign(ctx.curFinallyLevel - 1, gotoOut[0], n.info))
395406

@@ -891,13 +902,13 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
891902
nextState,
892903
ctx.g.newIntLit(info, 0))
893904

894-
let curExc = ctx.newCurExcAccess()
895-
let nilnode = newNodeIT(nkNilLit, info, curExc.typ)
905+
let curExc = ctx.newCurExcLevelAccess()
906+
# let nilnode = newNodeIT(nkNilLit, info, curExc.typ)
896907
let excNilCmp = newTreeIT(nkCall,
897908
info, ctx.g.getSysType(info, tyBool),
898-
newSymNode(ctx.g.getSysMagic(info, "==", mEqRef), info),
909+
newSymNode(ctx.g.getSysMagic(info, "==", mEqI), info),
899910
curExc,
900-
nilnode)
911+
ctx.g.newIntLit(info, 0))
901912

902913
let retStmt =
903914
block:
@@ -917,7 +928,7 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
917928
newTree(nkElse,
918929
newTree(nkStmtList,
919930
# newTreeI(nkCall, info, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode),
920-
newTreeI(nkRaiseStmt, info, curExc))))
931+
newTreeI(nkRaiseStmt, info, ctx.g.emptyNode))))
921932

922933
result = newTree(nkIfStmt,
923934
newTreeI(nkElifBranch, info, cmpStateToZero, ifBody),
@@ -1000,7 +1011,7 @@ proc transformReturnStmt(ctx: var Ctx, n: PNode): PNode =
10001011
# debug(n[0])
10011012

10021013
result = newNodeI(nkStmtList, n.info)
1003-
result.add(ctx.newNullifyCurExc(n.info))
1014+
result.add(ctx.newNullifyCurExcLevel(n.info))
10041015

10051016
var finallyChain = newSeq[PNode]()
10061017
@@ -1428,10 +1439,10 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
14281439
# result.add(ifStmt)
14291440

14301441
# :curExc = getCurrentException()
1431-
block:
1432-
result.add(newTree(nkAsgn,
1433-
ctx.newCurExcAccess(),
1434-
ctx.g.callCodegenProc("getCurrentException")))
1442+
# block:
1443+
# result.add(newTree(nkAsgn,
1444+
# ctx.newCurExcAccess(),
1445+
# ctx.g.callCodegenProc("getCurrentException")))
14351446

14361447
proc wrapIntoTryExcept(ctx: var Ctx, n: PNode): PNode {.inline.} =
14371448
# let setupExc = newTree(nkCall,
@@ -1454,6 +1465,8 @@ proc wrapIntoTryExcept(ctx: var Ctx, n: PNode): PNode {.inline.} =
14541465
exceptBody.add ctx.newTempVarAsgn(tempExc, getCurExc)
14551466

14561467
result.add newTree(nkCall, newSymNode(ctx.g.getCompilerProc("pushCurrentException")), ctx.newTempVarAccess(tempExc))
1468+
result.add ctx.newChangeCurExcLevel(n.info, 1)
1469+
14571470
# result = newTree(nkTryStmt, tryBody, exceptBranch)
14581471

14591472
proc wrapIntoStateLoop(ctx: var Ctx, n: PNode): PNode =
@@ -1648,7 +1661,7 @@ proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n:
16481661
result = wrapIntoStateLoop(ctx, caseDispatcher)
16491662
result = liftLocals(ctx, result)
16501663

1651-
when true:
1664+
when false:
16521665
echo "TRANSFORM TO STATES: "
16531666
echo renderTree(result)
16541667

tests/async/t23602.nim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import std/asyncdispatch
2+
3+
proc errval {.async.} =
4+
raise newException(ValueError, "err")
5+
6+
proc err {.async.} =
7+
try:
8+
doAssert false
9+
finally:
10+
echo "finally"
11+
# removing the following code will propagate the AssertionDefect
12+
try:
13+
await errval()
14+
except ValueError:
15+
echo "valueError"
16+
17+
proc main {.async.} =
18+
let errFut = err()
19+
await errFut
20+
21+
var ok = false
22+
try:
23+
waitFor main()
24+
except AssertionDefect:
25+
ok = true
26+
27+
doAssert(ok)

0 commit comments

Comments
 (0)