diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 6814e2b446ba..bde31609c982 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -5033,13 +5033,18 @@ BumpStaticLevel(ParseNode *pn, TreeContext *tc) return pn->pn_cookie.set(tc->sc->context, level, pn->pn_cookie.slot()); } -static void +static bool AdjustBlockId(ParseNode *pn, unsigned adjust, TreeContext *tc) { JS_ASSERT(pn->isArity(PN_LIST) || pn->isArity(PN_FUNC) || pn->isArity(PN_NAME)); + if (JS_BIT(20) - pn->pn_blockid <= adjust + 1) { + JS_ReportErrorNumber(tc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program"); + return false; + } pn->pn_blockid += adjust; if (pn->pn_blockid >= tc->blockidGen) tc->blockidGen = pn->pn_blockid + 1; + return true; } bool @@ -5056,8 +5061,10 @@ CompExprTransplanter::transplant(ParseNode *pn) if (!transplant(pn2)) return false; } - if (pn->pn_pos >= root->pn_pos) - AdjustBlockId(pn, adjust, tc); + if (pn->pn_pos >= root->pn_pos) { + if (!AdjustBlockId(pn, adjust, tc)) + return false; + } break; case PN_TERNARY: @@ -5142,7 +5149,8 @@ CompExprTransplanter::transplant(ParseNode *pn) if (dn->isPlaceholder() && dn->pn_pos >= root->pn_pos && dn->dn_uses == pn) { if (genexp && !BumpStaticLevel(dn, tc)) return false; - AdjustBlockId(dn, adjust, tc); + if (!AdjustBlockId(dn, adjust, tc)) + return false; } RootedAtom atom(parser->context, pn->pn_atom); @@ -5203,7 +5211,8 @@ CompExprTransplanter::transplant(ParseNode *pn) if (genexp && !visitedImplicitArguments.has(dn)) { if (!BumpStaticLevel(dn, tc)) return false; - AdjustBlockId(dn, adjust, tc); + if (!AdjustBlockId(dn, adjust, tc)) + return false; if (!visitedImplicitArguments.put(dn)) return false; } @@ -5211,8 +5220,10 @@ CompExprTransplanter::transplant(ParseNode *pn) } } - if (pn->pn_pos >= root->pn_pos) - AdjustBlockId(pn, adjust, tc); + if (pn->pn_pos >= root->pn_pos) { + if (!AdjustBlockId(pn, adjust, tc)) + return false; + } break; case PN_NAMESET: @@ -5292,7 +5303,8 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp, if (!transplanter.init()) return NULL; - transplanter.transplant(kid); + if (!transplanter.transplant(kid)) + return false; JS_ASSERT(tc->blockChain && tc->blockChain == pn->pn_objbox->object); data.initLet(HoistVars, *tc->blockChain, JSMSG_ARRAY_INIT_TOO_BIG); diff --git a/js/src/frontend/TreeContext.cpp b/js/src/frontend/TreeContext.cpp index b3b301fe1ff0..26a190f01bc4 100644 --- a/js/src/frontend/TreeContext.cpp +++ b/js/src/frontend/TreeContext.cpp @@ -30,6 +30,7 @@ frontend::GenerateBlockId(TreeContext *tc, uint32_t &blockid) JS_ReportErrorNumber(tc->sc->context, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, "program"); return false; } + JS_ASSERT(tc->blockidGen < JS_BIT(20)); blockid = tc->blockidGen++; return true; } diff --git a/js/src/jit-test/tests/basic/testBug773108.js b/js/src/jit-test/tests/basic/testBug773108.js new file mode 100644 index 000000000000..533ce60f7fa4 --- /dev/null +++ b/js/src/jit-test/tests/basic/testBug773108.js @@ -0,0 +1,10 @@ +// |jit-test| error:InternalError + +Function("\ +for each(l in[(let(c)([])\ +for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\ +(let(u)w for each(l in[]))(let(c)w for(u in[]))(let(u)w for(l in[]))(let(c)w for(u in[]))\ +(let(l)w for(l in[]))(let(u)w for(l in['']))(let(c)w for(u in[]))(let(u)w for(l in[]))\ +(let(c)w for(l in[]))(let(l)w for(l in[]))(let(c)w for(l in[]))(let(u)w for(l in[]))\ +(let(c)w for(l in[]))(let(u)w for each(l in[x]))(let(w,x)w for(u in[]))]){}\ +")