Fix else-if chains to be unbraced as required by single let declaration consequents (352268, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2006-09-13 07:20:48 +00:00
parent 1dd2b1359d
commit d75c529f29
4 changed files with 48 additions and 13 deletions

View File

@ -922,8 +922,12 @@ SrcNotes(JSContext *cx, JSScript *script)
(uintN) js_GetSrcNoteOffset(sn, 1),
(uintN) js_GetSrcNoteOffset(sn, 2));
break;
case SRC_COND:
case SRC_IF_ELSE:
fprintf(gOutFile, " else %u elseif %u",
(uintN) js_GetSrcNoteOffset(sn, 0),
(uintN) js_GetSrcNoteOffset(sn, 1));
break;
case SRC_COND:
case SRC_WHILE:
case SRC_PCBASE:
case SRC_PCDELTA:

View File

@ -4002,20 +4002,26 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
/* Emit code for the condition before pushing stmtInfo. */
if (!js_EmitTree(cx, cg, pn->pn_kid1))
return JS_FALSE;
top = CG_OFFSET(cg);
if (stmtInfo.type == STMT_IF) {
js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF,
CG_OFFSET(cg));
js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF, top);
} else {
/*
* We came here from the goto further below that detects else-if
* chains, so we must mutate stmtInfo back into a STMT_IF record.
* Also (see below for why) we need a note offset for SRC_IF_ELSE
* to help the decompiler.
* to help the decompiler. Actually, we need two offsets, one for
* decompiling any else clause and the second for decompiling an
* else-if chain without bracing, overindenting, or incorrectly
* scoping let declarations.
*/
JS_ASSERT(stmtInfo.type == STMT_ELSE);
stmtInfo.type = STMT_IF;
stmtInfo.update = top;
if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq))
return JS_FALSE;
if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 1, top - jmp))
return JS_FALSE;
}
/* Emit an annotated branch-if-false around the then part. */
@ -6251,7 +6257,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = {
{"null", 0, 0, 0},
{"if", 0, 0, 0},
{"if-else", 1, 0, 1},
{"if-else", 2, 0, 1},
{"while", 1, 0, 1},
{"for", 3, 1, 1},
{"continue", 0, 0, 0},

View File

@ -643,7 +643,7 @@ static void
SetDontBrace(JSPrinter *jp)
{
ptrdiff_t offset;
/* When not pretty-printing, newline after brace is chopped. */
JS_ASSERT(jp->spaceOffset < 0);
offset = jp->sprinter.offset - (jp->pretty ? 3 : 2);
@ -1547,7 +1547,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
#if JS_HAS_BLOCK_SCOPE
/*
* If a let declaration is the only child of a control
* structure that does not require braces, it must not
* structure that does not require braces, it must not
* be braced. If it were braced explicitly, it would
* be bracketed by JSOP_ENTERBLOCK/JSOP_LEAVEBLOCK.
*/
@ -1917,19 +1917,26 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
case JSOP_IFEQ:
case JSOP_IFEQX:
{
JSBool elseif = JS_FALSE;
if_again:
len = GetJumpOffset(pc, pc);
sn = js_GetSrcNote(jp->script, pc);
switch (sn ? SN_TYPE(sn) : SRC_NULL) {
case SRC_IF:
case SRC_IF_ELSE:
op = JSOP_NOP; /* turn off parens */
rval = POP_STR();
if (ss->inArrayInit) {
LOCAL_ASSERT(SN_TYPE(sn) == SRC_IF);
if (Sprint(&ss->sprinter, " if (%s)", rval) < 0)
return JS_FALSE;
} else {
js_printf(SET_MAYBE_BRACE(jp), "\tif (%s) {\n", rval);
js_printf(SET_MAYBE_BRACE(jp),
elseif ? " if (%s) {\n" : "\tif (%s) {\n",
rval);
jp->indent += 4;
}
@ -1937,14 +1944,31 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
DECOMPILE_CODE(pc + oplen, len - oplen);
} else {
LOCAL_ASSERT(!ss->inArrayInit);
len = js_GetSrcNoteOffset(sn, 0);
DECOMPILE_CODE(pc + oplen, len - oplen);
tail = js_GetSrcNoteOffset(sn, 0);
DECOMPILE_CODE(pc + oplen, tail - oplen);
jp->indent -= 4;
pc += len;
pc += tail;
LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
oplen = js_CodeSpec[*pc].length;
len = GetJumpOffset(pc, pc);
js_printf(jp, "\t} else");
/*
* If the second offset for sn is non-zero, it tells
* the distance from the goto around the else, to the
* ifeq for the if inside the else that forms an "if
* else if" chain. Thus cond spans the condition of
* the second if, so we simply decompile it and start
* over at label if_again.
*/
cond = js_GetSrcNoteOffset(sn, 1);
if (cond != 0) {
DECOMPILE_CODE(pc + oplen, cond - oplen);
pc += cond;
elseif = JS_TRUE;
goto if_again;
}
js_printf(SET_MAYBE_BRACE(jp), " {\n");
jp->indent += 4;
DECOMPILE_CODE(pc + oplen, len - oplen);
@ -1995,6 +2019,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
break;
}
break;
}
case JSOP_IFNE:
case JSOP_IFNEX:
@ -2259,7 +2284,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
sn = js_GetSrcNote(jp->script, pc - 1);
if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) {
todo = Sprint(&ss->sprinter, "%s %s= %s",
lval,
lval,
(lastop == JSOP_GETTER)
? js_getter_str
: (lastop == JSOP_SETTER)

View File

@ -200,7 +200,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
* before deserialization of bytecode. If the saved version does not match
* the current version, abort deserialization and invalidate the file.
*/
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 2)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 3)
/*
* Library-private functions.