Bug 1183400 - Fold !/~/+/- by kind. r=efaust

--HG--
extra : rebase_source : b22f1a97011aaca271d54c63d8ff5b85e8b910e6
This commit is contained in:
Jeff Walden 2015-05-22 19:02:41 -07:00
Родитель 4209f5efcd
Коммит 9ffd11a1f7
1 изменённых файлов: 76 добавлений и 58 удалений

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

@ -753,6 +753,75 @@ FoldDeleteProperty(ExclusiveContext* cx, ParseNode* node, FullParseHandler& hand
return true; return true;
} }
static bool
FoldNot(ExclusiveContext* cx, ParseNode* node, FullParseHandler& handler,
const ReadOnlyCompileOptions& options, bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_NOT));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, handler, options, inGenexpLambda, SyntacticContext::Condition))
return false;
if (expr->isKind(PNK_NUMBER)) {
double d = expr->pn_dval;
handler.prepareNodeForMutation(node);
if (d == 0 || IsNaN(d)) {
node->setKind(PNK_TRUE);
node->setOp(JSOP_TRUE);
} else {
node->setKind(PNK_FALSE);
node->setOp(JSOP_FALSE);
}
node->setArity(PN_NULLARY);
} else if (expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) {
bool newval = !expr->isKind(PNK_TRUE);
handler.prepareNodeForMutation(node);
node->setKind(newval ? PNK_TRUE : PNK_FALSE);
node->setArity(PN_NULLARY);
node->setOp(newval ? JSOP_TRUE : JSOP_FALSE);
}
return true;
}
static bool
FoldUnaryArithmetic(ExclusiveContext* cx, ParseNode* node, FullParseHandler& handler,
const ReadOnlyCompileOptions& options, bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_BITNOT) || node->isKind(PNK_POS) || node->isKind(PNK_NEG),
"need a different method for this node kind");
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, handler, options, inGenexpLambda, SyntacticContext::Other))
return false;
if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) {
double d = expr->isKind(PNK_NUMBER)
? expr->pn_dval
: double(expr->isKind(PNK_TRUE));
if (node->isKind(PNK_BITNOT))
d = ~ToInt32(d);
else if (node->isKind(PNK_NEG))
d = -d;
else
MOZ_ASSERT(node->isKind(PNK_POS)); // nothing to do
handler.prepareNodeForMutation(node);
node->setKind(PNK_NUMBER);
node->setOp(JSOP_DOUBLE);
node->setArity(PN_NULLARY);
node->pn_dval = d;
}
return true;
}
bool bool
Fold(ExclusiveContext* cx, ParseNode** pnp, Fold(ExclusiveContext* cx, ParseNode** pnp,
FullParseHandler& handler, const ReadOnlyCompileOptions& options, FullParseHandler& handler, const ReadOnlyCompileOptions& options,
@ -832,10 +901,14 @@ Fold(ExclusiveContext* cx, ParseNode** pnp,
return FoldDeleteProperty(cx, pn, handler, options, inGenexpLambda); return FoldDeleteProperty(cx, pn, handler, options, inGenexpLambda);
case PNK_NOT: case PNK_NOT:
return FoldNot(cx, pn, handler, options, inGenexpLambda);
case PNK_BITNOT: case PNK_BITNOT:
case PNK_THROW:
case PNK_POS: case PNK_POS:
case PNK_NEG: case PNK_NEG:
return FoldUnaryArithmetic(cx, pn, handler, options, inGenexpLambda);
case PNK_THROW:
case PNK_PREINCREMENT: case PNK_PREINCREMENT:
case PNK_POSTINCREMENT: case PNK_POSTINCREMENT:
case PNK_PREDECREMENT: case PNK_PREDECREMENT:
@ -1044,10 +1117,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp,
MOZ_ASSERT(!IsDeleteKind(pn->getKind()), MOZ_ASSERT(!IsDeleteKind(pn->getKind()),
"should have been handled above"); "should have been handled above");
if (pn->pn_kid) { if (pn->pn_kid) {
SyntacticContext kidsc = pn->isKind(PNK_NOT) if (!Fold(cx, &pn->pn_kid, handler, options, inGenexpLambda, SyntacticContext::Other))
? SyntacticContext::Condition
: SyntacticContext::Other;
if (!Fold(cx, &pn->pn_kid, handler, options, inGenexpLambda, kidsc))
return false; return false;
} }
pn1 = pn->pn_kid; pn1 = pn->pn_kid;
@ -1333,63 +1403,11 @@ Fold(ExclusiveContext* cx, ParseNode** pnp,
case PNK_TYPEOFNAME: case PNK_TYPEOFNAME:
case PNK_TYPEOFEXPR: case PNK_TYPEOFEXPR:
case PNK_VOID: case PNK_VOID:
MOZ_CRASH("should have been fully handled above");
case PNK_NOT: case PNK_NOT:
case PNK_BITNOT: case PNK_BITNOT:
case PNK_POS: case PNK_POS:
case PNK_NEG: case PNK_NEG:
if (pn1->isKind(PNK_NUMBER)) { MOZ_CRASH("should have been fully handled above");
double d;
/* Operate on one numeric constant. */
d = pn1->pn_dval;
switch (pn->getKind()) {
case PNK_BITNOT:
d = ~ToInt32(d);
break;
case PNK_NEG:
d = -d;
break;
case PNK_POS:
break;
case PNK_NOT:
if (d == 0 || IsNaN(d)) {
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
} else {
pn->setKind(PNK_FALSE);
pn->setOp(JSOP_FALSE);
}
pn->setArity(PN_NULLARY);
/* FALL THROUGH */
default:
/* Return early to dodge the common PNK_NUMBER code. */
goto restart;
}
pn->setKind(PNK_NUMBER);
pn->setOp(JSOP_DOUBLE);
pn->setArity(PN_NULLARY);
pn->pn_dval = d;
handler.freeTree(pn1);
} else if (pn1->isKind(PNK_TRUE) || pn1->isKind(PNK_FALSE)) {
if (pn->isKind(PNK_NOT)) {
ReplaceNode(pnp, pn1);
pn = pn1;
if (pn->isKind(PNK_TRUE)) {
pn->setKind(PNK_FALSE);
pn->setOp(JSOP_FALSE);
} else {
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
}
}
}
break;
case PNK_ELEM: { case PNK_ELEM: {
// An indexed expression, pn1[pn2]. A few cases can be improved. // An indexed expression, pn1[pn2]. A few cases can be improved.