Fix model stack management for catch guards in the decompiler; eliminate related SRC_HIDDEN abusage (375794, r=igor).

This commit is contained in:
brendan@mozilla.org 2007-05-02 00:09:27 -07:00
parent 60a0ed8c0b
commit 70efc15226
2 changed files with 35 additions and 12 deletions

View File

@ -5089,12 +5089,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* Dup the exception object if there is a guard for rethrowing to use
* it later when rethrowing or in other catches.
*/
if (pn->pn_kid2) {
if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 ||
js_Emit1(cx, cg, JSOP_DUP) < 0) {
return JS_FALSE;
}
}
if (pn->pn_kid2 && js_Emit1(cx, cg, JSOP_DUP) < 0)
return JS_FALSE;
pn2 = pn->pn_kid1;
switch (pn2->pn_type) {

View File

@ -1623,8 +1623,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
*/
#define ATOM_IS_IDENTIFIER(atom) js_IsIdentifier(ATOM_TO_STRING(atom))
#define ATOM_IS_KEYWORD(atom) \
(js_CheckKeyword(JSSTRING_CHARS(ATOM_TO_STRING(atom)), \
JSSTRING_LENGTH(ATOM_TO_STRING(atom))) != TOK_EOF)
(js_CheckKeyword(JSSTRING_CHARS(ATOM_TO_STRING(atom)), \
JSSTRING_LENGTH(ATOM_TO_STRING(atom))) != TOK_EOF)
/*
* Given an atom already fetched from jp->script's atom map, quote/escape its
@ -2431,18 +2431,31 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
pc += oplen;
LOCAL_ASSERT(*pc == JSOP_EXCEPTION);
pc += JSOP_EXCEPTION_LENGTH;
todo = Sprint(&ss->sprinter, exception_cookie);
if (todo < 0 || !PushOff(ss, todo, JSOP_EXCEPTION)) {
ok = JS_FALSE;
goto enterblock_out;
}
if (*pc == JSOP_DUP) {
sn2 = js_GetSrcNote(jp->script, pc);
if (sn2 && SN_TYPE(sn2) == SRC_HIDDEN) {
if (!sn2 || SN_TYPE(sn2) != SRC_DESTRUCT) {
/*
* This is a hidden dup to save the exception for
* later. It must exist only when the catch has
* This is a dup to save the exception for later.
* It is emitted only when the catch head contains
* an exception guard.
*/
LOCAL_ASSERT(js_GetSrcNoteOffset(sn, 0) != 0);
pc += JSOP_DUP_LENGTH;
todo = Sprint(&ss->sprinter, exception_cookie);
if (todo < 0 ||
!PushOff(ss, todo, JSOP_EXCEPTION)) {
ok = JS_FALSE;
goto enterblock_out;
}
}
}
#if JS_HAS_DESTRUCTURING
if (*pc == JSOP_DUP) {
pc = DecompileDestructuring(ss, pc, endpc);
@ -2459,6 +2472,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
LOCAL_ASSERT(*pc == JSOP_SETLOCALPOP);
i = GET_UINT16(pc);
pc += JSOP_SETLOCALPOP_LENGTH;
(void) PopOff(ss, JSOP_NOP);
atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
str = ATOM_TO_STRING(atom);
if (!QuoteString(&jp->sprinter, str, 0)) {
@ -2513,8 +2527,21 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
LOCAL_ASSERT(op == JSOP_LEAVEBLOCK);
if (SN_TYPE(sn) == SRC_HIDDEN)
break;
/*
* This JSOP_LEAVEBLOCK must be for a catch block. If sn's
* offset does not equal the model stack depth, there must
* be a copy of the exception value on the stack due to a
* catch guard (see above, the JSOP_ENTERBLOCK + SRC_CATCH
* case code).
*/
LOCAL_ASSERT(SN_TYPE(sn) == SRC_CATCH);
LOCAL_ASSERT((uintN)js_GetSrcNoteOffset(sn, 0) == ss->top);
if ((uintN)js_GetSrcNoteOffset(sn, 0) != ss->top) {
LOCAL_ASSERT((uintN)js_GetSrcNoteOffset(sn, 0)
== ss->top - 1);
rval = POP_STR();
LOCAL_ASSERT(strcmp(rval, exception_cookie) == 0);
}
}
top = ss->top;
depth = GET_UINT16(pc);