Fixed codegen (added blockLeaveActions) to closure iters
This commit is contained in:
parent
c854865d3e
commit
fb965719a6
1 changed files with 38 additions and 35 deletions
|
|
@ -157,6 +157,39 @@ proc genState(p: BProc, n: PNode) =
|
||||||
elif n0.kind == nkStrLit:
|
elif n0.kind == nkStrLit:
|
||||||
linefmt(p, cpsStmts, "$1: ;$n", n0.strVal.rope)
|
linefmt(p, cpsStmts, "$1: ;$n", n0.strVal.rope)
|
||||||
|
|
||||||
|
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 = newSeq[tuple[n: PNode, inExcept: bool]](0)
|
||||||
|
|
||||||
|
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 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.
|
||||||
|
stack.add(tryStmt)
|
||||||
|
|
||||||
|
# Find finally-stmt for this try-stmt
|
||||||
|
# and generate a copy of its sons
|
||||||
|
var finallyStmt = lastSon(tryStmt.n)
|
||||||
|
if finallyStmt.kind == nkFinally:
|
||||||
|
genStmts(p, finallyStmt.sons[0])
|
||||||
|
|
||||||
|
# push old elements again:
|
||||||
|
for i in countdown(howManyTrys-1, 0):
|
||||||
|
p.nestedTryStmts.add(stack[i])
|
||||||
|
|
||||||
|
if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
|
||||||
|
# Pop exceptions that was handled by the
|
||||||
|
# except-blocks we are in
|
||||||
|
for i in countdown(howManyExcepts-1, 0):
|
||||||
|
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||||
|
|
||||||
proc genGotoState(p: BProc, n: PNode) =
|
proc genGotoState(p: BProc, n: PNode) =
|
||||||
# we resist the temptation to translate it into duff's device as it later
|
# we resist the temptation to translate it into duff's device as it later
|
||||||
# will be translated into computed gotos anyway for GCC at least:
|
# will be translated into computed gotos anyway for GCC at least:
|
||||||
|
|
@ -167,7 +200,11 @@ proc genGotoState(p: BProc, n: PNode) =
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)])
|
lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)])
|
||||||
p.beforeRetNeeded = true
|
p.beforeRetNeeded = true
|
||||||
lineF(p, cpsStmts, "case -1: goto BeforeRet_;$n", [])
|
lineF(p, cpsStmts, "case -1:$n", [])
|
||||||
|
blockLeaveActions(p,
|
||||||
|
howManyTrys = p.nestedTryStmts.len,
|
||||||
|
howManyExcepts = p.inExceptBlockLen)
|
||||||
|
lineF(p, cpsStmts, " goto BeforeRet_;$n", [])
|
||||||
var statesCounter = lastOrd(n.sons[0].typ)
|
var statesCounter = lastOrd(n.sons[0].typ)
|
||||||
if n.len >= 2 and n[1].kind == nkIntLit:
|
if n.len >= 2 and n[1].kind == nkIntLit:
|
||||||
statesCounter = n[1].intVal
|
statesCounter = n[1].intVal
|
||||||
|
|
@ -328,40 +365,6 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
|
||||||
else: internalError(n.info, "genIf()")
|
else: internalError(n.info, "genIf()")
|
||||||
if sonsLen(n) > 1: fixLabel(p, lend)
|
if sonsLen(n) > 1: fixLabel(p, lend)
|
||||||
|
|
||||||
|
|
||||||
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 = newSeq[tuple[n: PNode, inExcept: bool]](0)
|
|
||||||
|
|
||||||
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 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.
|
|
||||||
stack.add(tryStmt)
|
|
||||||
|
|
||||||
# Find finally-stmt for this try-stmt
|
|
||||||
# and generate a copy of its sons
|
|
||||||
var finallyStmt = lastSon(tryStmt.n)
|
|
||||||
if finallyStmt.kind == nkFinally:
|
|
||||||
genStmts(p, finallyStmt.sons[0])
|
|
||||||
|
|
||||||
# push old elements again:
|
|
||||||
for i in countdown(howManyTrys-1, 0):
|
|
||||||
p.nestedTryStmts.add(stack[i])
|
|
||||||
|
|
||||||
if not p.module.compileToCpp or optNoCppExceptions in gGlobalOptions:
|
|
||||||
# Pop exceptions that was handled by the
|
|
||||||
# except-blocks we are in
|
|
||||||
for i in countdown(howManyExcepts-1, 0):
|
|
||||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
|
||||||
|
|
||||||
proc genReturnStmt(p: BProc, t: PNode) =
|
proc genReturnStmt(p: BProc, t: PNode) =
|
||||||
if nfPreventCg in t.flags: return
|
if nfPreventCg in t.flags: return
|
||||||
p.beforeRetNeeded = true
|
p.beforeRetNeeded = true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue