Bug 319490: return in finally should clear pending exceptions. r=mrbkap,

sr=brendan.
This commit is contained in:
shaver%mozilla.org 2005-12-24 01:09:19 +00:00
Родитель b9a9953584
Коммит 4b841da7b9
4 изменённых файлов: 27 добавлений и 6 удалений

Просмотреть файл

@ -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);