--define:nimQuirky exception handling for Nim; in preparation of a blog post
This commit is contained in:
parent
2ee2022c29
commit
cb9110c43d
7 changed files with 77 additions and 32 deletions
|
|
@ -167,7 +167,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
|
|||
let tryStmt = p.nestedTryStmts.pop
|
||||
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
|
||||
# Pop safe points generated by try
|
||||
if not tryStmt.inExcept:
|
||||
if not tryStmt.inExcept and not isDefined(p.config, "nimQuirky"):
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
|
||||
# Pop this try-stmt of the list of nested trys
|
||||
|
|
@ -382,7 +382,7 @@ proc genReturnStmt(p: BProc, t: PNode) =
|
|||
blockLeaveActions(p,
|
||||
howManyTrys = p.nestedTryStmts.len,
|
||||
howManyExcepts = p.inExceptBlockLen)
|
||||
if (p.finallySafePoints.len > 0):
|
||||
if (p.finallySafePoints.len > 0) and not isDefined(p.config, "nimQuirky"):
|
||||
# If we're in a finally block, and we came here by exception
|
||||
# consume it before we return.
|
||||
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
|
||||
|
|
@ -919,29 +919,38 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
#
|
||||
if not isEmptyType(t.typ) and d.k == locNone:
|
||||
getTemp(p, t.typ, d)
|
||||
p.module.includeHeader("<setjmp.h>")
|
||||
let quirkyExceptions = isDefined(p.config, "nimQuirky")
|
||||
if not quirkyExceptions:
|
||||
p.module.includeHeader("<setjmp.h>")
|
||||
genLineDir(p, t)
|
||||
var safePoint = getTempName(p.module)
|
||||
discard cgsym(p.module, "Exception")
|
||||
linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
|
||||
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
|
||||
if isDefined(p.config, "nimStdSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
elif isDefined(p.config, "nimSigSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint)
|
||||
elif isDefined(p.config, "nimRawSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint)
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
startBlock(p, "if ($1.status == 0) {$n", [safePoint])
|
||||
var safePoint: Rope
|
||||
if not quirkyExceptions:
|
||||
safePoint = getTempName(p.module)
|
||||
linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint)
|
||||
linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint)
|
||||
if isDefined(p.config, "nimStdSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint)
|
||||
elif isDefined(p.config, "nimSigSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint)
|
||||
elif isDefined(p.config, "nimRawSetjmp"):
|
||||
linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint)
|
||||
else:
|
||||
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, false))
|
||||
expr(p, t.sons[0], d)
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
endBlock(p)
|
||||
startBlock(p, "else {$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
genRestoreFrameAfterException(p)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
endBlock(p)
|
||||
startBlock(p, "else {$n")
|
||||
linefmt(p, cpsStmts, "#popSafePoint();$n")
|
||||
genRestoreFrameAfterException(p)
|
||||
elif 1 < length and t.sons[1].kind == nkExceptBranch:
|
||||
startBlock(p, "if (#getCurrentException()) {$n")
|
||||
else:
|
||||
startBlock(p)
|
||||
p.nestedTryStmts[^1].inExcept = true
|
||||
var i = 1
|
||||
while (i < length) and (t.sons[i].kind == nkExceptBranch):
|
||||
|
|
@ -952,7 +961,8 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
# general except section:
|
||||
if i > 1: lineF(p, cpsStmts, "else", [])
|
||||
startBlock(p)
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
expr(p, t.sons[i].sons[0], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
endBlock(p)
|
||||
|
|
@ -968,7 +978,8 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
[genTypeInfo(p.module, t[i][j].typ, t[i][j].info)])
|
||||
if i > 1: line(p, cpsStmts, "else ")
|
||||
startBlock(p, "if ($1) {$n", [orExpr])
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "$1.status = 0;$n", safePoint)
|
||||
expr(p, t.sons[i].sons[blen-1], d)
|
||||
linefmt(p, cpsStmts, "#popCurrentException();$n")
|
||||
endBlock(p)
|
||||
|
|
@ -979,7 +990,8 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
|
|||
p.finallySafePoints.add(safePoint)
|
||||
genSimpleBlock(p, t.sons[i].sons[0])
|
||||
discard pop(p.finallySafePoints)
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
||||
if not quirkyExceptions:
|
||||
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", safePoint)
|
||||
|
||||
proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
|
||||
var res = ""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue