mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
[Bug 428706] Making sure that all let blocks has non-zero stack depth. r=brendan a1.9=beltzner
This commit is contained in:
parent
e05963a7da
commit
1301d0403b
@ -1976,7 +1976,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
|
||||
if (!(sprop->flags & SPROP_HAS_SHORTID))
|
||||
continue;
|
||||
if (sprop->id == ATOM_TO_JSID(cx->runtime->atomState.emptyAtom)) {
|
||||
/* See comments before EnsureNonEmptyLet from jsparse.c. */
|
||||
/* See comments in CheckDestructuring from jsparse.c. */
|
||||
JS_ASSERT(sprop->shortid == 0);
|
||||
continue;
|
||||
}
|
||||
|
@ -1658,37 +1658,6 @@ 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)
|
||||
{
|
||||
@ -2058,7 +2027,6 @@ CheckDestructuring(JSContext *cx, BindData *data,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ok = JS_TRUE;
|
||||
fpvd.table.ops = NULL;
|
||||
lhs = left->pn_head;
|
||||
if (lhs && lhs->pn_type == TOK_DEFSHARP) {
|
||||
@ -2145,12 +2113,43 @@ CheckDestructuring(JSContext *cx, BindData *data,
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* 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. "let" 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 that OBJ_BLOCK_COUNT(cx, blockObj), which gives the number of
|
||||
* slots, would be always positive.
|
||||
*
|
||||
* Note that we add such a property even if the block has locals due to
|
||||
* later let declarations in it. We optimize for code simplicity here,
|
||||
* not the fastest runtime performance with empty [] or {}.
|
||||
*/
|
||||
if (data->binder == BindLet && OBJ_BLOCK_COUNT(cx, tc->blockChain) == 0) {
|
||||
ok = js_DefineNativeProperty(cx, tc->blockChain,
|
||||
ATOM_TO_JSID(cx->runtime->
|
||||
atomState.emptyAtom),
|
||||
JSVAL_VOID, NULL, NULL,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
SPROP_HAS_SHORTID, 0, NULL);
|
||||
if (!ok)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ok = JS_TRUE;
|
||||
|
||||
out:
|
||||
if (fpvd.table.ops)
|
||||
JS_DHashTableFinish(&fpvd.table);
|
||||
return ok;
|
||||
|
||||
no_var_name:
|
||||
no_var_name:
|
||||
js_ReportCompileErrorNumber(cx, TS(tc->parseContext), pn, JSREPORT_ERROR,
|
||||
JSMSG_NO_VARIABLE_NAME);
|
||||
ok = JS_FALSE;
|
||||
@ -3002,7 +3001,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
case TOK_LB:
|
||||
case TOK_LC:
|
||||
pn3 = DestructuringExpr(cx, &data, tc, tt);
|
||||
if (!pn3 || !EnsureNonEmptyLet(cx, tc))
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
break;
|
||||
#endif
|
||||
@ -3619,10 +3618,6 @@ 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;
|
||||
|
Loading…
Reference in New Issue
Block a user