Bug 487271 - Crash [@ js_Invoke ], and missing google-maps background, at padmapper.com (r=mrbkap).

This commit is contained in:
Brendan Eich 2009-04-08 13:14:02 -07:00
parent 240c326a21
commit 3f4a58e4f0
5 changed files with 43 additions and 22 deletions

View File

@ -856,7 +856,7 @@ struct JSContext {
/*
* Classic Algol "display" static link optimization.
*/
#define JS_DISPLAY_SIZE 16
#define JS_DISPLAY_SIZE 16U
JSStackFrame *display[JS_DISPLAY_SIZE];

View File

@ -1912,6 +1912,14 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
JSStackFrame *caller = cg->compiler->callerFrame;
if (caller) {
JS_ASSERT(cg->flags & TCF_COMPILE_N_GO);
/*
* Don't generate upvars on the left side of a for loop. See
* bug 470758.
*/
if (cg->flags & TCF_IN_FOR_INIT)
return JS_TRUE;
JS_ASSERT(caller->script);
if (!caller->fun || caller->varobj != cg->scopeChain)
return JS_TRUE;
@ -1922,18 +1930,16 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
* Optimize access to function's arguments and variable and the
* arguments object.
*/
if (op != JSOP_NAME || cg->staticLevel >= JS_DISPLAY_SIZE)
if (op != JSOP_NAME)
return JS_TRUE;
JSLocalKind localKind = js_LookupLocal(cx, caller->fun, atom, &index);
if (localKind == JSLOCAL_NONE)
return JS_TRUE;
/*
* Don't generate upvars on the left side of a for loop. See
* bug 470758.
*/
if (cg->flags & TCF_IN_FOR_INIT)
uintN upvarLevel = caller->fun->u.i.script->staticLevel;
JS_ASSERT(cg->staticLevel > upvarLevel);
if (upvarLevel >= JS_DISPLAY_SIZE)
return JS_TRUE;
ale = cg->upvarList.lookup(atom);
@ -1962,8 +1968,7 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
index += caller->fun->nargs;
JS_ASSERT(index < JS_BIT(16));
JS_ASSERT(cg->staticLevel > caller->fun->u.i.script->staticLevel);
uintN skip = cg->staticLevel - caller->fun->u.i.script->staticLevel;
uintN skip = cg->staticLevel - upvarLevel;
cg->upvarMap.vector[ALE_INDEX(ale)] = MAKE_UPVAR_COOKIE(skip, index);
}
@ -2034,15 +2039,18 @@ BindNameToSlot(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
/*
* If op is a mutating opcode or the function is heavyweight, we fall
* back on JSOP_*NAME*.
* If op is a mutating opcode, this upvar's static level is too big to
* index into the display, or the function is heavyweight, we fall back
* on JSOP_*NAME*.
*/
if (op != JSOP_NAME || (cg->flags & TCF_FUN_HEAVYWEIGHT))
if (op != JSOP_NAME)
return JS_TRUE;
if (level >= JS_DISPLAY_SIZE)
return JS_TRUE;
if (cg->flags & TCF_FUN_HEAVYWEIGHT)
return JS_TRUE;
if (FUN_FLAT_CLOSURE(cg->fun)) {
/* Flat closure is formed one frame up from its static level. */
--skip;
op = JSOP_GETDSLOT;
} else {
/*

View File

@ -2205,14 +2205,14 @@ js_NewFlatClosure(JSContext *cx, JSFunction *fun)
JSUpvarArray *uva = JS_SCRIPT_UPVARS(fun->u.i.script);
JS_ASSERT(uva->length <= size_t(closure->dslots[-1]));
JSStackFrame *fp = js_GetTopStackFrame(cx);
for (uint32 i = 0, n = uva->length; i < n; i++) {
JSStackFrame *fp2 = fp;
for (uintN skip = UPVAR_FRAME_SKIP(uva->vector[i]); skip != 0; --skip)
fp2 = fp2->down;
uint32 cookie = uva->vector[i];
uintN slot = UPVAR_FRAME_SLOT(uva->vector[i]);
uintN upvarLevel = fun->u.i.script->staticLevel - UPVAR_FRAME_SKIP(cookie);
JS_ASSERT(upvarLevel <= JS_DISPLAY_SIZE);
JSStackFrame *fp2 = cx->display[upvarLevel];
uintN slot = UPVAR_FRAME_SLOT(cookie);
jsval *vp;
if (fp2->fun && slot < fp2->fun->nargs) {
vp = fp2->argv;

View File

@ -1659,6 +1659,19 @@ FindFunArgs(JSFunctionBox *funbox, int level, JSFunctionBoxQueue *queue)
JSParseNode *fn = funbox->node;
int fnlevel = level;
/*
* An eval can leak funbox, functions along its ancestor line, and its
* immediate kids. Since FindFunArgs uses DFS and the parser propagates
* TCF_FUN_HEAVYWEIGHT bottom up, funbox's ancestor function nodes have
* already been marked as funargs by this point. Therefore we have to
* flag only funbox->node and funbox->kids' nodes here.
*/
if (funbox->tcflags & TCF_FUN_HEAVYWEIGHT) {
fn->pn_dflags |= PND_FUNARG;
for (JSFunctionBox *kid = funbox->kids; kid; kid = kid->siblings)
kid->node->pn_dflags |= PND_FUNARG;
}
if (fn->isFunArg()) {
queue->push(funbox);
fnlevel = int(funbox->level);
@ -2280,7 +2293,7 @@ LeaveFunction(JSParseNode *fn, JSTreeContext *funtc, JSTreeContext *tc,
if (!fn->pn_body)
return false;
fn->pn_body->pn_type = TOK_UPVARS;
fn->pn_pos = body->pn_pos;
fn->pn_body->pn_pos = body->pn_pos;
fn->pn_body->pn_names = funtc->upvars;
fn->pn_body->pn_tree = body;
funtc->upvars.clear();

View File

@ -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 - 43)
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 44)
/*
* Library-private functions.