Merge with mozilla-central as of c5dc9d84d476, and restore obj-to-boolean fixes

from 2b107c27dedf (accidentally backed out during an earlier merge).  22 test
suite failures for -L lc2 lc3 spidermonkey-n slow-n, probably needs some guard
work in TRY_BRANCH_AFTER_COND.
This commit is contained in:
2008-06-29 10:01:59 -04:00
3804 changed files with 1123974 additions and 83543 deletions

View File

@@ -436,7 +436,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
break;
case JOF_UINT24:
JS_ASSERT(op == JSOP_UINT24);
JS_ASSERT(op == JSOP_UINT24 || op == JSOP_NEWARRAY);
i = (jsint)GET_UINT24(pc);
goto print_int;
@@ -923,7 +923,11 @@ GetStr(SprintStack *ss, uintN i)
return OFF2STR(&ss->sprinter, off);
}
/* Gap between stacked strings to allow for insertion of parens and commas. */
/*
* Gap between stacked strings to allow for insertion of parens and commas
* when auto-parenthesizing expressions and decompiling array initialisers
* (see the JSOP_NEWARRAY case in Decompile).
*/
#define PAREN_SLOP (2 + 1)
/*
@@ -2045,31 +2049,42 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
cond = js_GetSrcNoteOffset(sn, 0);
next = js_GetSrcNoteOffset(sn, 1);
tail = js_GetSrcNoteOffset(sn, 2);
LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0);
/*
* If this loop has a condition, then pc points at a goto
* targeting the condition.
*/
if (cond != tail) {
LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX);
pc += (*pc == JSOP_GOTO)
? JSOP_GOTO_LENGTH
: JSOP_GOTOX_LENGTH;
}
LOCAL_ASSERT(tail == -GetJumpOffset(pc+tail, pc+tail));
/* Print the keyword and the possibly empty init-part. */
js_printf(jp, "\tfor (%s;", rval);
if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) {
if (cond != tail) {
/* Decompile the loop condition. */
DECOMPILE_CODE(pc, cond);
DECOMPILE_CODE(pc + cond, tail - cond);
js_printf(jp, " %s", POP_STR());
}
/* Need a semicolon whether or not there was a cond. */
js_puts(jp, ";");
if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) {
if (next != cond) {
/* Decompile the loop updater. */
DECOMPILE_CODE(pc + next, tail - next - 1);
DECOMPILE_CODE(pc + next,
cond - next - JSOP_POP_LENGTH);
js_printf(jp, " %s", POP_STR());
}
/* Do the loop body. */
js_printf(jp, ") {\n");
jp->indent += 4;
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
DECOMPILE_CODE(pc, next);
jp->indent -= 4;
js_printf(jp, "\t}\n");
@@ -3894,32 +3909,37 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* 1. It is the complete expression consumed by a control
* flow bytecode such as JSOP_TABLESWITCH whose syntax
* always parenthesizes the controlling expression.
* 2. It is the sole argument to a function call.
* 3. It is the condition of an if statement and not of a
* 2. It is the condition of a loop other than a for (;;).
* 3. It is the sole argument to a function call.
* 4. It is the condition of an if statement and not of a
* ?: expression.
*
* But (first, before anything else) always parenthesize
* if this genexp runs up against endpc and the next op is
* not a while or do-while loop JSOP_IFNE* opcode. In such
* cases, this Decompile activation has been recursively
* called by a comma operator, &&, or || bytecode.
* not a loop condition (JSOP_IFNE*) opcode. In such cases,
* this Decompile activation has been recursively called by
* a comma operator, &&, or || bytecode.
*/
LOCAL_ASSERT(pc + len < endpc ||
pc2 = pc + len;
LOCAL_ASSERT(pc2 < endpc ||
endpc < outer->code + outer->length);
LOCAL_ASSERT(ss2.top == 1);
ss2.opcodes[0] = JSOP_POP;
if (pc + len == endpc &&
((JSOp) *endpc != JSOP_IFNE &&
(JSOp) *endpc != JSOP_IFNEX)) {
if (pc2 == endpc &&
(JSOp) *endpc != JSOP_IFNE &&
(JSOp) *endpc != JSOP_IFNEX) {
op = JSOP_SETNAME;
} else {
op = (JSOp) pc[len];
op = (JSOp) *pc2;
op = ((js_CodeSpec[op].format & JOF_PARENHEAD) ||
((op == JSOP_IFNE || op == JSOP_IFNEX) &&
(!(sn2 = js_GetSrcNote(outer, pc2)) ||
SN_TYPE(sn2) != SRC_GENEXP)) ||
((js_CodeSpec[op].format & JOF_INVOKE) &&
GET_ARGC(pc + len) == 1) ||
(((op == JSOP_IFEQ || op == JSOP_IFEQX) &&
(sn2 = js_GetSrcNote(outer, pc + len)) &&
SN_TYPE(sn2) != SRC_COND)))
GET_ARGC(pc2) == 1) ||
((op == JSOP_IFEQ || op == JSOP_IFEQX) &&
(sn2 = js_GetSrcNote(outer, pc2)) &&
SN_TYPE(sn2) != SRC_COND))
? JSOP_POP
: JSOP_SETNAME;
@@ -4252,6 +4272,59 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
todo = -2;
break;
case JSOP_HOLE:
todo = SprintPut(&ss->sprinter, "", 0);
break;
case JSOP_NEWARRAY:
{
ptrdiff_t off;
char *base, *from, *to;
/*
* All operands are stacked and ready for in-place formatting.
* We know that PAREN_SLOP is 3 here, and take advantage of it
* to avoid strdup'ing.
*/
argc = GET_UINT24(pc);
LOCAL_ASSERT(ss->top >= (uintN) argc);
sn = js_GetSrcNote(jp->script, pc);
if (argc == 0) {
todo = Sprint(&ss->sprinter, "[%s]",
(sn && SN_TYPE(sn) == SRC_CONTINUE)
? ", "
: "");
} else {
ss->top -= argc;
off = GetOff(ss, ss->top);
LOCAL_ASSERT(off >= PAREN_SLOP);
base = OFF2STR(&ss->sprinter, off);
to = base + 1;
i = 0;
for (;;) {
/* Move to the next string that had been stacked. */
from = OFF2STR(&ss->sprinter, off);
todo = strlen(from);
memmove(to, from, todo);
to += todo;
if (++i == argc &&
!(sn && SN_TYPE(sn) == SRC_CONTINUE)) {
break;
}
*to++ = ',';
*to++ = ' ';
off = GetOff(ss, ss->top + i);
}
LOCAL_ASSERT(to - base < ss->sprinter.offset - PAREN_SLOP);
*base = '[';
*to++ = ']';
*to = '\0';
ss->sprinter.offset = STR2OFF(&ss->sprinter, to);
todo = STR2OFF(&ss->sprinter, base);
}
break;
}
case JSOP_NEWINIT:
{
i = GET_INT8(pc);
@@ -5130,6 +5203,14 @@ ReconstructPCStack(JSContext *cx, JSScript *script, jsbytecode *pc,
continue;
}
if (op == JSOP_NEWARRAY) {
pcdepth -= GET_UINT24(pc) - 1;
LOCAL_ASSERT(pcdepth > 0);
if (pcstack)
pcstack[pcdepth - 1] = pc;
continue;
}
/*
* A (C ? T : E) expression requires skipping either T (if begin is in
* E) or both T and E (if begin is after the whole expression) before