Bug 1660055 - Convert FoldConstants to use ParserAtoms. r=tcampbell

Differential Revision: https://phabricator.services.mozilla.com/D87643
This commit is contained in:
Kannan Vijayan 2020-08-24 16:50:28 +00:00
Родитель 7f624e0a5e
Коммит 0afd0b76f9
3 изменённых файлов: 133 добавлений и 122 удалений

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

@ -29,6 +29,13 @@ using mozilla::IsNegative;
using mozilla::NegativeInfinity;
using mozilla::PositiveInfinity;
struct FoldInfo {
CompilationInfo& compilationInfo;
FullParseHandler* handler;
JSContext* cx() { return compilationInfo.cx; }
};
// Don't use ReplaceNode directly, because we want the constant folder to keep
// the attributes isInParens and isDirectRHSAnonFunction of the old node being
// replaced.
@ -448,19 +455,18 @@ restart:
* Fold from one constant type to another.
* XXX handles only strings and numbers for now
*/
static bool FoldType(JSContext* cx, FullParseHandler* handler, ParseNode** pnp,
ParseNodeKind kind) {
static bool FoldType(FoldInfo info, ParseNode** pnp, ParseNodeKind kind) {
const ParseNode* pn = *pnp;
if (!pn->isKind(kind)) {
switch (kind) {
case ParseNodeKind::NumberExpr:
if (pn->isKind(ParseNodeKind::StringExpr)) {
double d;
if (!StringToNumber(cx, pn->as<NameNode>().atom(), &d)) {
if (!StringToNumber(info.cx(), pn->as<NameNode>().atom(), &d)) {
return false;
}
if (!TryReplaceNode(pnp,
handler->newNumber(d, NoDecimal, pn->pn_pos))) {
if (!TryReplaceNode(
pnp, info.handler->newNumber(d, NoDecimal, pn->pn_pos))) {
return false;
}
}
@ -468,12 +474,12 @@ static bool FoldType(JSContext* cx, FullParseHandler* handler, ParseNode** pnp,
case ParseNodeKind::StringExpr:
if (pn->isKind(ParseNodeKind::NumberExpr)) {
JSAtom* atom = pn->as<NumericLiteral>().toAtom(cx);
JSAtom* atom = pn->as<NumericLiteral>().toAtom(info.cx());
if (!atom) {
return false;
}
if (!TryReplaceNode(pnp,
handler->newStringLiteral(atom, pn->pn_pos))) {
if (!TryReplaceNode(
pnp, info.handler->newStringLiteral(atom, pn->pn_pos))) {
return false;
}
}
@ -543,8 +549,7 @@ static Truthiness Boolish(ParseNode* pn) {
}
}
static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool SimplifyCondition(FoldInfo info, ParseNode** nodePtr) {
// Conditions fold like any other expression, but then they sometimes can be
// further folded to constants. *nodePtr should already have been
// constant-folded.
@ -556,8 +561,8 @@ static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler,
// that appears on a method list corrupts the method list. However,
// methods are M's in statements of the form 'this.foo = M;', which we
// never fold, so we're okay.
if (!TryReplaceNode(
nodePtr, handler->newBooleanLiteral(t == Truthy, node->pn_pos))) {
if (!TryReplaceNode(nodePtr, info.handler->newBooleanLiteral(
t == Truthy, node->pn_pos))) {
return false;
}
}
@ -565,33 +570,32 @@ static bool SimplifyCondition(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldTypeOfExpr(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldTypeOfExpr(FoldInfo info, ParseNode** nodePtr) {
UnaryNode* node = &(*nodePtr)->as<UnaryNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::TypeOfExpr));
ParseNode* expr = node->kid();
// Constant-fold the entire |typeof| if given a constant with known type.
RootedPropertyName result(cx);
RootedPropertyName result(info.cx());
if (expr->isKind(ParseNodeKind::StringExpr) ||
expr->isKind(ParseNodeKind::TemplateStringExpr)) {
result = cx->names().string;
result = info.cx()->names().string;
} else if (expr->isKind(ParseNodeKind::NumberExpr)) {
result = cx->names().number;
result = info.cx()->names().number;
} else if (expr->isKind(ParseNodeKind::BigIntExpr)) {
result = cx->names().bigint;
result = info.cx()->names().bigint;
} else if (expr->isKind(ParseNodeKind::NullExpr)) {
result = cx->names().object;
result = info.cx()->names().object;
} else if (expr->isKind(ParseNodeKind::TrueExpr) ||
expr->isKind(ParseNodeKind::FalseExpr)) {
result = cx->names().boolean;
result = info.cx()->names().boolean;
} else if (expr->is<FunctionNode>()) {
result = cx->names().function;
result = info.cx()->names().function;
}
if (result) {
if (!TryReplaceNode(nodePtr,
handler->newStringLiteral(result, node->pn_pos))) {
info.handler->newStringLiteral(result, node->pn_pos))) {
return false;
}
}
@ -599,8 +603,7 @@ static bool FoldTypeOfExpr(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldDeleteExpr(FoldInfo info, ParseNode** nodePtr) {
UnaryNode* node = &(*nodePtr)->as<UnaryNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteExpr));
@ -610,7 +613,7 @@ static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler,
// For effectless expressions, eliminate the expression evaluation.
if (IsEffectless(expr)) {
if (!TryReplaceNode(nodePtr,
handler->newBooleanLiteral(true, node->pn_pos))) {
info.handler->newBooleanLiteral(true, node->pn_pos))) {
return false;
}
}
@ -618,8 +621,7 @@ static bool FoldDeleteExpr(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldDeleteElement(FoldInfo info, ParseNode** nodePtr) {
UnaryNode* node = &(*nodePtr)->as<UnaryNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::DeleteElemExpr));
ParseNode* expr = node->kid();
@ -635,7 +637,7 @@ static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler,
if (expr->isKind(ParseNodeKind::DotExpr)) {
// newDelete will detect and use DeletePropExpr
if (!TryReplaceNode(nodePtr,
handler->newDelete(node->pn_pos.begin, expr))) {
info.handler->newDelete(node->pn_pos.begin, expr))) {
return false;
}
MOZ_ASSERT((*nodePtr)->getKind() == ParseNodeKind::DeletePropExpr);
@ -644,12 +646,11 @@ static bool FoldDeleteElement(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldNot(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldNot(FoldInfo info, ParseNode** nodePtr) {
UnaryNode* node = &(*nodePtr)->as<UnaryNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::NotExpr));
if (!SimplifyCondition(cx, handler, node->unsafeKidReference())) {
if (!SimplifyCondition(info, node->unsafeKidReference())) {
return false;
}
@ -659,8 +660,8 @@ static bool FoldNot(JSContext* cx, FullParseHandler* handler,
expr->isKind(ParseNodeKind::FalseExpr)) {
bool newval = !expr->isKind(ParseNodeKind::TrueExpr);
if (!TryReplaceNode(nodePtr,
handler->newBooleanLiteral(newval, node->pn_pos))) {
if (!TryReplaceNode(
nodePtr, info.handler->newBooleanLiteral(newval, node->pn_pos))) {
return false;
}
}
@ -668,8 +669,7 @@ static bool FoldNot(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldUnaryArithmetic(FoldInfo info, ParseNode** nodePtr) {
UnaryNode* node = &(*nodePtr)->as<UnaryNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::BitNotExpr) ||
node->isKind(ParseNodeKind::PosExpr) ||
@ -694,7 +694,7 @@ static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler,
}
if (!TryReplaceNode(nodePtr,
handler->newNumber(d, NoDecimal, node->pn_pos))) {
info.handler->newNumber(d, NoDecimal, node->pn_pos))) {
return false;
}
}
@ -702,7 +702,7 @@ static bool FoldUnaryArithmetic(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldAndOrCoalesce(JSContext* cx, ParseNode** nodePtr) {
static bool FoldAndOrCoalesce(FoldInfo info, ParseNode** nodePtr) {
ListNode* node = &(*nodePtr)->as<ListNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::AndExpr) ||
@ -779,10 +779,9 @@ static bool FoldAndOrCoalesce(JSContext* cx, ParseNode** nodePtr) {
return true;
}
static bool Fold(JSContext* cx, FullParseHandler* handler, ParseNode** pnp);
static bool Fold(FoldInfo info, ParseNode** pnp);
static bool FoldConditional(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldConditional(FoldInfo info, ParseNode** nodePtr) {
ParseNode** nextNode = nodePtr;
do {
@ -796,15 +795,15 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler,
MOZ_ASSERT(node->isKind(ParseNodeKind::ConditionalExpr));
ParseNode** expr = node->unsafeKid1Reference();
if (!Fold(cx, handler, expr)) {
if (!Fold(info, expr)) {
return false;
}
if (!SimplifyCondition(cx, handler, expr)) {
if (!SimplifyCondition(info, expr)) {
return false;
}
ParseNode** ifTruthy = node->unsafeKid2Reference();
if (!Fold(cx, handler, ifTruthy)) {
if (!Fold(info, ifTruthy)) {
return false;
}
@ -821,7 +820,7 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler,
MOZ_ASSERT((*ifFalsy)->is<TernaryNode>());
nextNode = ifFalsy;
} else {
if (!Fold(cx, handler, ifFalsy)) {
if (!Fold(info, ifFalsy)) {
return false;
}
}
@ -847,8 +846,7 @@ static bool FoldConditional(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldIf(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldIf(FoldInfo info, ParseNode** nodePtr) {
ParseNode** nextNode = nodePtr;
do {
@ -861,15 +859,15 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler,
MOZ_ASSERT(node->isKind(ParseNodeKind::IfStmt));
ParseNode** expr = node->unsafeKid1Reference();
if (!Fold(cx, handler, expr)) {
if (!Fold(info, expr)) {
return false;
}
if (!SimplifyCondition(cx, handler, expr)) {
if (!SimplifyCondition(info, expr)) {
return false;
}
ParseNode** consequent = node->unsafeKid2Reference();
if (!Fold(cx, handler, consequent)) {
if (!Fold(info, consequent)) {
return false;
}
@ -884,7 +882,7 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler,
MOZ_ASSERT((*alternative)->is<TernaryNode>());
nextNode = alternative;
} else {
if (!Fold(cx, handler, alternative)) {
if (!Fold(info, alternative)) {
return false;
}
}
@ -914,7 +912,8 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler,
// A declaration that hoists outside the discarded arm prevents the
// |if| from being folded away.
bool containsHoistedDecls;
if (!ContainsHoistedDeclaration(cx, discarded, &containsHoistedDecls)) {
if (!ContainsHoistedDeclaration(info.cx(), discarded,
&containsHoistedDecls)) {
return false;
}
@ -929,7 +928,8 @@ static bool FoldIf(JSContext* cx, FullParseHandler* handler,
// If there's no replacement node, we have a constantly-false |if|
// with no |else|. Replace the entire thing with an empty
// statement list.
if (!TryReplaceNode(nodePtr, handler->newStatementList(node->pn_pos))) {
if (!TryReplaceNode(nodePtr,
info.handler->newStatementList(node->pn_pos))) {
return false;
}
} else {
@ -978,8 +978,7 @@ static double ComputeBinary(ParseNodeKind kind, double left, double right) {
return int32_t((kind == ParseNodeKind::LshExpr) ? uint32_t(i) << j : i >> j);
}
static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldBinaryArithmetic(FoldInfo info, ParseNode** nodePtr) {
ListNode* node = &(*nodePtr)->as<ListNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::SubExpr) ||
node->isKind(ParseNodeKind::MulExpr) ||
@ -993,7 +992,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler,
// Fold each operand to a number if possible.
ParseNode** listp = node->unsafeHeadReference();
for (; *listp; listp = &(*listp)->pn_next) {
if (!FoldType(cx, handler, listp, ParseNodeKind::NumberExpr)) {
if (!FoldType(info, listp, ParseNodeKind::NumberExpr)) {
return false;
}
}
@ -1017,7 +1016,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler,
(*next)->as<NumericLiteral>().value());
TokenPos pos((*elem)->pn_pos.begin, (*next)->pn_pos.end);
if (!TryReplaceNode(elem, handler->newNumber(d, NoDecimal, pos))) {
if (!TryReplaceNode(elem, info.handler->newNumber(d, NoDecimal, pos))) {
return false;
}
@ -1039,8 +1038,7 @@ static bool FoldBinaryArithmetic(JSContext* cx, FullParseHandler* handler,
return true;
}
static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldExponentiation(FoldInfo info, ParseNode** nodePtr) {
ListNode* node = &(*nodePtr)->as<ListNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::PowExpr));
MOZ_ASSERT(node->count() >= 2);
@ -1048,7 +1046,7 @@ static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler,
// Fold each operand, ideally into a number.
ParseNode** listp = node->unsafeHeadReference();
for (; *listp; listp = &(*listp)->pn_next) {
if (!FoldType(cx, handler, listp, ParseNodeKind::NumberExpr)) {
if (!FoldType(info, listp, ParseNodeKind::NumberExpr)) {
return false;
}
}
@ -1074,12 +1072,11 @@ static bool FoldExponentiation(JSContext* cx, FullParseHandler* handler,
double d1 = base->as<NumericLiteral>().value();
double d2 = exponent->as<NumericLiteral>().value();
return TryReplaceNode(
nodePtr, handler->newNumber(ecmaPow(d1, d2), NoDecimal, node->pn_pos));
return TryReplaceNode(nodePtr, info.handler->newNumber(
ecmaPow(d1, d2), NoDecimal, node->pn_pos));
}
static bool FoldElement(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldElement(FoldInfo info, ParseNode** nodePtr) {
PropertyByValue* elem = &(*nodePtr)->as<PropertyByValue>();
ParseNode* expr = &elem->expression();
@ -1092,8 +1089,9 @@ static bool FoldElement(JSContext* cx, FullParseHandler* handler,
if (atom->isIndex(&index)) {
// Optimization 1: We have something like expr["100"]. This is
// equivalent to expr[100] which is faster.
if (!TryReplaceNode(elem->unsafeRightReference(),
handler->newNumber(index, NoDecimal, key->pn_pos))) {
if (!TryReplaceNode(
elem->unsafeRightReference(),
info.handler->newNumber(index, NoDecimal, key->pn_pos))) {
return false;
}
key = &elem->key();
@ -1107,7 +1105,7 @@ static bool FoldElement(JSContext* cx, FullParseHandler* handler,
// Optimization 2: We have something like expr[3.14]. The number
// isn't an array index, so it converts to a string ("3.14"),
// enabling optimization 3 below.
JSAtom* atom = numeric->toAtom(cx);
JSAtom* atom = numeric->toAtom(info.cx());
if (!atom) {
return false;
}
@ -1123,20 +1121,19 @@ static bool FoldElement(JSContext* cx, FullParseHandler* handler,
// Optimization 3: We have expr["foo"] where foo is not an index. Convert
// to a property access (like expr.foo) that optimizes better downstream.
NameNode* propertyNameExpr = handler->newPropertyName(name, key->pn_pos);
NameNode* propertyNameExpr = info.handler->newPropertyName(name, key->pn_pos);
if (!propertyNameExpr) {
return false;
}
if (!TryReplaceNode(nodePtr,
handler->newPropertyAccess(expr, propertyNameExpr))) {
if (!TryReplaceNode(
nodePtr, info.handler->newPropertyAccess(expr, propertyNameExpr))) {
return false;
}
return true;
}
static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
ParseNode** nodePtr) {
static bool FoldAdd(FoldInfo info, ParseNode** nodePtr) {
ListNode* node = &(*nodePtr)->as<ListNode>();
MOZ_ASSERT(node->isKind(ParseNodeKind::AddExpr));
@ -1160,8 +1157,8 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
double right = (*next)->as<NumericLiteral>().value();
TokenPos pos((*current)->pn_pos.begin, (*next)->pn_pos.end);
if (!TryReplaceNode(current,
handler->newNumber(left + right, NoDecimal, pos))) {
if (!TryReplaceNode(
current, info.handler->newNumber(left + right, NoDecimal, pos))) {
return false;
}
@ -1183,7 +1180,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
// the list: (x + 1 + "2" !== x + "12") when x is a number.
if ((*current)->isKind(ParseNodeKind::NumberExpr) &&
(*next)->isKind(ParseNodeKind::StringExpr)) {
if (!FoldType(cx, handler, current, ParseNodeKind::StringExpr)) {
if (!FoldType(info, current, ParseNodeKind::StringExpr)) {
return false;
}
next = &(*current)->pn_next;
@ -1205,8 +1202,8 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
break;
}
RootedString combination(cx);
RootedString tmp(cx);
RootedString combination(info.cx());
RootedString tmp(info.cx());
do {
// Create a rope of the current string and all succeeding
// constants that we can convert to strings, then atomize it
@ -1217,7 +1214,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
do {
// Try folding the next operand to a string.
if (!FoldType(cx, handler, next, ParseNodeKind::StringExpr)) {
if (!FoldType(info, next, ParseNodeKind::StringExpr)) {
return false;
}
@ -1228,7 +1225,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
// Add this string to the combination and remove the node.
tmp = (*next)->as<NameNode>().atom();
combination = ConcatStrings<CanGC>(cx, combination, tmp);
combination = ConcatStrings<CanGC>(info.cx(), combination, tmp);
if (!combination) {
return false;
}
@ -1241,7 +1238,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
// Replace |current|'s string with the entire combination.
MOZ_ASSERT((*current)->isKind(ParseNodeKind::StringExpr));
combination = AtomizeString(cx, combination);
combination = AtomizeString(info.cx(), combination);
if (!combination) {
return false;
}
@ -1265,7 +1262,7 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
do {
current = next;
if (!FoldType(cx, handler, current, ParseNodeKind::StringExpr)) {
if (!FoldType(info, current, ParseNodeKind::StringExpr)) {
return false;
}
next = &(*current)->pn_next;
@ -1290,99 +1287,104 @@ static bool FoldAdd(JSContext* cx, FullParseHandler* handler,
class FoldVisitor : public RewritingParseNodeVisitor<FoldVisitor> {
using Base = RewritingParseNodeVisitor;
CompilationInfo& compilationInfo;
FullParseHandler* handler;
FoldInfo info() const { return FoldInfo{compilationInfo, handler}; }
public:
explicit FoldVisitor(JSContext* cx, FullParseHandler* handler)
: RewritingParseNodeVisitor(cx), handler(handler) {}
explicit FoldVisitor(JSContext* cx, CompilationInfo& compilationInfo,
FullParseHandler* handler)
: RewritingParseNodeVisitor(cx),
compilationInfo(compilationInfo),
handler(handler) {}
bool visitElemExpr(ParseNode*& pn) {
return Base::visitElemExpr(pn) && FoldElement(cx_, handler, &pn);
return Base::visitElemExpr(pn) && FoldElement(info(), &pn);
}
bool visitTypeOfExpr(ParseNode*& pn) {
return Base::visitTypeOfExpr(pn) && FoldTypeOfExpr(cx_, handler, &pn);
return Base::visitTypeOfExpr(pn) && FoldTypeOfExpr(info(), &pn);
}
bool visitDeleteExpr(ParseNode*& pn) {
return Base::visitDeleteExpr(pn) && FoldDeleteExpr(cx_, handler, &pn);
return Base::visitDeleteExpr(pn) && FoldDeleteExpr(info(), &pn);
}
bool visitDeleteElemExpr(ParseNode*& pn) {
return Base::visitDeleteElemExpr(pn) &&
FoldDeleteElement(cx_, handler, &pn);
return Base::visitDeleteElemExpr(pn) && FoldDeleteElement(info(), &pn);
}
bool visitNotExpr(ParseNode*& pn) {
return Base::visitNotExpr(pn) && FoldNot(cx_, handler, &pn);
return Base::visitNotExpr(pn) && FoldNot(info(), &pn);
}
bool visitBitNotExpr(ParseNode*& pn) {
return Base::visitBitNotExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn);
return Base::visitBitNotExpr(pn) && FoldUnaryArithmetic(info(), &pn);
}
bool visitPosExpr(ParseNode*& pn) {
return Base::visitPosExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn);
return Base::visitPosExpr(pn) && FoldUnaryArithmetic(info(), &pn);
}
bool visitNegExpr(ParseNode*& pn) {
return Base::visitNegExpr(pn) && FoldUnaryArithmetic(cx_, handler, &pn);
return Base::visitNegExpr(pn) && FoldUnaryArithmetic(info(), &pn);
}
bool visitPowExpr(ParseNode*& pn) {
return Base::visitPowExpr(pn) && FoldExponentiation(cx_, handler, &pn);
return Base::visitPowExpr(pn) && FoldExponentiation(info(), &pn);
}
bool visitMulExpr(ParseNode*& pn) {
return Base::visitMulExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitMulExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitDivExpr(ParseNode*& pn) {
return Base::visitDivExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitDivExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitModExpr(ParseNode*& pn) {
return Base::visitModExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitModExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitAddExpr(ParseNode*& pn) {
return Base::visitAddExpr(pn) && FoldAdd(cx_, handler, &pn);
return Base::visitAddExpr(pn) && FoldAdd(info(), &pn);
}
bool visitSubExpr(ParseNode*& pn) {
return Base::visitSubExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitSubExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitLshExpr(ParseNode*& pn) {
return Base::visitLshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitLshExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitRshExpr(ParseNode*& pn) {
return Base::visitRshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitRshExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitUrshExpr(ParseNode*& pn) {
return Base::visitUrshExpr(pn) && FoldBinaryArithmetic(cx_, handler, &pn);
return Base::visitUrshExpr(pn) && FoldBinaryArithmetic(info(), &pn);
}
bool visitAndExpr(ParseNode*& pn) {
// Note that this does result in the unfortunate fact that dead arms of this
// node get constant folded. The same goes for visitOr and visitCoalesce.
return Base::visitAndExpr(pn) && FoldAndOrCoalesce(cx_, &pn);
return Base::visitAndExpr(pn) && FoldAndOrCoalesce(info(), &pn);
}
bool visitOrExpr(ParseNode*& pn) {
return Base::visitOrExpr(pn) && FoldAndOrCoalesce(cx_, &pn);
return Base::visitOrExpr(pn) && FoldAndOrCoalesce(info(), &pn);
}
bool visitCoalesceExpr(ParseNode*& pn) {
return Base::visitCoalesceExpr(pn) && FoldAndOrCoalesce(cx_, &pn);
return Base::visitCoalesceExpr(pn) && FoldAndOrCoalesce(info(), &pn);
}
bool visitConditionalExpr(ParseNode*& pn) {
// Don't call base-class visitConditional because FoldConditional processes
// pn's child nodes specially to save stack space.
return FoldConditional(cx_, handler, &pn);
return FoldConditional(info(), &pn);
}
private:
@ -1447,7 +1449,7 @@ class FoldVisitor : public RewritingParseNodeVisitor<FoldVisitor> {
bool visitIfStmt(ParseNode*& pn) {
// Don't call base-class visitIf because FoldIf processes pn's child nodes
// specially to save stack space.
return FoldIf(cx_, handler, &pn);
return FoldIf(info(), &pn);
}
bool visitForStmt(ParseNode*& pn) {
@ -1460,7 +1462,7 @@ class FoldVisitor : public RewritingParseNodeVisitor<FoldVisitor> {
TernaryNode& head = stmt.left()->as<TernaryNode>();
ParseNode** test = head.unsafeKid2Reference();
if (*test) {
if (!SimplifyCondition(cx_, handler, test)) {
if (!SimplifyCondition(info(), test)) {
return false;
}
if ((*test)->isKind(ParseNodeKind::TrueExpr)) {
@ -1475,13 +1477,13 @@ class FoldVisitor : public RewritingParseNodeVisitor<FoldVisitor> {
bool visitWhileStmt(ParseNode*& pn) {
BinaryNode& node = pn->as<BinaryNode>();
return Base::visitWhileStmt(pn) &&
SimplifyCondition(cx_, handler, node.unsafeLeftReference());
SimplifyCondition(info(), node.unsafeLeftReference());
}
bool visitDoWhileStmt(ParseNode*& pn) {
BinaryNode& node = pn->as<BinaryNode>();
return Base::visitDoWhileStmt(pn) &&
SimplifyCondition(cx_, handler, node.unsafeRightReference());
SimplifyCondition(info(), node.unsafeRightReference());
}
bool visitFunction(ParseNode*& pn) {
@ -1540,15 +1542,19 @@ class FoldVisitor : public RewritingParseNodeVisitor<FoldVisitor> {
}
};
bool Fold(JSContext* cx, FullParseHandler* handler, ParseNode** pnp) {
FoldVisitor visitor(cx, handler);
static bool Fold(JSContext* cx, CompilationInfo& compilationInfo,
FullParseHandler* handler, ParseNode** pnp) {
FoldVisitor visitor(cx, compilationInfo, handler);
return visitor.visit(*pnp);
}
static bool Fold(FoldInfo info, ParseNode** pnp) {
return Fold(info.cx(), info.compilationInfo, info.handler, pnp);
}
bool frontend::FoldConstants(JSContext* cx, ParseNode** pnp,
FullParseHandler* handler) {
bool frontend::FoldConstants(JSContext* cx, CompilationInfo& compilationInfo,
ParseNode** pnp, FullParseHandler* handler) {
AutoTraceLog traceLog(TraceLoggerForCurrentThread(cx),
TraceLogger_BytecodeFoldConstants);
return Fold(cx, handler, pnp);
return Fold(cx, compilationInfo, handler, pnp);
}

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

@ -12,6 +12,8 @@
namespace js {
namespace frontend {
struct CompilationInfo;
class FullParseHandler;
template <class ParseHandler>
class PerHandlerParser;
@ -31,12 +33,15 @@ class PerHandlerParser;
// if (!FoldConstants(cx, &pn, parser)) {
// return false;
// }
extern MOZ_MUST_USE bool FoldConstants(JSContext* cx, ParseNode** pnp,
FullParseHandler* parser);
extern MOZ_MUST_USE bool FoldConstants(JSContext* cx,
CompilationInfo& compilationInfo,
ParseNode** pnp,
FullParseHandler* handler);
inline MOZ_MUST_USE bool FoldConstants(JSContext* cx,
CompilationInfo& compilationInfo,
typename SyntaxParseHandler::Node* pnp,
SyntaxParseHandler* parser) {
SyntaxParseHandler* handler) {
return true;
}

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

@ -384,7 +384,7 @@ typename ParseHandler::ListNodeType GeneralParser<ParseHandler, Unit>::parse() {
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}
@ -1561,7 +1561,7 @@ LexicalScopeNode* Parser<FullParseHandler, Unit>::evalBody(
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}
@ -1621,7 +1621,7 @@ ListNode* Parser<FullParseHandler, Unit>::globalBody(
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}
@ -1732,7 +1732,7 @@ ModuleNode* Parser<FullParseHandler, Unit>::moduleBody(
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}
@ -2121,7 +2121,7 @@ FunctionNode* Parser<FullParseHandler, Unit>::standaloneFunction(
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}
@ -3195,7 +3195,7 @@ FunctionNode* Parser<FullParseHandler, Unit>::standaloneLazyFunction(
// Don't constant-fold inside "use asm" code, as this could create a parse
// tree that doesn't type-check as asm.js.
if (!pc_->useAsmOrInsideUseAsm()) {
if (!FoldConstants(cx_, &node, &handler_)) {
if (!FoldConstants(cx_, this->getCompilationInfo(), &node, &handler_)) {
return null();
}
}