only store finally block in exception stack (#11876)

This commit is contained in:
Jacek Sieka 2019-08-28 12:08:54 +02:00 • committed by Andreas Rumpf
commit 42d2e68bca
2 changed files with 12 additions and 10 deletions

View file

@ -199,7 +199,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
# Called by return and break stmts. # Called by return and break stmts.
# Deals with issues faced when jumping out of try/except/finally stmts, # Deals with issues faced when jumping out of try/except/finally stmts,
var stack = newSeq[tuple[n: PNode, inExcept: bool]](0) var stack = newSeq[tuple[fin: PNode, inExcept: bool]](0)
for i in 1 .. howManyTrys: for i in 1 .. howManyTrys:
let tryStmt = p.nestedTryStmts.pop let tryStmt = p.nestedTryStmts.pop
@ -214,9 +214,9 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
# Find finally-stmt for this try-stmt # Find finally-stmt for this try-stmt
# and generate a copy of its sons # and generate a copy of its sons
var finallyStmt = lastSon(tryStmt.n) var finallyStmt = tryStmt.fin
if finallyStmt.kind == nkFinally: if finallyStmt != nil:
genStmts(p, finallyStmt.sons[0]) genStmts(p, finallyStmt[0])
# push old elements again: # push old elements again:
for i in countdown(howManyTrys-1, 0): for i in countdown(howManyTrys-1, 0):
@ -675,8 +675,8 @@ proc genRaiseStmt(p: BProc, t: PNode) =
if p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept: if p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept:
# if the current try stmt have a finally block, # if the current try stmt have a finally block,
# we must execute it before reraising # we must execute it before reraising
var finallyBlock = p.nestedTryStmts[^1].n[^1] let finallyBlock = p.nestedTryStmts[^1].fin
if finallyBlock.kind == nkFinally: if finallyBlock != nil:
genSimpleBlock(p, finallyBlock[0]) genSimpleBlock(p, finallyBlock[0])
if t[0].kind != nkEmpty: if t[0].kind != nkEmpty:
var a: TLoc var a: TLoc
@ -924,7 +924,8 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
getTemp(p, t.typ, d) getTemp(p, t.typ, d)
genLineDir(p, t) genLineDir(p, t)
discard cgsym(p.module, "popCurrentExceptionEx") discard cgsym(p.module, "popCurrentExceptionEx")
add(p.nestedTryStmts, (t, false)) let fin = if t[^1].kind == nkFinally: t[^1] else: nil
add(p.nestedTryStmts, (fin, false))
startBlock(p, "try {$n") startBlock(p, "try {$n")
expr(p, t[0], d) expr(p, t[0], d)
endBlock(p) endBlock(p)
@ -1021,8 +1022,9 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
else: else:
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint]) linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint])
startBlock(p, "if ($1.status == 0) {$n", [safePoint]) startBlock(p, "if ($1.status == 0) {$n", [safePoint])
var length = sonsLen(t) let length = sonsLen(t)
add(p.nestedTryStmts, (t, quirkyExceptions)) let fin = if t[^1].kind == nkFinally: t[^1] else: nil
add(p.nestedTryStmts, (fin, quirkyExceptions))
expr(p, t.sons[0], d) expr(p, t.sons[0], d)
if not quirkyExceptions: if not quirkyExceptions:
linefmt(p, cpsStmts, "#popSafePoint();$n", []) linefmt(p, cpsStmts, "#popSafePoint();$n", [])

View file

@ -73,7 +73,7 @@ type
noSafePoints*: bool # the proc doesn't use safe points in exception handling noSafePoints*: bool # the proc doesn't use safe points in exception handling
lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements lastLineInfo*: TLineInfo # to avoid generating excessive 'nimln' statements
currLineInfo*: TLineInfo # AST codegen will make this superfluous currLineInfo*: TLineInfo # AST codegen will make this superfluous
nestedTryStmts*: seq[tuple[n: PNode, inExcept: bool]] nestedTryStmts*: seq[tuple[fin: PNode, inExcept: bool]]
# in how many nested try statements we are # in how many nested try statements we are
# (the vars must be volatile then) # (the vars must be volatile then)
# bool is true when are in the except part of a try block # bool is true when are in the except part of a try block