parent
50229293ae
commit
bcda71a8a7
3 changed files with 44 additions and 27 deletions
|
|
@ -37,6 +37,10 @@ proc isAssignedImmediately(n: PNode): bool {.inline.} =
|
|||
return false
|
||||
result = true
|
||||
|
||||
proc inExceptBlockLen(p: BProc): int =
|
||||
for x in p.nestedTryStmts:
|
||||
if x.inExcept: result.inc
|
||||
|
||||
proc genVarTuple(p: BProc, n: PNode) =
|
||||
var tup, field: TLoc
|
||||
if n.kind != nkVarTuple: internalError(n.info, "genVarTuple")
|
||||
|
|
@ -96,7 +100,7 @@ proc startBlock(p: BProc, start: FormatStr = "{$n",
|
|||
setLen(p.blocks, result + 1)
|
||||
p.blocks[result].id = p.labels
|
||||
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
|
||||
p.blocks[result].nestedExceptStmts = p.inExceptBlock.int16
|
||||
p.blocks[result].nestedExceptStmts = p.inExceptBlockLen.int16
|
||||
|
||||
proc assignLabel(b: var TBlock): Rope {.inline.} =
|
||||
b.label = "LA" & b.id.rope
|
||||
|
|
@ -344,26 +348,22 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
|||
# Called by return and break stmts.
|
||||
# Deals with issues faced when jumping out of try/except/finally stmts,
|
||||
|
||||
var stack: seq[PNode]
|
||||
newSeq(stack, 0)
|
||||
var stack = newSeq[tuple[n: PNode, inExcept: bool]](0)
|
||||
|
||||
var alreadyPoppedCnt = p.inExceptBlock
|
||||
for i in countup(1, howManyTrys):
|
||||
let tryStmt = p.nestedTryStmts.pop
|
||||
if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
|
||||
# Pop safe points generated by try
|
||||
if alreadyPoppedCnt > 0:
|
||||
dec alreadyPoppedCnt
|
||||
else:
|
||||
if not tryStmt.inExcept:
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
|
||||
# Pop this try-stmt of the list of nested trys
|
||||
# so we don't infinite recurse on it in the next step.
|
||||
var tryStmt = p.nestedTryStmts.pop
|
||||
stack.add(tryStmt)
|
||||
|
||||
# Find finally-stmt for this try-stmt
|
||||
# and generate a copy of its sons
|
||||
var finallyStmt = lastSon(tryStmt)
|
||||
var finallyStmt = lastSon(tryStmt.n)
|
||||
if finallyStmt.kind == nkFinally:
|
||||
genStmts(p, finallyStmt.sons[0])
|
||||
|
||||
|
|
@ -384,7 +384,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
|
|||
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
|
||||
blockLeaveActions(p,
|
||||
howManyTrys = p.nestedTryStmts.len,
|
||||
howManyExcepts = p.inExceptBlock)
|
||||
howManyExcepts = p.inExceptBlockLen)
|
||||
if (p.finallySafePoints.len > 0):
|
||||
# If we're in a finally block, and we came here by exception
|
||||
# consume it before we return.
|
||||
|
|
@ -567,15 +567,15 @@ proc genBreakStmt(p: BProc, t: PNode) =
|
|||
let label = assignLabel(p.blocks[idx])
|
||||
blockLeaveActions(p,
|
||||
p.nestedTryStmts.len - p.blocks[idx].nestedTryStmts,
|
||||
p.inExceptBlock - p.blocks[idx].nestedExceptStmts)
|
||||
p.inExceptBlockLen - p.blocks[idx].nestedExceptStmts)
|
||||
genLineDir(p, t)
|
||||
lineF(p, cpsStmts, "goto $1;$n", [label])
|
||||
|
||||
proc genRaiseStmt(p: BProc, t: PNode) =
|
||||
if p.inExceptBlock > 0 and p.inExceptBlock == p.nestedTryStmts.len:
|
||||
if p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept:
|
||||
# if the current try stmt have a finally block,
|
||||
# we must execute it before reraising
|
||||
var finallyBlock = p.nestedTryStmts[p.nestedTryStmts.len - 1].lastSon
|
||||
var finallyBlock = p.nestedTryStmts[^1].n[^1]
|
||||
if finallyBlock.kind == nkFinally:
|
||||
genSimpleBlock(p, finallyBlock.sons[0])
|
||||
if t.sons[0].kind != nkEmpty:
|
||||
|
|
@ -812,14 +812,14 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
|
||||
let end_label = getLabel(p)
|
||||
discard cgsym(p.module, "Exception")
|
||||
add(p.nestedTryStmts, t)
|
||||
add(p.nestedTryStmts, (t, false))
|
||||
startBlock(p, "try {$n")
|
||||
expr(p, t[0], d)
|
||||
endBlock(p)
|
||||
|
||||
var catchAllPresent = false
|
||||
|
||||
inc p.inExceptBlock
|
||||
p.nestedTryStmts[^1].inExcept = true
|
||||
for i in 1..<t.len:
|
||||
if t[i].kind != nkExceptBranch: break
|
||||
|
||||
|
|
@ -839,6 +839,8 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
genExceptBranchBody(t[i][^1]) # exception handler body will duplicated for every type
|
||||
endBlock(p)
|
||||
|
||||
discard pop(p.nestedTryStmts)
|
||||
|
||||
if not catchAllPresent and t[^1].kind == nkFinally:
|
||||
# finally requires catch all presence
|
||||
startBlock(p, "catch (...) {$n")
|
||||
|
|
@ -846,9 +848,6 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
|||
line(p, cpsStmts, ~"throw;$n")
|
||||
endBlock(p)
|
||||
|
||||
dec p.inExceptBlock
|
||||
discard pop(p.nestedTryStmts)
|
||||
|
||||
if t[^1].kind == nkFinally:
|
||||
genSimpleBlock(p, t[^1][0])
|
||||
|
||||
|
|
@ -902,7 +901,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
||||
var length = sonsLen(t)
|
||||
add(p.nestedTryStmts, t)
|
||||
add(p.nestedTryStmts, (t, false))
|
||||
expr(p, t.sons[0], d)
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
endBlock(p)
|
||||
|
|
@ -910,7 +909,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
if optStackTrace in p.options:
|
||||
linefmt(p, cpsStmts, "#setFrame((TFrame*)&FR_);$n")
|
||||
inc p.inExceptBlock
|
||||
p.nestedTryStmts[^1].inExcept = true
|
||||
var i = 1
|
||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
||||
# bug #4230: avoid false sharing between branches:
|
||||
|
|
@ -941,7 +940,6 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
endBlock(p)
|
||||
inc(i)
|
||||
dec p.inExceptBlock
|
||||
discard pop(p.nestedTryStmts)
|
||||
endBlock(p) # end of else block
|
||||
if i < length and t.sons[i].kind == nkFinally:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue