From 9403abe82d9b2a56efd49ffd68d4dc47343baf74 Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Fri, 18 Apr 2008 07:59:48 +0000 Subject: [PATCH] [Bug 428706] Backing out to investigate startup failures --- js/src/jsobj.c | 2 +- js/src/jsparse.c | 73 ++++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/js/src/jsobj.c b/js/src/jsobj.c index 7e786a682d0..785f54c042d 100644 --- a/js/src/jsobj.c +++ b/js/src/jsobj.c @@ -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 in CheckDestructuring from jsparse.c. */ + /* See comments before EnsureNonEmptyLet from jsparse.c. */ JS_ASSERT(sprop->shortid == 0); continue; } diff --git a/js/src/jsparse.c b/js/src/jsparse.c index a74eba93ae6..12d5403ba29 100644 --- a/js/src/jsparse.c +++ b/js/src/jsparse.c @@ -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) { @@ -2027,6 +2058,7 @@ 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) { @@ -2113,43 +2145,12 @@ CheckDestructuring(JSContext *cx, BindData *data, } } - /* - * 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: +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; @@ -3001,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 @@ -3618,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;