Bug 773108 - Avoid overflowing blockid in CompExprTransplanter (r=dvander)

This commit is contained in:
Luke Wagner 2012-07-11 22:07:25 -07:00
Родитель ecbebd6e01
Коммит 112a3cced0
3 изменённых файлов: 31 добавлений и 8 удалений

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

@ -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);

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

@ -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;
}

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

@ -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[]))]){}\
")