Restore framePtr after exceptions

This commit is contained in:
Yuriy Glukhov 2016-08-27 18:09:24 +03:00
commit 62785be5a5

View file

@ -558,11 +558,13 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
# code to generate: # code to generate:
# #
# ++excHandler; # ++excHandler;
# var tmpFramePtr = framePtr;
# try { # try {
# stmts; # stmts;
# --excHandler; # --excHandler;
# } catch (EXC) { # } catch (EXC) {
# var prevJSError = lastJSError; lastJSError = EXC; # var prevJSError = lastJSError; lastJSError = EXC;
# framePtr = tmpFramePtr;
# --excHandler; # --excHandler;
# if (e.typ && e.typ == NTI433 || e.typ == NTI2321) { # if (e.typ && e.typ == NTI433 || e.typ == NTI2321) {
# stmts; # stmts;
@ -573,6 +575,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
# } # }
# lastJSError = prevJSError; # lastJSError = prevJSError;
# } finally { # } finally {
# framePtr = tmpFramePtr;
# stmts; # stmts;
# } # }
genLineDir(p, n) genLineDir(p, n)
@ -585,8 +588,10 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch
if catchBranchesExist and p.target == targetJS: if catchBranchesExist and p.target == targetJS:
add(p.body, "++excHandler;" & tnl) add(p.body, "++excHandler;" & tnl)
var safePoint = "Tmp$1" % [rope(p.unique)] var tmpFramePtr = rope"F"
if optStackTrace in p.options: add(p.body, "framePtr = F;" & tnl) if optStackTrace notin p.options:
tmpFramePtr = p.getTemp(true)
add(p.body, tmpFramePtr & " = framePtr;" & tnl)
addf(p.body, "try {$n", []) addf(p.body, "try {$n", [])
if p.target == targetPHP and p.globals == nil: if p.target == targetPHP and p.globals == nil:
p.globals = "global $lastJSError; global $prevJSError;".rope p.globals = "global $lastJSError; global $prevJSError;".rope
@ -598,6 +603,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
if p.target == targetJS and catchBranchesExist: if p.target == targetJS and catchBranchesExist:
addf(p.body, "--excHandler;$n} catch (EXC) {$n var prevJSError = lastJSError;$n" & addf(p.body, "--excHandler;$n} catch (EXC) {$n var prevJSError = lastJSError;$n" &
" lastJSError = EXC;$n --excHandler;$n", []) " lastJSError = EXC;$n --excHandler;$n", [])
add(p.body, "framePtr = $1;$n" % [tmpFramePtr])
elif p.target == targetPHP: elif p.target == targetPHP:
addf(p.body, "} catch (Exception $$EXC) {$n $$prevJSError = $$lastJSError;$n $$lastJSError = $$EXC;$n", []) addf(p.body, "} catch (Exception $$EXC) {$n $$prevJSError = $$lastJSError;$n $$lastJSError = $$EXC;$n", [])
while i < length and n.sons[i].kind == nkExceptBranch: while i < length and n.sons[i].kind == nkExceptBranch:
@ -619,8 +625,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
addf(orExpr, "isObj($2lastJSError.m_type, $1)", addf(orExpr, "isObj($2lastJSError.m_type, $1)",
[genTypeInfo(p, n.sons[i].sons[j].typ), dollar]) [genTypeInfo(p, n.sons[i].sons[j].typ), dollar])
if i > 1: add(p.body, "else ") if i > 1: add(p.body, "else ")
addf(p.body, "if ($3lastJSError && ($2)) {$n", addf(p.body, "if ($1lastJSError && ($2)) {$n", [dollar, orExpr])
[safePoint, orExpr, dollar])
gen(p, n.sons[i].sons[blen - 1], a) gen(p, n.sons[i].sons[blen - 1], a)
moveInto(p, a, r) moveInto(p, a, r)
addf(p.body, "}$n", []) addf(p.body, "}$n", [])
@ -632,6 +637,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
addf(p.body, "$1lastJSError = $1prevJSError;$n", [dollar]) addf(p.body, "$1lastJSError = $1prevJSError;$n", [dollar])
if p.target == targetJS: if p.target == targetJS:
add(p.body, "} finally {" & tnl) add(p.body, "} finally {" & tnl)
add(p.body, "framePtr = $1;$n" % [tmpFramePtr])
if p.target == targetPHP: if p.target == targetPHP:
# XXX ugly hack for PHP codegen # XXX ugly hack for PHP codegen
add(p.body, "}" & tnl) add(p.body, "}" & tnl)