[Bug 389605] r=brendan a1.9=beltzner

This commit is contained in:
igor@mir2.org 2008-04-10 08:50:02 -07:00
Родитель ae5b3ccab3
Коммит 328d4e2b81
4 изменённых файлов: 44 добавлений и 2 удалений

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

@ -6483,6 +6483,7 @@ interrupt:
LOAD_OBJECT(0);
JS_ASSERT(fp->spbase + OBJ_BLOCK_DEPTH(cx, obj) == regs.sp);
vp = regs.sp + OBJ_BLOCK_COUNT(cx, obj);
JS_ASSERT(regs.sp < vp);
JS_ASSERT(vp <= fp->spbase + script->depth);
while (regs.sp < vp) {
STORE_OPND(0, JSVAL_VOID);

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

@ -1975,6 +1975,12 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
continue;
if (!(sprop->flags & SPROP_HAS_SHORTID))
continue;
if (sprop->id == ATOM_TO_JSID(cx->runtime->atomState.emptyAtom)) {
/* See comments before EnsureNonEmptyLet from jsparse.c. */
JS_ASSERT(OBJ_BLOCK_COUNT(cx, obj) == 1);
JS_ASSERT(sprop->shortid == 0);
continue;
}
slot = depth + (uintN) sprop->shortid;
JS_ASSERT(slot < (size_t) (fp->regs->sp - fp->spbase));
if (!js_DefineNativeProperty(cx, obj, sprop->id,

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

@ -1658,6 +1658,37 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
NULL);
}
#if JS_HAS_DESTRUCTURING
/*
* The catch/finally handler implementation in the interpreter assumes that
* any operation that introduces a new scope (like a "let" or "with" block)
* increases the stack depth. This way, it is possible to restore the scope
* chain based on stack depth of the handler alone. A let block with an empty
* destructuring pattern like in
*
* let [] = 1;
*
* would violate this assumption as the there would be no let locals to store
* on the stack. To satisfy it we add an empty property to such blocks so
* OBJ_BLOCK_COUNT(cx, blockObj), that gives the number of slots, would be
* always positive.
*/
static JSBool
EnsureNonEmptyLet(JSContext *cx, JSTreeContext *tc)
{
jsid id;
if (OBJ_BLOCK_COUNT(cx, tc->blockChain) != 0)
return JS_TRUE;
id = ATOM_TO_JSID(cx->runtime->atomState.emptyAtom);
return js_DefineNativeProperty(cx, tc->blockChain, id,
JSVAL_VOID, NULL, NULL,
JSPROP_PERMANENT | JSPROP_READONLY,
SPROP_HAS_SHORTID, 0, NULL);
}
#endif
static JSBool
BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
{
@ -2971,7 +3002,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_LB:
case TOK_LC:
pn3 = DestructuringExpr(cx, &data, tc, tt);
if (!pn3)
if (!pn3 || !EnsureNonEmptyLet(cx, tc))
return NULL;
break;
#endif
@ -3588,6 +3619,10 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
tc->flags |= TCF_FUN_HEAVYWEIGHT;
}
} while (js_MatchToken(cx, ts, TOK_COMMA));
#if JS_HAS_DESTRUCTURING
if (let && !EnsureNonEmptyLet(cx, tc))
return NULL;
#endif
pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
return pn;

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

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