Bug 473096 - js1_5/Regress/regress-366601.js - Internal Error: script too large. r=brendan

This commit is contained in:
Jeff Walden 2009-04-10 17:41:13 -07:00
Родитель 5e45c9c2e3
Коммит d5fbd4024f
7 изменённых файлов: 61 добавлений и 45 удалений

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

@ -6274,32 +6274,40 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
case TOK_ARRAYCOMP:
#endif
/*
* Emit code for [a, b, c] of the form:
* Emit code for [a, b, c] that is equivalent to constructing a new
* array and in source order evaluating each element value and adding
* it to the array, without invoking latent setters. We use the
* JSOP_NEWINIT and JSOP_INITELEM bytecodes to ignore setters and to
* avoid dup'ing and popping the array as each element is added, as
* JSOP_SETELEM/JSOP_SETPROP would do.
*
* t = new Array; t[0] = a; t[1] = b; t[2] = c; t;
*
* but use a stack slot for t and avoid dup'ing and popping it using
* the JSOP_NEWINIT and JSOP_INITELEM bytecodes.
*
* If no sharp variable is defined and the initialiser is not for an
* array comprehension, use JSOP_NEWARRAY.
* If no sharp variable is defined, the initializer is not for an array
* comprehension, the initializer is not overlarge, and the initializer
* is not in global code (whose stack growth cannot be precisely modeled
* due to the need to reserve space for global variables and regular
* expressions), use JSOP_NEWARRAY to minimize opcodes and to create the
* array using a fast, all-at-once process rather than a slow, element-
* by-element process.
*/
#if JS_HAS_SHARP_VARS
sharpnum = -1;
do_emit_array:
#endif
#if JS_HAS_GENERATORS || JS_HAS_SHARP_VARS
op = JSOP_NEWARRAY;
# if JS_HAS_GENERATORS
op = (JS_LIKELY(pn->pn_count < JS_BIT(16)) && (cg->flags & TCF_IN_FUNCTION))
? JSOP_NEWARRAY
: JSOP_NEWINIT;
#if JS_HAS_GENERATORS
if (pn->pn_type == TOK_ARRAYCOMP)
op = JSOP_NEWINIT;
# endif
# if JS_HAS_SHARP_VARS
#endif
#if JS_HAS_SHARP_VARS
JS_ASSERT_IF(sharpnum >= 0, cg->flags & TCF_HAS_SHARPS);
if (cg->flags & TCF_HAS_SHARPS)
op = JSOP_NEWINIT;
# endif
#endif
if (op == JSOP_NEWINIT) {
if (js_Emit2(cx, cg, op, (jsbytecode) JSProto_Array) < 0)
return JS_FALSE;
@ -6308,7 +6316,6 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
EMIT_UINT16_IMM_OP(JSOP_DEFSHARP, (jsatomid) sharpnum);
# endif
}
#endif
#if JS_HAS_GENERATORS
if (pn->pn_type == TOK_ARRAYCOMP) {
@ -6335,10 +6342,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
pn2 = pn->pn_head;
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
#if JS_HAS_SHARP_VARS
if (op == JSOP_NEWINIT && !EmitNumberOp(cx, atomIndex, cg))
return JS_FALSE;
#endif
if (pn2->pn_type == TOK_COMMA) {
if (js_Emit1(cx, cg, JSOP_HOLE) < 0)
return JS_FALSE;
@ -6346,10 +6351,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
if (!js_EmitTree(cx, cg, pn2))
return JS_FALSE;
}
#if JS_HAS_SHARP_VARS
if (op == JSOP_NEWINIT && js_Emit1(cx, cg, JSOP_INITELEM) < 0)
return JS_FALSE;
#endif
}
JS_ASSERT(atomIndex == pn->pn_count);
@ -6359,20 +6362,18 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
return JS_FALSE;
}
#if JS_HAS_SHARP_VARS
if (op == JSOP_NEWINIT) {
/* Emit an op for sharp array cleanup and decompilation. */
/*
* Emit an op to finish the array and, secondarily, to aid in sharp
* array cleanup (if JS_HAS_SHARP_VARS) and decompilation.
*/
if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0)
return JS_FALSE;
break;
}
#endif
off = js_EmitN(cx, cg, JSOP_NEWARRAY, 3);
if (off < 0)
return JS_FALSE;
pc = CG_CODE(cg, off);
SET_UINT24(pc, atomIndex);
UpdateDepth(cx, cg, off);
JS_ASSERT(atomIndex < JS_BIT(16));
EMIT_UINT16_IMM_OP(JSOP_NEWARRAY, atomIndex);
break;
case TOK_RC:
@ -6388,12 +6389,12 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
}
#endif
/*
* Emit code for {p:a, '%q':b, 2:c} of the form:
*
* t = new Object; t.p = a; t['%q'] = b; t[2] = c; t;
*
* but use a stack slot for t and avoid dup'ing and popping it via
* the JSOP_NEWINIT and JSOP_INITELEM/JSOP_INITPROP bytecodes.
* Emit code for {p:a, '%q':b, 2:c} that is equivalent to constructing
* a new object and in source order evaluating each property value and
* adding the property to the object, without invoking latent setters.
* We use the JSOP_NEWINIT and JSOP_INITELEM/JSOP_INITPROP bytecodes to
* ignore setters and to avoid dup'ing and popping the object as each
* property is added, as JSOP_SETELEM/JSOP_SETPROP would do.
*/
if (js_Emit2(cx, cg, JSOP_NEWINIT, (jsbytecode) JSProto_Object) < 0)
return JS_FALSE;

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

@ -6253,8 +6253,8 @@ js_Interpret(JSContext *cx)
END_CASE(JSOP_HOLE)
BEGIN_CASE(JSOP_NEWARRAY)
len = GET_UINT24(regs.pc);
JS_ASSERT(len <= regs.sp - StackBase(fp));
len = GET_UINT16(regs.pc);
cx->fp->assertValidStackDepth(len);
obj = js_NewArrayObject(cx, len, regs.sp - len, JS_TRUE);
if (!obj)
goto error;

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

@ -132,6 +132,14 @@ struct JSStackFrame {
#ifdef DEBUG
jsrefcount pcDisabledSave; /* for balanced property cache control */
#endif
#ifdef __cplusplus /* Aargh, LiveConnect, bug 442399. */
void assertValidStackDepth(uintN depth) {
extern jsval *StackBase(JSStackFrame *fp);
JS_ASSERT(0 <= regs->sp - StackBase(this));
JS_ASSERT(depth <= uintptr_t(regs->sp - StackBase(this)));
}
#endif
};
#ifdef __cplusplus

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

@ -214,7 +214,7 @@ js_GetVariableStackUses(JSOp op, jsbytecode *pc)
case JSOP_LEAVEBLOCKEXPR:
return GET_UINT16(pc) + 1;
case JSOP_NEWARRAY:
return GET_UINT24(pc);
return GET_UINT16(pc);
default:
/* stack: fun, this, [argc arguments] */
JS_ASSERT(op == JSOP_NEW || op == JSOP_CALL ||
@ -4357,7 +4357,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
break;
case JSOP_NEWARRAY:
argc = GET_UINT24(pc);
argc = GET_UINT16(pc);
LOCAL_ASSERT(ss->top >= (uintN) argc);
if (argc == 0) {
todo = SprintCString(&ss->sprinter, "[]");

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

@ -554,9 +554,9 @@ OPDEF(JSOP_LENGTH, 221, "length", NULL, 1, 1, 1, 18, JOF_BYTE|J
* stack, consuming those values and replacing them with the newly-constructed
* array. The topmost value is the last value in the new array, and the
* bottommost value is the first value in the array; the array length is a
* 24-bit immediate operand to the instruction.
* 16-bit immediate operand to the instruction.
*/
OPDEF(JSOP_NEWARRAY, 222, "newarray", NULL, 4, -1, 1, 19, JOF_UINT24)
OPDEF(JSOP_NEWARRAY, 222, "newarray", NULL, 3, -1, 1, 19, JOF_UINT16)
/*
* Push a JSVAL_HOLE value onto the stack, representing an omitted property in

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

@ -7180,7 +7180,9 @@ TraceRecorder::functionCall(bool constructing, uintN argc)
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_NEW()
{
return functionCall(true, GET_ARGC(cx->fp->regs->pc));
uintN argc = GET_ARGC(cx->fp->regs->pc);
cx->fp->assertValidStackDepth(argc + 2);
return functionCall(true, argc);
}
JS_REQUIRES_STACK bool
@ -7893,7 +7895,9 @@ TraceRecorder::interpretedFunctionCall(jsval& fval, JSFunction* fun, uintN argc,
JS_REQUIRES_STACK bool
TraceRecorder::record_JSOP_CALL()
{
return functionCall(false, GET_ARGC(cx->fp->regs->pc));
uintN argc = GET_ARGC(cx->fp->regs->pc);
cx->fp->assertValidStackDepth(argc + 2);
return functionCall(false, argc);
}
static jsbytecode* apply_imacro_table[] = {
@ -7926,8 +7930,9 @@ TraceRecorder::record_JSOP_APPLY()
JSStackFrame* fp = cx->fp;
jsbytecode *pc = fp->regs->pc;
uintN argc = GET_ARGC(pc);
cx->fp->assertValidStackDepth(argc + 2);
jsval* vp = fp->regs->sp - (argc + 2);
JS_ASSERT(vp >= StackBase(fp));
jsuint length = 0;
JSObject* aobj = NULL;
LIns* aobj_ins = NULL;
@ -9919,7 +9924,9 @@ TraceRecorder::record_JSOP_NEWARRAY()
if (!getClassPrototype(JSProto_Array, proto_ins))
return false;
uint32 len = GET_UINT24(cx->fp->regs->pc);
uint32 len = GET_UINT16(cx->fp->regs->pc);
cx->fp->assertValidStackDepth(len);
LIns* args[] = { lir->insImm(len), proto_ins, cx_ins };
LIns* v_ins = lir->insCall(&js_NewUninitializedArray_ci, args);
guard(false, lir->ins_eq0(v_ins), OOM_EXIT);

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

@ -204,7 +204,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 - 45)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 46)
/*
* Library-private functions.