Issue #2173 - Add accessors to BinaryNode and subclasses

Based-on: m-c 1479659/3
This commit is contained in:
Martok 2023-03-26 06:08:53 +02:00 committed by roytam1
commit 662419c507
14 changed files with 1134 additions and 919 deletions

View file

@ -1161,31 +1161,40 @@ ModuleBuilder::initModule()
}
bool
ModuleBuilder::processImport(frontend::ParseNode* pn)
ModuleBuilder::processImport(frontend::BinaryNode* importNode)
{
MOZ_ASSERT(pn->isKind(PNK_IMPORT));
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST));
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
MOZ_ASSERT(importNode->isKind(PNK_IMPORT));
ListNode* specList = &importNode->left()->as<ListNode>();
MOZ_ASSERT(specList->isKind(PNK_IMPORT_SPEC_LIST));
ParseNode* moduleSpec = importNode->right();
MOZ_ASSERT(moduleSpec->isKind(PNK_STRING));
RootedAtom module(cx_, pn->pn_right->pn_atom);
RootedAtom module(cx_, moduleSpec->pn_atom);
if (!maybeAppendRequestedModule(module))
return false;
for (ParseNode* spec : pn->pn_left->as<ListNode>().contents()) {
RootedAtom importName(cx_);
RootedAtom localName(cx_);
for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(PNK_IMPORT_SPEC));
MOZ_ASSERT(spec->pn_left->isArity(PN_NAME));
MOZ_ASSERT(spec->pn_right->isArity(PN_NAME));
ParseNode* importNameNode = spec->left();
MOZ_ASSERT(importNameNode->isArity(PN_NAME));
ParseNode* localNameNode = spec->right();
MOZ_ASSERT(localNameNode->isArity(PN_NAME));
RootedAtom importName(cx_, spec->pn_left->pn_atom);
RootedAtom localName(cx_, spec->pn_right->pn_atom);
RootedAtom importName(cx_, importNameNode->pn_atom);
RootedAtom localName(cx_, localNameNode->pn_atom);
if (!importedBoundNames_.append(localName))
return false;
uint32_t line;
uint32_t column;
tokenStream_.srcCoords.lineNumAndColumnIndex(spec->pn_left->pn_pos.begin, &line, &column);
tokenStream_.srcCoords.lineNumAndColumnIndex(importNameNode->pn_pos.begin, &line, &column);
RootedImportEntryObject importEntry(cx_);
importEntry = ImportEntryObject::create(cx_, module, importName, localName, line, column);
@ -1197,15 +1206,16 @@ ModuleBuilder::processImport(frontend::ParseNode* pn)
}
bool
ModuleBuilder::processExport(frontend::ParseNode* pn)
ModuleBuilder::processExport(frontend::ParseNode* exportNode)
{
MOZ_ASSERT(pn->isKind(PNK_EXPORT) || pn->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT(pn->getArity() == (pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY));
MOZ_ASSERT(exportNode->isKind(PNK_EXPORT) ||
exportNode->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT_IF(exportNode->isKind(PNK_EXPORT), exportNode->is<UnaryNode>());
bool isDefault = pn->getKind() == PNK_EXPORT_DEFAULT;
ParseNode* kid = isDefault ? pn->pn_left : pn->pn_kid;
bool isDefault = exportNode->isKind(PNK_EXPORT_DEFAULT);
ParseNode* kid = isDefault ? exportNode->as<BinaryNode>().left() : exportNode->pn_kid;
if (isDefault && pn->pn_right) {
if (isDefault && exportNode->as<BinaryNode>().right()) {
// This is an export default containing an expression.
RootedAtom localName(cx_, cx_->names().starDefaultStar);
RootedAtom exportName(cx_, cx_->names().default_);
@ -1213,16 +1223,23 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
}
switch (kid->getKind()) {
case PNK_EXPORT_SPEC_LIST:
case PNK_EXPORT_SPEC_LIST: {
MOZ_ASSERT(!isDefault);
for (ParseNode* spec : kid->as<ListNode>().contents()) {
RootedAtom localName(cx_);
RootedAtom exportName(cx_);
for (ParseNode* item : kid->as<ListNode>().contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(PNK_EXPORT_SPEC));
RootedAtom localName(cx_, spec->pn_left->pn_atom);
RootedAtom exportName(cx_, spec->pn_right->pn_atom);
ParseNode* localNameNode = spec->left();
ParseNode* exportNameNode = spec->right();
localName = localNameNode->pn_atom;
exportName = exportNameNode->pn_atom;
if (!appendExportEntry(exportName, localName, spec))
return false;
}
break;
}
case PNK_CLASS: {
const ClassNode& cls = kid->as<ClassNode>();
@ -1240,7 +1257,7 @@ ModuleBuilder::processExport(frontend::ParseNode* pn)
MOZ_ASSERT(kid->isArity(PN_LIST));
for (ParseNode* binding : kid->as<ListNode>().contents()) {
if (binding->isKind(PNK_ASSIGN))
binding = binding->pn_left;
binding = binding->as<AssignmentNode>().left();
else
MOZ_ASSERT(binding->isKind(PNK_NAME));
@ -1306,7 +1323,7 @@ ModuleBuilder::processExportArrayBinding(frontend::ListNode* array)
if (node->isKind(PNK_SPREAD))
node = node->pn_kid;
else if (node->isKind(PNK_ASSIGN))
node = node->pn_left;
node = node->as<AssignmentNode>().left();
if (!processExportBinding(node))
return false;
@ -1333,10 +1350,10 @@ ModuleBuilder::processExportObjectBinding(frontend::ListNode* obj)
if (node->isKind(PNK_MUTATEPROTO))
target = node->pn_kid;
else
target = node->pn_right;
target = node->as<BinaryNode>().right();
if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
target = target->as<AssignmentNode>().left();
}
if (!processExportBinding(target))
@ -1347,27 +1364,34 @@ ModuleBuilder::processExportObjectBinding(frontend::ListNode* obj)
}
bool
ModuleBuilder::processExportFrom(frontend::ParseNode* pn)
ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode)
{
MOZ_ASSERT(pn->isKind(PNK_EXPORT_FROM));
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(PNK_EXPORT_SPEC_LIST));
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
MOZ_ASSERT(exportNode->isKind(PNK_EXPORT_FROM));
RootedAtom module(cx_, pn->pn_right->pn_atom);
ListNode* specList = &exportNode->left()->as<ListNode>();
MOZ_ASSERT(specList->isKind(PNK_EXPORT_SPEC_LIST));
ParseNode* moduleSpec = exportNode->right();
MOZ_ASSERT(moduleSpec->isKind(PNK_STRING));
RootedAtom module(cx_, moduleSpec->pn_atom);
if (!maybeAppendRequestedModule(module))
return false;
for (ParseNode* spec : pn->pn_left->as<ListNode>().contents()) {
RootedAtom bindingName(cx_);
RootedAtom exportName(cx_);
for (ParseNode* spec : specList->contents()) {
if (spec->isKind(PNK_EXPORT_SPEC)) {
RootedAtom bindingName(cx_, spec->pn_left->pn_atom);
RootedAtom exportName(cx_, spec->pn_right->pn_atom);
if (!appendExportFromEntry(exportName, module, bindingName, spec->pn_left))
ParseNode* localNameNode = spec->as<BinaryNode>().left();
ParseNode* exportNameNode = spec->as<BinaryNode>().right();
bindingName = localNameNode->pn_atom;
exportName = exportNameNode->pn_atom;
if (!appendExportFromEntry(exportName, module, bindingName, localNameNode))
return false;
} else {
MOZ_ASSERT(spec->isKind(PNK_EXPORT_BATCH_SPEC));
RootedAtom importName(cx_, cx_->names().star);
if (!appendExportFromEntry(nullptr, module, importName, spec))
exportName = cx_->names().star;
if (!appendExportFromEntry(nullptr, module, exportName, spec))
return false;
}
}

View file

@ -24,6 +24,7 @@ class ModuleEnvironmentObject;
class ModuleObject;
namespace frontend {
class BinaryNode;
class ListNode;
class ParseNode;
class TokenStream;
@ -319,9 +320,9 @@ class MOZ_STACK_CLASS ModuleBuilder
explicit ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
const frontend::TokenStream& tokenStream);
bool processImport(frontend::ParseNode* pn);
bool processExport(frontend::ParseNode* pn);
bool processExportFrom(frontend::ParseNode* pn);
bool processImport(frontend::BinaryNode* importNode);
bool processExport(frontend::ParseNode* exportNode);
bool processExportFrom(frontend::BinaryNode* exportNode);
bool hasExportedName(JSAtom* name) const;

View file

@ -1802,10 +1802,10 @@ class ASTSerializer
bool declaration(ParseNode* pn, MutableHandleValue dst);
bool variableDeclaration(ListNode* declList, bool lexical, MutableHandleValue dst);
bool variableDeclarator(ParseNode* pn, MutableHandleValue dst);
bool importDeclaration(ParseNode* pn, MutableHandleValue dst);
bool importSpecifier(ParseNode* pn, MutableHandleValue dst);
bool exportDeclaration(ParseNode* pn, MutableHandleValue dst);
bool exportSpecifier(ParseNode* pn, MutableHandleValue dst);
bool importDeclaration(BinaryNode* importNode, MutableHandleValue dst);
bool importSpecifier(BinaryNode* importSpec, MutableHandleValue dst);
bool exportDeclaration(ParseNode* exportNode, MutableHandleValue dst);
bool exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst);
bool classDefinition(ClassNode* pn, bool expr, MutableHandleValue dst);
bool optStatement(ParseNode* pn, MutableHandleValue dst) {
@ -1817,14 +1817,14 @@ class ASTSerializer
}
bool forInit(ParseNode* pn, MutableHandleValue dst);
bool forIn(ParseNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
bool forIn(ForNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst);
bool forOf(ParseNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
bool forOf(ForNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst);
bool statement(ParseNode* pn, MutableHandleValue dst);
bool blockStatement(ListNode* node, MutableHandleValue dst);
bool switchStatement(ParseNode* pn, MutableHandleValue dst);
bool switchCase(ParseNode* pn, MutableHandleValue dst);
bool switchStatement(SwitchStatement* switchStmt, MutableHandleValue dst);
bool switchCase(CaseClause* caseClause, MutableHandleValue dst);
bool tryStatement(TernaryNode* tryNode, MutableHandleValue dst);
bool catchClause(TernaryNode* clauseNode, bool* isGuarded, MutableHandleValue dst);
@ -1841,7 +1841,7 @@ class ASTSerializer
bool propertyName(ParseNode* pn, MutableHandleValue dst);
bool property(ParseNode* pn, MutableHandleValue dst);
bool classMethod(ParseNode* pn, MutableHandleValue dst);
bool classMethod(ClassMethod* classMethod, MutableHandleValue dst);
bool optIdentifier(HandleAtom atom, TokenPos* pos, MutableHandleValue dst) {
if (!atom) {
@ -1873,7 +1873,7 @@ class ASTSerializer
MutableHandleValue body, MutableHandleValue rest);
bool functionBody(ParseNode* pn, TokenPos* pos, MutableHandleValue dst);
bool comprehensionBlock(ParseNode* pn, MutableHandleValue dst);
bool comprehensionBlock(ForNode* forNode, MutableHandleValue dst);
bool comprehensionIf(TernaryNode* ifNode, MutableHandleValue dst);
bool comprehension(ParseNode* pn, MutableHandleValue dst);
bool generatorExpression(ParseNode* pn, MutableHandleValue dst);
@ -2135,45 +2135,48 @@ ASTSerializer::variableDeclaration(ListNode* declList, bool lexical, MutableHand
bool
ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst)
{
ParseNode* pnleft;
ParseNode* pnright;
ParseNode* patternNode;
ParseNode* initNode;
if (pn->isKind(PNK_NAME)) {
pnleft = pn;
pnright = pn->pn_expr;
MOZ_ASSERT_IF(pnright, pn->pn_pos.encloses(pnright->pn_pos));
patternNode = pn;
initNode = pn->pn_expr;
MOZ_ASSERT_IF(initNode, pn->pn_pos.encloses(initNode->pn_pos));
} else if (pn->isKind(PNK_ASSIGN)) {
pnleft = pn->pn_left;
pnright = pn->pn_right;
MOZ_ASSERT(pn->pn_pos.encloses(pnleft->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pnright->pn_pos));
AssignmentNode* assignNode = &pn->as<AssignmentNode>();
patternNode = assignNode->left();
initNode = assignNode->right();
MOZ_ASSERT(pn->pn_pos.encloses(patternNode->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(initNode->pn_pos));
} else {
/* This happens for a destructuring declarator in a for-in/of loop. */
pnleft = pn;
pnright = nullptr;
patternNode = pn;
initNode = nullptr;
}
RootedValue left(cx), right(cx);
return pattern(pnleft, &left) &&
optExpression(pnright, &right) &&
builder.variableDeclarator(left, right, &pn->pn_pos, dst);
RootedValue patternVal(cx), init(cx);
return pattern(patternNode, &patternVal) &&
optExpression(initNode, &init) &&
builder.variableDeclarator(patternVal, init, &pn->pn_pos, dst);
}
bool
ASTSerializer::importDeclaration(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::importDeclaration(BinaryNode* importNode, MutableHandleValue dst)
{
MOZ_ASSERT(pn->isKind(PNK_IMPORT));
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST));
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
MOZ_ASSERT(importNode->isKind(PNK_IMPORT));
ListNode* specList = &pn->pn_left->as<ListNode>();
ListNode* specList = &importNode->left()->as<ListNode>();
MOZ_ASSERT(specList->isKind(PNK_IMPORT_SPEC_LIST));
ParseNode* moduleSpecNode = importNode->right();
MOZ_ASSERT(moduleSpecNode->isKind(PNK_STRING));
NodeVector elts(cx);
if (!elts.reserve(specList->count()))
return false;
for (ParseNode* spec : specList->contents()) {
for (ParseNode* item : specList->contents()) {
BinaryNode* spec = &item->as<BinaryNode>();
RootedValue elt(cx);
if (!importSpecifier(spec, &elt))
return false;
@ -2181,48 +2184,51 @@ ASTSerializer::importDeclaration(ParseNode* pn, MutableHandleValue dst)
}
RootedValue moduleSpec(cx);
return literal(pn->pn_right, &moduleSpec) &&
builder.importDeclaration(elts, moduleSpec, &pn->pn_pos, dst);
return literal(moduleSpecNode, &moduleSpec) &&
builder.importDeclaration(elts, moduleSpec, &importNode->pn_pos, dst);
}
bool
ASTSerializer::importSpecifier(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::importSpecifier(BinaryNode* importSpec, MutableHandleValue dst)
{
MOZ_ASSERT(pn->isKind(PNK_IMPORT_SPEC));
MOZ_ASSERT(importSpec->isKind(PNK_IMPORT_SPEC));
RootedValue importName(cx);
RootedValue bindingName(cx);
return identifier(pn->pn_left, &importName) &&
identifier(pn->pn_right, &bindingName) &&
builder.importSpecifier(importName, bindingName, &pn->pn_pos, dst);
return identifier(importSpec->left(), &importName) &&
identifier(importSpec->right(), &bindingName) &&
builder.importSpecifier(importName, bindingName, &importSpec->pn_pos, dst);
}
bool
ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::exportDeclaration(ParseNode* exportNode, MutableHandleValue dst)
{
MOZ_ASSERT(pn->isKind(PNK_EXPORT) ||
pn->isKind(PNK_EXPORT_FROM) ||
pn->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT(pn->getArity() == (pn->isKind(PNK_EXPORT) ? PN_UNARY : PN_BINARY));
MOZ_ASSERT_IF(pn->isKind(PNK_EXPORT_FROM), pn->pn_right->isKind(PNK_STRING));
MOZ_ASSERT(exportNode->isKind(PNK_EXPORT) ||
exportNode->isKind(PNK_EXPORT_FROM) ||
exportNode->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT_IF(exportNode->isKind(PNK_EXPORT), exportNode->is<UnaryNode>());
MOZ_ASSERT_IF(exportNode->isKind(PNK_EXPORT_FROM),
exportNode->as<BinaryNode>().right()->isKind(PNK_STRING));
RootedValue decl(cx, NullValue());
NodeVector elts(cx);
ParseNode* kid = pn->isKind(PNK_EXPORT) ? pn->pn_kid : pn->pn_left;
ParseNode* kid = exportNode->isKind(PNK_EXPORT)
? exportNode->pn_kid
: exportNode->as<BinaryNode>().left();
switch (ParseNodeKind kind = kid->getKind()) {
case PNK_EXPORT_SPEC_LIST: {
ListNode* specList = &pn->pn_left->as<ListNode>();
ListNode* specList = &kid->as<ListNode>();
if (!elts.reserve(specList->count()))
return false;
for (ParseNode* spec : specList->contents()) {
RootedValue elt(cx);
if (spec->isKind(PNK_EXPORT_SPEC)) {
if (!exportSpecifier(spec, &elt))
if (!exportSpecifier(&spec->as<BinaryNode>(), &elt))
return false;
} else {
if (!builder.exportBatchSpecifier(&pn->pn_pos, &elt))
if (!builder.exportBatchSpecifier(&exportNode->pn_pos, &elt))
return false;
}
elts.infallibleAppend(elt);
@ -2254,70 +2260,72 @@ ASTSerializer::exportDeclaration(ParseNode* pn, MutableHandleValue dst)
}
RootedValue moduleSpec(cx, NullValue());
if (pn->isKind(PNK_EXPORT_FROM) && !literal(pn->pn_right, &moduleSpec))
return false;
if (exportNode->isKind(PNK_EXPORT_FROM)) {
if (!literal(exportNode->as<BinaryNode>().right(), &moduleSpec)) {
return false;
}
}
RootedValue isDefault(cx, BooleanValue(false));
if (pn->isKind(PNK_EXPORT_DEFAULT))
if (exportNode->isKind(PNK_EXPORT_DEFAULT))
isDefault.setBoolean(true);
return builder.exportDeclaration(decl, elts, moduleSpec, isDefault, &pn->pn_pos, dst);
return builder.exportDeclaration(decl, elts, moduleSpec, isDefault, &exportNode->pn_pos, dst);
}
bool
ASTSerializer::exportSpecifier(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst)
{
MOZ_ASSERT(pn->isKind(PNK_EXPORT_SPEC));
MOZ_ASSERT(exportSpec->isKind(PNK_EXPORT_SPEC));
RootedValue bindingName(cx);
RootedValue exportName(cx);
return identifier(pn->pn_left, &bindingName) &&
identifier(pn->pn_right, &exportName) &&
builder.exportSpecifier(bindingName, exportName, &pn->pn_pos, dst);
return identifier(exportSpec->left(), &bindingName) &&
identifier(exportSpec->right(), &exportName) &&
builder.exportSpecifier(bindingName, exportName, &exportSpec->pn_pos, dst);
}
bool
ASTSerializer::switchCase(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::switchCase(CaseClause* caseClause, MutableHandleValue dst)
{
MOZ_ASSERT_IF(pn->pn_left, pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
MOZ_ASSERT_IF(caseClause->caseExpression(),
caseClause->pn_pos.encloses(caseClause->caseExpression()->pn_pos));
MOZ_ASSERT(caseClause->pn_pos.encloses(caseClause->statementList()->pn_pos));
NodeVector stmts(cx);
RootedValue expr(cx);
return optExpression(pn->as<CaseClause>().caseExpression(), &expr) &&
statements(pn->as<CaseClause>().statementList(), stmts) &&
builder.switchCase(expr, stmts, &pn->pn_pos, dst);
return optExpression(caseClause->caseExpression(), &expr) &&
statements(caseClause->statementList(), stmts) &&
builder.switchCase(expr, stmts, &caseClause->pn_pos, dst);
}
bool
ASTSerializer::switchStatement(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::switchStatement(SwitchStatement* switchStmt, MutableHandleValue dst)
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
MOZ_ASSERT(switchStmt->pn_pos.encloses(switchStmt->discriminant().pn_pos));
MOZ_ASSERT(switchStmt->pn_pos.encloses(switchStmt->lexicalForCaseList().pn_pos));
RootedValue disc(cx);
if (!expression(pn->pn_left, &disc))
if (!expression(&switchStmt->discriminant(), &disc))
return false;
MOZ_ASSERT(pn->pn_right->isKind(PNK_LEXICALSCOPE));
ListNode* caseList = &pn->pn_right->scopeBody()->as<ListNode>();
ListNode* caseList = &switchStmt->lexicalForCaseList().scopeBody()->as<ListNode>();
NodeVector cases(cx);
if (!cases.reserve(caseList->count()))
return false;
for (ParseNode* caseNode : caseList->contents()) {
for (ParseNode* item : caseList->contents()) {
CaseClause* caseClause = &item->as<CaseClause>();
RootedValue child(cx);
if (!switchCase(caseNode, &child))
if (!switchCase(caseClause, &child))
return false;
cases.infallibleAppend(child);
}
return builder.switchStatement(disc, cases, /* lexical = */ true, &pn->pn_pos, dst);
return builder.switchStatement(disc, cases, /* lexical = */ true, &switchStmt->pn_pos, dst);
}
bool
@ -2401,8 +2409,8 @@ ASTSerializer::forInit(ParseNode* pn, MutableHandleValue dst)
}
bool
ASTSerializer::forOf(ParseNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst)
ASTSerializer::forOf(ForNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst)
{
RootedValue expr(cx);
@ -2411,11 +2419,11 @@ ASTSerializer::forOf(ParseNode* loop, ParseNode* iterExpr, HandleValue var, Hand
}
bool
ASTSerializer::forIn(ParseNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst)
ASTSerializer::forIn(ForNode* loop, ParseNode* iterExpr, HandleValue var, HandleValue stmt,
MutableHandleValue dst)
{
RootedValue expr(cx);
bool isForEach = loop->pn_iflags & JSITER_FOREACH;
bool isForEach = loop->iflags() & JSITER_FOREACH;
return expression(iterExpr, &expr) &&
builder.forInStatement(var, expr, stmt, isForEach, &loop->pn_pos, dst);
@ -2452,7 +2460,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return declaration(pn, dst);
case PNK_IMPORT:
return importDeclaration(pn, dst);
return importDeclaration(&pn->as<BinaryNode>(), dst);
case PNK_EXPORT:
case PNK_EXPORT_DEFAULT:
@ -2498,7 +2506,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
}
case PNK_SWITCH:
return switchStatement(pn, dst);
return switchStatement(&pn->as<SwitchStatement>(), dst);
case PNK_TRY:
return tryStatement(&pn->as<TernaryNode>(), dst);
@ -2506,37 +2514,50 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
case PNK_WITH:
case PNK_WHILE:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* exprNode = node->left();
MOZ_ASSERT(node->pn_pos.encloses(exprNode->pn_pos));
ParseNode* stmtNode = node->right();
MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos));
RootedValue expr(cx), stmt(cx);
return expression(pn->pn_left, &expr) &&
statement(pn->pn_right, &stmt) &&
(pn->isKind(PNK_WITH)
? builder.withStatement(expr, stmt, &pn->pn_pos, dst)
: builder.whileStatement(expr, stmt, &pn->pn_pos, dst));
return expression(exprNode, &expr) &&
statement(stmtNode, &stmt) &&
(node->isKind(PNK_WITH)
? builder.withStatement(expr, stmt, &node->pn_pos, dst)
: builder.whileStatement(expr, stmt, &node->pn_pos, dst));
}
case PNK_DOWHILE:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* stmtNode = node->left();
MOZ_ASSERT(node->pn_pos.encloses(stmtNode->pn_pos));
ParseNode* testNode = node->right();
MOZ_ASSERT(node->pn_pos.encloses(testNode->pn_pos));
RootedValue stmt(cx), test(cx);
return statement(pn->pn_left, &stmt) &&
expression(pn->pn_right, &test) &&
builder.doWhileStatement(stmt, test, &pn->pn_pos, dst);
return statement(stmtNode, &stmt) &&
expression(testNode, &test) &&
builder.doWhileStatement(stmt, test, &node->pn_pos, dst);
}
case PNK_FOR:
case PNK_COMPREHENSIONFOR:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
ForNode* forNode = &pn->as<ForNode>();
TernaryNode* head = &pn->pn_left->as<TernaryNode>();
TernaryNode* head = forNode->head();
MOZ_ASSERT(forNode->pn_pos.encloses(head->pn_pos));
ParseNode* stmtNode = forNode->right();
MOZ_ASSERT(forNode->pn_pos.encloses(stmtNode->pn_pos));
ParseNode* initNode = head->kid1();
MOZ_ASSERT_IF(initNode, head->pn_pos.encloses(initNode->pn_pos));
@ -2548,7 +2569,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
MOZ_ASSERT_IF(updateOrIter, head->pn_pos.encloses(updateOrIter->pn_pos));
RootedValue stmt(cx);
if (!statement(pn->pn_right, &stmt))
if (!statement(stmtNode, &stmt))
return false;
if (head->isKind(PNK_FORIN) || head->isKind(PNK_FOROF)) {
@ -2572,8 +2593,8 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
}
}
if (head->isKind(PNK_FORIN))
return forIn(pn, updateOrIter, var, stmt, dst);
return forOf(pn, updateOrIter, var, stmt, dst);
return forIn(forNode, updateOrIter, var, stmt, dst);
return forOf(forNode, updateOrIter, var, stmt, dst);
}
RootedValue init(cx), test(cx), update(cx);
@ -2581,7 +2602,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return forInit(initNode, &init) &&
optExpression(maybeTest, &test) &&
optExpression(updateOrIter, &update) &&
builder.forStatement(init, test, update, stmt, &pn->pn_pos, dst);
builder.forStatement(init, test, update, stmt, &forNode->pn_pos, dst);
}
case PNK_BREAK:
@ -2639,7 +2660,8 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
if (!methods.reserve(methodList->count()))
return false;
for (ParseNode* method : methodList->contents()) {
for (ParseNode* item : methodList->contents()) {
ClassMethod* method = &item->as<ClassMethod>();
MOZ_ASSERT(methodList->pn_pos.encloses(method->pn_pos));
RootedValue prop(cx);
@ -2660,10 +2682,10 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
}
bool
ASTSerializer::classMethod(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::classMethod(ClassMethod* classMethod, MutableHandleValue dst)
{
PropKind kind;
switch (pn->getOp()) {
switch (classMethod->getOp()) {
case JSOP_INITPROP:
kind = PROP_INIT;
break;
@ -2681,10 +2703,10 @@ ASTSerializer::classMethod(ParseNode* pn, MutableHandleValue dst)
}
RootedValue key(cx), val(cx);
bool isStatic = pn->as<ClassMethod>().isStatic();
return propertyName(pn->pn_left, &key) &&
expression(pn->pn_right, &val) &&
builder.classMethod(key, val, kind, isStatic, &pn->pn_pos, dst);
bool isStatic = classMethod->isStatic();
return propertyName(&classMethod->name(), &key) &&
expression(&classMethod->method(), &val) &&
builder.classMethod(key, val, kind, isStatic, &classMethod->pn_pos, dst);
}
bool
@ -2767,15 +2789,13 @@ ASTSerializer::rightAssociate(ListNode* node, MutableHandleValue dst)
}
bool
ASTSerializer::comprehensionBlock(ParseNode* pn, MutableHandleValue dst)
ASTSerializer::comprehensionBlock(ForNode* forNode, MutableHandleValue dst)
{
LOCAL_ASSERT(pn->isArity(PN_BINARY));
TernaryNode* in = &pn->pn_left->as<TernaryNode>();
TernaryNode* in = forNode->head();
LOCAL_ASSERT(in && (in->isKind(PNK_FORIN) || in->isKind(PNK_FOROF)));
bool isForEach = in->isKind(PNK_FORIN) && (pn->pn_iflags & JSITER_FOREACH);
bool isForEach = in->isKind(PNK_FORIN) && (forNode->iflags() & JSITER_FOREACH);
bool isForOf = in->isKind(PNK_FOROF);
ListNode* decl;
@ -2817,10 +2837,11 @@ ASTSerializer::comprehension(ParseNode* pn, MutableHandleValue dst)
RootedValue filter(cx, MagicValue(JS_SERIALIZE_NO_NODE));
while (true) {
if (next->isKind(PNK_COMPREHENSIONFOR)) {
ForNode* forNode = &next->as<ForNode>();
RootedValue block(cx);
if (!comprehensionBlock(next, &block) || !blocks.append(block))
if (!comprehensionBlock(forNode, &block) || !blocks.append(block))
return false;
next = next->pn_right;
next = forNode->body();
} else if (next->isKind(PNK_IF)) {
TernaryNode* tn = &next->as<TernaryNode>();
if (isLegacy) {
@ -2862,10 +2883,11 @@ ASTSerializer::generatorExpression(ParseNode* pn, MutableHandleValue dst)
RootedValue filter(cx, MagicValue(JS_SERIALIZE_NO_NODE));
while (true) {
if (next->isKind(PNK_COMPREHENSIONFOR)) {
ForNode* forNode = &next->as<ForNode>();
RootedValue block(cx);
if (!comprehensionBlock(next, &block) || !blocks.append(block))
if (!comprehensionBlock(forNode, &block) || !blocks.append(block))
return false;
next = next->pn_right;
next = forNode->body();
} else if (next->isKind(PNK_IF)) {
TernaryNode* tn = &next->as<TernaryNode>();
if (isLegacy) {
@ -2972,16 +2994,19 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_MODASSIGN:
case PNK_POWASSIGN:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
AssignmentNode* assignNode = &pn->as<AssignmentNode>();
ParseNode* lhsNode = assignNode->left();
ParseNode* rhsNode = assignNode->right();
MOZ_ASSERT(assignNode->pn_pos.encloses(lhsNode->pn_pos));
MOZ_ASSERT(assignNode->pn_pos.encloses(rhsNode->pn_pos));
AssignmentOperator op = aop(pn->getOp());
AssignmentOperator op = aop(assignNode->getOp());
LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT);
RootedValue lhs(cx), rhs(cx);
return pattern(pn->pn_left, &lhs) &&
expression(pn->pn_right, &rhs) &&
builder.assignmentExpression(op, lhs, rhs, &pn->pn_pos, dst);
return pattern(lhsNode, &lhs) &&
expression(rhsNode, &rhs) &&
builder.assignmentExpression(op, lhs, rhs, &assignNode->pn_pos, dst);
}
case PNK_ADD:
@ -3033,7 +3058,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
}
case PNK_GENEXP: {
ParseNode* callee = pn->pn_left;
ParseNode* callee = pn->as<BinaryNode>().left();
MOZ_ASSERT(callee->isKind(PNK_FUNCTION));
ListNode* paramsBody = &callee->pn_body->as<ListNode>();
@ -3064,17 +3089,18 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_OPTCALL:
case PNK_SUPERCALL:
{
ParseNode* pn_callee = pn->pn_left;
ListNode* argsList = &pn->pn_right->as<ListNode>();
MOZ_ASSERT(pn->pn_pos.encloses(pn_callee->pn_pos));
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* calleeNode = node->left();
ListNode* argsList = &node->right()->as<ListNode>();
MOZ_ASSERT(node->pn_pos.encloses(calleeNode->pn_pos));
RootedValue callee(cx);
if (pn->isKind(PNK_SUPERCALL)) {
MOZ_ASSERT(pn_callee->isKind(PNK_SUPERBASE));
if (!builder.super(&pn_callee->pn_pos, &callee))
if (node->isKind(PNK_SUPERCALL)) {
MOZ_ASSERT(calleeNode->isKind(PNK_SUPERBASE));
if (!builder.super(&calleeNode->pn_pos, &callee))
return false;
} else {
if (!expression(pn_callee, &callee))
if (!expression(calleeNode, &callee))
return false;
}
@ -3083,7 +3109,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
return false;
for (ParseNode* argNode : argsList->contents()) {
MOZ_ASSERT(pn->pn_pos.encloses(argNode->pn_pos));
MOZ_ASSERT(node->pn_pos.encloses(argNode->pn_pos));
RootedValue arg(cx);
if (!expression(argNode, &arg))
@ -3091,67 +3117,63 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
args.infallibleAppend(arg);
}
if (pn->getKind() == PNK_TAGGED_TEMPLATE)
return builder.taggedTemplate(callee, args, &pn->pn_pos, dst);
if (node->getKind() == PNK_TAGGED_TEMPLATE)
return builder.taggedTemplate(callee, args, &node->pn_pos, dst);
bool isOptional = pn->isKind(PNK_OPTCALL);
bool isOptional = node->isKind(PNK_OPTCALL);
// SUPERCALL is Call(super, args)
return pn->isKind(PNK_NEW)
? builder.newExpression(callee, args, &pn->pn_pos, dst)
: builder.callExpression(callee, args, &pn->pn_pos, dst, isOptional);
return node->isKind(PNK_NEW)
? builder.newExpression(callee, args, &node->pn_pos, dst)
: builder.callExpression(callee, args, &node->pn_pos, dst, isOptional);
}
case PNK_OPTDOT:
case PNK_DOT:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
PropertyAccess* prop = &pn->as<PropertyAccess>();
MOZ_ASSERT(prop->pn_pos.encloses(prop->expression().pn_pos));
RootedValue expr(cx);
RootedValue propname(cx);
RootedAtom pnAtom(cx, pn->pn_right->pn_atom);
RootedAtom pnAtom(cx, prop->key().pn_atom);
bool isSuper = pn->is<PropertyAccess>() &&
pn->as<PropertyAccess>().isSuper();
if (isSuper) {
if (!builder.super(&pn->pn_left->pn_pos, &expr))
if (prop->isSuper()) {
if (!builder.super(&prop->expression().pn_pos, &expr))
return false;
} else {
if (!expression(pn->pn_left, &expr))
if (!expression(&prop->expression(), &expr))
return false;
}
bool isOptional = pn->isKind(PNK_OPTDOT);
bool isOptional = prop->isKind(PNK_OPTDOT);
return identifier(pnAtom, nullptr, &propname) &&
builder.memberExpression(false, expr, propname, &pn->pn_pos,
builder.memberExpression(false, expr, propname, &prop->pn_pos,
dst, isOptional);
}
case PNK_OPTELEM:
case PNK_ELEM:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
PropertyByValueBase* elem = &pn->as<PropertyByValueBase>();
MOZ_ASSERT(elem->pn_pos.encloses(elem->expression().pn_pos));
MOZ_ASSERT(elem->pn_pos.encloses(elem->key().pn_pos));
RootedValue left(cx), right(cx);
RootedValue expr(cx), key(cx);
bool isSuper = pn->is<PropertyByValue>() &&
pn->as<PropertyByValue>().isSuper();
if (isSuper) {
if (!builder.super(&pn->pn_left->pn_pos, &left))
if (elem->isSuper()) {
if (!builder.super(&elem->expression().pn_pos, &expr))
return false;
} else {
if (!expression(pn->pn_left, &left))
if (!expression(&elem->expression(), &expr))
return false;
}
bool isOptional = pn->isKind(PNK_OPTELEM);
bool isOptional = elem->isKind(PNK_OPTELEM);
return expression(pn->pn_right, &right) &&
builder.memberExpression(true, left, right, &pn->pn_pos, dst,
return expression(&elem->key(), &key) &&
builder.memberExpression(true, expr, key, &elem->pn_pos, dst,
isOptional);
}
@ -3288,7 +3310,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos));
RootedValue arg(cx);
return expression(pn->pn_left, &arg) &&
return expression(pn->pn_kid, &arg) &&
builder.yieldExpression(arg, Delegating, &pn->pn_pos, dst);
}
@ -3316,10 +3338,14 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_NEWTARGET:
{
MOZ_ASSERT(pn->pn_left->isKind(PNK_POSHOLDER));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_right->isKind(PNK_POSHOLDER));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* firstNode = node->left();
MOZ_ASSERT(firstNode->isKind(PNK_POSHOLDER));
MOZ_ASSERT(node->pn_pos.encloses(firstNode->pn_pos));
ParseNode* secondNode = node->right();
MOZ_ASSERT(secondNode->isKind(PNK_POSHOLDER));
MOZ_ASSERT(node->pn_pos.encloses(secondNode->pn_pos));
RootedValue newIdent(cx);
RootedValue targetIdent(cx);
@ -3327,16 +3353,18 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
RootedAtom newStr(cx, cx->names().new_);
RootedAtom targetStr(cx, cx->names().target);
return identifier(newStr, &pn->pn_left->pn_pos, &newIdent) &&
identifier(targetStr, &pn->pn_right->pn_pos, &targetIdent) &&
builder.metaProperty(newIdent, targetIdent, &pn->pn_pos, dst);
return identifier(newStr, &firstNode->pn_pos, &newIdent) &&
identifier(targetStr, &secondNode->pn_pos, &targetIdent) &&
builder.metaProperty(newIdent, targetIdent, &node->pn_pos, dst);
}
case PNK_SETTHIS:
case PNK_SETTHIS: {
// SETTHIS is used to assign the result of a super() call to |this|.
// It's not part of the original AST, so just forward to the call.
MOZ_ASSERT(pn->pn_left->isKind(PNK_NAME));
return expression(pn->pn_right, dst);
BinaryNode* node = &pn->as<BinaryNode>();
MOZ_ASSERT(node->left()->isKind(PNK_NAME));
return expression(node->right(), dst);
}
default:
LOCAL_NOT_REACHED("unexpected expression type");
@ -3385,14 +3413,18 @@ ASTSerializer::property(ParseNode* pn, MutableHandleValue dst)
LOCAL_NOT_REACHED("unexpected object-literal property");
}
bool isShorthand = pn->isKind(PNK_SHORTHAND);
BinaryNode* node = &pn->as<BinaryNode>();
ParseNode* keyNode = node->left();
ParseNode* valNode = node->right();
bool isShorthand = node->isKind(PNK_SHORTHAND);
bool isMethod =
pn->pn_right->isKind(PNK_FUNCTION) &&
pn->pn_right->pn_funbox->function()->kind() == JSFunction::Method;
valNode->isKind(PNK_FUNCTION) &&
valNode->pn_funbox->function()->kind() == JSFunction::Method;
RootedValue key(cx), val(cx);
return propertyName(pn->pn_left, &key) &&
expression(pn->pn_right, &val) &&
builder.propertyInitializer(key, val, kind, isShorthand, isMethod, &pn->pn_pos, dst);
return propertyName(keyNode, &key) &&
expression(valNode, &val) &&
builder.propertyInitializer(key, val, kind, isShorthand, isMethod, &node->pn_pos, dst);
}
bool
@ -3506,9 +3538,10 @@ ASTSerializer::objectPattern(ListNode* obj, MutableHandleValue dst)
return false;
target = propdef->pn_kid;
} else {
if (!propertyName(propdef->pn_left, &key))
BinaryNode* prop = &propdef->as<BinaryNode>();
if (!propertyName(prop->left(), &key))
return false;
target = propdef->pn_right;
target = prop->right();
}
RootedValue patt(cx), prop(cx);
@ -3665,9 +3698,9 @@ ASTSerializer::functionArgs(ParseNode* pn, ListNode* argsList,
pat = arg;
defNode = nullptr;
} else {
MOZ_ASSERT(arg->isKind(PNK_ASSIGN));
pat = arg->pn_left;
defNode = arg->pn_right;
AssignmentNode* assignNode = &arg->as<AssignmentNode>();
pat = assignNode->left();
defNode = assignNode->right();
}
// Process the name or pattern.

File diff suppressed because it is too large Load diff

View file

@ -469,7 +469,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitGetFunctionThis(ParseNode* pn);
MOZ_MUST_USE bool emitGetFunctionThis(const mozilla::Maybe<uint32_t>& offset);
MOZ_MUST_USE bool emitGetThisForSuperBase(ParseNode* pn);
MOZ_MUST_USE bool emitSetThis(ParseNode* pn);
MOZ_MUST_USE bool emitSetThis(BinaryNode* setThisNode);
MOZ_MUST_USE bool emitCheckDerivedClassConstructorReturn();
// Handle jump opcodes and jump targets.
@ -564,7 +564,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
}
MOZ_MUST_USE bool emitAwaitInInnermostScope(ParseNode* pn);
MOZ_MUST_USE bool emitAwaitInScope(EmitterScope& currentScope);
MOZ_MUST_USE bool emitPropLHS(ParseNode* pn);
MOZ_MUST_USE bool emitPropLHS(PropertyAccess* prop);
MOZ_MUST_USE bool emitPropIncDec(ParseNode* pn);
MOZ_MUST_USE bool emitAsyncWrapperLambda(unsigned index, bool isArrow);
@ -577,7 +577,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
// opcode onto the stack in the right order. In the case of SETELEM, the
// value to be assigned must already be pushed.
enum class EmitElemOption { Get, Set, Call, IncDec, CompoundAssign, Ref };
MOZ_MUST_USE bool emitElemOperands(ParseNode* pn, EmitElemOption opts);
MOZ_MUST_USE bool emitElemOperands(PropertyByValue* elem, EmitElemOption opts);
MOZ_MUST_USE bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEmitter& eoe);
MOZ_MUST_USE bool emitElemOpBase(JSOp op);
@ -585,13 +585,13 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitCatch(TernaryNode* catchNode);
MOZ_MUST_USE bool emitIf(TernaryNode* ifNode);
MOZ_MUST_USE bool emitWith(ParseNode* pn);
MOZ_MUST_USE bool emitWith(BinaryNode* withNode);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitLabeledStatement(const LabeledStatement* pn);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitLexicalScope(ParseNode* pn);
MOZ_MUST_USE bool emitLexicalScopeBody(ParseNode* body,
EmitLineNumberNote emitLineNote = EMIT_LINENOTE);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitSwitch(SwitchStatement* pn);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitSwitch(SwitchStatement* switchStmt);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitTry(TernaryNode* tryNode);
enum DestructuringFlavor {
@ -720,7 +720,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitOptionalElemExpression(PropertyByValueBase* elem,
ElemOpEmitter& eoe, bool isSuper,
OptionalEmitter& oe);
MOZ_MUST_USE bool emitOptionalCall(ParseNode* callNode,
MOZ_MUST_USE bool emitOptionalCall(BinaryNode* callNode,
OptionalEmitter& oe,
ValueUsage valueUsage);
MOZ_MUST_USE bool emitDeletePropertyInOptChain(PropertyAccessBase* propExpr,
@ -750,7 +750,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
ListNode* argsList);
MOZ_MUST_USE bool emitArguments(ListNode* argsList, bool isCall, bool isSpread,
CallOrNewEmitter& cone);
MOZ_MUST_USE bool emitCallOrNew(ParseNode* pn,
MOZ_MUST_USE bool emitCallOrNew(BinaryNode* pn,
ValueUsage valueUsage = ValueUsage::WantValue);
MOZ_MUST_USE bool emitCalleeAndThis(ParseNode* callNode,
ParseNode* calleeNode,
@ -760,23 +760,23 @@ struct MOZ_STACK_CLASS BytecodeEmitter
CallOrNewEmitter& cone,
OptionalEmitter& oe);
MOZ_MUST_USE bool emitSelfHostedCallFunction(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedResumeGenerator(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedCallFunction(BinaryNode* callNode);
MOZ_MUST_USE bool emitSelfHostedResumeGenerator(BinaryNode* callNode);
MOZ_MUST_USE bool emitSelfHostedForceInterpreter(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedAllowContentIter(ParseNode* pn);
MOZ_MUST_USE bool emitSelfHostedAllowContentIter(BinaryNode* callNode);
MOZ_MUST_USE bool emitComprehensionFor(ParseNode* compFor);
MOZ_MUST_USE bool emitComprehensionForIn(ParseNode* pn);
MOZ_MUST_USE bool emitComprehensionFor(ForNode* forNode);
MOZ_MUST_USE bool emitComprehensionForIn(ForNode* forNode);
MOZ_MUST_USE bool emitComprehensionForInOrOfVariables(ParseNode* pn, bool* lexicalScope);
MOZ_MUST_USE bool emitComprehensionForOf(ParseNode* pn);
MOZ_MUST_USE bool emitComprehensionForOf(ForNode* forNode);
MOZ_MUST_USE bool emitDo(ParseNode* pn);
MOZ_MUST_USE bool emitWhile(ParseNode* pn);
MOZ_MUST_USE bool emitDo(BinaryNode* doNode);
MOZ_MUST_USE bool emitWhile(BinaryNode* whileNode);
MOZ_MUST_USE bool emitFor(ParseNode* pn, EmitterScope* headLexicalEmitterScope = nullptr);
MOZ_MUST_USE bool emitCStyleFor(ParseNode* pn, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitForIn(ParseNode* pn, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitForOf(ParseNode* pn, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitFor(ForNode* forNode, EmitterScope* headLexicalEmitterScope = nullptr);
MOZ_MUST_USE bool emitCStyleFor(ForNode* forNode, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitForIn(ForNode* forNode, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitForOf(ForNode* forNode, EmitterScope* headLexicalEmitterScope);
MOZ_MUST_USE bool emitInitializeForInOrOfTarget(TernaryNode* forHead);

View file

@ -141,14 +141,14 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// Statements possibly containing hoistable declarations only in the left
// half, in ParseNode terms -- the loop body in AST terms.
case PNK_DOWHILE:
return ContainsHoistedDeclaration(cx, node->pn_left, result);
return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().left(), result);
// Statements possibly containing hoistable declarations only in the
// right half, in ParseNode terms -- the loop body or nested statement
// (usually a block statement), in AST terms.
case PNK_WHILE:
case PNK_WITH:
return ContainsHoistedDeclaration(cx, node->pn_right, result);
return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().right(), result);
case PNK_LABEL:
return ContainsHoistedDeclaration(cx, node->pn_expr, result);
@ -228,18 +228,20 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
// A switch node's left half is an expression; only its right half (a
// list of cases/defaults, or a block node) could contain hoisted
// declarations.
case PNK_SWITCH:
MOZ_ASSERT(node->isArity(PN_BINARY));
return ContainsHoistedDeclaration(cx, node->pn_right, result);
case PNK_SWITCH: {
SwitchStatement* switchNode = &node->as<SwitchStatement>();
return ContainsHoistedDeclaration(cx, &switchNode->lexicalForCaseList(), result);
}
case PNK_CASE:
return ContainsHoistedDeclaration(cx, node->as<CaseClause>().statementList(), result);
case PNK_CASE: {
CaseClause* caseClause = &node->as<CaseClause>();
return ContainsHoistedDeclaration(cx, caseClause->statementList(), result);
}
case PNK_FOR:
case PNK_COMPREHENSIONFOR: {
MOZ_ASSERT(node->isArity(PN_BINARY));
TernaryNode* loopHead = &node->pn_left->as<TernaryNode>();
ForNode* forNode = &node->as<ForNode>();
TernaryNode* loopHead = forNode->head();
MOZ_ASSERT(loopHead->isKind(PNK_FORHEAD) ||
loopHead->isKind(PNK_FORIN) ||
loopHead->isKind(PNK_FOROF));
@ -275,7 +277,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
}
}
ParseNode* loopBody = node->pn_right;
ParseNode* loopBody = forNode->body();
return ContainsHoistedDeclaration(cx, loopBody, result);
}
@ -1301,19 +1303,16 @@ static bool
FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
ParseNode* node = *nodePtr;
PropertyByValueBase* elem = &(*nodePtr)->as<PropertyByValueBase>();
MOZ_ASSERT(node->isKind(PNK_ELEM) || node->isKind(PNK_OPTELEM));
MOZ_ASSERT(node->isArity(PN_BINARY));
ParseNode*& expr = node->pn_left;
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, elem->unsafeLeftReference(), parser, inGenexpLambda))
return false;
ParseNode*& key = node->pn_right;
if (!Fold(cx, &key, parser, inGenexpLambda))
if (!Fold(cx, elem->unsafeRightReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = &elem->expression();
ParseNode* key = &elem->key();
PropertyName* name = nullptr;
if (key->isKind(PNK_STRING)) {
JSAtom* atom = key->pn_atom;
@ -1351,7 +1350,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
if (!nameNode)
return false;
ParseNode* dottedAccess;
if (node->isKind(PNK_OPTELEM)) {
if (elem->isKind(PNK_OPTELEM)) {
dottedAccess = parser.handler.newOptionalPropertyAccess(expr, nameNode);
} else {
dottedAccess = parser.handler.newPropertyAccess(expr, nameNode);
@ -1359,7 +1358,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
if (!dottedAccess) {
return false;
}
dottedAccess->setInParens(node->isInParens());
dottedAccess->setInParens(elem->isInParens());
ReplaceNode(nodePtr, dottedAccess);
// If we've replaced |expr["prop"]| with |expr.prop|, we can now free the
@ -1367,10 +1366,10 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
// now using as a sub-node of |dottedAccess|. Munge |expr["prop"]| into a
// node with |"prop"| as its only child, that'll pass AST sanity-checking
// assertions during freeing, then free it.
node->setKind(PNK_TYPEOFEXPR);
node->setArity(PN_UNARY);
node->pn_kid = key;
parser.freeTree(node);
elem->setKind(PNK_TYPEOFEXPR);
elem->setArity(PN_UNARY);
elem->pn_kid = key;
parser.freeTree(elem);
return true;
}
@ -1523,7 +1522,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par
}
static bool
FoldCall(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldCall(ExclusiveContext* cx, BinaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_CALL) ||
@ -1531,7 +1530,6 @@ FoldCall(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser
node->isKind(PNK_SUPERCALL) ||
node->isKind(PNK_NEW) ||
node->isKind(PNK_TAGGED_TEMPLATE));
MOZ_ASSERT(node->isArity(PN_BINARY));
// Don't fold a parenthesized callable component in an invocation, as this
// might cause a different |this| value to be used, changing semantics:
@ -1544,14 +1542,13 @@ FoldCall(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser
// assertEq(obj.f``, "obj");
//
// See bug 537673 and bug 1182373.
ParseNode** pn_callee = &node->pn_left;
if (node->isKind(PNK_NEW) || !(*pn_callee)->isInParens()) {
if (!Fold(cx, pn_callee, parser, inGenexpLambda))
ParseNode* callee = node->left();
if (node->isKind(PNK_NEW) || !callee->isInParens()) {
if (!Fold(cx, node->unsafeLeftReference(), parser, inGenexpLambda))
return false;
}
ParseNode** pn_args = &node->pn_right;
if (!Fold(cx, pn_args, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda))
return false;
return true;
@ -1616,18 +1613,14 @@ FoldForHead(ExclusiveContext* cx, TernaryNode* node, Parser<FullParseHandler>& p
}
static bool
FoldDottedProperty(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldDottedProperty(ExclusiveContext* cx, PropertyAccessBase* prop, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_DOT) || node->isKind(PNK_OPTDOT));
MOZ_ASSERT(node->isArity(PN_BINARY));
// Iterate through a long chain of dotted property accesses to find the
// most-nested non-dotted property node, then fold that.
ParseNode** nested = &node->pn_left;
ParseNode** nested = prop->unsafeLeftReference();
while ((*nested)->isKind(PNK_DOT) || (*nested)->isKind(PNK_OPTDOT)) {
MOZ_ASSERT((*nested)->isArity(PN_BINARY));
nested = &(*nested)->pn_left;
nested = (*nested)->as<PropertyAccessBase>().unsafeLeftReference();
}
return Fold(cx, nested, parser, inGenexpLambda);
@ -1736,8 +1729,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_EXPORT_DEFAULT:
case PNK_GENEXP:
MOZ_ASSERT(pn->isArity(PN_BINARY));
return Fold(cx, &pn->pn_left, parser, inGenexpLambda);
return Fold(cx, pn->as<BinaryNode>().unsafeLeftReference(), parser, inGenexpLambda);
case PNK_DELETEOPTCHAIN:
case PNK_OPTCHAIN:
@ -1804,12 +1796,15 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_IMPORT_SPEC_LIST:
return FoldList(cx, &pn->as<ListNode>(), parser, inGenexpLambda);
case PNK_INITIALYIELD:
case PNK_INITIALYIELD: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->pn_kid->isKind(PNK_ASSIGN) &&
pn->pn_kid->pn_left->isKind(PNK_NAME) &&
pn->pn_kid->pn_right->isKind(PNK_GENERATOR));
#ifdef DEBUG
AssignmentNode* assignNode = &pn->pn_kid->as<AssignmentNode>();
MOZ_ASSERT(assignNode->left()->isKind(PNK_NAME));
MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR));
#endif
return true;
}
case PNK_YIELD_STAR:
MOZ_ASSERT(pn->isArity(PN_UNARY));
@ -1836,6 +1831,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_OPTELEM:
case PNK_ELEM:
MOZ_ASSERT((*pnp)->is<PropertyByValueBase>());
return FoldElement(cx, pnp, parser, inGenexpLambda);
case PNK_ADD:
@ -1847,7 +1843,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_NEW:
case PNK_SUPERCALL:
case PNK_TAGGED_TEMPLATE:
return FoldCall(cx, pn, parser, inGenexpLambda);
return FoldCall(cx, &pn->as<BinaryNode>(), parser, inGenexpLambda);
case PNK_ARGUMENTS:
return FoldArguments(cx, &pn->as<ListNode>(), parser, inGenexpLambda);
@ -1875,50 +1871,59 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_CLASSMETHOD:
case PNK_IMPORT_SPEC:
case PNK_EXPORT_SPEC:
case PNK_SETTHIS:
MOZ_ASSERT(pn->isArity(PN_BINARY));
return Fold(cx, &pn->pn_left, parser, inGenexpLambda) &&
Fold(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_NEWTARGET:
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(PNK_POSHOLDER));
MOZ_ASSERT(pn->pn_right->isKind(PNK_POSHOLDER));
return true;
case PNK_CLASSNAMES:
MOZ_ASSERT(pn->isArity(PN_BINARY));
if (ParseNode*& outerBinding = pn->pn_left) {
if (!Fold(cx, &outerBinding, parser, inGenexpLambda))
return false;
}
return Fold(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_DOWHILE:
MOZ_ASSERT(pn->isArity(PN_BINARY));
return Fold(cx, &pn->pn_left, parser, inGenexpLambda) &&
FoldCondition(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_WHILE:
MOZ_ASSERT(pn->isArity(PN_BINARY));
return FoldCondition(cx, &pn->pn_left, parser, inGenexpLambda) &&
Fold(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_CASE: {
MOZ_ASSERT(pn->isArity(PN_BINARY));
// pn_left is null for DefaultClauses.
if (pn->pn_left) {
if (!Fold(cx, &pn->pn_left, parser, inGenexpLambda))
return false;
}
return Fold(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_SETTHIS: {
BinaryNode* node = &pn->as<BinaryNode>();
return Fold(cx, node->unsafeLeftReference(), parser, inGenexpLambda) &&
Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_WITH:
MOZ_ASSERT(pn->isArity(PN_BINARY));
return Fold(cx, &pn->pn_left, parser, inGenexpLambda) &&
Fold(cx, &pn->pn_right, parser, inGenexpLambda);
case PNK_NEWTARGET:{
#ifdef DEBUG
BinaryNode* node = &pn->as<BinaryNode>();
MOZ_ASSERT(node->left()->isKind(PNK_POSHOLDER));
MOZ_ASSERT(node->right()->isKind(PNK_POSHOLDER));
#endif
return true;
}
case PNK_CLASSNAMES: {
ClassNames* names = &pn->as<ClassNames>();
if (names->outerBinding()) {
if (!Fold(cx, names->unsafeLeftReference(), parser, inGenexpLambda)) {
return false;
}
}
return Fold(cx, names->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_DOWHILE: {
BinaryNode* node = &pn->as<BinaryNode>();
return Fold(cx, node->unsafeLeftReference(), parser, inGenexpLambda) &&
FoldCondition(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_WHILE: {
BinaryNode* node = &pn->as<BinaryNode>();
return FoldCondition(cx, node->unsafeLeftReference(), parser, inGenexpLambda) &&
Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_CASE: {
CaseClause* caseClause = &pn->as<CaseClause>();
// left (caseExpression) is null for DefaultClauses.
if (caseClause->left()) {
if (!Fold(cx, caseClause->unsafeLeftReference(), parser, inGenexpLambda))
return false;
}
return Fold(cx, caseClause->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_WITH: {
BinaryNode* node = &pn->as<BinaryNode>();
return Fold(cx, node->unsafeLeftReference(), parser, inGenexpLambda) &&
Fold(cx, node->unsafeRightReference(), parser, inGenexpLambda);
}
case PNK_FORIN:
case PNK_FOROF:
@ -1936,7 +1941,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_OPTDOT:
case PNK_DOT:
return FoldDottedProperty(cx, pn, parser, inGenexpLambda);
return FoldDottedProperty(cx, &pn->as<PropertyAccessBase>(), parser, inGenexpLambda);
case PNK_LEXICALSCOPE:
MOZ_ASSERT(pn->isArity(PN_SCOPE));

View file

@ -279,14 +279,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<UnaryNode>(PNK_ARRAYPUSH, JSOP_ARRAYPUSH, pos, kid);
}
ParseNode* newBinary(ParseNodeKind kind, JSOp op = JSOP_NOP) {
BinaryNodeType newBinary(ParseNodeKind kind, JSOp op = JSOP_NOP) {
return new_<BinaryNode>(kind, op, pos(), (ParseNode*) nullptr, (ParseNode*) nullptr);
}
ParseNode* newBinary(ParseNodeKind kind, ParseNode* left,
BinaryNodeType newBinary(ParseNodeKind kind, ParseNode* left,
JSOp op = JSOP_NOP) {
return new_<BinaryNode>(kind, op, left->pn_pos, left, (ParseNode*) nullptr);
}
ParseNode* newBinary(ParseNodeKind kind, ParseNode* left, ParseNode* right,
BinaryNodeType newBinary(ParseNodeKind kind, ParseNode* left, ParseNode* right,
JSOp op = JSOP_NOP) {
TokenPos pos(left->pn_pos.begin, right->pn_pos.end);
return new_<BinaryNode>(kind, op, pos, left, right);
@ -340,11 +340,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
literal->append(element);
}
ParseNode* newCall(ParseNode* callee, ParseNode* args) {
BinaryNodeType newCall(ParseNode* callee, ParseNode* args) {
return new_<BinaryNode>(PNK_CALL, JSOP_CALL, callee, args);
}
ParseNode* newOptionalCall(ParseNode* callee, ParseNode* args) {
BinaryNodeType newOptionalCall(ParseNode* callee, ParseNode* args) {
return new_<BinaryNode>(PNK_OPTCALL, JSOP_CALL, callee, args);
}
@ -352,15 +352,15 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<ListNode>(PNK_ARGUMENTS, JSOP_NOP, pos);
}
ParseNode* newSuperCall(ParseNode* callee, ParseNode* args) {
BinaryNodeType newSuperCall(ParseNode* callee, ParseNode* args) {
return new_<BinaryNode>(PNK_SUPERCALL, JSOP_SUPERCALL, callee, args);
}
ParseNode* newTaggedTemplate(ParseNode* tag, ParseNode* args) {
BinaryNodeType newTaggedTemplate(ParseNode* tag, ParseNode* args) {
return new_<BinaryNode>(PNK_TAGGED_TEMPLATE, JSOP_CALL, tag, args);
}
ParseNode* newGenExp(ParseNode* callee, ParseNode* args) {
BinaryNodeType newGenExp(ParseNode* callee, ParseNode* args) {
return new_<BinaryNode>(PNK_GENEXP, JSOP_CALL, callee, args);
}
@ -378,10 +378,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
ListNodeType newClassMethodList(uint32_t begin) {
return new_<ListNode>(PNK_CLASSMETHODLIST, TokenPos(begin, begin + 1));
}
ParseNode* newClassNames(ParseNode* outer, ParseNode* inner, const TokenPos& pos) {
ClassNamesType newClassNames(ParseNode* outer, ParseNode* inner, const TokenPos& pos) {
return new_<ClassNames>(outer, inner, pos);
}
ParseNode* newNewTarget(ParseNode* newHolder, ParseNode* targetHolder) {
BinaryNodeType newNewTarget(ParseNode* newHolder, ParseNode* targetHolder) {
return new_<BinaryNode>(PNK_NEWTARGET, JSOP_NOP, newHolder, targetHolder);
}
ParseNode* newPosHolder(const TokenPos& pos) {
@ -410,7 +410,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
key->isKind(PNK_STRING) ||
key->isKind(PNK_COMPUTED_NAME));
ParseNode* propdef = newBinary(PNK_COLON, key, val, JSOP_INITPROP);
BinaryNode* propdef = newBinary(PNK_COLON, key, val, JSOP_INITPROP);
if (!propdef)
return false;
@ -428,7 +428,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_ASSERT(name->pn_atom == expr->pn_atom);
literal->setHasNonConstInitializer();
ParseNode* propdef = newBinary(PNK_SHORTHAND, name, expr, JSOP_INITPROP);
BinaryNode* propdef = newBinary(PNK_SHORTHAND, name, expr, JSOP_INITPROP);
if (!propdef)
return false;
literal->append(propdef);
@ -471,7 +471,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
key->isKind(PNK_STRING) ||
key->isKind(PNK_COMPUTED_NAME));
ParseNode* classMethod = new_<ClassMethod>(key, fn, op, isStatic);
ClassMethod* classMethod = new_<ClassMethod>(key, fn, op, isStatic);
if (!classMethod)
return false;
methodList->append(classMethod);
@ -527,14 +527,12 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
}
}
void addCaseStatementToList(ListNodeType list, ParseNode* caseClause) {
void addCaseStatementToList(ListNodeType list, CaseClauseType caseClause) {
MOZ_ASSERT(list->isKind(PNK_STATEMENTLIST));
MOZ_ASSERT(caseClause->isKind(PNK_CASE));
MOZ_ASSERT(caseClause->pn_right->isKind(PNK_STATEMENTLIST));
list->append(caseClause);
if (caseClause->pn_right->as<ListNode>().hasTopLevelFunctionDeclarations())
if (caseClause->statementList()->hasTopLevelFunctionDeclarations())
list->setHasTopLevelFunctionDeclarations();
}
@ -560,7 +558,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return true;
}
ParseNode* newSetThis(ParseNode* thisName, ParseNode* val) {
BinaryNodeType newSetThis(ParseNode* thisName, ParseNode* val) {
MOZ_ASSERT(thisName->getOp() == JSOP_GETNAME);
thisName->setOp(JSOP_SETNAME);
return newBinary(PNK_SETTHIS, thisName, val);
@ -570,13 +568,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode*) nullptr);
}
ParseNode* newImportDeclaration(ParseNode* importSpecSet,
ParseNode* moduleSpec, const TokenPos& pos)
BinaryNodeType newImportDeclaration(Node importSpecSet, Node moduleSpec, const TokenPos& pos)
{
ParseNode* pn = new_<BinaryNode>(PNK_IMPORT, JSOP_NOP, pos,
importSpecSet, moduleSpec);
if (!pn)
return null();
BinaryNode* pn = new_<BinaryNode>(PNK_IMPORT, JSOP_NOP, pos,
importSpecSet, moduleSpec);
return pn;
}
@ -584,18 +579,21 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<UnaryNode>(PNK_EXPORT, JSOP_NOP, pos, kid);
}
ParseNode* newExportFromDeclaration(uint32_t begin, ParseNode* exportSpecSet,
ParseNode* moduleSpec)
{
ParseNode* pn = new_<BinaryNode>(PNK_EXPORT_FROM, JSOP_NOP, exportSpecSet, moduleSpec);
if (!pn)
BinaryNodeType newExportFromDeclaration(uint32_t begin, Node exportSpecSet, Node moduleSpec) {
BinaryNode* decl = new_<BinaryNode>(PNK_EXPORT_FROM, JSOP_NOP, exportSpecSet, moduleSpec);
if (!decl)
return null();
pn->pn_pos.begin = begin;
return pn;
decl->pn_pos.begin = begin;
return decl;
}
ParseNode* newExportDefaultDeclaration(ParseNode* kid, ParseNode* maybeBinding,
const TokenPos& pos) {
BinaryNodeType newExportDefaultDeclaration(Node kid, Node maybeBinding, const TokenPos& pos) {
if (maybeBinding) {
MOZ_ASSERT(maybeBinding->isKind(PNK_NAME));
MOZ_ASSERT(!maybeBinding->isInParens());
checkAndSetIsDirectRHSAnonFunction(kid);
}
return new_<BinaryNode>(PNK_EXPORT_DEFAULT, JSOP_NOP, pos, kid, maybeBinding);
}
@ -612,36 +610,28 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return node;
}
ParseNode* newDoWhileStatement(ParseNode* body, ParseNode* cond, const TokenPos& pos) {
BinaryNodeType newDoWhileStatement(Node body, Node cond, const TokenPos& pos) {
return new_<BinaryNode>(PNK_DOWHILE, JSOP_NOP, pos, body, cond);
}
ParseNode* newWhileStatement(uint32_t begin, ParseNode* cond, ParseNode* body) {
BinaryNodeType newWhileStatement(uint32_t begin, Node cond, Node body) {
TokenPos pos(begin, body->pn_pos.end);
return new_<BinaryNode>(PNK_WHILE, JSOP_NOP, pos, cond, body);
}
Node newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags) {
/* A FOR node is binary, left is loop control and right is the body. */
JSOp op = forHead->isKind(PNK_FORIN) ? JSOP_ITER : JSOP_NOP;
BinaryNode* pn = new_<BinaryNode>(PNK_FOR, op, TokenPos(begin, body->pn_pos.end),
forHead, body);
if (!pn)
return null();
pn->pn_iflags = iflags;
return pn;
ForNodeType newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags)
{
return new_<ForNode>(TokenPos(begin, body->pn_pos.end), forHead, body, iflags);
}
Node newComprehensionFor(uint32_t begin, TernaryNodeType forHead, Node body) {
ForNodeType newComprehensionFor(uint32_t begin, TernaryNodeType forHead, Node body) {
// A PNK_COMPREHENSIONFOR node is binary: left is loop control, right
// is the body.
MOZ_ASSERT(forHead->isKind(PNK_FORIN) || forHead->isKind(PNK_FOROF));
JSOp op = forHead->isKind(PNK_FORIN) ? JSOP_ITER : JSOP_NOP;
BinaryNode* pn = new_<BinaryNode>(PNK_COMPREHENSIONFOR, op,
TokenPos(begin, body->pn_pos.end), forHead, body);
ForNode* pn = new_<ForNode>(TokenPos(begin, body->pn_pos.end), forHead, body, JSOP_ITER);
if (!pn)
return null();
pn->pn_iflags = JSOP_ITER;
pn->setKind(PNK_COMPREHENSIONFOR);
return pn;
}
@ -661,14 +651,13 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<TernaryNode>(kind, JSOP_NOP, target, nullptr, iteratedExpr, pos);
}
ParseNode* newSwitchStatement(uint32_t begin, ParseNode* discriminant,
ParseNode* lexicalForCaseList, bool hasDefault)
SwitchStatementType newSwitchStatement(uint32_t begin, Node discriminant,
Node lexicalForCaseList, bool hasDefault)
{
return new_<SwitchStatement>(begin, discriminant, lexicalForCaseList, hasDefault);
}
ParseNode* newCaseOrDefault(uint32_t begin, ParseNode* expr, ParseNode* body) {
CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) {
return new_<CaseClause>(expr, body, begin);
}
@ -685,7 +674,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, pos, expr);
}
ParseNode* newWithStatement(uint32_t begin, ParseNode* expr, ParseNode* body) {
BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) {
return new_<BinaryNode>(PNK_WITH, JSOP_NOP, TokenPos(begin, body->pn_pos.end),
expr, body);
}
@ -713,11 +702,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<NameNode>(PNK_PROPERTYNAME, JSOP_NOP, name, pos);
}
ParseNode* newPropertyAccess(ParseNode* expr, ParseNode* key) {
PropertyAccessType newPropertyAccess(Node expr, Node key) {
return new_<PropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end);
}
ParseNode* newPropertyByValue(ParseNode* lhs, ParseNode* index, uint32_t end) {
PropertyByValueType newPropertyByValue(Node lhs, Node index, uint32_t end) {
return new_<PropertyByValue>(lhs, index, lhs->pn_pos.begin, end);
}
@ -783,7 +772,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<CodeNode>(PNK_MODULE, JSOP_NOP, pos());
}
Node newNewExpression(uint32_t begin, ParseNode* ctor, ParseNode* args) {
BinaryNodeType newNewExpression(uint32_t begin, Node ctor, Node args) {
return new_<BinaryNode>(PNK_NEW, JSOP_NEW, TokenPos(begin, args->pn_pos.end), ctor, args);
}
@ -791,10 +780,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<LexicalScopeNode>(bindings, body);
}
ParseNode* newAssignment(ParseNodeKind kind, ParseNode* lhs, ParseNode* rhs,
JSOp op)
{
return newBinary(kind, lhs, rhs, op);
AssignmentNodeType newAssignment(ParseNodeKind kind, Node lhs, Node rhs, JSOp op) {
return new_<AssignmentNode>(kind, op, lhs, rhs);
}
bool isUnparenthesizedYieldExpression(ParseNode* node) {

View file

@ -73,12 +73,14 @@ class NameResolver
*/
bool nameExpression(ParseNode* n, bool* foundName) {
switch (n->getKind()) {
case PNK_DOT:
if (!nameExpression(n->pn_left, foundName))
case PNK_DOT: {
PropertyAccess* prop = &n->as<PropertyAccess>();
if (!nameExpression(&prop->expression(), foundName))
return false;
if (!*foundName)
return true;
return appendPropertyReference(n->pn_right->pn_atom);
return appendPropertyReference(prop->right()->pn_atom);
}
case PNK_NAME:
*foundName = true;
@ -88,16 +90,18 @@ class NameResolver
*foundName = true;
return buf->append("this");
case PNK_ELEM:
if (!nameExpression(n->pn_left, foundName))
case PNK_ELEM: {
PropertyByValue* elem = &n->as<PropertyByValue>();
if (!nameExpression(&elem->expression(), foundName))
return false;
if (!*foundName)
return true;
if (!buf->append('[') || !nameExpression(n->pn_right, foundName))
if (!buf->append('[') || !nameExpression(elem->right(), foundName))
return false;
if (!*foundName)
return true;
return buf->append(']');
}
case PNK_NUMBER:
*foundName = true;
@ -128,7 +132,7 @@ class NameResolver
for (int pos = nparents - 1; pos >= 0; pos--) {
ParseNode* cur = parents[pos];
if (cur->isAssignment())
if (cur->is<AssignmentNode>())
return cur;
switch (cur->getKind()) {
@ -222,8 +226,8 @@ class NameResolver
/* If the function is assigned to something, then that is very relevant */
if (assignment) {
if (assignment->isAssignment())
assignment = assignment->pn_left;
if (assignment->is<AssignmentNode>())
assignment = assignment->as<AssignmentNode>().left();
bool foundName = false;
if (!nameExpression(assignment, &foundName))
return false;
@ -240,7 +244,7 @@ class NameResolver
ParseNode* node = toName[pos];
if (node->isKind(PNK_COLON) || node->isKind(PNK_SHORTHAND)) {
ParseNode* left = node->pn_left;
ParseNode* left = node->as<BinaryNode>().left();
if (left->isKind(PNK_OBJECT_PROPERTY_NAME) || left->isKind(PNK_STRING)) {
if (!appendPropertyReference(left->pn_atom))
return false;
@ -284,7 +288,7 @@ class NameResolver
* for new variables and then return an anonymous function using this scope.
*/
bool isDirectCall(int pos, ParseNode* cur) {
return pos >= 0 && call(parents[pos]) && parents[pos]->pn_left == cur;
return pos >= 0 && call(parents[pos]) && parents[pos]->as<BinaryNode>().left() == cur;
}
bool resolveTemplateLiteral(ListNode* node, HandleAtom prefix) {
@ -304,10 +308,10 @@ class NameResolver
}
}
bool resolveTaggedTemplate(ParseNode* node, HandleAtom prefix) {
MOZ_ASSERT(node->isKind(PNK_TAGGED_TEMPLATE));
bool resolveTaggedTemplate(BinaryNode* taggedTemplate, HandleAtom prefix) {
MOZ_ASSERT(taggedTemplate->isKind(PNK_TAGGED_TEMPLATE));
ParseNode* tag = node->pn_left;
ParseNode* tag = taggedTemplate->left();
// The leading expression, e.g. |tag| in |tag`foo`|,
// that might contain functions.
@ -317,7 +321,8 @@ class NameResolver
// The callsite object node is first. This node only contains
// internal strings or undefined and an array -- no user-controlled
// expressions.
CallSiteNode* element = &node->pn_right->as<ListNode>().head()->as<CallSiteNode>();
CallSiteNode* element =
&taggedTemplate->right()->as<ListNode>().head()->as<CallSiteNode>();
#ifdef DEBUG
{
ListNode* rawNodes = &element->head()->as<ListNode>();
@ -404,11 +409,11 @@ class NameResolver
MOZ_ASSERT(!cur->pn_kid->expr());
break;
case PNK_NEWTARGET:
MOZ_ASSERT(cur->isArity(PN_BINARY));
MOZ_ASSERT(cur->pn_left->isKind(PNK_POSHOLDER));
MOZ_ASSERT(cur->pn_right->isKind(PNK_POSHOLDER));
case PNK_NEWTARGET: {
MOZ_ASSERT(cur->as<BinaryNode>().left()->isKind(PNK_POSHOLDER));
MOZ_ASSERT(cur->as<BinaryNode>().right()->isKind(PNK_POSHOLDER));
break;
}
// Nodes with a single non-null child requiring name resolution.
case PNK_TYPEOFEXPR:
@ -468,45 +473,54 @@ class NameResolver
case PNK_FOR:
case PNK_COMPREHENSIONFOR:
case PNK_CLASSMETHOD:
case PNK_SETTHIS:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolve(cur->pn_left, prefix))
case PNK_SETTHIS: {
BinaryNode* node = &cur->as<BinaryNode>();
if (!resolve(node->left(), prefix)) {
return false;
if (!resolve(cur->pn_right, prefix))
}
if (!resolve(node->right(), prefix)) {
return false;
}
break;
}
case PNK_ELEM: {
PropertyByValue* elem = &cur->as<PropertyByValue>();
if (!elem->isSuper() && !resolve(&elem->expression(), prefix))
return false;
if (!resolve(&elem->key(), prefix))
return false;
break;
}
case PNK_ELEM:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!cur->as<PropertyByValue>().isSuper() && !resolve(cur->pn_left, prefix))
case PNK_WITH: {
BinaryNode* node = &cur->as<BinaryNode>();
if (!resolve(node->left(), prefix))
return false;
if (!resolve(cur->pn_right, prefix))
if (!resolve(node->right(), prefix))
return false;
break;
}
case PNK_WITH:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolve(cur->pn_left, prefix))
return false;
if (!resolve(cur->pn_right, prefix))
return false;
break;
case PNK_CASE:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (ParseNode* caseExpr = cur->pn_left) {
case PNK_CASE: {
CaseClause* caseClause = &cur->as<CaseClause>();
if (ParseNode* caseExpr = caseClause->caseExpression()) {
if (!resolve(caseExpr, prefix))
return false;
}
if (!resolve(cur->pn_right, prefix))
if (!resolve(caseClause->statementList(), prefix))
return false;
break;
}
case PNK_INITIALYIELD:
MOZ_ASSERT(cur->pn_kid->isKind(PNK_ASSIGN) &&
cur->pn_kid->pn_left->isKind(PNK_NAME) &&
cur->pn_kid->pn_right->isKind(PNK_GENERATOR));
case PNK_INITIALYIELD: {
#ifdef DEBUG
AssignmentNode* assignNode = &cur->pn_kid->as<AssignmentNode>();
MOZ_ASSERT(assignNode->left()->isKind(PNK_NAME));
MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR));
#endif
break;
}
case PNK_YIELD_STAR:
MOZ_ASSERT(cur->isArity(PN_UNARY));
@ -533,16 +547,18 @@ class NameResolver
case PNK_IMPORT:
case PNK_EXPORT_FROM:
case PNK_EXPORT_DEFAULT:
case PNK_EXPORT_DEFAULT: {
BinaryNode* node = &cur->as<BinaryNode>();
MOZ_ASSERT(cur->isArity(PN_BINARY));
// The left halves of these nodes don't contain any unconstrained
// expressions, but it's very hard to assert this to safely rely on
// it. So recur anyway.
if (!resolve(cur->pn_left, prefix))
if (!resolve(node->left(), prefix))
return false;
MOZ_ASSERT_IF(!cur->isKind(PNK_EXPORT_DEFAULT),
cur->pn_right->isKind(PNK_STRING));
MOZ_ASSERT_IF(!node->isKind(PNK_EXPORT_DEFAULT),
node->right()->isKind(PNK_STRING));
break;
}
// Ternary nodes with three expression children.
case PNK_CONDITIONAL: {
@ -601,13 +617,15 @@ class NameResolver
ClassNode* classNode = &cur->as<ClassNode>();
#ifdef DEBUG
if (classNode->names()) {
ParseNode* name = classNode->names();
MOZ_ASSERT(name->isKind(PNK_CLASSNAMES));
MOZ_ASSERT(name->isArity(PN_BINARY));
MOZ_ASSERT_IF(name->pn_left, name->pn_left->isKind(PNK_NAME));
MOZ_ASSERT_IF(name->pn_left, !name->pn_left->expr());
MOZ_ASSERT(name->pn_right->isKind(PNK_NAME));
MOZ_ASSERT(!name->pn_right->expr());
ClassNames* names = classNode->names();
if (ParseNode* outerBinding = names->outerBinding()) {
MOZ_ASSERT(outerBinding->isKind(PNK_NAME));
MOZ_ASSERT(!outerBinding->expr());
}
ParseNode* innerBinding = names->innerBinding();
MOZ_ASSERT(innerBinding->isKind(PNK_NAME));
MOZ_ASSERT(!innerBinding->expr());
}
#endif
if (ParseNode* heritage = classNode->heritage()) {
@ -744,21 +762,21 @@ class NameResolver
break;
case PNK_TAGGED_TEMPLATE:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolveTaggedTemplate(cur, prefix))
if (!resolveTaggedTemplate(&cur->as<BinaryNode>(), prefix))
return false;
break;
case PNK_NEW:
case PNK_CALL:
case PNK_GENEXP:
case PNK_SUPERCALL:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolve(cur->pn_left, prefix))
case PNK_SUPERCALL: {
BinaryNode* callNode = &cur->as<BinaryNode>();
if (!resolve(callNode->left(), prefix))
return false;
if (!resolve(cur->pn_right, prefix))
if (!resolve(callNode->right(), prefix))
return false;
break;
}
// Handles the arguments for new/call/supercall, but does _not_ handle
// the Arguments node used by tagged template literals, since that is
@ -784,12 +802,12 @@ class NameResolver
break;
}
for (ParseNode* item : list->contents()) {
MOZ_ASSERT(item->isKind(isImport ? PNK_IMPORT_SPEC : PNK_EXPORT_SPEC));
MOZ_ASSERT(item->isArity(PN_BINARY));
MOZ_ASSERT(item->pn_left->isKind(PNK_NAME));
MOZ_ASSERT(!item->pn_left->expr());
MOZ_ASSERT(item->pn_right->isKind(PNK_NAME));
MOZ_ASSERT(!item->pn_right->expr());
BinaryNode* spec = &item->as<BinaryNode>();
MOZ_ASSERT(spec->isKind(isImport ? PNK_IMPORT_SPEC : PNK_EXPORT_SPEC));
MOZ_ASSERT(spec->left()->isKind(PNK_NAME));
MOZ_ASSERT(!spec->left()->expr());
MOZ_ASSERT(spec->right()->isKind(PNK_NAME));
MOZ_ASSERT(!spec->right()->expr());
}
#endif
break;
@ -807,15 +825,17 @@ class NameResolver
break;
}
case PNK_DOT:
MOZ_ASSERT(cur->isArity(PN_BINARY));
case PNK_DOT: {
// Super prop nodes do not have a meaningful LHS
if (cur->as<PropertyAccess>().isSuper())
PropertyAccess* prop = &cur->as<PropertyAccess>();
if (prop->isSuper()) {
break;
if (!resolve(cur->pn_left, prefix))
}
if (!resolve(&prop->expression(), prefix)) {
return false;
}
break;
}
case PNK_LABEL:
MOZ_ASSERT(cur->isArity(PN_NAME));

View file

@ -276,9 +276,9 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_FOR:
case PNK_COMPREHENSIONFOR:
case PNK_WITH: {
MOZ_ASSERT(pn->isArity(PN_BINARY));
stack->push(pn->pn_left);
stack->push(pn->pn_right);
BinaryNode* bn = &pn->as<BinaryNode>();
stack->push(bn->left());
stack->push(bn->right());
return PushResult::Recyclable;
}
@ -287,10 +287,10 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
// So both are binary nodes with a possibly-null pn_left.
case PNK_CASE:
case PNK_CLASSNAMES: {
MOZ_ASSERT(pn->isArity(PN_BINARY));
if (pn->pn_left)
stack->push(pn->pn_left);
stack->push(pn->pn_right);
BinaryNode* bn = &pn->as<BinaryNode>();
if (bn->left())
stack->push(bn->left());
stack->push(bn->right());
return PushResult::Recyclable;
}
@ -298,9 +298,12 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
// '.generator' local, for a synthesized, prepended initial yield.
case PNK_INITIALYIELD: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->pn_kid->isKind(PNK_ASSIGN) &&
pn->pn_kid->pn_left->isKind(PNK_NAME) &&
pn->pn_kid->pn_right->isKind(PNK_GENERATOR));
#ifdef DEBUG
MOZ_ASSERT(pn->pn_kid->isKind(PNK_ASSIGN));
BinaryNode* bn = &pn->pn_kid->as<BinaryNode>();
MOZ_ASSERT(bn->left()->isKind(PNK_NAME) &&
bn->right()->isKind(PNK_GENERATOR));
#endif
stack->push(pn->pn_kid);
return PushResult::Recyclable;
}
@ -328,22 +331,22 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
// and a module string on the right.
case PNK_IMPORT:
case PNK_EXPORT_FROM: {
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT_IF(pn->isKind(PNK_IMPORT), pn->pn_left->isKind(PNK_IMPORT_SPEC_LIST));
MOZ_ASSERT_IF(pn->isKind(PNK_EXPORT_FROM), pn->pn_left->isKind(PNK_EXPORT_SPEC_LIST));
MOZ_ASSERT(pn->pn_left->isArity(PN_LIST));
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
stack->pushList(&pn->pn_left->as<ListNode>());
stack->push(pn->pn_right);
BinaryNode* bn = &pn->as<BinaryNode>();
MOZ_ASSERT_IF(pn->isKind(PNK_IMPORT), bn->left()->isKind(PNK_IMPORT_SPEC_LIST));
MOZ_ASSERT_IF(pn->isKind(PNK_EXPORT_FROM), bn->left()->isKind(PNK_EXPORT_SPEC_LIST));
MOZ_ASSERT(bn->left()->isArity(PN_LIST));
MOZ_ASSERT(bn->right()->isKind(PNK_STRING));
stack->pushList(&bn->left()->as<ListNode>());
stack->push(bn->right());
return PushResult::Recyclable;
}
case PNK_EXPORT_DEFAULT: {
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT_IF(pn->pn_right, pn->pn_right->isKind(PNK_NAME));
stack->push(pn->pn_left);
if (pn->pn_right)
stack->push(pn->pn_right);
BinaryNode* bn = &pn->as<BinaryNode>();
MOZ_ASSERT_IF(bn->right(), bn->right()->isKind(PNK_NAME));
stack->push(bn->left());
if (bn->right())
stack->push(bn->right());
return PushResult::Recyclable;
}
@ -660,7 +663,7 @@ ParseNode::dump(int indent)
((UnaryNode*) this)->dump(indent);
break;
case PN_BINARY:
((BinaryNode*) this)->dump(indent);
as<BinaryNode>().dump(indent);
break;
case PN_TERNARY:
as<TernaryNode>().dump(indent);
@ -730,13 +733,13 @@ BinaryNode::dump(int indent)
if (isKind(PNK_DOT)) {
fprintf(stderr, "(.");
DumpParseTree(pn_right, indent + 2);
DumpParseTree(right(), indent + 2);
fprintf(stderr, " ");
if (as<PropertyAccess>().isSuper())
fprintf(stderr, "super");
else
DumpParseTree(pn_left, indent + 2);
DumpParseTree(left(), indent + 2);
fprintf(stderr, ")");
return;
@ -745,9 +748,9 @@ BinaryNode::dump(int indent)
const char* name = parseNodeNames[getKind()];
fprintf(stderr, "(%s ", name);
indent += strlen(name) + 2;
DumpParseTree(pn_left, indent);
DumpParseTree(left(), indent);
IndentNewLine(indent);
DumpParseTree(pn_right, indent);
DumpParseTree(right(), indent);
fprintf(stderr, ")");
}

View file

@ -249,8 +249,9 @@ IsTypeofKind(ParseNodeKind kind)
* * PNK_LEXICALSCOPE which contains PNK_CLASSMETHODLIST as scopeBody,
* if named class
* PNK_CLASSNAMES (ClassNames)
* pn_left: Name node for outer binding. can be null
* pn_right: Name node for inner binding
* left: Name node for outer binding, or null if the class is an expression
* that doesn't create an outer binding
* right: Name node for inner binding
* PNK_CLASSMETHODLIST (ListNode)
* head: list of N PNK_CLASSMETHOD nodes
* count: N >= 0
@ -266,21 +267,29 @@ IsTypeofKind(ParseNodeKind kind)
* kid1: cond
* kid2: then = PNK_YIELD, PNK_ARRAYPUSH, (empty) PNK_STATEMENTLIST
* kid3: else or null
* PNK_SWITCH binary pn_left: discriminant
* pn_right: PNK_LEXICALSCOPE node that contains the list
* of PNK_CASE nodes, with at most one default node.
* hasDefault: true if there's a default case
* PNK_CASE binary pn_left: case-expression if CaseClause, or
* null if DefaultClause
* pn_right: PNK_STATEMENTLIST node for this case's
* statements
* PNK_WHILE binary pn_left: cond, pn_right: body
* PNK_DOWHILE binary pn_left: body, pn_right: cond
* PNK_FOR binary pn_left: either PNK_FORIN (for-in statement),
* PNK_FOROF (for-of) or PNK_FORHEAD (for(;;))
* pn_right: body
* PNK_COMPREHENSIONFOR pn_left: either PNK_FORIN or PNK_FOROF
* binary pn_right: body
* PNK_SWITCH (SwitchStatement)
* left: discriminant
* right: LexicalScope node that contains the list of Case nodes, with at
* most one default node.
* hasDefault: true if there's a default case
* PNK_CASE (CaseClause)
* left: case-expression if CaseClause, or null if DefaultClause
* right: StatementList node for this case's statements
* PNK_WHILE (BinaryNode)
* left: cond
* right: body
* PNK_DOWHILE (BinaryNode)
* left: body
* right: cond
* PNK_FOR (ForNode)
* left: one of
* * PNK_FORIN: for (x in y) ...
* * PNK_FOROF: for (x of x) ...
* * PNK_FORHEAD: for (;;) ...
* right: body
* PNK_COMPREHENSIONFOR (ForNode)
* left: either PNK_FORIN or PNK_FOROF
* right: body
* PNK_FORIN (TernaryNode)
* kid1: declaration or expression to left of 'in'
* kid2: null
@ -307,7 +316,9 @@ IsTypeofKind(ParseNodeKind kind)
* kid3: catch block statements
* PNK_BREAK name pn_atom: label or null
* PNK_CONTINUE name pn_atom: label or null
* PNK_WITH binary pn_left: head expr; pn_right: body;
* PNK_WITH (BinaryNode)
* left: head expr
* right: body
* PNK_VAR, PNK_LET, PNK_CONST (ListNode)
* head: list of N Name or Assign nodes
* each name node has either
@ -319,9 +330,9 @@ IsTypeofKind(ParseNodeKind kind)
* pn_atom: variable name
* pn_lexdef: def node
* each assignment node has
* pn_left: Name with pn_used true and
* left: Name with pn_used true and
* pn_lexdef (NOT pn_expr) set
* pn_right: initializer
* right: initializer
* count: N > 0
* PNK_RETURN unary pn_kid: return expr or null
* PNK_SEMI unary pn_kid: expr or null statement
@ -329,18 +340,28 @@ IsTypeofKind(ParseNodeKind kind)
* in original source, not introduced via
* constant folding or other tree rewriting
* PNK_LABEL name pn_atom: label, pn_expr: labeled statement
* PNK_IMPORT binary pn_left: PNK_IMPORT_SPEC_LIST import specifiers
* pn_right: PNK_STRING module specifier
* PNK_IMPORT (BinaryNode)
* left: PNK_IMPORT_SPEC_LIST import specifiers
* right: PNK_STRING module specifier
* PNK_IMPORT_SPEC_LIST (ListNode)
* head: list of N ImportSpec nodes
* count: N >= 0 (N = 0 for `import {} from ...`)
* PNK_IMPORT_SPEC (BinaryNode)
* left: import name
* right: local binding name
* PNK_EXPORT unary pn_kid: declaration expression
* PNK_EXPORT_FROM binary pn_left: PNK_EXPORT_SPEC_LIST export specifiers
* pn_right: PNK_STRING module specifier
* PNK_EXPORT_FROM (BinaryNode)
* left: PNK_EXPORT_SPEC_LIST export specifiers
* right: PNK_STRING module specifier
* PNK_EXPORT_SPEC_LIST (ListNode)
* head: list of N ExportSpec nodes
* count: N >= 0 (N = 0 for `export {}`)
* PNK_EXPORT_DEFAULT unary pn_kid: export default declaration or expression
* PNK_EXPORT (BinaryNode)
* left: local binding name
* right: export name
* PNK_EXPORT_DEFAULT (BinaryNode)
* left: export default declaration or expression
* right: PNK_NAME node for assignment
*
* <Expressions>
* All left-associated binary trees of the same type are optimized into lists
@ -348,19 +369,15 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_COMMA (ListNode)
* head: list of N comma-separated exprs
* count: N >= 2
* PNK_ASSIGN binary pn_left: lvalue, pn_right: rvalue
* PNK_ADDASSIGN, binary pn_left: lvalue, pn_right: rvalue
* PNK_SUBASSIGN, pn_op: JSOP_ADD for +=, etc.
* PNK_BITORASSIGN,
* PNK_BITXORASSIGN,
* PNK_BITANDASSIGN,
* PNK_LSHASSIGN,
* PNK_RSHASSIGN,
* PNK_URSHASSIGN,
* PNK_MULASSIGN,
* PNK_DIVASSIGN,
* PNK_MODASSIGN,
* PNK_POWASSIGN
* PNK_ASSIGN (BinaryNode)
* left: target of assignment
* right: value to assign
* PNK_ADDASSIGN, PNK_SUBASSIGN, PNK_BITORASSIGN, PNK_BITXORASSIGN,
* PNK_BITANDASSIGN, PNK_LSHASSIGN, PNK_RSHASSIGN, PNK_URSHASSIGN,
* PNK_MULASSIGN, PNK_DIVASSIGN, PNK_MODASSIGN, PNK_POWASSIGN (AssignmentNode)
* left: target of assignment
* right: value to assign
* pn_op: JSOP_ADD for +=, etc
* PNK_CONDITIONAL (ConditionalExpression)
* (cond ? thenExpr : elseExpr)
* kid1: cond
@ -392,8 +409,9 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_POSTINCREMENT,
* PNK_PREDECREMENT,
* PNK_POSTDECREMENT
* PNK_NEW binary pn_left: ctor expression on the left of the (
* pn_right: Arguments
* PNK_NEW (BinaryNode)
* left: ctor expression on the left of the '('
* right: Arguments
* PNK_DELETENAME unary pn_kid: PNK_NAME expr
* PNK_DELETEPROP unary pn_kid: PNK_DOT expr
* PNK_DELETEELEM unary pn_kid: PNK_ELEM expr
@ -415,26 +433,16 @@ IsTypeofKind(ParseNodeKind kind)
* contains are nullish. An optional chain can also
* contain nodes such as PNK_DOT, PNK_ELEM, PNK_NAME,
* PNK_CALL, etc. These are evaluated normally.
* PNK_OPTDOT binary pn_left: MEMBER expr to left of .
* short circuits back to PNK_OPTCHAIN if nullish.
* pn_right: PropertyName to right of .
* PNK_OPTELEM binary pn_left: MEMBER expr to left of [
* short circuits back to PNK_OPTCHAIN if nullish.
* pn_right: expr between [ and ]
* PNK_OPTCALL list pn_head: list of call, arg1, arg2, ... argN
* pn_count: 1 + N (where N is number of args)
* call is a MEMBER expr naming a callable object,
* short circuits back to PNK_OPTCHAIN if nullish.
* PNK_PROPERTYNAME pn_atom: property being accessed
* name
* PNK_DOT binary pn_left: MEMBER expr to left of .
* pn_right: PropertyName to right of .
* PNK_ELEM binary pn_left: MEMBER expr to left of [
* pn_right: expr between [ and ]
* PNK_CALL binary pn_left: callee expression on the left of the (
* pn_right: Arguments
* PNK_ARGUMENTS list pn_head: list of arg1, arg2, ... argN
* pn_count: N (where N is number of args)
* PNK_PROPERTYNAME name pn_atom: property being accessed
* PNK_DOT, PNK_OPTDOT (PropertyAccess) short circuits back to PNK_OPTCHAIN if nullish.
* left: MEMBER expr to left of '.'
* right: PropertyName to right of '.'
* PNK_ELEM, PNK_OPTELEM (PropertyByValue) short circuits back to PNK_OPTCHAIN if nullish.
* left: MEMBER expr to left of '['
* right: expr between '[' and ']'
* PNK_CALL, PNK_OPTCALL (BinaryNode) short circuits back to PNK_OPTCHAIN if nullish.
* left: callee expression on the left of the '('
* right: Arguments
* PNK_GENEXP binary Exactly like PNK_CALL, used for the implicit call
* in the desugaring of a generator-expression.
* PNK_ARGUMENTS (ListNode)
@ -452,11 +460,13 @@ IsTypeofKind(ParseNodeKind kind)
* * Shorthand
* * Spread
* count: N >= 0
* PNK_COLON binary key-value pair in object initializer or
* destructuring lhs
* pn_left: property id, pn_right: value
* PNK_SHORTHAND binary Same fields as PNK_COLON. This is used for object
* literal properties using shorthand ({x}).
* PNK_COLON (BinaryNode)
* key-value pair in object initializer or destructuring lhs
* left: property id
* right: value
* PNK_SHORTHAND (BinaryNode)
* Same fields as Colon. This is used for object literal properties using
* shorthand ({x}).
* PNK_COMPUTED_NAME unary ES6 ComputedPropertyName.
* pn_kid: the AssignmentExpression inside the square brackets
* PNK_NAME, name pn_atom: name, string, or object atom
@ -470,8 +480,10 @@ IsTypeofKind(ParseNodeKind kind)
* no ${}-delimited expression, it's parsed as a single TemplateString
* PNK_TEMPLATE_STRING pn_atom: template string atom
nullary pn_op: JSOP_NOP
* PNK_TAGGED_TEMPLATE pn_left: tag expression
* binary pn_right: Arguments, with the first being the call site object, then arg1, arg2, ... argN
* PNK_TAGGED_TEMPLATE (BinaryNode)
* left: tag expression
* right: Arguments, with the first being the call site object, then
* arg1, arg2, ... argN
* PNK_CALLSITEOBJ (CallSiteNode)
* head: an Array of raw TemplateString, then corresponding cooked
* TemplateString nodes
@ -488,16 +500,18 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_THIS, unary pn_kid: '.this' Name if function `this`, else nullptr
* PNK_SUPERBASE unary pn_kid: '.this' Name
*
* PNK_SUPERCALL binary pn_left: SuperBase pn_right: Arguments
*
* PNK_SETTHIS binary pn_left: '.this' Name, pn_right: SuperCall
*
* PNK_SUPERCALL (BinaryNode)
* left: SuperBase
* right: Arguments
* PNK_SETTHIS (BinaryNode)
* left: '.this' Name
* right: SuperCall
* PNK_LEXICALSCOPE scope pn_u.scope.bindings: scope bindings
* pn_u.scope.body: scope body
* PNK_GENERATOR nullary
* PNK_INITIALYIELD unary pn_kid: generator object
* PNK_YIELD, unary pn_kid: expr or null
* PNK_YIELD_STAR,
* PNK_YIELD_STAR
* PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally
@ -519,6 +533,16 @@ enum ParseNodeArity
};
#define FOR_EACH_PARSENODE_SUBCLASS(macro) \
macro(BinaryNode, BinaryNodeType, asBinary) \
macro(AssignmentNode, AssignmentNodeType, asAssignment) \
macro(CaseClause, CaseClauseType, asCaseClause) \
macro(ClassMethod, ClassMethodType, asClassMethod) \
macro(ClassNames, ClassNamesType, asClassNames) \
macro(ForNode, ForNodeType, asFor) \
macro(PropertyAccess, PropertyAccessType, asPropertyAccess) \
macro(PropertyByValue, PropertyByValueType, asPropertyByValue) \
macro(SwitchStatement, SwitchStatementType, asSwitchStatement) \
\
macro(ListNode, ListNodeType, asList) \
macro(CallSiteNode, CallSiteNodeType, asCallSite) \
\
@ -529,7 +553,6 @@ enum ParseNodeArity
class LoopControlStatement;
class BreakStatement;
class ContinueStatement;
class PropertyAccess;
#define DECLARE_CLASS(typeName, longTypeName, asMethodName) \
class typeName;
@ -594,11 +617,6 @@ class ParseNode
bool isArity(ParseNodeArity a) const { return getArity() == a; }
void setArity(ParseNodeArity a) { pn_arity = a; }
bool isAssignment() const {
ParseNodeKind kind = getKind();
return PNK_ASSIGNMENT_START <= kind && kind <= PNK_ASSIGNMENT_LAST;
}
bool isBinaryOperation() const {
ParseNodeKind kind = getKind();
return PNK_BINOP_FIRST <= kind && kind <= PNK_BINOP_LAST;
@ -636,6 +654,12 @@ class ParseNode
ParseNode* kid3; /* else-part, default case, etc. */
} ternary;
struct { /* two kids if binary */
private:
friend class BinaryNode;
friend class ForNode;
friend class ClassMethod;
friend class PropertyAccessBase;
friend class SwitchStatement;
ParseNode* left;
ParseNode* right;
union {
@ -675,10 +699,6 @@ class ParseNode
#define pn_objbox pn_u.name.objbox
#define pn_funbox pn_u.name.funbox
#define pn_body pn_u.name.expr
#define pn_left pn_u.binary.left
#define pn_right pn_u.binary.right
#define pn_pval pn_u.binary.pval
#define pn_iflags pn_u.binary.iflags
#define pn_kid pn_u.unary.kid
#define pn_prologue pn_u.unary.prologue
#define pn_atom pn_u.name.atom
@ -857,25 +877,97 @@ struct UnaryNode : public ParseNode
#endif
};
struct BinaryNode : public ParseNode
class BinaryNode : public ParseNode
{
public:
BinaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, ParseNode* left, ParseNode* right)
: ParseNode(kind, op, PN_BINARY, pos)
{
pn_left = left;
pn_right = right;
pn_u.binary.left = left;
pn_u.binary.right = right;
}
BinaryNode(ParseNodeKind kind, JSOp op, ParseNode* left, ParseNode* right)
: ParseNode(kind, op, PN_BINARY, TokenPos::box(left->pn_pos, right->pn_pos))
{
pn_left = left;
pn_right = right;
pn_u.binary.left = left;
pn_u.binary.right = right;
}
static bool test(const ParseNode& node) {
return node.isArity(PN_BINARY);
}
#ifdef DEBUG
void dump(int indent);
#endif
ParseNode* left() const {
return pn_u.binary.left;
}
ParseNode* right() const {
return pn_u.binary.right;
}
// Methods used by FoldConstants.cpp.
// caller are responsible for keeping the list consistent.
ParseNode** unsafeLeftReference() {
return &pn_u.binary.left;
}
ParseNode** unsafeRightReference() {
return &pn_u.binary.right;
}
};
class AssignmentNode : public BinaryNode
{
public:
AssignmentNode(ParseNodeKind kind, JSOp op, ParseNode* left, ParseNode* right)
: BinaryNode(kind, op, TokenPos(left->pn_pos.begin, right->pn_pos.end), left, right)
{}
static bool test(const ParseNode& node) {
ParseNodeKind kind = node.getKind();
bool match = PNK_ASSIGNMENT_START <= kind &&
kind <= PNK_ASSIGNMENT_LAST;
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
};
class ForNode : public BinaryNode
{
public:
ForNode(const TokenPos& pos, ParseNode* forHead, ParseNode* body, unsigned iflags)
: BinaryNode(PNK_FOR,
forHead->isKind(PNK_FORIN) ? JSOP_ITER : JSOP_NOP,
pos, forHead, body)
{
MOZ_ASSERT(forHead->isKind(PNK_FORIN) ||
forHead->isKind(PNK_FOROF) ||
forHead->isKind(PNK_FORHEAD));
pn_u.binary.iflags = iflags;
}
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_FOR) || node.isKind(PNK_COMPREHENSIONFOR);
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
TernaryNode* head() const {
return &left()->as<TernaryNode>();
}
ParseNode* body() const {
return right();
}
unsigned iflags() const {
return pn_u.binary.iflags;
}
};
class TernaryNode : public ParseNode
@ -1353,13 +1445,21 @@ class CaseClause : public BinaryNode
CaseClause(ParseNode* expr, ParseNode* stmts, uint32_t begin)
: BinaryNode(PNK_CASE, JSOP_NOP, TokenPos(begin, stmts->pn_pos.end), expr, stmts) {}
ParseNode* caseExpression() const { return pn_left; }
bool isDefault() const { return !caseExpression(); }
ListNode* statementList() const { return &pn_right->as<ListNode>(); }
ParseNode* caseExpression() const {
return left();
}
bool isDefault() const {
return !caseExpression();
}
ListNode* statementList() const {
return &right()->as<ListNode>();
}
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_CASE);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
return match;
}
@ -1515,7 +1615,7 @@ class PropertyAccessBase : public BinaryNode
public:
/*
* PropertyAccess nodes can have any expression/'super' as left-hand
* side, but the name must be a ParseNodeKind::PropertyName node.
* side, but the name must be a PNK_PROPERTYNAME node.
*/
PropertyAccessBase(ParseNodeKind kind, ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end)
: BinaryNode(kind, JSOP_NOP, TokenPos(begin, end), lhs, name)
@ -1527,21 +1627,37 @@ class PropertyAccessBase : public BinaryNode
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_DOT) ||
node.isKind(PNK_OPTDOT);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.pn_right->isKind(PNK_PROPERTYNAME));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
MOZ_ASSERT_IF(match, node.as<BinaryNode>().right()->isKind(PNK_PROPERTYNAME));
return match;
}
ParseNode& expression() const {
return *pn_u.binary.left;
return *left();
}
ParseNode& key() const {
return *right();
}
// Method used by BytecodeEmitter::emitPropLHS for optimization.
// Those methods allow expression to temporarily be nullptr for
// optimization purpose.
ParseNode* maybeExpression() const {
return left();
}
void setExpression(ParseNode* pn) {
pn_u.binary.left = pn;
}
PropertyName& name() const {
return *pn_u.binary.right->pn_atom->asPropertyName();
return *right()->pn_atom->asPropertyName();
}
JSAtom* nameAtom() const {
return pn_u.binary.right->pn_atom;
bool isSuper() const {
// PNK_SUPERBASE cannot result from any expression syntax.
return expression().isKind(PNK_SUPERBASE);
}
};
@ -1557,15 +1673,10 @@ class PropertyAccess : public PropertyAccessBase
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_DOT);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.pn_right->isKind(PNK_PROPERTYNAME));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
MOZ_ASSERT_IF(match, node.as<BinaryNode>().right()->isKind(PNK_PROPERTYNAME));
return match;
}
bool isSuper() const {
// PNK_SUPERBASE cannot result from any expression syntax.
return expression().isKind(PNK_SUPERBASE);
}
};
class OptionalPropertyAccess : public PropertyAccessBase
@ -1580,35 +1691,36 @@ class OptionalPropertyAccess : public PropertyAccessBase
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_OPTDOT);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.pn_right->isKind(PNK_PROPERTYNAME));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
MOZ_ASSERT_IF(match, node.as<BinaryNode>().right()->isKind(PNK_PROPERTYNAME));
return match;
}
};
class PropertyByValueBase : public ParseNode
class PropertyByValueBase : public BinaryNode
{
public:
PropertyByValueBase(ParseNodeKind kind, ParseNode* lhs, ParseNode* propExpr,
uint32_t begin, uint32_t end)
: ParseNode(kind, JSOP_NOP, PN_BINARY, TokenPos(begin, end))
{
pn_u.binary.left = lhs;
pn_u.binary.right = propExpr;
}
: BinaryNode(kind, JSOP_NOP, TokenPos(begin, end), lhs, propExpr)
{}
ParseNode& expression() const {
return *pn_u.binary.left;
return *left();
}
ParseNode& key() const {
return *pn_u.binary.right;
return *right();
}
bool isSuper() const {
return left()->isKind(PNK_SUPERBASE);
}
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_ELEM) ||
node.isKind(PNK_OPTELEM);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
};
@ -1624,10 +1736,6 @@ class PropertyByValue : public PropertyByValueBase {
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
return match;
}
bool isSuper() const {
return pn_left->isKind(PNK_SUPERBASE);
}
};
class OptionalPropertyByValue : public PropertyByValueBase {
@ -1667,7 +1775,9 @@ class CallSiteNode : public ListNode
}
};
struct ClassMethod : public BinaryNode {
class ClassMethod : public BinaryNode
{
public:
/*
* Method definitions often keep a name and function body that overlap,
* so explicitly define the beginning and end here.
@ -1680,22 +1790,24 @@ struct ClassMethod : public BinaryNode {
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_CLASSMETHOD);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
ParseNode& name() const {
return *pn_u.binary.left;
return *left();
}
ParseNode& method() const {
return *pn_u.binary.right;
return *right();
}
bool isStatic() const {
return pn_u.binary.isStatic;
}
};
struct SwitchStatement : public BinaryNode {
class SwitchStatement : public BinaryNode
{
public:
SwitchStatement(uint32_t begin, ParseNode* discriminant, ParseNode* lexicalForCaseList,
bool hasDefault)
: BinaryNode(PNK_SWITCH, JSOP_NOP,
@ -1722,22 +1834,24 @@ struct SwitchStatement : public BinaryNode {
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_SWITCH);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
ParseNode& discriminant() const {
return *pn_u.binary.left;
return *left();
}
ParseNode& lexicalForCaseList() const {
return *pn_u.binary.right;
ParseNode& lexicalForCaseList() const {;
return *right();
}
bool hasDefault() const {
return pn_u.binary.hasDefault;
}
};
struct ClassNames : public BinaryNode {
class ClassNames : public BinaryNode
{
public:
ClassNames(ParseNode* outerBinding, ParseNode* innerBinding, const TokenPos& pos)
: BinaryNode(PNK_CLASSNAMES, JSOP_NOP, pos, outerBinding, innerBinding)
{
@ -1748,7 +1862,7 @@ struct ClassNames : public BinaryNode {
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_CLASSNAMES);
MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
MOZ_ASSERT_IF(match, node.is<BinaryNode>());
return match;
}
@ -1761,10 +1875,10 @@ struct ClassNames : public BinaryNode {
* the outer binding has been overwritten.
*/
ParseNode* outerBinding() const {
return pn_u.binary.left;
return left();
}
ParseNode* innerBinding() const {
return pn_u.binary.right;
return right();
}
};

View file

@ -4307,7 +4307,7 @@ Parser<ParseHandler>::PossibleError::transferErrorsTo(PossibleError* other)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::bindingInitializer(Node lhs, DeclarationKind kind,
YieldHandling yieldHandling)
{
@ -4322,12 +4322,17 @@ Parser<ParseHandler>::bindingInitializer(Node lhs, DeclarationKind kind,
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
Node assign = handler.newAssignment(PNK_ASSIGN, lhs, rhs, JSOP_NOP);
BinaryNodeType assign = handler.newAssignment(PNK_ASSIGN, lhs, rhs, JSOP_NOP);
if (!assign)
return null();
if (foldConstants && !FoldConstants(context, &assign, this))
return null();
if (foldConstants) {
Node node = assign;
if (!FoldConstants(context, &node, this)) {
return null();
}
assign = handler.asBinary(node);
}
return assign;
}
@ -4454,7 +4459,7 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y
tokenStream.consumeKnownToken(TOK_ASSIGN);
Node bindingExpr = bindingInitializer(binding, kind, yieldHandling);
BinaryNodeType bindingExpr = bindingInitializer(binding, kind, yieldHandling);
if (!bindingExpr)
return null();
@ -5030,7 +5035,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
if (!importNameNode)
return false;
Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importNameNode, bindingName);
BinaryNodeType importSpec = handler.newBinary(PNK_IMPORT_SPEC, importNameNode, bindingName);
if (!importSpec)
return false;
@ -5076,7 +5081,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
// environment.
pc->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingNameNode);
BinaryNodeType importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingNameNode);
if (!importSpec)
return false;
@ -5087,7 +5092,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
}
template<>
ParseNode*
BinaryNode*
Parser<FullParseHandler>::importDeclaration()
{
MOZ_ASSERT(tokenStream.currentToken().type == TOK_IMPORT);
@ -5134,7 +5139,7 @@ Parser<FullParseHandler>::importDeclaration()
if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos()))
return null();
Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
BinaryNodeType importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
if (!importSpec)
return null();
@ -5173,7 +5178,7 @@ Parser<FullParseHandler>::importDeclaration()
if (!matchOrInsertSemicolonAfterNonExpression())
return null();
ParseNode* node =
BinaryNode* node =
handler.newImportDeclaration(importSpecSet, moduleSpec, TokenPos(begin, pos().end));
if (!node || !pc->sc()->asModuleContext()->builder.processImport(node))
return null();
@ -5182,7 +5187,7 @@ Parser<FullParseHandler>::importDeclaration()
}
template<>
SyntaxParseHandler::Node
SyntaxParseHandler::BinaryNodeType
Parser<SyntaxParseHandler>::importDeclaration()
{
JS_ALWAYS_FALSE(abortIfSyntaxParser());
@ -5226,7 +5231,7 @@ Parser<FullParseHandler>::checkExportedNamesForArrayBinding(ListNode* array)
if (node->isKind(PNK_SPREAD))
binding = node->pn_kid;
else if (node->isKind(PNK_ASSIGN))
binding = node->pn_left;
binding = node->as<AssignmentNode>().left();
else
binding = node;
@ -5264,10 +5269,10 @@ Parser<FullParseHandler>::checkExportedNamesForObjectBinding(ListNode* obj)
if (node->isKind(PNK_MUTATEPROTO))
target = node->pn_kid;
else
target = node->pn_right;
target = node->as<BinaryNode>().right();
if (target->isKind(PNK_ASSIGN))
target = target->pn_left;
target = target->as<AssignmentNode>().left();
}
if (!checkExportedNamesForDeclaration(target))
@ -5318,7 +5323,7 @@ Parser<FullParseHandler>::checkExportedNamesForDeclarationList(ListNode* node)
{
for (ParseNode* binding : node->contents()) {
if (binding->isKind(PNK_ASSIGN))
binding = binding->pn_left;
binding = binding->as<AssignmentNode>().left();
else
MOZ_ASSERT(binding->isKind(PNK_NAME));
@ -5400,21 +5405,21 @@ Parser<SyntaxParseHandler>::processExport(Node node)
template<>
bool
Parser<FullParseHandler>::processExportFrom(ParseNode* node)
Parser<FullParseHandler>::processExportFrom(BinaryNodeType node)
{
return pc->sc()->asModuleContext()->builder.processExportFrom(node);
}
template<>
bool
Parser<SyntaxParseHandler>::processExportFrom(Node node)
Parser<SyntaxParseHandler>::processExportFrom(BinaryNodeType node)
{
MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
return false;
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportFrom(uint32_t begin, Node specList)
{
if (!abortIfSyntaxParser())
@ -5434,7 +5439,7 @@ Parser<ParseHandler>::exportFrom(uint32_t begin, Node specList)
if (!matchOrInsertSemicolonAfterNonExpression())
return null();
Node node = handler.newExportFromDeclaration(begin, specList, moduleSpec);
BinaryNodeType node = handler.newExportFromDeclaration(begin, specList, moduleSpec);
if (!node)
return null();
@ -5445,7 +5450,7 @@ Parser<ParseHandler>::exportFrom(uint32_t begin, Node specList)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportBatch(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5476,7 +5481,7 @@ Parser<FullParseHandler>::checkLocalExportNames(ListNode* node)
{
// ES 2017 draft 15.2.3.1.
for (ParseNode* next : node->contents()) {
ParseNode* name = next->pn_left;
ParseNode* name = next->as<BinaryNode>().left();
MOZ_ASSERT(name->isKind(PNK_NAME));
RootedPropertyName ident(context, name->pn_atom->asPropertyName());
@ -5540,7 +5545,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
if (!checkExportedNameForClause(exportName))
return null();
Node exportSpec = handler.newBinary(PNK_EXPORT_SPEC, bindingName, exportName);
BinaryNodeType exportSpec = handler.newBinary(PNK_EXPORT_SPEC, bindingName, exportName);
if (!exportSpec)
return null();
@ -5702,7 +5707,7 @@ Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind k
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportDefaultFunctionDeclaration(uint32_t begin,
FunctionAsyncKind asyncKind
/* = SyncFunction */)
@ -5716,7 +5721,7 @@ Parser<ParseHandler>::exportDefaultFunctionDeclaration(uint32_t begin,
if (!kid)
return null();
Node node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
BinaryNodeType node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
if (!node)
return null();
@ -5727,7 +5732,7 @@ Parser<ParseHandler>::exportDefaultFunctionDeclaration(uint32_t begin,
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportDefaultClassDeclaration(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5739,7 +5744,7 @@ Parser<ParseHandler>::exportDefaultClassDeclaration(uint32_t begin)
if (!kid)
return null();
Node node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
BinaryNodeType node = handler.newExportDefaultDeclaration(kid, null(), TokenPos(begin, pos().end));
if (!node)
return null();
@ -5750,7 +5755,7 @@ Parser<ParseHandler>::exportDefaultClassDeclaration(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportDefaultAssignExpr(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5769,7 +5774,7 @@ Parser<ParseHandler>::exportDefaultAssignExpr(uint32_t begin)
if (!matchOrInsertSemicolonAfterExpression())
return null();
Node node = handler.newExportDefaultDeclaration(kid, nameNode, TokenPos(begin, pos().end));
BinaryNodeType node = handler.newExportDefaultDeclaration(kid, nameNode, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5780,7 +5785,7 @@ Parser<ParseHandler>::exportDefaultAssignExpr(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::exportDefault(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -6027,7 +6032,7 @@ Parser<ParseHandler>::ifStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::doWhileStatement(YieldHandling yieldHandling)
{
uint32_t begin = pos().begin;
@ -6053,7 +6058,7 @@ Parser<ParseHandler>::doWhileStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::whileStatement(YieldHandling yieldHandling)
{
uint32_t begin = pos().begin;
@ -6414,7 +6419,7 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
if (!body)
return null();
Node forLoop = handler.newForStatement(begin, forHead, body, iflags);
BinaryNodeType forLoop = handler.newForStatement(begin, forHead, body, iflags);
if (!forLoop)
return null();
@ -6425,7 +6430,7 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::SwitchStatementType
Parser<ParseHandler>::switchStatement(YieldHandling yieldHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_SWITCH));
@ -6516,10 +6521,10 @@ Parser<ParseHandler>::switchStatement(YieldHandling yieldHandling)
handler.addStatementToList(body, stmt);
}
Node casepn = handler.newCaseOrDefault(caseBegin, caseExpr, body);
if (!casepn)
CaseClauseType caseClause = handler.newCaseOrDefault(caseBegin, caseExpr, body);
if (!caseClause)
return null();
handler.addCaseStatementToList(caseList, casepn);
handler.addCaseStatementToList(caseList, caseClause);
}
Node lexicalForCaseList = finishLexicalScope(scope, caseList);
@ -6818,7 +6823,7 @@ Parser<ParseHandler>::yieldExpression(InHandling inHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::BinaryNodeType
Parser<ParseHandler>::withStatement(YieldHandling yieldHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_WITH));
@ -9181,8 +9186,8 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
if (tt == TOK_NEW) {
uint32_t newBegin = pos().begin;
// Make sure this wasn't a |new.target| in disguise.
Node newTarget;
if (!tryNewTarget(newTarget))
BinaryNodeType newTarget;
if (!tryNewTarget(&newTarget))
return null();
if (newTarget) {
lhs = newTarget;
@ -10246,7 +10251,7 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
handler.checkAndSetIsDirectRHSAnonFunction(rhs);
Node propExpr = handler.newAssignment(PNK_ASSIGN, lhs, rhs, JSOP_NOP);
BinaryNodeType propExpr = handler.newAssignment(PNK_ASSIGN, lhs, rhs, JSOP_NOP);
if (!propExpr)
return null();
@ -10362,11 +10367,11 @@ Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType prop
template <typename ParseHandler>
bool
Parser<ParseHandler>::tryNewTarget(Node &newTarget)
Parser<ParseHandler>::tryNewTarget(BinaryNodeType* newTarget)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_NEW));
newTarget = null();
*newTarget = null();
Node newHolder = handler.newPosHolder(pos());
if (!newHolder)
@ -10400,8 +10405,8 @@ Parser<ParseHandler>::tryNewTarget(Node &newTarget)
if (!targetHolder)
return false;
newTarget = handler.newNewTarget(newHolder, targetHolder);
return !!newTarget;
*newTarget = handler.newNewTarget(newHolder, targetHolder);
return !!*newTarget;
}
template <typename ParseHandler>

View file

@ -1198,8 +1198,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
Node blockStatement(YieldHandling yieldHandling,
unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
Node doWhileStatement(YieldHandling yieldHandling);
Node whileStatement(YieldHandling yieldHandling);
BinaryNodeType doWhileStatement(YieldHandling yieldHandling);
BinaryNodeType whileStatement(YieldHandling yieldHandling);
Node forStatement(YieldHandling yieldHandling);
bool forHeadStart(YieldHandling yieldHandling,
@ -1210,11 +1210,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
Node* forInOrOfExpression);
Node expressionAfterForInOrOf(ParseNodeKind forHeadKind, YieldHandling yieldHandling);
Node switchStatement(YieldHandling yieldHandling);
SwitchStatementType switchStatement(YieldHandling yieldHandling);
Node continueStatement(YieldHandling yieldHandling);
Node breakStatement(YieldHandling yieldHandling);
Node returnStatement(YieldHandling yieldHandling);
Node withStatement(YieldHandling yieldHandling);
BinaryNodeType withStatement(YieldHandling yieldHandling);
Node throwStatement(YieldHandling yieldHandling);
TernaryNodeType tryStatement(YieldHandling yieldHandling);
Node catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
@ -1235,24 +1235,24 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
ListNodeType lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
Node importDeclaration();
inline BinaryNodeType importDeclaration();
bool processExport(Node node);
bool processExportFrom(Node node);
bool processExportFrom(BinaryNodeType node);
Node exportFrom(uint32_t begin, Node specList);
Node exportBatch(uint32_t begin);
BinaryNodeType exportFrom(uint32_t begin, Node specList);
BinaryNodeType exportBatch(uint32_t begin);
bool checkLocalExportNames(ListNodeType node);
Node exportClause(uint32_t begin);
Node exportFunctionDeclaration(uint32_t begin);
Node exportVariableStatement(uint32_t begin);
Node exportClassDeclaration(uint32_t begin);
Node exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
Node exportDefaultFunctionDeclaration(uint32_t begin,
FunctionAsyncKind asyncKind = SyncFunction);
Node exportDefaultClassDeclaration(uint32_t begin);
Node exportDefaultAssignExpr(uint32_t begin);
Node exportDefault(uint32_t begin);
BinaryNodeType exportDefaultFunctionDeclaration(uint32_t begin,
FunctionAsyncKind asyncKind = SyncFunction);
BinaryNodeType exportDefaultClassDeclaration(uint32_t begin);
BinaryNodeType exportDefaultAssignExpr(uint32_t begin);
BinaryNodeType exportDefault(uint32_t begin);
Node exportDeclaration();
Node expressionStatement(YieldHandling yieldHandling,
@ -1343,7 +1343,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr);
bool tryNewTarget(Node& newTarget);
bool tryNewTarget(BinaryNodeType* newTarget);
bool checkAndMarkSuperScope();
Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
@ -1526,7 +1526,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
ListNodeType objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
Node bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
TokenKind tt);

View file

@ -304,19 +304,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE bool addSpreadElement(ListNodeType literal, uint32_t begin, Node inner) { return true; }
void addArrayElement(ListNodeType literal, Node element) { }
Node newCall(Node callee, Node args) { return NodeFunctionCall; }
Node newOptionalCall(Node callee, Node args) { return NodeOptionalFunctionCall; }
BinaryNodeType newCall(Node callee, Node args) { return NodeFunctionCall; }
BinaryNodeType newOptionalCall(Node callee, Node args) { return NodeOptionalFunctionCall; }
ListNodeType newArguments(const TokenPos& pos) { return NodeGeneric; }
Node newSuperCall(Node callee, Node args) { return NodeGeneric; }
Node newTaggedTemplate(Node callee, Node args) { return NodeGeneric; }
BinaryNodeType newSuperCall(Node callee, Node args) { return NodeGeneric; }
BinaryNodeType newTaggedTemplate(Node callee, Node args) { return NodeGeneric; }
Node newGenExp(Node callee, Node args) { return NodeGeneric; }
ListNodeType newObjectLiteral(uint32_t begin) { return NodeUnparenthesizedObject; }
ListNodeType newClassMethodList(uint32_t begin) { return NodeGeneric; }
Node newClassNames(Node outer, Node inner, const TokenPos& pos) { return NodeGeneric; }
ClassNamesType newClassNames(Node outer, Node inner, const TokenPos& pos) { return NodeGeneric; }
ClassNodeType newClass(Node name, Node heritage, Node methodBlock, const TokenPos& pos) { return NodeGeneric; }
Node newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; }
BinaryNodeType newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; }
Node newPosHolder(const TokenPos& pos) { return NodeGeneric; }
Node newSuperBase(Node thisName, const TokenPos& pos) { return NodeSuperBase; }
@ -335,21 +335,21 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
ListNodeType newStatementList(const TokenPos& pos) { return NodeGeneric; }
void addStatementToList(ListNodeType list, Node stmt) {}
void addCaseStatementToList(ListNodeType list, Node caseClause) {}
void addCaseStatementToList(ListNodeType list, CaseClauseType caseClause) {}
MOZ_MUST_USE bool prependInitialYield(ListNodeType stmtList, Node genName) { return true; }
Node newEmptyStatement(const TokenPos& pos) { return NodeEmptyStatement; }
Node newExportDeclaration(Node kid, const TokenPos& pos) {
return NodeGeneric;
}
Node newExportFromDeclaration(uint32_t begin, Node exportSpecSet, Node moduleSpec) {
BinaryNodeType newExportFromDeclaration(uint32_t begin, Node exportSpecSet, Node moduleSpec) {
return NodeGeneric;
}
Node newExportDefaultDeclaration(Node kid, Node maybeBinding, const TokenPos& pos) {
BinaryNodeType newExportDefaultDeclaration(Node kid, Node maybeBinding, const TokenPos& pos) {
return NodeGeneric;
}
Node newSetThis(Node thisName, Node value) { return value; }
BinaryNodeType newSetThis(Node thisName, Node value) { return value; }
Node newExprStatement(Node expr, uint32_t end) {
return expr == NodeUnparenthesizedString ? NodeStringExprStatement : NodeGeneric;
@ -358,17 +358,17 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
TernaryNodeType newIfStatement(uint32_t begin, Node cond, Node thenBranch, Node elseBranch) {
return NodeGeneric;
}
Node newDoWhileStatement(Node body, Node cond, const TokenPos& pos) { return NodeGeneric; }
Node newWhileStatement(uint32_t begin, Node cond, Node body) { return NodeGeneric; }
Node newSwitchStatement(uint32_t begin, Node discriminant, Node lexicalForCaseList, bool hasDefault)
BinaryNodeType newDoWhileStatement(Node body, Node cond, const TokenPos& pos) { return NodeGeneric; }
BinaryNodeType newWhileStatement(uint32_t begin, Node cond, Node body) { return NodeGeneric; }
SwitchStatementType newSwitchStatement(uint32_t begin, Node discriminant, Node lexicalForCaseList, bool hasDefault)
{
return NodeGeneric;
}
Node newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
Node newContinueStatement(PropertyName* label, const TokenPos& pos) { return NodeGeneric; }
Node newBreakStatement(PropertyName* label, const TokenPos& pos) { return NodeBreak; }
Node newReturnStatement(Node expr, const TokenPos& pos) { return NodeReturn; }
Node newWithStatement(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
Node newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) {
return NodeGeneric;
@ -385,7 +385,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeGeneric;
}
Node newPropertyAccess(Node expr, Node key) {
PropertyAccessType newPropertyAccess(Node expr, Node key) {
return NodeDottedProperty;
}
@ -393,7 +393,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeOptionalDottedProperty;
}
Node newPropertyByValue(Node pn, Node kid, uint32_t end) { return NodeElement; }
PropertyByValueType newPropertyByValue(Node lhs, Node index, uint32_t end) { return NodeElement; }
Node newOptionalPropertyByValue(Node pn, Node kid, uint32_t end) { return NodeOptionalElement; }
@ -414,7 +414,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
void setFunctionBox(Node pn, FunctionBox* funbox) {}
void addFunctionFormalParameter(Node pn, Node argpn) {}
Node newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags) {
ForNodeType newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags) {
return NodeGeneric;
}
@ -518,11 +518,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
}
Node newNewExpression(uint32_t begin, Node ctor, Node args) {
BinaryNodeType newNewExpression(uint32_t begin, Node ctor, Node args) {
return NodeGeneric;
}
Node newAssignment(ParseNodeKind kind, Node lhs, Node rhs, JSOp op) {
AssignmentNodeType newAssignment(ParseNodeKind kind, Node lhs, Node rhs, JSOp op) {
if (kind == PNK_ASSIGN)
return NodeUnparenthesizedAssignment;
return newBinary(kind, lhs, rhs, op);

View file

@ -408,15 +408,13 @@ UnaryKid(ParseNode* pn)
static inline ParseNode*
BinaryRight(ParseNode* pn)
{
MOZ_ASSERT(pn->isArity(PN_BINARY));
return pn->pn_right;
return pn->as<BinaryNode>().right();
}
static inline ParseNode*
BinaryLeft(ParseNode* pn)
{
MOZ_ASSERT(pn->isArity(PN_BINARY));
return pn->pn_left;
return pn->as<BinaryNode>().left();
}
static inline ParseNode*
@ -634,31 +632,25 @@ NumberNodeHasFrac(ParseNode* pn)
static ParseNode*
DotBase(ParseNode* pn)
{
MOZ_ASSERT(pn->isKind(PNK_DOT));
MOZ_ASSERT(pn->isArity(PN_BINARY));
return pn->pn_left;
return &pn->as<PropertyAccess>().expression();
}
static PropertyName*
DotMember(ParseNode* pn)
{
MOZ_ASSERT(pn->isKind(PNK_DOT));
MOZ_ASSERT(pn->isArity(PN_BINARY));
return pn->pn_right->pn_atom->asPropertyName();
return &pn->as<PropertyAccess>().name();
}
static ParseNode*
ElemBase(ParseNode* pn)
{
MOZ_ASSERT(pn->isKind(PNK_ELEM));
return BinaryLeft(pn);
return &pn->as<PropertyByValueBase>().expression();
}
static ParseNode*
ElemIndex(ParseNode* pn)
{
MOZ_ASSERT(pn->isKind(PNK_ELEM));
return BinaryRight(pn);
return &pn->as<PropertyByValueBase>().key();
}
static inline JSFunction*