diff options
-rw-r--r-- | compiler/jsgen.nim | 19 | ||||
-rw-r--r-- | lib/system/jssys.nim | 24 |
2 files changed, 35 insertions, 8 deletions
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index fd0e600b7..d84b0f2f9 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -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)] diff --git a/lib/system/jssys.nim b/lib/system/jssys.nim index a6711a778..4d5ba1f73 100644 --- a/lib/system/jssys.nim +++ b/lib/system/jssys.nim @@ -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.} = |