зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1513040 - Change FOR_EACH_PARSE_NODE_KIND to use type instead of arity. r=jorendorff
Depends on D14321 Differential Revision: https://phabricator.services.mozilla.com/D14323 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
c7bba078e0
Коммит
b2449665be
|
@ -99,7 +99,7 @@ ParseNode* ParseNode::appendOrCreateList(ParseNodeKind kind, ParseNode* left,
|
|||
}
|
||||
|
||||
const ParseNodeArity js::frontend::ParseNodeKindArity[] = {
|
||||
#define ARITY(_name, arity) arity,
|
||||
#define ARITY(_name, type) type::arity(),
|
||||
FOR_EACH_PARSE_NODE_KIND(ARITY)
|
||||
#undef ARITY
|
||||
};
|
||||
|
@ -107,7 +107,7 @@ const ParseNodeArity js::frontend::ParseNodeKindArity[] = {
|
|||
#ifdef DEBUG
|
||||
|
||||
static const char* const parseNodeNames[] = {
|
||||
#define STRINGIFY(name, _arity) #name,
|
||||
#define STRINGIFY(name, _type) #name,
|
||||
FOR_EACH_PARSE_NODE_KIND(STRINGIFY)
|
||||
#undef STRINGIFY
|
||||
};
|
||||
|
|
|
@ -53,156 +53,156 @@ class BigIntBox;
|
|||
#endif
|
||||
|
||||
#define FOR_EACH_PARSE_NODE_KIND(F) \
|
||||
F(EmptyStmt, PN_NULLARY) \
|
||||
F(ExpressionStmt, PN_UNARY) \
|
||||
F(CommaExpr, PN_LIST) \
|
||||
F(ConditionalExpr, PN_TERNARY) \
|
||||
F(Colon, PN_BINARY) \
|
||||
F(Shorthand, PN_BINARY) \
|
||||
F(PosExpr, PN_UNARY) \
|
||||
F(NegExpr, PN_UNARY) \
|
||||
F(PreIncrementExpr, PN_UNARY) \
|
||||
F(PostIncrementExpr, PN_UNARY) \
|
||||
F(PreDecrementExpr, PN_UNARY) \
|
||||
F(PostDecrementExpr, PN_UNARY) \
|
||||
F(PropertyNameExpr, PN_NAME) \
|
||||
F(DotExpr, PN_BINARY) \
|
||||
F(ElemExpr, PN_BINARY) \
|
||||
F(ArrayExpr, PN_LIST) \
|
||||
F(Elision, PN_NULLARY) \
|
||||
F(StatementList, PN_LIST) \
|
||||
F(LabelStmt, PN_NAME) \
|
||||
F(ObjectExpr, PN_LIST) \
|
||||
F(CallExpr, PN_BINARY) \
|
||||
F(Arguments, PN_LIST) \
|
||||
F(Name, PN_NAME) \
|
||||
F(ObjectPropertyName, PN_NAME) \
|
||||
F(PrivateName, PN_NAME) \
|
||||
F(ComputedName, PN_UNARY) \
|
||||
F(NumberExpr, PN_NUMBER) \
|
||||
IF_BIGINT(F(BigIntExpr, PN_BIGINT), /**/) \
|
||||
F(StringExpr, PN_NAME) \
|
||||
F(TemplateStringListExpr, PN_LIST) \
|
||||
F(TemplateStringExpr, PN_NAME) \
|
||||
F(TaggedTemplateExpr, PN_BINARY) \
|
||||
F(CallSiteObjExpr, PN_LIST) \
|
||||
F(RegExpExpr, PN_REGEXP) \
|
||||
F(TrueExpr, PN_NULLARY) \
|
||||
F(FalseExpr, PN_NULLARY) \
|
||||
F(NullExpr, PN_NULLARY) \
|
||||
F(RawUndefinedExpr, PN_NULLARY) \
|
||||
F(ThisExpr, PN_UNARY) \
|
||||
F(Function, PN_CODE) \
|
||||
F(Module, PN_CODE) \
|
||||
F(IfStmt, PN_TERNARY) \
|
||||
F(SwitchStmt, PN_BINARY) \
|
||||
F(Case, PN_BINARY) \
|
||||
F(WhileStmt, PN_BINARY) \
|
||||
F(DoWhileStmt, PN_BINARY) \
|
||||
F(ForStmt, PN_BINARY) \
|
||||
F(BreakStmt, PN_LOOP) \
|
||||
F(ContinueStmt, PN_LOOP) \
|
||||
F(VarStmt, PN_LIST) \
|
||||
F(ConstDecl, PN_LIST) \
|
||||
F(WithStmt, PN_BINARY) \
|
||||
F(ReturnStmt, PN_UNARY) \
|
||||
F(NewExpr, PN_BINARY) \
|
||||
F(EmptyStmt, NullaryNode) \
|
||||
F(ExpressionStmt, UnaryNode) \
|
||||
F(CommaExpr, ListNode) \
|
||||
F(ConditionalExpr, ConditionalExpression) \
|
||||
F(Colon, BinaryNode) \
|
||||
F(Shorthand, BinaryNode) \
|
||||
F(PosExpr, UnaryNode) \
|
||||
F(NegExpr, UnaryNode) \
|
||||
F(PreIncrementExpr, UnaryNode) \
|
||||
F(PostIncrementExpr, UnaryNode) \
|
||||
F(PreDecrementExpr, UnaryNode) \
|
||||
F(PostDecrementExpr, UnaryNode) \
|
||||
F(PropertyNameExpr, NameNode) \
|
||||
F(DotExpr, PropertyAccess) \
|
||||
F(ElemExpr, PropertyByValue) \
|
||||
F(ArrayExpr, ListNode) \
|
||||
F(Elision, NullaryNode) \
|
||||
F(StatementList, ListNode) \
|
||||
F(LabelStmt, LabeledStatement) \
|
||||
F(ObjectExpr, ListNode) \
|
||||
F(CallExpr, BinaryNode) \
|
||||
F(Arguments, ListNode) \
|
||||
F(Name, NameNode) \
|
||||
F(ObjectPropertyName, NameNode) \
|
||||
F(PrivateName, NameNode) \
|
||||
F(ComputedName, UnaryNode) \
|
||||
F(NumberExpr, NumericLiteral) \
|
||||
IF_BIGINT(F(BigIntExpr, BigIntLiteral), /**/) \
|
||||
F(StringExpr, NameNode) \
|
||||
F(TemplateStringListExpr, ListNode) \
|
||||
F(TemplateStringExpr, NameNode) \
|
||||
F(TaggedTemplateExpr, BinaryNode) \
|
||||
F(CallSiteObjExpr, CallSiteNode) \
|
||||
F(RegExpExpr, RegExpLiteral) \
|
||||
F(TrueExpr, BooleanLiteral) \
|
||||
F(FalseExpr, BooleanLiteral) \
|
||||
F(NullExpr, NullLiteral) \
|
||||
F(RawUndefinedExpr, RawUndefinedLiteral) \
|
||||
F(ThisExpr, UnaryNode) \
|
||||
F(Function, CodeNode) \
|
||||
F(Module, CodeNode) \
|
||||
F(IfStmt, TernaryNode) \
|
||||
F(SwitchStmt, SwitchStatement) \
|
||||
F(Case, CaseClause) \
|
||||
F(WhileStmt, BinaryNode) \
|
||||
F(DoWhileStmt, BinaryNode) \
|
||||
F(ForStmt, ForNode) \
|
||||
F(BreakStmt, BreakStatement) \
|
||||
F(ContinueStmt, ContinueStatement) \
|
||||
F(VarStmt, ListNode) \
|
||||
F(ConstDecl, ListNode) \
|
||||
F(WithStmt, BinaryNode) \
|
||||
F(ReturnStmt, UnaryNode) \
|
||||
F(NewExpr, BinaryNode) \
|
||||
/* Delete operations. These must be sequential. */ \
|
||||
F(DeleteNameExpr, PN_UNARY) \
|
||||
F(DeletePropExpr, PN_UNARY) \
|
||||
F(DeleteElemExpr, PN_UNARY) \
|
||||
F(DeleteExpr, PN_UNARY) \
|
||||
F(TryStmt, PN_TERNARY) \
|
||||
F(Catch, PN_BINARY) \
|
||||
F(ThrowStmt, PN_UNARY) \
|
||||
F(DebuggerStmt, PN_NULLARY) \
|
||||
F(Generator, PN_NULLARY) \
|
||||
F(InitialYield, PN_UNARY) \
|
||||
F(YieldExpr, PN_UNARY) \
|
||||
F(YieldStarExpr, PN_UNARY) \
|
||||
F(LexicalScope, PN_SCOPE) \
|
||||
F(LetDecl, PN_LIST) \
|
||||
F(ImportDecl, PN_BINARY) \
|
||||
F(ImportSpecList, PN_LIST) \
|
||||
F(ImportSpec, PN_BINARY) \
|
||||
F(ExportStmt, PN_UNARY) \
|
||||
F(ExportFromStmt, PN_BINARY) \
|
||||
F(ExportDefaultStmt, PN_BINARY) \
|
||||
F(ExportSpecList, PN_LIST) \
|
||||
F(ExportSpec, PN_BINARY) \
|
||||
F(ExportBatchSpecStmt, PN_NULLARY) \
|
||||
F(ForIn, PN_TERNARY) \
|
||||
F(ForOf, PN_TERNARY) \
|
||||
F(ForHead, PN_TERNARY) \
|
||||
F(ParamsBody, PN_LIST) \
|
||||
F(Spread, PN_UNARY) \
|
||||
F(MutateProto, PN_UNARY) \
|
||||
F(ClassDecl, PN_TERNARY) \
|
||||
F(ClassMethod, PN_BINARY) \
|
||||
F(ClassField, PN_FIELD) \
|
||||
F(ClassMemberList, PN_LIST) \
|
||||
F(ClassNames, PN_BINARY) \
|
||||
F(NewTargetExpr, PN_BINARY) \
|
||||
F(PosHolder, PN_NULLARY) \
|
||||
F(SuperBase, PN_UNARY) \
|
||||
F(SuperCallExpr, PN_BINARY) \
|
||||
F(SetThis, PN_BINARY) \
|
||||
F(ImportMetaExpr, PN_BINARY) \
|
||||
F(CallImportExpr, PN_BINARY) \
|
||||
F(DeleteNameExpr, UnaryNode) \
|
||||
F(DeletePropExpr, UnaryNode) \
|
||||
F(DeleteElemExpr, UnaryNode) \
|
||||
F(DeleteExpr, UnaryNode) \
|
||||
F(TryStmt, TernaryNode) \
|
||||
F(Catch, BinaryNode) \
|
||||
F(ThrowStmt, UnaryNode) \
|
||||
F(DebuggerStmt, DebuggerStatement) \
|
||||
F(Generator, NullaryNode) \
|
||||
F(InitialYield, UnaryNode) \
|
||||
F(YieldExpr, UnaryNode) \
|
||||
F(YieldStarExpr, UnaryNode) \
|
||||
F(LexicalScope, LexicalScopeNode) \
|
||||
F(LetDecl, ListNode) \
|
||||
F(ImportDecl, BinaryNode) \
|
||||
F(ImportSpecList, ListNode) \
|
||||
F(ImportSpec, BinaryNode) \
|
||||
F(ExportStmt, UnaryNode) \
|
||||
F(ExportFromStmt, BinaryNode) \
|
||||
F(ExportDefaultStmt, BinaryNode) \
|
||||
F(ExportSpecList, ListNode) \
|
||||
F(ExportSpec, BinaryNode) \
|
||||
F(ExportBatchSpecStmt, NullaryNode) \
|
||||
F(ForIn, TernaryNode) \
|
||||
F(ForOf, TernaryNode) \
|
||||
F(ForHead, TernaryNode) \
|
||||
F(ParamsBody, ListNode) \
|
||||
F(Spread, UnaryNode) \
|
||||
F(MutateProto, UnaryNode) \
|
||||
F(ClassDecl, ClassNode) \
|
||||
F(ClassMethod, ClassMethod) \
|
||||
F(ClassField, ClassField) \
|
||||
F(ClassMemberList, ListNode) \
|
||||
F(ClassNames, ClassNames) \
|
||||
F(NewTargetExpr, BinaryNode) \
|
||||
F(PosHolder, NullaryNode) \
|
||||
F(SuperBase, UnaryNode) \
|
||||
F(SuperCallExpr, BinaryNode) \
|
||||
F(SetThis, BinaryNode) \
|
||||
F(ImportMetaExpr, BinaryNode) \
|
||||
F(CallImportExpr, BinaryNode) \
|
||||
\
|
||||
/* Unary operators. */ \
|
||||
F(TypeOfNameExpr, PN_UNARY) \
|
||||
F(TypeOfExpr, PN_UNARY) \
|
||||
F(VoidExpr, PN_UNARY) \
|
||||
F(NotExpr, PN_UNARY) \
|
||||
F(BitNotExpr, PN_UNARY) \
|
||||
F(AwaitExpr, PN_UNARY) \
|
||||
F(TypeOfNameExpr, UnaryNode) \
|
||||
F(TypeOfExpr, UnaryNode) \
|
||||
F(VoidExpr, UnaryNode) \
|
||||
F(NotExpr, UnaryNode) \
|
||||
F(BitNotExpr, UnaryNode) \
|
||||
F(AwaitExpr, UnaryNode) \
|
||||
\
|
||||
/* \
|
||||
* Binary operators. \
|
||||
* These must be in the same order as TOK_OR and friends in TokenStream.h. \
|
||||
*/ \
|
||||
F(PipelineExpr, PN_LIST) \
|
||||
F(OrExpr, PN_LIST) \
|
||||
F(AndExpr, PN_LIST) \
|
||||
F(BitOrExpr, PN_LIST) \
|
||||
F(BitXorExpr, PN_LIST) \
|
||||
F(BitAndExpr, PN_LIST) \
|
||||
F(StrictEqExpr, PN_LIST) \
|
||||
F(EqExpr, PN_LIST) \
|
||||
F(StrictNeExpr, PN_LIST) \
|
||||
F(NeExpr, PN_LIST) \
|
||||
F(LtExpr, PN_LIST) \
|
||||
F(LeExpr, PN_LIST) \
|
||||
F(GtExpr, PN_LIST) \
|
||||
F(GeExpr, PN_LIST) \
|
||||
F(InstanceOfExpr, PN_LIST) \
|
||||
F(InExpr, PN_LIST) \
|
||||
F(LshExpr, PN_LIST) \
|
||||
F(RshExpr, PN_LIST) \
|
||||
F(UrshExpr, PN_LIST) \
|
||||
F(AddExpr, PN_LIST) \
|
||||
F(SubExpr, PN_LIST) \
|
||||
F(MulExpr, PN_LIST) \
|
||||
F(DivExpr, PN_LIST) \
|
||||
F(ModExpr, PN_LIST) \
|
||||
F(PowExpr, PN_LIST) \
|
||||
F(PipelineExpr, ListNode) \
|
||||
F(OrExpr, ListNode) \
|
||||
F(AndExpr, ListNode) \
|
||||
F(BitOrExpr, ListNode) \
|
||||
F(BitXorExpr, ListNode) \
|
||||
F(BitAndExpr, ListNode) \
|
||||
F(StrictEqExpr, ListNode) \
|
||||
F(EqExpr, ListNode) \
|
||||
F(StrictNeExpr, ListNode) \
|
||||
F(NeExpr, ListNode) \
|
||||
F(LtExpr, ListNode) \
|
||||
F(LeExpr, ListNode) \
|
||||
F(GtExpr, ListNode) \
|
||||
F(GeExpr, ListNode) \
|
||||
F(InstanceOfExpr, ListNode) \
|
||||
F(InExpr, ListNode) \
|
||||
F(LshExpr, ListNode) \
|
||||
F(RshExpr, ListNode) \
|
||||
F(UrshExpr, ListNode) \
|
||||
F(AddExpr, ListNode) \
|
||||
F(SubExpr, ListNode) \
|
||||
F(MulExpr, ListNode) \
|
||||
F(DivExpr, ListNode) \
|
||||
F(ModExpr, ListNode) \
|
||||
F(PowExpr, ListNode) \
|
||||
\
|
||||
/* Assignment operators (= += -= etc.). */ \
|
||||
/* ParseNode::isAssignment assumes all these are consecutive. */ \
|
||||
F(AssignExpr, PN_BINARY) \
|
||||
F(AddAssignExpr, PN_BINARY) \
|
||||
F(SubAssignExpr, PN_BINARY) \
|
||||
F(BitOrAssignExpr, PN_BINARY) \
|
||||
F(BitXorAssignExpr, PN_BINARY) \
|
||||
F(BitAndAssignExpr, PN_BINARY) \
|
||||
F(LshAssignExpr, PN_BINARY) \
|
||||
F(RshAssignExpr, PN_BINARY) \
|
||||
F(UrshAssignExpr, PN_BINARY) \
|
||||
F(MulAssignExpr, PN_BINARY) \
|
||||
F(DivAssignExpr, PN_BINARY) \
|
||||
F(ModAssignExpr, PN_BINARY) \
|
||||
F(PowAssignExpr, PN_BINARY)
|
||||
F(AssignExpr, AssignmentNode) \
|
||||
F(AddAssignExpr, AssignmentNode) \
|
||||
F(SubAssignExpr, AssignmentNode) \
|
||||
F(BitOrAssignExpr, AssignmentNode) \
|
||||
F(BitXorAssignExpr, AssignmentNode) \
|
||||
F(BitAndAssignExpr, AssignmentNode) \
|
||||
F(LshAssignExpr, AssignmentNode) \
|
||||
F(RshAssignExpr, AssignmentNode) \
|
||||
F(UrshAssignExpr, AssignmentNode) \
|
||||
F(MulAssignExpr, AssignmentNode) \
|
||||
F(DivAssignExpr, AssignmentNode) \
|
||||
F(ModAssignExpr, AssignmentNode) \
|
||||
F(PowAssignExpr, AssignmentNode)
|
||||
|
||||
/*
|
||||
* Parsing builds a tree of nodes that directs code generation. This tree is
|
||||
|
@ -215,7 +215,7 @@ class BigIntBox;
|
|||
* The long comment after this enum block describes the kinds in detail.
|
||||
*/
|
||||
enum class ParseNodeKind : uint16_t {
|
||||
#define EMIT_ENUM(name, _arity) name,
|
||||
#define EMIT_ENUM(name, _type) name,
|
||||
FOR_EACH_PARSE_NODE_KIND(EMIT_ENUM)
|
||||
#undef EMIT_ENUM
|
||||
Limit, /* domain size */
|
||||
|
@ -852,6 +852,13 @@ class NullaryNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_NULLARY); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_NULLARY; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out);
|
||||
#endif
|
||||
|
@ -877,6 +884,18 @@ class NameNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_NAME); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_NAME; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (pn_u.name.initOrStmt) {
|
||||
if (!visitor.visit(pn_u.name.initOrStmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -893,9 +912,6 @@ class NameNode : public ParseNode {
|
|||
void setAtom(JSAtom* atom) { pn_u.name.atom = atom; }
|
||||
|
||||
void setInitializer(ParseNode* init) { pn_u.name.initOrStmt = init; }
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeInitializerReference() { return &pn_u.name.initOrStmt; }
|
||||
};
|
||||
|
||||
inline bool ParseNode::isName(PropertyName* name) const {
|
||||
|
@ -912,6 +928,18 @@ class UnaryNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_UNARY); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_UNARY; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (pn_u.unary.kid) {
|
||||
if (!visitor.visit(pn_u.unary.kid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -969,6 +997,23 @@ class BinaryNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_BINARY); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_BINARY; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (pn_u.binary.left) {
|
||||
if (!visitor.visit(pn_u.binary.left)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pn_u.binary.right) {
|
||||
if (!visitor.visit(pn_u.binary.right)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1044,6 +1089,28 @@ class TernaryNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_TERNARY); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_TERNARY; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (pn_u.ternary.kid1) {
|
||||
if (!visitor.visit(pn_u.ternary.kid1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pn_u.ternary.kid2) {
|
||||
if (!visitor.visit(pn_u.ternary.kid2)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (pn_u.ternary.kid3) {
|
||||
if (!visitor.visit(pn_u.ternary.kid3)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1123,6 +1190,26 @@ class ListNode : public ParseNode {
|
|||
|
||||
static bool test(const ParseNode& node) { return node.isArity(PN_LIST); }
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_LIST; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
ParseNode** listp = &pn_u.list.head;
|
||||
for (; *listp; listp = &(*listp)->pn_next) {
|
||||
// Don't use PN*& because we want to check if it changed, so we can use
|
||||
// ReplaceNode
|
||||
ParseNode* pn = *listp;
|
||||
if (!visitor.visit(pn)) {
|
||||
return false;
|
||||
}
|
||||
if (pn != *listp) {
|
||||
ReplaceNode(listp, pn);
|
||||
}
|
||||
}
|
||||
unsafeReplaceTail(listp);
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1379,6 +1466,19 @@ class CodeNode : public ParseNode {
|
|||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_CODE; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
// Note: body is null for lazily-parsed functions.
|
||||
if (pn_u.code.body) {
|
||||
if (!visitor.visit(pn_u.code.body)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1393,9 +1493,6 @@ class CodeNode : public ParseNode {
|
|||
|
||||
void setBody(ListNode* body) { pn_u.code.body = body; }
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeBodyReference() { return &pn_u.code.body; }
|
||||
|
||||
bool functionIsHoisted() const {
|
||||
MOZ_ASSERT(isKind(ParseNodeKind::Function));
|
||||
MOZ_ASSERT(
|
||||
|
@ -1424,6 +1521,13 @@ class NumericLiteral : public ParseNode {
|
|||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_NUMBER; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1451,6 +1555,13 @@ class BigIntLiteral : public ParseNode {
|
|||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_BIGINT; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1473,6 +1584,13 @@ class LexicalScopeNode : public ParseNode {
|
|||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_SCOPE; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return visitor.visit(pn_u.scope.body);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
@ -1490,8 +1608,6 @@ class LexicalScopeNode : public ParseNode {
|
|||
void setScopeBody(ParseNode* body) { pn_u.scope.body = body; }
|
||||
|
||||
bool isEmptyScope() const { return !pn_u.scope.bindings; }
|
||||
|
||||
ParseNode** unsafeScopeBodyReference() { return &pn_u.scope.body; }
|
||||
};
|
||||
|
||||
class LabeledStatement : public NameNode {
|
||||
|
@ -1510,11 +1626,6 @@ class LabeledStatement : public NameNode {
|
|||
MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
|
||||
return match;
|
||||
}
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeStatementReference() {
|
||||
return unsafeInitializerReference();
|
||||
}
|
||||
};
|
||||
|
||||
// Inside a switch statement, a CaseClause is a case-label and the subsequent
|
||||
|
@ -1566,6 +1677,13 @@ class LoopControlStatement : public ParseNode {
|
|||
MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
|
||||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_LOOP; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class BreakStatement : public LoopControlStatement {
|
||||
|
@ -1731,6 +1849,13 @@ class RegExpLiteral : public ParseNode {
|
|||
MOZ_ASSERT_IF(match, node.isOp(JSOP_REGEXP));
|
||||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_REGEXP; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class PropertyAccess : public BinaryNode {
|
||||
|
@ -1857,7 +1982,24 @@ class ClassField : public ParseNode {
|
|||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
return node.isKind(ParseNodeKind::ClassField);
|
||||
bool match = node.isKind(ParseNodeKind::ClassField);
|
||||
MOZ_ASSERT_IF(match, node.isArity(PN_FIELD));
|
||||
return match;
|
||||
}
|
||||
|
||||
static constexpr ParseNodeArity arity() { return PN_FIELD; }
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (!visitor.visit(pn_u.field.name)) {
|
||||
return false;
|
||||
}
|
||||
if (pn_u.field.initializer) {
|
||||
if (!visitor.visit(pn_u.field.initializer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ParseNode& name() const { return *pn_u.field.name; }
|
||||
|
@ -1869,12 +2011,6 @@ class ClassField : public ParseNode {
|
|||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
// callers are responsible for keeping the list consistent.
|
||||
ParseNode** unsafeNameReference() { return &pn_u.field.name; }
|
||||
|
||||
ParseNode** unsafeInitializerReference() { return &pn_u.field.initializer; }
|
||||
};
|
||||
|
||||
class SwitchStatement : public BinaryNode {
|
||||
|
|
|
@ -59,8 +59,8 @@ class ParseNodeVisitor {
|
|||
}
|
||||
|
||||
switch (pn->getKind()) {
|
||||
#define VISIT_CASE(KIND, _arity) \
|
||||
case ParseNodeKind::KIND: \
|
||||
#define VISIT_CASE(KIND, _type) \
|
||||
case ParseNodeKind::KIND: \
|
||||
return static_cast<Super*>(this)->visit##KIND(pn);
|
||||
FOR_EACH_PARSE_NODE_KIND(VISIT_CASE)
|
||||
#undef VISIT_CASE
|
||||
|
@ -69,128 +69,15 @@ class ParseNodeVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
#define VISIT_METHOD(KIND, ARITY) \
|
||||
MOZ_MUST_USE bool visit##KIND(ParseNode*& pn) { \
|
||||
return visit_##ARITY##_children(pn); \
|
||||
// using static_cast<Super*> here allows plain visit() to be overridden.
|
||||
#define VISIT_METHOD(KIND, TYPE) \
|
||||
MOZ_MUST_USE bool visit##KIND(ParseNode*& pn) { \
|
||||
MOZ_ASSERT(pn->is<TYPE>(), \
|
||||
"Node of kind " #KIND " was not of type " #TYPE); \
|
||||
return pn->as<TYPE>().accept(*static_cast<Super*>(this)); \
|
||||
}
|
||||
FOR_EACH_PARSE_NODE_KIND(VISIT_METHOD)
|
||||
#undef VISIT_METHOD
|
||||
|
||||
private:
|
||||
MOZ_MUST_USE bool visit_PN_NULLARY_children(ParseNode*& pn) { return true; }
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_UNARY_children(ParseNode*& pn) {
|
||||
UnaryNode& node = pn->as<UnaryNode>();
|
||||
if (node.kid()) {
|
||||
if (!visit(*node.unsafeKidReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_BINARY_children(ParseNode*& pn) {
|
||||
BinaryNode& node = pn->as<BinaryNode>();
|
||||
if (node.left()) {
|
||||
if (!visit(*node.unsafeLeftReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (node.right()) {
|
||||
if (!visit(*node.unsafeRightReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_TERNARY_children(ParseNode*& pn) {
|
||||
TernaryNode& node = pn->as<TernaryNode>();
|
||||
if (node.kid1()) {
|
||||
if (!visit(*node.unsafeKid1Reference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (node.kid2()) {
|
||||
if (!visit(*node.unsafeKid2Reference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (node.kid3()) {
|
||||
if (!visit(*node.unsafeKid3Reference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_CODE_children(ParseNode*& pn) {
|
||||
CodeNode& node = pn->as<CodeNode>();
|
||||
|
||||
// Note: body is null for lazily-parsed functions.
|
||||
if (node.body()) {
|
||||
if (!visit(*node.unsafeBodyReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_LIST_children(ParseNode*& pn) {
|
||||
ListNode& node = pn->as<ListNode>();
|
||||
ParseNode** listp = node.unsafeHeadReference();
|
||||
for (; *listp; listp = &(*listp)->pn_next) {
|
||||
// Don't use PN*& because we want to check if it changed, so we can use
|
||||
// ReplaceNode
|
||||
ParseNode* pn = *listp;
|
||||
if (!visit(pn)) {
|
||||
return false;
|
||||
}
|
||||
if (pn != *listp) {
|
||||
ReplaceNode(listp, pn);
|
||||
}
|
||||
}
|
||||
node.unsafeReplaceTail(listp);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_NAME_children(ParseNode*& pn) {
|
||||
NameNode& node = pn->as<NameNode>();
|
||||
if (node.initializer()) {
|
||||
if (!visit(*node.unsafeInitializerReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_FIELD_children(ParseNode*& pn) {
|
||||
ClassField& node = pn->as<ClassField>();
|
||||
if (!visit(*node.unsafeNameReference())) {
|
||||
return false;
|
||||
}
|
||||
if (node.hasInitializer()) {
|
||||
if (!visit(*node.unsafeInitializerReference())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_NUMBER_children(ParseNode*& pn) { return true; }
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
MOZ_MUST_USE bool visit_PN_BIGINT_children(ParseNode*& pn) { return true; }
|
||||
#endif
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_REGEXP_children(ParseNode*& pn) { return true; }
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_LOOP_children(ParseNode*& pn) { return true; }
|
||||
|
||||
MOZ_MUST_USE bool visit_PN_SCOPE_children(ParseNode*& pn) {
|
||||
LexicalScopeNode& node = pn->as<LexicalScopeNode>();
|
||||
return visit(*node.unsafeScopeBodyReference());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
|
Загрузка…
Ссылка в новой задаче