зеркало из https://github.com/mozilla/gecko-dev.git
Bug 319490: return in finally should clear pending exceptions. r=mrbkap,
sr=brendan.
This commit is contained in:
Родитель
b9a9953584
Коммит
4b841da7b9
|
@ -1193,12 +1193,12 @@ js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_InWithStatement(JSTreeContext *tc)
|
||||
js_InStatement(JSTreeContext *tc, JSStmtType type)
|
||||
{
|
||||
JSStmtInfo *stmt;
|
||||
|
||||
for (stmt = tc->topStmt; stmt; stmt = stmt->down) {
|
||||
if (stmt->type == STMT_WITH)
|
||||
if (stmt->type == type)
|
||||
return JS_TRUE;
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
@ -3872,6 +3872,20 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
break;
|
||||
|
||||
case TOK_RETURN:
|
||||
/*
|
||||
* If we're in a finally clause, then returning must clear any pending
|
||||
* exception state. Failure to do so could cause a subsequent
|
||||
* non-throwing API failure or native use of JS_IsPendingException to
|
||||
* mislead.
|
||||
*/
|
||||
if (js_InStatement(&cg->treeContext, STMT_SUBROUTINE) &&
|
||||
(js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
|
||||
js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 ||
|
||||
js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
|
||||
js_Emit1(cx, cg, JSOP_POP) < 0)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Push a return value */
|
||||
pn2 = pn->pn_kid;
|
||||
if (pn2) {
|
||||
|
|
|
@ -305,9 +305,12 @@ extern JSBool
|
|||
js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc,
|
||||
ptrdiff_t off);
|
||||
|
||||
/* Test whether we're in a with statement. */
|
||||
/* Test whether we're in a statement of given type. */
|
||||
extern JSBool
|
||||
js_InWithStatement(JSTreeContext *tc);
|
||||
js_InStatement(JSTreeContext *tc, JSStmtType type);
|
||||
|
||||
/* Test whether we're in a with statement. */
|
||||
#define js_InWithStatement(tc) js_InStatement(tc, STMT_WITH)
|
||||
|
||||
/* Test whether we're in a catch block with exception named by atom. */
|
||||
extern JSBool
|
||||
|
|
|
@ -2099,6 +2099,7 @@ interrupt:
|
|||
END_CASE(JSOP_LEAVEWITH)
|
||||
|
||||
BEGIN_CASE(JSOP_SETRVAL)
|
||||
JS_ASSERT(!cx->throwing);
|
||||
fp->rval = POP_OPND();
|
||||
END_CASE(JSOP_SETRVAL)
|
||||
|
||||
|
@ -2108,6 +2109,7 @@ interrupt:
|
|||
/* FALL THROUGH */
|
||||
|
||||
BEGIN_CASE(JSOP_RETRVAL) /* fp->rval already set */
|
||||
JS_ASSERT(!cx->throwing);
|
||||
if (inlineCallCount)
|
||||
inline_return:
|
||||
{
|
||||
|
|
|
@ -1232,8 +1232,10 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
|
||||
case JSOP_EXCEPTION:
|
||||
/*
|
||||
* The only other JSOP_EXCEPTION case occurs as part of a code
|
||||
* sequence that follows a SRC_CATCH-annotated JSOP_NOP.
|
||||
* The only other JSOP_EXCEPTION cases occur as part of a code
|
||||
* sequence that follows a SRC_CATCH-annotated JSOP_NOP or
|
||||
* precedes a SRC_HIDDEN-annotated JSOP_POP emitted when
|
||||
* returning from within a finally clause.
|
||||
*/
|
||||
sn = js_GetSrcNote(jp->script, pc);
|
||||
LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN);
|
||||
|
|
Загрузка…
Ссылка в новой задаче