mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-09 14:32:53 +00:00
Unhandled exceptions handling brought back.
This commit is contained in:
@@ -505,12 +505,12 @@ proc moveInto(p: PProc, src: var TCompRes, dest: TCompRes) =
|
||||
proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
# code to generate:
|
||||
#
|
||||
# var sp = {prev: excHandler, exc: null};
|
||||
# excHandler = sp;
|
||||
# ++excHandler;
|
||||
# try {
|
||||
# stmts;
|
||||
# } catch (EXC) {
|
||||
# var prevJSError = lastJSError; lastJSError = EXC;
|
||||
# --excHandler;
|
||||
# if (e.typ && e.typ == NTI433 || e.typ == NTI2321) {
|
||||
# stmts;
|
||||
# } else if (e.typ && e.typ == NTI32342) {
|
||||
@@ -527,6 +527,11 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
r.kind = resVal
|
||||
r.res = getTemp(p)
|
||||
inc(p.unique)
|
||||
var i = 1
|
||||
var length = sonsLen(n)
|
||||
var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch
|
||||
if catchBranchesExist:
|
||||
add(p.body, "++excHandler;" & tnl)
|
||||
var safePoint = "Tmp$1" % [rope(p.unique)]
|
||||
addf(p.body,
|
||||
"" |
|
||||
@@ -534,15 +539,13 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
[safePoint])
|
||||
if optStackTrace in p.options: add(p.body, "framePtr = F;" & tnl)
|
||||
addf(p.body, "try {$n" | "function()$n", [])
|
||||
var length = sonsLen(n)
|
||||
var a: TCompRes
|
||||
gen(p, n.sons[0], a)
|
||||
moveInto(p, a, r)
|
||||
var i = 1
|
||||
var generalCatchBranchExists = false
|
||||
var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch
|
||||
if p.target == targetJS and catchBranchesExist:
|
||||
addf(p.body, "} catch (EXC) {$n var prevJSError = lastJSError; lastJSError = EXC;$n", [])
|
||||
addf(p.body, "} catch (EXC) {$n var prevJSError = lastJSError;$n" &
|
||||
" lastJSError = EXC;$n --excHandler;$n", [])
|
||||
elif p.target == targetLua:
|
||||
addf(p.body, "end)$n", [])
|
||||
while i < length and n.sons[i].kind == nkExceptBranch:
|
||||
@@ -574,7 +577,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
|
||||
if catchBranchesExist:
|
||||
if not generalCatchBranchExists:
|
||||
useMagic(p, "reraiseException")
|
||||
add(p.body, "else { reraiseException(); }")
|
||||
add(p.body, "else {" & tnl & "reraiseException();" & tnl & "}" & tnl)
|
||||
add(p.body, "lastJSError = prevJSError;" & tnl)
|
||||
add(p.body, "} finally {" & tnl)
|
||||
if i < length and n.sons[i].kind == nkFinally:
|
||||
@@ -1685,7 +1688,7 @@ proc genHeader(): Rope =
|
||||
result = ("/* Generated by the Nim Compiler v$1 */$n" &
|
||||
"/* (c) 2015 Andreas Rumpf */$n$n" &
|
||||
"var framePtr = null;$n" &
|
||||
"var excHandler = null;$n" &
|
||||
"var excHandler = 0;$n" &
|
||||
"var lastJSError = null;$n") %
|
||||
[rope(VersionAsString)]
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ type
|
||||
|
||||
var
|
||||
framePtr {.importc, nodecl, volatile.}: PCallFrame
|
||||
excHandler {.importc, nodecl, volatile.}: int = 0
|
||||
lastJSError {.importc, nodecl, volatile.}: PJSError = nil
|
||||
|
||||
{.push stacktrace: off, profiler:off.}
|
||||
@@ -94,15 +95,38 @@ proc rawWriteStackTrace(): string =
|
||||
else:
|
||||
result = "No stack traceback available\n"
|
||||
|
||||
proc unhandledException(e: ref Exception) {.
|
||||
compilerproc, asmNoStackFrame.} =
|
||||
when NimStackTrace:
|
||||
var buf = rawWriteStackTrace()
|
||||
else:
|
||||
var buf = ""
|
||||
if e.msg != nil and e.msg[0] != '\0':
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
add(buf, e.msg)
|
||||
else:
|
||||
add(buf, "Error: unhandled exception")
|
||||
add(buf, " [")
|
||||
add(buf, e.name)
|
||||
add(buf, "]\n")
|
||||
alert(buf)
|
||||
|
||||
proc raiseException(e: ref Exception, ename: cstring) {.
|
||||
compilerproc, asmNoStackFrame.} =
|
||||
e.name = ename
|
||||
if excHandler == 0:
|
||||
unhandledException(e)
|
||||
asm "throw `e`;"
|
||||
|
||||
proc reraiseException() {.compilerproc, asmNoStackFrame.} =
|
||||
if lastJSError == nil:
|
||||
raise newException(ReraiseError, "no exception to reraise")
|
||||
else:
|
||||
if excHandler == 0:
|
||||
var isNimException : bool
|
||||
asm "`isNimException` = lastJSError.m_type;"
|
||||
if isNimException:
|
||||
unhandledException(cast[ref Exception](lastJSError))
|
||||
asm "throw lastJSError;"
|
||||
|
||||
proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} =
|
||||
|
||||
Reference in New Issue
Block a user