mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Issue #2173 - Add accessors to BinaryNode and subclasses
Based-on: m-c 1479659/3
This commit is contained in:
parent
4726d96fd2
commit
662419c507
14 changed files with 1134 additions and 919 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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, ")");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue