mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[Bug 389605] r=brendan a1.9=beltzner
This commit is contained in:
parent
b8b85c46b1
commit
8160179799
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user