summaryrefslogtreecommitdiff
path: root/js/src/frontend/FoldConstants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/FoldConstants.cpp')
-rw-r--r--js/src/frontend/FoldConstants.cpp198
1 files changed, 97 insertions, 101 deletions
diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp
index 4ad1b4d6fe..ee1d5983aa 100644
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -81,7 +81,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// Similarly to the lexical declarations above, classes cannot add hoisted
// declarations
case PNK_CLASS:
- MOZ_ASSERT(node->isArity(PN_TERNARY));
+ MOZ_ASSERT(node->is<ClassNode>());
*result = false;
return true;
@@ -158,15 +158,14 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// if-statement nodes may have hoisted declarations in their consequent
// and alternative components.
case PNK_IF: {
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- ParseNode* consequent = node->pn_kid2;
+ TernaryNode* ifNode = &node->as<TernaryNode>();
+ ParseNode* consequent = ifNode->kid2();
if (!ContainsHoistedDeclaration(cx, consequent, result))
return false;
if (*result)
return true;
- if ((node = node->pn_kid3))
+ if ((node = ifNode->kid3()))
goto restart;
*result = false;
@@ -192,25 +191,25 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// try-statements have statements to execute, and one or both of a
// catch-list and a finally-block.
case PNK_TRY: {
- MOZ_ASSERT(node->isArity(PN_TERNARY));
- MOZ_ASSERT(node->pn_kid2 || node->pn_kid3,
+ TernaryNode* tryNode = &node->as<TernaryNode>();
+ MOZ_ASSERT(tryNode->kid2() || tryNode->kid3(),
"must have either catch(es) or finally");
- ParseNode* tryBlock = node->pn_kid1;
+ ParseNode* tryBlock = tryNode->kid1();
if (!ContainsHoistedDeclaration(cx, tryBlock, result))
return false;
if (*result)
return true;
- if (node->pn_kid2) {
- if (ListNode* catchList = &node->pn_kid2->as<ListNode>()) {
+ if (tryNode->kid2()) {
+ if (ListNode* catchList = &tryNode->kid2()->as<ListNode>()) {
for (ParseNode* lexicalScope : catchList->contents()) {
MOZ_ASSERT(lexicalScope->isKind(PNK_LEXICALSCOPE));
- ParseNode* catchNode = lexicalScope->scopeBody();
+ TernaryNode* catchNode = &lexicalScope->scopeBody()->as<TernaryNode>();
MOZ_ASSERT(catchNode->isKind(PNK_CATCH));
- ParseNode* catchStatements = catchNode->pn_kid3;
+ ParseNode* catchStatements = catchNode->kid3();
if (!ContainsHoistedDeclaration(cx, catchStatements, result))
return false;
if (*result)
@@ -219,7 +218,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
}
}
- if (ParseNode* finallyBlock = node->pn_kid3)
+ if (ParseNode* finallyBlock = tryNode->kid3())
return ContainsHoistedDeclaration(cx, finallyBlock, result);
*result = false;
@@ -240,7 +239,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_COMPREHENSIONFOR: {
MOZ_ASSERT(node->isArity(PN_BINARY));
- ParseNode* loopHead = node->pn_left;
+ TernaryNode* loopHead = &node->pn_left->as<TernaryNode>();
MOZ_ASSERT(loopHead->isKind(PNK_FORHEAD) ||
loopHead->isKind(PNK_FORIN) ||
loopHead->isKind(PNK_FOROF));
@@ -251,9 +250,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// (at present) hoisted in SpiderMonkey parlance -- but such
// hoisting doesn't extend outside of this statement, so it is not
// hoisting in the sense meant by ContainsHoistedDeclaration.)
- MOZ_ASSERT(loopHead->isArity(PN_TERNARY));
-
- ParseNode* init = loopHead->pn_kid1;
+ ParseNode* init = loopHead->kid1();
if (init && init->isKind(PNK_VAR)) {
*result = true;
return true;
@@ -271,9 +268,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
//
// Either way, if |target| contains a declaration, it's |loopHead|'s
// first kid.
- MOZ_ASSERT(loopHead->isArity(PN_TERNARY));
-
- ParseNode* decl = loopHead->pn_kid1;
+ ParseNode* decl = loopHead->kid1();
if (decl && decl->isKind(PNK_VAR)) {
*result = true;
return true;
@@ -856,19 +851,17 @@ FoldConditional(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandl
nodePtr = nextNode;
nextNode = nullptr;
- ParseNode* node = *nodePtr;
+ TernaryNode* node = &(*nodePtr)->as<TernaryNode>();
MOZ_ASSERT(node->isKind(PNK_CONDITIONAL));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- ParseNode*& expr = node->pn_kid1;
- if (!FoldCondition(cx, &expr, parser, inGenexpLambda))
+ ParseNode** expr = node->unsafeKid1Reference();
+ if (!FoldCondition(cx, expr, parser, inGenexpLambda))
return false;
- ParseNode*& ifTruthy = node->pn_kid2;
- if (!Fold(cx, &ifTruthy, parser, inGenexpLambda))
+ ParseNode** ifTruthy = node->unsafeKid2Reference();
+ if (!Fold(cx, ifTruthy, parser, inGenexpLambda))
return false;
- ParseNode*& ifFalsy = node->pn_kid3;
+ ParseNode** ifFalsy = node->unsafeKid3Reference();
// If our C?T:F node has F as another ?: node, *iteratively* constant-
// fold F *after* folding C and T (and possibly eliminating C and one
@@ -877,15 +870,16 @@ FoldConditional(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandl
//
// Conceivably we could instead/also iteratively constant-fold T, if T
// were more complex than F. Such an optimization is unimplemented.
- if (ifFalsy->isKind(PNK_CONDITIONAL)) {
- nextNode = &ifFalsy;
+ if ((*ifFalsy)->isKind(PNK_CONDITIONAL)) {
+ MOZ_ASSERT((*ifFalsy)->is<TernaryNode>());
+ nextNode = ifFalsy;
} else {
- if (!Fold(cx, &ifFalsy, parser, inGenexpLambda))
+ if (!Fold(cx, ifFalsy, parser, inGenexpLambda))
return false;
}
// Try to constant-fold based on the condition expression.
- Truthiness t = Boolish(expr);
+ Truthiness t = Boolish(*expr);
if (t == Unknown)
continue;
@@ -893,11 +887,11 @@ FoldConditional(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandl
ParseNode* replacement;
ParseNode* discarded;
if (t == Truthy) {
- replacement = ifTruthy;
- discarded = ifFalsy;
+ replacement = *ifTruthy;
+ discarded = *ifFalsy;
} else {
- replacement = ifFalsy;
- discarded = ifTruthy;
+ replacement = *ifFalsy;
+ discarded = *ifTruthy;
}
// Otherwise perform a replacement. This invalidates |nextNode|, so
@@ -925,29 +919,28 @@ FoldIf(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& pars
nodePtr = nextNode;
nextNode = nullptr;
- ParseNode* node = *nodePtr;
+ TernaryNode* node = &(*nodePtr)->as<TernaryNode>();
MOZ_ASSERT(node->isKind(PNK_IF));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- ParseNode*& expr = node->pn_kid1;
- if (!FoldCondition(cx, &expr, parser, inGenexpLambda))
+ ParseNode** expr = node->unsafeKid1Reference();
+ if (!FoldCondition(cx, expr, parser, inGenexpLambda))
return false;
- ParseNode*& consequent = node->pn_kid2;
- if (!Fold(cx, &consequent, parser, inGenexpLambda))
+ ParseNode** consequent = node->unsafeKid2Reference();
+ if (!Fold(cx, consequent, parser, inGenexpLambda))
return false;
- ParseNode*& alternative = node->pn_kid3;
- if (alternative) {
+ ParseNode** alternative = node->unsafeKid3Reference();
+ if (*alternative) {
// If in |if (C) T; else F;| we have |F| as another |if|,
// *iteratively* constant-fold |F| *after* folding |C| and |T| (and
// possibly completely replacing the whole thing with |T| or |F|);
// otherwise fold F normally. Making |nextNode| non-null causes
// this loop to run again to fold F.
- if (alternative->isKind(PNK_IF)) {
- nextNode = &alternative;
+ if ((*alternative)->isKind(PNK_IF)) {
+ MOZ_ASSERT((*alternative)->is<TernaryNode>());
+ nextNode = alternative;
} else {
- if (!Fold(cx, &alternative, parser, inGenexpLambda))
+ if (!Fold(cx, alternative, parser, inGenexpLambda))
return false;
}
}
@@ -956,7 +949,7 @@ FoldIf(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& pars
// constant truthiness. Don't eliminate if we have an |if (0)| in
// trailing position in a generator expression, as this is a special
// form we can't fold away.
- Truthiness t = Boolish(expr);
+ Truthiness t = Boolish(*expr);
if (t == Unknown || inGenexpLambda)
continue;
@@ -965,11 +958,11 @@ FoldIf(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& pars
ParseNode* replacement;
ParseNode* discarded;
if (t == Truthy) {
- replacement = consequent;
- discarded = alternative;
+ replacement = *consequent;
+ discarded = *alternative;
} else {
- replacement = alternative;
- discarded = consequent;
+ replacement = *alternative;
+ discarded = *consequent;
}
bool performReplacement = true;
@@ -1234,23 +1227,23 @@ FoldReturn(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& pars
}
static bool
-FoldTry(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
+FoldTry(ExclusiveContext* cx, TernaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_TRY));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- ParseNode*& statements = node->pn_kid1;
- if (!Fold(cx, &statements, parser, inGenexpLambda))
+ ParseNode** statements = node->unsafeKid1Reference();
+ if (!Fold(cx, statements, parser, inGenexpLambda))
return false;
- if (ParseNode*& catchList = node->pn_kid2) {
- if (!Fold(cx, &catchList, parser, inGenexpLambda))
+ ParseNode** catchList = node->unsafeKid2Reference();
+ if (*catchList) {
+ if (!Fold(cx, catchList, parser, inGenexpLambda))
return false;
}
- if (ParseNode*& finally = node->pn_kid3) {
- if (!Fold(cx, &finally, parser, inGenexpLambda))
+ ParseNode** finally = node->unsafeKid3Reference();
+ if (*finally) {
+ if (!Fold(cx, finally, parser, inGenexpLambda))
return false;
}
@@ -1258,24 +1251,25 @@ FoldTry(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
}
static bool
-FoldCatch(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
+FoldCatch(ExclusiveContext* cx, TernaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_CATCH));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
- if (ParseNode*& declPattern = node->pn_kid1) {
- if (!Fold(cx, &declPattern, parser, inGenexpLambda))
+ ParseNode** binding = node->unsafeKid1Reference();
+ if (*binding) {
+ if (!Fold(cx, binding, parser, inGenexpLambda))
return false;
}
- if (ParseNode*& cond = node->pn_kid2) {
- if (!FoldCondition(cx, &cond, parser, inGenexpLambda))
+ ParseNode** cond = node->unsafeKid2Reference();
+ if (*cond) {
+ if (!FoldCondition(cx, cond, parser, inGenexpLambda))
return false;
}
- if (ParseNode*& statements = node->pn_kid3) {
- if (!Fold(cx, &statements, parser, inGenexpLambda))
+ if (ParseNode** statements = node->unsafeKid3Reference()) {
+ if (!Fold(cx, statements, parser, inGenexpLambda))
return false;
}
@@ -1283,24 +1277,24 @@ FoldCatch(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parse
}
static bool
-FoldClass(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
+FoldClass(ExclusiveContext* cx, ClassNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_CLASS));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- if (ParseNode*& classNames = node->pn_kid1) {
- if (!Fold(cx, &classNames, parser, inGenexpLambda))
+ ParseNode** classNames = node->unsafeKid1Reference();
+ if (*classNames) {
+ if (!Fold(cx, classNames, parser, inGenexpLambda))
return false;
}
- if (ParseNode*& heritage = node->pn_kid2) {
- if (!Fold(cx, &heritage, parser, inGenexpLambda))
+ ParseNode** heritage = node->unsafeKid2Reference();
+ if (*heritage) {
+ if (!Fold(cx, heritage, parser, inGenexpLambda))
return false;
}
- ParseNode*& body = node->pn_kid3;
- return Fold(cx, &body, parser, inGenexpLambda);
+ ParseNode** body = node->unsafeKid3Reference();
+ return Fold(cx, body, parser, inGenexpLambda);
}
static bool
@@ -1580,41 +1574,41 @@ FoldArguments(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandler>& pa
}
static bool
-FoldForInOrOf(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
+FoldForInOrOf(ExclusiveContext* cx, TernaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_FORIN) || node->isKind(PNK_FOROF));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
- MOZ_ASSERT(!node->pn_kid2);
+ MOZ_ASSERT(!node->kid2());
- return Fold(cx, &node->pn_kid1, parser, inGenexpLambda) &&
- Fold(cx, &node->pn_kid3, parser, inGenexpLambda);
+ return Fold(cx, node->unsafeKid1Reference(), parser, inGenexpLambda) &&
+ Fold(cx, node->unsafeKid3Reference(), parser, inGenexpLambda);
}
static bool
-FoldForHead(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
+FoldForHead(ExclusiveContext* cx, TernaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_FORHEAD));
- MOZ_ASSERT(node->isArity(PN_TERNARY));
-
- if (ParseNode*& init = node->pn_kid1) {
- if (!Fold(cx, &init, parser, inGenexpLambda))
+ ParseNode** init = node->unsafeKid1Reference();
+ if (*init) {
+ if (!Fold(cx, init, parser, inGenexpLambda))
return false;
}
- if (ParseNode*& test = node->pn_kid2) {
- if (!FoldCondition(cx, &test, parser, inGenexpLambda))
+ ParseNode** test = node->unsafeKid2Reference();
+ if (*test) {
+ if (!FoldCondition(cx, test, parser, inGenexpLambda))
return false;
- if (test->isKind(PNK_TRUE)) {
- parser.freeTree(test);
- test = nullptr;
+ if ((*test)->isKind(PNK_TRUE)) {
+ parser.freeTree(*test);
+ *test = nullptr;
}
}
- if (ParseNode*& update = node->pn_kid3) {
- if (!Fold(cx, &update, parser, inGenexpLambda))
+ ParseNode** update = node->unsafeKid3Reference();
+ if (*update) {
+ if (!Fold(cx, update, parser, inGenexpLambda))
return false;
}
@@ -1709,9 +1703,11 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldDeleteProperty(cx, pn, parser, inGenexpLambda);
case PNK_CONDITIONAL:
+ MOZ_ASSERT((*pnp)->is<TernaryNode>());
return FoldConditional(cx, pnp, parser, inGenexpLambda);
case PNK_IF:
+ MOZ_ASSERT((*pnp)->is<TernaryNode>());
return FoldIf(cx, pnp, parser, inGenexpLambda);
case PNK_NOT:
@@ -1830,13 +1826,13 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldReturn(cx, pn, parser, inGenexpLambda);
case PNK_TRY:
- return FoldTry(cx, pn, parser, inGenexpLambda);
+ return FoldTry(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);
case PNK_CATCH:
- return FoldCatch(cx, pn, parser, inGenexpLambda);
+ return FoldCatch(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);
case PNK_CLASS:
- return FoldClass(cx, pn, parser, inGenexpLambda);
+ return FoldClass(cx, &pn->as<ClassNode>(), parser, inGenexpLambda);
case PNK_OPTELEM:
case PNK_ELEM:
@@ -1926,10 +1922,10 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_FORIN:
case PNK_FOROF:
- return FoldForInOrOf(cx, pn, parser, inGenexpLambda);
+ return FoldForInOrOf(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);
case PNK_FORHEAD:
- return FoldForHead(cx, pn, parser, inGenexpLambda);
+ return FoldForHead(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);
case PNK_LABEL:
MOZ_ASSERT(pn->isArity(PN_NAME));