mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
Issue #2173 - Add accessors to NameNode, CodeNode, RegExpLiteral, and add NumericLiteral
Based-on: m-c 1479659/{5,9,10}, m-c 1491147
This commit is contained in:
parent
68a407c935
commit
ba730c488f
16 changed files with 994 additions and 796 deletions
|
|
@ -1168,10 +1168,10 @@ ModuleBuilder::processImport(frontend::BinaryNode* importNode)
|
|||
ListNode* specList = &importNode->left()->as<ListNode>();
|
||||
MOZ_ASSERT(specList->isKind(PNK_IMPORT_SPEC_LIST));
|
||||
|
||||
ParseNode* moduleSpec = importNode->right();
|
||||
NameNode* moduleSpec = &importNode->right()->as<NameNode>();
|
||||
MOZ_ASSERT(moduleSpec->isKind(PNK_STRING));
|
||||
|
||||
RootedAtom module(cx_, moduleSpec->pn_atom);
|
||||
RootedAtom module(cx_, moduleSpec->atom());
|
||||
if (!maybeAppendRequestedModule(module))
|
||||
return false;
|
||||
|
||||
|
|
@ -1180,14 +1180,12 @@ ModuleBuilder::processImport(frontend::BinaryNode* importNode)
|
|||
for (ParseNode* item : specList->contents()) {
|
||||
BinaryNode* spec = &item->as<BinaryNode>();
|
||||
MOZ_ASSERT(spec->isKind(PNK_IMPORT_SPEC));
|
||||
|
||||
ParseNode* importNameNode = spec->left();
|
||||
MOZ_ASSERT(importNameNode->isArity(PN_NAME));
|
||||
ParseNode* localNameNode = spec->right();
|
||||
MOZ_ASSERT(localNameNode->isArity(PN_NAME));
|
||||
|
||||
RootedAtom importName(cx_, importNameNode->pn_atom);
|
||||
RootedAtom localName(cx_, localNameNode->pn_atom);
|
||||
NameNode* importNameNode = &spec->left()->as<NameNode>();
|
||||
NameNode* localNameNode = &spec->right()->as<NameNode>();
|
||||
|
||||
importName = importNameNode->atom();
|
||||
localName = localNameNode->atom();
|
||||
|
||||
if (!importedBoundNames_.append(localName))
|
||||
return false;
|
||||
|
|
@ -1232,10 +1230,10 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
|
|||
BinaryNode* spec = &item->as<BinaryNode>();
|
||||
MOZ_ASSERT(spec->isKind(PNK_EXPORT_SPEC));
|
||||
|
||||
ParseNode* localNameNode = spec->left();
|
||||
ParseNode* exportNameNode = spec->right();
|
||||
localName = localNameNode->pn_atom;
|
||||
exportName = exportNameNode->pn_atom;
|
||||
NameNode* localNameNode = &spec->left()->as<NameNode>();
|
||||
NameNode* exportNameNode = &spec->right()->as<NameNode>();
|
||||
localName = localNameNode->atom();
|
||||
exportName = exportNameNode->atom();
|
||||
if (!appendExportEntry(exportName, localName, spec))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1245,7 +1243,7 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
|
|||
case PNK_CLASS: {
|
||||
const ClassNode& cls = kid->as<ClassNode>();
|
||||
MOZ_ASSERT(cls.names());
|
||||
RootedAtom localName(cx_, cls.names()->innerBinding()->pn_atom);
|
||||
RootedAtom localName(cx_, cls.names()->innerBinding()->atom());
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
|
|
@ -1255,7 +1253,8 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
|
|||
case PNK_VAR:
|
||||
case PNK_CONST:
|
||||
case PNK_LET: {
|
||||
MOZ_ASSERT(kid->isArity(PN_LIST));
|
||||
RootedAtom localName(cx_);
|
||||
RootedAtom exportName(cx_);
|
||||
for (ParseNode* binding : kid->as<ListNode>().contents()) {
|
||||
if (binding->isKind(PNK_ASSIGN))
|
||||
binding = binding->as<AssignmentNode>().left();
|
||||
|
|
@ -1263,8 +1262,8 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
|
|||
MOZ_ASSERT(binding->isKind(PNK_NAME));
|
||||
|
||||
if (binding->isKind(PNK_NAME)) {
|
||||
RootedAtom localName(cx_, binding->pn_atom);
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
localName = binding->as<NameNode>().atom();
|
||||
exportName = isDefault ? cx_->names().default_ : localName.get();
|
||||
if (!appendExportEntry(exportName, localName))
|
||||
return false;
|
||||
} else if (binding->isKind(PNK_ARRAY)) {
|
||||
|
|
@ -1280,7 +1279,7 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
|
|||
}
|
||||
|
||||
case PNK_FUNCTION: {
|
||||
RootedFunction func(cx_, kid->pn_funbox->function());
|
||||
RootedFunction func(cx_, kid->as<CodeNode>().funbox()->function());
|
||||
MOZ_ASSERT(!func->isArrow());
|
||||
RootedAtom localName(cx_, func->explicitName());
|
||||
RootedAtom exportName(cx_, isDefault ? cx_->names().default_ : localName.get());
|
||||
|
|
@ -1301,7 +1300,7 @@ bool
|
|||
ModuleBuilder::processExportBinding(frontend::ParseNode* binding)
|
||||
{
|
||||
if (binding->isKind(PNK_NAME)) {
|
||||
RootedAtom name(cx_, binding->pn_atom);
|
||||
RootedAtom name(cx_, binding->as<NameNode>().atom());
|
||||
return appendExportEntry(name, name);
|
||||
}
|
||||
|
||||
|
|
@ -1372,10 +1371,10 @@ ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode)
|
|||
ListNode* specList = &exportNode->left()->as<ListNode>();
|
||||
MOZ_ASSERT(specList->isKind(PNK_EXPORT_SPEC_LIST));
|
||||
|
||||
ParseNode* moduleSpec = exportNode->right();
|
||||
NameNode* moduleSpec = &exportNode->right()->as<NameNode>();
|
||||
MOZ_ASSERT(moduleSpec->isKind(PNK_STRING));
|
||||
|
||||
RootedAtom module(cx_, moduleSpec->pn_atom);
|
||||
RootedAtom module(cx_, moduleSpec->atom());
|
||||
if (!maybeAppendRequestedModule(module))
|
||||
return false;
|
||||
|
||||
|
|
@ -1383,10 +1382,10 @@ ModuleBuilder::processExportFrom(frontend::BinaryNode* exportNode)
|
|||
RootedAtom exportName(cx_);
|
||||
for (ParseNode* spec : specList->contents()) {
|
||||
if (spec->isKind(PNK_EXPORT_SPEC)) {
|
||||
ParseNode* localNameNode = spec->as<BinaryNode>().left();
|
||||
ParseNode* exportNameNode = spec->as<BinaryNode>().right();
|
||||
bindingName = localNameNode->pn_atom;
|
||||
exportName = exportNameNode->pn_atom;
|
||||
NameNode* localNameNode = &spec->as<BinaryNode>().left()->as<NameNode>();
|
||||
NameNode* exportNameNode = &spec->as<BinaryNode>().right()->as<NameNode>();
|
||||
bindingName = localNameNode->atom();
|
||||
exportName = exportNameNode->atom();
|
||||
if (!appendExportFromEntry(exportName, module, bindingName, localNameNode))
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1838,7 +1838,7 @@ class ASTSerializer
|
|||
|
||||
bool expression(ParseNode* pn, MutableHandleValue dst);
|
||||
|
||||
bool propertyName(ParseNode* pn, MutableHandleValue dst);
|
||||
bool propertyName(ParseNode* key, MutableHandleValue dst);
|
||||
bool property(ParseNode* pn, MutableHandleValue dst);
|
||||
|
||||
bool classMethod(ClassMethod* classMethod, MutableHandleValue dst);
|
||||
|
|
@ -1852,7 +1852,7 @@ class ASTSerializer
|
|||
}
|
||||
|
||||
bool identifier(HandleAtom atom, TokenPos* pos, MutableHandleValue dst);
|
||||
bool identifier(ParseNode* pn, MutableHandleValue dst);
|
||||
bool identifier(NameNode* id, MutableHandleValue dst);
|
||||
bool literal(ParseNode* pn, MutableHandleValue dst);
|
||||
|
||||
bool optPattern(ParseNode* pn, MutableHandleValue dst) {
|
||||
|
|
@ -1867,7 +1867,7 @@ class ASTSerializer
|
|||
bool arrayPattern(ListNode* array, MutableHandleValue dst);
|
||||
bool objectPattern(ListNode* obj, MutableHandleValue dst);
|
||||
|
||||
bool function(ParseNode* pn, ASTType type, MutableHandleValue dst);
|
||||
bool function(CodeNode* funNode, ASTType type, MutableHandleValue dst);
|
||||
bool functionArgsAndBody(ParseNode* pn, NodeVector& args, NodeVector& defaults,
|
||||
bool isAsync, bool isExpression,
|
||||
MutableHandleValue body, MutableHandleValue rest);
|
||||
|
|
@ -2095,7 +2095,7 @@ ASTSerializer::declaration(ParseNode* pn, MutableHandleValue dst)
|
|||
|
||||
switch (pn->getKind()) {
|
||||
case PNK_FUNCTION:
|
||||
return function(pn, AST_FUNC_DECL, dst);
|
||||
return function(&pn->as<CodeNode>(), AST_FUNC_DECL, dst);
|
||||
|
||||
case PNK_VAR:
|
||||
return variableDeclaration(&pn->as<ListNode>(), false, dst);
|
||||
|
|
@ -2140,7 +2140,7 @@ ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst)
|
|||
|
||||
if (pn->isKind(PNK_NAME)) {
|
||||
patternNode = pn;
|
||||
initNode = pn->pn_expr;
|
||||
initNode = pn->as<NameNode>().initializer();
|
||||
MOZ_ASSERT_IF(initNode, pn->pn_pos.encloses(initNode->pn_pos));
|
||||
} else if (pn->isKind(PNK_ASSIGN)) {
|
||||
AssignmentNode* assignNode = &pn->as<AssignmentNode>();
|
||||
|
|
@ -2192,11 +2192,13 @@ bool
|
|||
ASTSerializer::importSpecifier(BinaryNode* importSpec, MutableHandleValue dst)
|
||||
{
|
||||
MOZ_ASSERT(importSpec->isKind(PNK_IMPORT_SPEC));
|
||||
NameNode* importNameNode = &importSpec->left()->as<NameNode>();
|
||||
NameNode* bindingNameNode = &importSpec->right()->as<NameNode>();
|
||||
|
||||
RootedValue importName(cx);
|
||||
RootedValue bindingName(cx);
|
||||
return identifier(importSpec->left(), &importName) &&
|
||||
identifier(importSpec->right(), &bindingName) &&
|
||||
return identifier(importNameNode, &importName) &&
|
||||
identifier(bindingNameNode, &bindingName) &&
|
||||
builder.importSpecifier(importName, bindingName, &importSpec->pn_pos, dst);
|
||||
}
|
||||
|
||||
|
|
@ -2237,7 +2239,7 @@ ASTSerializer::exportDeclaration(ParseNode* exportNode, MutableHandleValue dst)
|
|||
}
|
||||
|
||||
case PNK_FUNCTION:
|
||||
if (!function(kid, AST_FUNC_DECL, &decl))
|
||||
if (!function(&kid->as<CodeNode>(), AST_FUNC_DECL, &decl))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
|
@ -2277,11 +2279,13 @@ bool
|
|||
ASTSerializer::exportSpecifier(BinaryNode* exportSpec, MutableHandleValue dst)
|
||||
{
|
||||
MOZ_ASSERT(exportSpec->isKind(PNK_EXPORT_SPEC));
|
||||
NameNode* bindingNameNode = &exportSpec->left()->as<NameNode>();
|
||||
NameNode* exportNameNode = &exportSpec->right()->as<NameNode>();
|
||||
|
||||
RootedValue bindingName(cx);
|
||||
RootedValue exportName(cx);
|
||||
return identifier(exportSpec->left(), &bindingName) &&
|
||||
identifier(exportSpec->right(), &exportName) &&
|
||||
return identifier(bindingNameNode, &bindingName) &&
|
||||
identifier(exportNameNode, &exportName) &&
|
||||
builder.exportSpecifier(bindingName, exportName, &exportSpec->pn_pos, dst);
|
||||
}
|
||||
|
||||
|
|
@ -2476,7 +2480,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
|
|||
return builder.emptyStatement(&pn->pn_pos, dst);
|
||||
|
||||
case PNK_LEXICALSCOPE:
|
||||
pn = pn->pn_expr;
|
||||
pn = pn->scopeBody();
|
||||
if (!pn->isKind(PNK_STATEMENTLIST))
|
||||
return statement(pn, dst);
|
||||
MOZ_FALLTHROUGH;
|
||||
|
|
@ -2608,23 +2612,26 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
|
|||
case PNK_BREAK:
|
||||
case PNK_CONTINUE:
|
||||
{
|
||||
LoopControlStatement* node = &pn->as<LoopControlStatement>();
|
||||
RootedValue label(cx);
|
||||
RootedAtom pnAtom(cx, pn->pn_atom);
|
||||
RootedAtom pnAtom(cx, node->label());
|
||||
return optIdentifier(pnAtom, nullptr, &label) &&
|
||||
(pn->isKind(PNK_BREAK)
|
||||
? builder.breakStatement(label, &pn->pn_pos, dst)
|
||||
: builder.continueStatement(label, &pn->pn_pos, dst));
|
||||
(node->isKind(PNK_BREAK)
|
||||
? builder.breakStatement(label, &node->pn_pos, dst)
|
||||
: builder.continueStatement(label, &node->pn_pos, dst));
|
||||
}
|
||||
|
||||
case PNK_LABEL:
|
||||
{
|
||||
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_expr->pn_pos));
|
||||
LabeledStatement* labelNode = &pn->as<LabeledStatement>();
|
||||
ParseNode* stmtNode = labelNode->statement();
|
||||
MOZ_ASSERT(labelNode->pn_pos.encloses(stmtNode->pn_pos));
|
||||
|
||||
RootedValue label(cx), stmt(cx);
|
||||
RootedAtom pnAtom(cx, pn->as<LabeledStatement>().label());
|
||||
RootedAtom pnAtom(cx, labelNode->label());
|
||||
return identifier(pnAtom, nullptr, &label) &&
|
||||
statement(pn->pn_expr, &stmt) &&
|
||||
builder.labeledStatement(label, stmt, &pn->pn_pos, dst);
|
||||
statement(stmtNode, &stmt) &&
|
||||
builder.labeledStatement(label, stmt, &labelNode->pn_pos, dst);
|
||||
}
|
||||
|
||||
case PNK_THROW:
|
||||
|
|
@ -2804,7 +2811,7 @@ ASTSerializer::comprehensionBlock(ForNode* forNode, MutableHandleValue dst)
|
|||
|
||||
ListNode* decl;
|
||||
if (in->kid1()->isKind(PNK_LEXICALSCOPE))
|
||||
decl = &in->kid1()->pn_expr->as<ListNode>();
|
||||
decl = &in->kid1()->scopeBody()->as<ListNode>();
|
||||
else
|
||||
decl = &in->kid1()->as<ListNode>();
|
||||
MOZ_ASSERT(decl->count() == 1);
|
||||
|
|
@ -2834,7 +2841,7 @@ ASTSerializer::comprehension(ParseNode* pn, MutableHandleValue dst)
|
|||
// 2. The kind that was in ES6 for a while: [for (x of y) z]
|
||||
// They have slightly different parse trees and scoping.
|
||||
bool isLegacy = pn->isKind(PNK_LEXICALSCOPE);
|
||||
ParseNode* next = isLegacy ? pn->pn_expr : pn;
|
||||
ParseNode* next = isLegacy ? pn->scopeBody() : pn;
|
||||
LOCAL_ASSERT(next->isKind(PNK_COMPREHENSIONFOR));
|
||||
|
||||
NodeVector blocks(cx);
|
||||
|
|
@ -2880,7 +2887,7 @@ ASTSerializer::generatorExpression(ParseNode* pn, MutableHandleValue dst)
|
|||
// ASTSerializer::comprehension), there are legacy and modern generator
|
||||
// expression.
|
||||
bool isLegacy = pn->isKind(PNK_LEXICALSCOPE);
|
||||
ParseNode* next = isLegacy ? pn->pn_expr : pn;
|
||||
ParseNode* next = isLegacy ? pn->scopeBody() : pn;
|
||||
LOCAL_ASSERT(next->isKind(PNK_COMPREHENSIONFOR));
|
||||
|
||||
NodeVector blocks(cx);
|
||||
|
|
@ -2929,8 +2936,9 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
switch (pn->getKind()) {
|
||||
case PNK_FUNCTION:
|
||||
{
|
||||
ASTType type = pn->pn_funbox->function()->isArrow() ? AST_ARROW_EXPR : AST_FUNC_EXPR;
|
||||
return function(pn, type, dst);
|
||||
CodeNode* funNode = &pn->as<CodeNode>();
|
||||
ASTType type = funNode->funbox()->function()->isArrow() ? AST_ARROW_EXPR : AST_FUNC_EXPR;
|
||||
return function(funNode, type, dst);
|
||||
}
|
||||
|
||||
case PNK_COMMA:
|
||||
|
|
@ -3072,7 +3080,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
ParseNode* callee = pn->as<BinaryNode>().left();
|
||||
MOZ_ASSERT(callee->isKind(PNK_FUNCTION));
|
||||
|
||||
ListNode* paramsBody = &callee->pn_body->as<ListNode>();
|
||||
ListNode* paramsBody = callee->as<CodeNode>().body();
|
||||
MOZ_ASSERT(paramsBody->isKind(PNK_PARAMSBODY));
|
||||
|
||||
ListNode* body = ¶msBody->last()->as<ListNode>();
|
||||
|
|
@ -3147,7 +3155,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
|
||||
RootedValue expr(cx);
|
||||
RootedValue propname(cx);
|
||||
RootedAtom pnAtom(cx, prop->key().pn_atom);
|
||||
RootedAtom pnAtom(cx, prop->key().atom());
|
||||
|
||||
if (prop->isSuper()) {
|
||||
if (!builder.super(&prop->expression().pn_pos, &expr))
|
||||
|
|
@ -3195,11 +3203,12 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
NodeVector raw(cx);
|
||||
if (!raw.reserve(rawNodes->count()))
|
||||
return false;
|
||||
for (ParseNode* rawItem : rawNodes->contents()) {
|
||||
for (ParseNode* item : rawNodes->contents()) {
|
||||
NameNode* rawItem = &item->as<NameNode>();
|
||||
MOZ_ASSERT(callSiteObj->pn_pos.encloses(rawItem->pn_pos));
|
||||
|
||||
RootedValue expr(cx);
|
||||
expr.setString(rawItem->pn_atom);
|
||||
expr.setString(rawItem->atom());
|
||||
raw.infallibleAppend(expr);
|
||||
}
|
||||
|
||||
|
|
@ -3207,9 +3216,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
if (!cooked.reserve(callSiteObj->count() - 1))
|
||||
return false;
|
||||
|
||||
for (ParseNode* cookedItem = callSiteObj->head()->pn_next;
|
||||
cookedItem;
|
||||
cookedItem = cookedItem->pn_next) {
|
||||
for (ParseNode* cookedItem : callSiteObj->contentsFrom(rawNodes->pn_next)) {
|
||||
MOZ_ASSERT(callSiteObj->pn_pos.encloses(cookedItem->pn_pos));
|
||||
|
||||
RootedValue expr(cx);
|
||||
|
|
@ -3217,7 +3224,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
expr.setUndefined();
|
||||
} else {
|
||||
MOZ_ASSERT(cookedItem->isKind(PNK_TEMPLATE_STRING));
|
||||
expr.setString(cookedItem->pn_atom);
|
||||
expr.setString(cookedItem->as<NameNode>().atom());
|
||||
}
|
||||
cooked.infallibleAppend(expr);
|
||||
}
|
||||
|
|
@ -3282,7 +3289,7 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
}
|
||||
|
||||
case PNK_NAME:
|
||||
return identifier(pn, dst);
|
||||
return identifier(&pn->as<NameNode>(), dst);
|
||||
|
||||
case PNK_THIS:
|
||||
return builder.thisExpression(&pn->pn_pos, dst);
|
||||
|
|
@ -3387,16 +3394,16 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::propertyName(ParseNode* pn, MutableHandleValue dst)
|
||||
ASTSerializer::propertyName(ParseNode* key, MutableHandleValue dst)
|
||||
{
|
||||
if (pn->isKind(PNK_COMPUTED_NAME))
|
||||
return expression(pn, dst);
|
||||
if (pn->isKind(PNK_OBJECT_PROPERTY_NAME))
|
||||
return identifier(pn, dst);
|
||||
if (key->isKind(PNK_COMPUTED_NAME))
|
||||
return expression(key, dst);
|
||||
if (key->isKind(PNK_OBJECT_PROPERTY_NAME))
|
||||
return identifier(&key->as<NameNode>(), dst);
|
||||
|
||||
LOCAL_ASSERT(pn->isKind(PNK_STRING) || pn->isKind(PNK_NUMBER));
|
||||
LOCAL_ASSERT(key->isKind(PNK_STRING) || key->isKind(PNK_NUMBER));
|
||||
|
||||
return literal(pn, dst);
|
||||
return literal(key, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -3435,7 +3442,7 @@ ASTSerializer::property(ParseNode* pn, MutableHandleValue dst)
|
|||
bool isShorthand = node->isKind(PNK_SHORTHAND);
|
||||
bool isMethod =
|
||||
valNode->isKind(PNK_FUNCTION) &&
|
||||
valNode->pn_funbox->function()->kind() == JSFunction::Method;
|
||||
valNode->as<CodeNode>().funbox()->function()->kind() == JSFunction::Method;
|
||||
RootedValue key(cx), val(cx);
|
||||
return propertyName(keyNode, &key) &&
|
||||
expression(valNode, &val) &&
|
||||
|
|
@ -3449,7 +3456,7 @@ ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst)
|
|||
switch (pn->getKind()) {
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_STRING:
|
||||
val.setString(pn->pn_atom);
|
||||
val.setString(pn->as<NameNode>().atom());
|
||||
break;
|
||||
|
||||
case PNK_REGEXP:
|
||||
|
|
@ -3466,7 +3473,7 @@ ASTSerializer::literal(ParseNode* pn, MutableHandleValue dst)
|
|||
}
|
||||
|
||||
case PNK_NUMBER:
|
||||
val.setNumber(pn->pn_dval);
|
||||
val.setNumber(pn->as<NumericLiteral>().value());
|
||||
break;
|
||||
|
||||
case PNK_NULL:
|
||||
|
|
@ -3597,29 +3604,29 @@ ASTSerializer::identifier(HandleAtom atom, TokenPos* pos, MutableHandleValue dst
|
|||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::identifier(ParseNode* pn, MutableHandleValue dst)
|
||||
ASTSerializer::identifier(NameNode* id, MutableHandleValue dst)
|
||||
{
|
||||
LOCAL_ASSERT(pn->isArity(PN_NAME) || pn->isArity(PN_NULLARY));
|
||||
LOCAL_ASSERT(pn->pn_atom);
|
||||
LOCAL_ASSERT(id->atom());
|
||||
|
||||
RootedAtom pnAtom(cx, pn->pn_atom);
|
||||
return identifier(pnAtom, &pn->pn_pos, dst);
|
||||
RootedAtom pnAtom(cx, id->atom());
|
||||
return identifier(pnAtom, &id->pn_pos, dst);
|
||||
}
|
||||
|
||||
bool
|
||||
ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
|
||||
ASTSerializer::function(CodeNode* funNode, ASTType type, MutableHandleValue dst)
|
||||
{
|
||||
RootedFunction func(cx, pn->pn_funbox->function());
|
||||
FunctionBox* funbox = funNode->funbox();
|
||||
RootedFunction func(cx, funbox->function());
|
||||
|
||||
GeneratorStyle generatorStyle =
|
||||
pn->pn_funbox->isStarGenerator()
|
||||
funbox->isStarGenerator()
|
||||
? GeneratorStyle::ES6
|
||||
: pn->pn_funbox->isLegacyGenerator()
|
||||
: funbox->isLegacyGenerator()
|
||||
? GeneratorStyle::Legacy
|
||||
: GeneratorStyle::None;
|
||||
|
||||
bool isAsync = pn->pn_funbox->isAsync();
|
||||
bool isExpression = pn->pn_funbox->isExprBody();
|
||||
bool isAsync = funbox->isAsync();
|
||||
bool isExpression = funbox->isExprBody();
|
||||
|
||||
RootedValue id(cx);
|
||||
RootedAtom funcAtom(cx, func->explicitName());
|
||||
|
|
@ -3630,12 +3637,13 @@ ASTSerializer::function(ParseNode* pn, ASTType type, MutableHandleValue dst)
|
|||
NodeVector defaults(cx);
|
||||
|
||||
RootedValue body(cx), rest(cx);
|
||||
if (pn->pn_funbox->hasRest())
|
||||
if (funbox->hasRest())
|
||||
rest.setUndefined();
|
||||
else
|
||||
rest.setNull();
|
||||
return functionArgsAndBody(pn->pn_body, args, defaults, isAsync, isExpression, &body, &rest) &&
|
||||
builder.function(type, &pn->pn_pos, id, args, defaults, body,
|
||||
return functionArgsAndBody(funNode->body(), args, defaults, isAsync, isExpression,
|
||||
&body, &rest) &&
|
||||
builder.function(type, &funNode->pn_pos, id, args, defaults, body,
|
||||
rest, generatorStyle, isAsync, isExpression, dst);
|
||||
}
|
||||
|
||||
|
|
@ -3930,7 +3938,7 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
|
|||
return false;
|
||||
|
||||
MOZ_ASSERT(pn->getKind() == PNK_MODULE);
|
||||
pn = pn->pn_body;
|
||||
pn = pn->as<CodeNode>().body();
|
||||
}
|
||||
|
||||
RootedValue val(cx);
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ BytecodeCompiler::compileModule()
|
|||
Maybe<BytecodeEmitter> emitter;
|
||||
if (!emplaceEmitter(emitter, &modulesc))
|
||||
return nullptr;
|
||||
if (!emitter->emitScript(pn->pn_body))
|
||||
if (!emitter->emitScript(pn->as<CodeNode>().body()))
|
||||
return nullptr;
|
||||
|
||||
if (!NameFunctions(cx, pn))
|
||||
|
|
@ -466,19 +466,20 @@ BytecodeCompiler::compileStandaloneFunction(MutableHandleFunction fun,
|
|||
return false;
|
||||
} while (!fn);
|
||||
|
||||
if (fn->pn_funbox->function()->isInterpreted()) {
|
||||
MOZ_ASSERT(fun == fn->pn_funbox->function());
|
||||
FunctionBox* funbox = fn->as<CodeNode>().funbox();
|
||||
if (funbox->function()->isInterpreted()) {
|
||||
MOZ_ASSERT(fun == funbox->function());
|
||||
|
||||
if (!createScript(fn->pn_funbox->toStringStart, fn->pn_funbox->toStringEnd))
|
||||
if (!createScript(funbox->toStringStart, funbox->toStringEnd))
|
||||
return false;
|
||||
|
||||
Maybe<BytecodeEmitter> emitter;
|
||||
if (!emplaceEmitter(emitter, fn->pn_funbox))
|
||||
if (!emplaceEmitter(emitter, funbox))
|
||||
return false;
|
||||
if (!emitter->emitFunctionScript(fn->pn_body))
|
||||
if (!emitter->emitFunctionScript(&fn->as<CodeNode>()))
|
||||
return false;
|
||||
} else {
|
||||
fun.set(fn->pn_funbox->function());
|
||||
fun.set(funbox->function());
|
||||
MOZ_ASSERT(IsAsmJSModule(fun));
|
||||
}
|
||||
|
||||
|
|
@ -673,12 +674,12 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
|
|||
if (lazy->hasBeenCloned())
|
||||
script->setHasBeenCloned();
|
||||
|
||||
BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->pn_funbox, script, lazy,
|
||||
BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->as<CodeNode>().funbox(), script, lazy,
|
||||
pn->pn_pos, BytecodeEmitter::LazyFunction);
|
||||
if (!bce.init())
|
||||
return false;
|
||||
|
||||
if (!bce.emitFunctionScript(pn->pn_body))
|
||||
if (!bce.emitFunctionScript(&pn->as<CodeNode>()))
|
||||
return false;
|
||||
|
||||
if (!NameFunctions(cx, pn))
|
||||
|
|
|
|||
|
|
@ -1054,21 +1054,33 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
switch (pn->getKind()) {
|
||||
// Trivial cases with no side effects.
|
||||
case PNK_NOP:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_REGEXP:
|
||||
case PNK_TRUE:
|
||||
case PNK_FALSE:
|
||||
case PNK_NULL:
|
||||
case PNK_RAW_UNDEFINED:
|
||||
case PNK_ELISION:
|
||||
case PNK_GENERATOR:
|
||||
case PNK_NUMBER:
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
MOZ_ASSERT(pn->isArity(PN_NULLARY));
|
||||
*answer = false;
|
||||
return true;
|
||||
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
MOZ_ASSERT(pn->is<NameNode>());
|
||||
*answer = false;
|
||||
return true;
|
||||
|
||||
case PNK_REGEXP:
|
||||
MOZ_ASSERT(pn->is<RegExpLiteral>());
|
||||
*answer = false;
|
||||
return true;
|
||||
|
||||
case PNK_NUMBER:
|
||||
MOZ_ASSERT(pn->is<NumericLiteral>());
|
||||
*answer = false;
|
||||
return true;
|
||||
|
||||
// |this| can throw in derived class constructors, including nested arrow
|
||||
// functions or eval.
|
||||
case PNK_THIS:
|
||||
|
|
@ -1381,7 +1393,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
return true;
|
||||
|
||||
case PNK_NAME:
|
||||
MOZ_ASSERT(pn->isArity(PN_NAME));
|
||||
MOZ_ASSERT(pn->is<NameNode>());
|
||||
*answer = true;
|
||||
return true;
|
||||
|
||||
|
|
@ -1395,7 +1407,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
return true;
|
||||
|
||||
case PNK_FUNCTION:
|
||||
MOZ_ASSERT(pn->isArity(PN_CODE));
|
||||
MOZ_ASSERT(pn->is<CodeNode>());
|
||||
/*
|
||||
* A named function, contrary to ES3, is no longer effectful, because
|
||||
* we bind its name lexically (using JSOP_CALLEE) instead of creating
|
||||
|
|
@ -1463,8 +1475,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
}
|
||||
|
||||
case PNK_LABEL:
|
||||
MOZ_ASSERT(pn->isArity(PN_NAME));
|
||||
return checkSideEffects(pn->expr(), answer);
|
||||
return checkSideEffects(pn->as<LabeledStatement>().statement(), answer);
|
||||
|
||||
case PNK_LEXICALSCOPE:
|
||||
MOZ_ASSERT(pn->isArity(PN_SCOPE));
|
||||
|
|
@ -1855,7 +1866,7 @@ BytecodeEmitter::emitPropLHS(PropertyAccess* prop)
|
|||
|
||||
while (true) {
|
||||
/* Walk back up the list, emitting annotated name ops. */
|
||||
if (!emitAtomOp(pndot->key().pn_atom, JSOP_GETPROP))
|
||||
if (!emitAtomOp(pndot->key().atom(), JSOP_GETPROP))
|
||||
return false;
|
||||
|
||||
/* Reverse the pn_left link again. */
|
||||
|
|
@ -1897,7 +1908,7 @@ BytecodeEmitter::emitPropIncDec(UnaryNode* incDec)
|
|||
if (!emitPropLHS(prop)) // OBJ
|
||||
return false;
|
||||
}
|
||||
if (!poe.emitIncDec(prop->key().pn_atom)) { // RESULT
|
||||
if (!poe.emitIncDec(prop->key().atom())) { // RESULT
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1911,7 +1922,7 @@ BytecodeEmitter::emitNameIncDec(UnaryNode* incDec)
|
|||
|
||||
ParseNodeKind kind = incDec->getKind();
|
||||
NameNode* name = &incDec->kid()->as<NameNode>();
|
||||
NameOpEmitter noe(this, name->pn_atom,
|
||||
NameOpEmitter noe(this, name->atom(),
|
||||
kind == PNK_POSTINCREMENT ? NameOpEmitter::Kind::PostIncrement
|
||||
: kind == PNK_PREINCREMENT ? NameOpEmitter::Kind::PreIncrement
|
||||
: kind == PNK_POSTDECREMENT ? NameOpEmitter::Kind::PostDecrement
|
||||
|
|
@ -2113,7 +2124,7 @@ BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt)
|
|||
}
|
||||
|
||||
int32_t i;
|
||||
if (!NumberIsInt32(caseValue->pn_dval, &i)) {
|
||||
if (!NumberIsInt32(caseValue->as<NumericLiteral>().value(), &i)) {
|
||||
tableGen.setInvalid();
|
||||
break;
|
||||
}
|
||||
|
|
@ -2166,8 +2177,15 @@ BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt)
|
|||
ParseNode* caseValue = caseClause->caseExpression();
|
||||
MOZ_ASSERT(caseValue->isKind(PNK_NUMBER));
|
||||
|
||||
int32_t i = int32_t(caseValue->pn_dval);
|
||||
MOZ_ASSERT(double(i) == caseValue->pn_dval);
|
||||
NumericLiteral* literal = &caseValue->as<NumericLiteral>();
|
||||
#ifdef DEBUG
|
||||
// Use NumberEqualsInt32 here because switches compare using
|
||||
// strict equality, which will equate -0 and +0. In contrast
|
||||
// NumberIsInt32 would return false for -0.
|
||||
int32_t v;
|
||||
MOZ_ASSERT(mozilla::NumberEqualsInt32(literal->value(), &v));
|
||||
#endif
|
||||
int32_t i = int32_t(literal->value());
|
||||
|
||||
if (!se.emitCaseBody(i, tableGen))
|
||||
return false;
|
||||
|
|
@ -2360,8 +2378,10 @@ BytecodeEmitter::emitScript(ParseNode* body)
|
|||
}
|
||||
|
||||
bool
|
||||
BytecodeEmitter::emitFunctionScript(ParseNode* body)
|
||||
BytecodeEmitter::emitFunctionScript(CodeNode* funNode)
|
||||
{
|
||||
MOZ_ASSERT(funNode->isKind(PNK_FUNCTION));
|
||||
ParseNode* body = funNode->body();
|
||||
FunctionBox* funbox = sc->asFunctionBox();
|
||||
|
||||
// The ordering of these EmitterScopes is important. The named lambda
|
||||
|
|
@ -2619,8 +2639,8 @@ BytecodeEmitter::emitSetOrInitializeDestructuring(ParseNode* target, Destructuri
|
|||
if (!poe.skipObjAndRhs()) {
|
||||
return false;
|
||||
}
|
||||
if (!poe.emitAssignment(prop->key().pn_atom)) {
|
||||
return false; // VAL
|
||||
if (!poe.emitAssignment(prop->key().atom())) { // VAL
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2943,7 +2963,7 @@ BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name,
|
|||
if (maybeFun->isKind(PNK_FUNCTION)) {
|
||||
// Function doesn't have 'name' property at this point.
|
||||
// Set function's name at compile time.
|
||||
RootedFunction fun(cx, maybeFun->pn_funbox->function());
|
||||
RootedFunction fun(cx, maybeFun->as<CodeNode>().funbox()->function());
|
||||
|
||||
// Single node can be emitted multiple times if it appears in
|
||||
// array destructuring default. If function already has a name,
|
||||
|
|
@ -2953,7 +2973,7 @@ BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name,
|
|||
RootedAtom funName(cx, NameToFunctionName(cx, name, prefixKind));
|
||||
if (!funName)
|
||||
return false;
|
||||
MOZ_ASSERT(funName == maybeFun->pn_funbox->function()->compileTimeName());
|
||||
MOZ_ASSERT(funName == fun->compileTimeName());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3409,11 +3429,11 @@ BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern, DestructuringFlav
|
|||
|
||||
ParseNode* key = member->as<BinaryNode>().left();
|
||||
if (key->isKind(PNK_NUMBER)) {
|
||||
if (!emitNumberOp(key->pn_dval)) // ... *SET RHS *LREF RHS KEY
|
||||
return false;
|
||||
if (!emitNumberOp(key->as<NumericLiteral>().value()))
|
||||
return false; // ... *SET RHS *LREF RHS KEY
|
||||
} else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) {
|
||||
if (!emitAtomOp(key->pn_atom, JSOP_GETPROP)) // ... *SET RHS *LREF PROP
|
||||
return false;
|
||||
if (!emitAtomOp(key->as<NameNode>().atom(), JSOP_GETPROP))
|
||||
return false; // ... *SET RHS *LREF PROP
|
||||
needsGetElem = false;
|
||||
} else {
|
||||
if (!emitComputedPropertyName(&key->as<UnaryNode>())) // ... *SET RHS *LREF RHS KEY
|
||||
|
|
@ -3486,11 +3506,11 @@ BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern)
|
|||
} else {
|
||||
ParseNode* key = member->as<BinaryNode>().left();
|
||||
if (key->isKind(PNK_NUMBER)) {
|
||||
if (!emitNumberOp(key->pn_dval))
|
||||
if (!emitNumberOp(key->as<NumericLiteral>().value()))
|
||||
return false;
|
||||
isIndex = true;
|
||||
} else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) {
|
||||
pnatom.set(key->pn_atom);
|
||||
pnatom.set(key->as<NameNode>().atom());
|
||||
} else {
|
||||
// Otherwise this is a computed property name which needs to
|
||||
// be added dynamically.
|
||||
|
|
@ -3558,7 +3578,7 @@ BytecodeEmitter::emitTemplateString(ListNode* templateString)
|
|||
// Skip empty strings. These are very common: a template string like
|
||||
// `${a}${b}` has three empty strings and without this optimization
|
||||
// we'd emit four JSOP_ADD operations instead of just one.
|
||||
if (isString && item->pn_atom->empty())
|
||||
if (isString && item->as<NameNode>().atom()->empty())
|
||||
continue;
|
||||
|
||||
if (!isString) {
|
||||
|
|
@ -3618,7 +3638,7 @@ BytecodeEmitter::emitDeclarationList(ListNode* declList)
|
|||
if (!emit1(JSOP_POP))
|
||||
return false;
|
||||
} else {
|
||||
if (!emitSingleDeclaration(declList, decl, decl->expr()))
|
||||
if (!emitSingleDeclaration(declList, decl, decl->as<NameNode>().initializer()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -3809,7 +3829,7 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs)
|
|||
switch (lhs->getKind()) {
|
||||
case PNK_DOT: {
|
||||
PropertyAccess* prop = &lhs->as<PropertyAccess>();
|
||||
if (!poe->emitGet(prop->key().pn_atom)) { // [Super]
|
||||
if (!poe->emitGet(prop->key().atom())) { // [Super]
|
||||
// // THIS SUPERBASE PROP
|
||||
// // [Other]
|
||||
// // OBJ PROP
|
||||
|
|
@ -3878,7 +3898,7 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs)
|
|||
switch (lhs->getKind()) {
|
||||
case PNK_DOT: {
|
||||
PropertyAccess* prop = &lhs->as<PropertyAccess>();
|
||||
if (!poe->emitAssignment(prop->key().pn_atom)) { // VAL
|
||||
if (!poe->emitAssignment(prop->key().atom())) { // VAL
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3916,11 +3936,11 @@ ParseNode::getConstantValue(ExclusiveContext* cx, AllowConstantObjects allowObje
|
|||
|
||||
switch (getKind()) {
|
||||
case PNK_NUMBER:
|
||||
vp.setNumber(pn_dval);
|
||||
vp.setNumber(as<NumericLiteral>().value());
|
||||
return true;
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_STRING:
|
||||
vp.setString(pn_atom);
|
||||
vp.setString(as<NameNode>().atom());
|
||||
return true;
|
||||
case PNK_TRUE:
|
||||
vp.setBoolean(true);
|
||||
|
|
@ -4009,12 +4029,12 @@ ParseNode::getConstantValue(ExclusiveContext* cx, AllowConstantObjects allowObje
|
|||
|
||||
ParseNode* key = prop->left();
|
||||
if (key->isKind(PNK_NUMBER)) {
|
||||
idvalue = NumberValue(key->pn_dval);
|
||||
idvalue = NumberValue(key->as<NumericLiteral>().value());
|
||||
} else {
|
||||
MOZ_ASSERT(key->isKind(PNK_OBJECT_PROPERTY_NAME) ||
|
||||
key->isKind(PNK_STRING));
|
||||
MOZ_ASSERT(key->pn_atom != cx->names().proto);
|
||||
idvalue = StringValue(key->pn_atom);
|
||||
MOZ_ASSERT(key->as<NameNode>().atom() != cx->names().proto);
|
||||
idvalue = StringValue(key->as<NameNode>().atom());
|
||||
}
|
||||
|
||||
RootedId id(cx);
|
||||
|
|
@ -4330,7 +4350,7 @@ BytecodeEmitter::emitHoistedFunctionsInList(ListNode* stmtList)
|
|||
maybeFun = maybeFun->as<LabeledStatement>().statement();
|
||||
}
|
||||
|
||||
if (maybeFun->isKind(PNK_FUNCTION) && maybeFun->functionIsHoisted()) {
|
||||
if (maybeFun->isKind(PNK_FUNCTION) && maybeFun->as<CodeNode>().functionIsHoisted()) {
|
||||
if (!emitTree(maybeFun))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -4935,7 +4955,7 @@ BytecodeEmitter::emitForIn(ForNode* forNode, EmitterScope* headLexicalEmitterSco
|
|||
if (parser->handler.isDeclarationList(forInTarget)) {
|
||||
ParseNode* decl = parser->handler.singleBindingFromDeclaration(&forInTarget->as<ListNode>());
|
||||
if (decl->isKind(PNK_NAME)) {
|
||||
if (ParseNode* initializer = decl->expr()) {
|
||||
if (ParseNode* initializer = decl->as<NameNode>().initializer()) {
|
||||
MOZ_ASSERT(forInTarget->isKind(PNK_VAR),
|
||||
"for-in initializers are only permitted for |var| declarations");
|
||||
|
||||
|
|
@ -5341,7 +5361,7 @@ BytecodeEmitter::emitComprehensionForOf(ForNode* forNode)
|
|||
Maybe<EmitterScope> emitterScope;
|
||||
ParseNode* loopVariableName;
|
||||
if (lexicalScope) {
|
||||
loopVariableName = parser->handler.singleBindingFromDeclaration(&loopDecl->pn_expr->as<ListNode>());
|
||||
loopVariableName = parser->handler.singleBindingFromDeclaration(&loopDecl->scopeBody()->as<ListNode>());
|
||||
emitterScope.emplace(this);
|
||||
if (!emitterScope->enterComprehensionFor(this, loopDecl->scopeBindings()))
|
||||
return false;
|
||||
|
|
@ -5584,9 +5604,9 @@ BytecodeEmitter::emitComprehensionFor(ForNode* forNode)
|
|||
}
|
||||
|
||||
MOZ_NEVER_INLINE bool
|
||||
BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
||||
BytecodeEmitter::emitFunction(CodeNode* funNode, bool needsProto)
|
||||
{
|
||||
FunctionBox* funbox = pn->pn_funbox;
|
||||
FunctionBox* funbox = funNode->funbox();
|
||||
RootedFunction fun(cx, funbox->function());
|
||||
RootedAtom name(cx, fun->explicitName());
|
||||
MOZ_ASSERT_IF(fun->isInterpretedLazy(), fun->lazyScript());
|
||||
|
|
@ -5637,7 +5657,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
}
|
||||
|
||||
MOZ_ASSERT_IF(fun->hasScript(), fun->nonLazyScript());
|
||||
MOZ_ASSERT(pn->functionIsHoisted());
|
||||
MOZ_ASSERT(funNode->functionIsHoisted());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -5687,12 +5707,12 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
return false;
|
||||
|
||||
BytecodeEmitter bce2(this, parser, funbox, script, /* lazyScript = */ nullptr,
|
||||
pn->pn_pos, emitterMode);
|
||||
funNode->pn_pos, emitterMode);
|
||||
if (!bce2.init())
|
||||
return false;
|
||||
|
||||
/* We measured the max scope depth when we parsed the function. */
|
||||
if (!bce2.emitFunctionScript(pn->pn_body))
|
||||
if (!bce2.emitFunctionScript(funNode))
|
||||
return false;
|
||||
|
||||
if (funbox->isLikelyConstructorWrapper())
|
||||
|
|
@ -5706,12 +5726,12 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
}
|
||||
|
||||
/* Make the function object a literal in the outer script's pool. */
|
||||
unsigned index = objectList.add(pn->pn_funbox);
|
||||
unsigned index = objectList.add(funNode->funbox());
|
||||
|
||||
/* Non-hoisted functions simply emit their respective op. */
|
||||
if (!pn->functionIsHoisted()) {
|
||||
if (!funNode->functionIsHoisted()) {
|
||||
/* JSOP_LAMBDA_ARROW is always preceded by a new.target */
|
||||
MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW));
|
||||
MOZ_ASSERT(fun->isArrow() == (funNode->getOp() == JSOP_LAMBDA_ARROW));
|
||||
if (funbox->isAsync()) {
|
||||
MOZ_ASSERT(!needsProto);
|
||||
return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow(),
|
||||
|
|
@ -5729,17 +5749,17 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
}
|
||||
|
||||
if (needsProto) {
|
||||
MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA);
|
||||
pn->setOp(JSOP_FUNWITHPROTO);
|
||||
MOZ_ASSERT(funNode->getOp() == JSOP_LAMBDA);
|
||||
funNode->setOp(JSOP_FUNWITHPROTO);
|
||||
}
|
||||
|
||||
if (pn->getOp() == JSOP_DEFFUN) {
|
||||
if (funNode->getOp() == JSOP_DEFFUN) {
|
||||
if (!emitIndex32(JSOP_LAMBDA, index))
|
||||
return false;
|
||||
return emit1(JSOP_DEFFUN);
|
||||
}
|
||||
|
||||
return emitIndex32(pn->getOp(), index);
|
||||
return emitIndex32(funNode->getOp(), index);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!needsProto);
|
||||
|
|
@ -5767,7 +5787,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext());
|
||||
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
|
||||
MOZ_ASSERT(funNode->getOp() == JSOP_NOP);
|
||||
switchToPrologue();
|
||||
if (funbox->isAsync()) {
|
||||
if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow(),
|
||||
|
|
@ -5781,7 +5801,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
}
|
||||
if (!emit1(JSOP_DEFFUN))
|
||||
return false;
|
||||
if (!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||
if (!updateSourceCoordNotes(funNode->pn_pos.begin))
|
||||
return false;
|
||||
switchToMain();
|
||||
}
|
||||
|
|
@ -6693,10 +6713,10 @@ BytecodeEmitter::emitDeleteName(UnaryNode* deleteNode)
|
|||
{
|
||||
MOZ_ASSERT(deleteNode->isKind(PNK_DELETENAME));
|
||||
|
||||
ParseNode* nameExpr = deleteNode->kid();
|
||||
NameNode* nameExpr = &deleteNode->kid()->as<NameNode>();
|
||||
MOZ_ASSERT(nameExpr->isKind(PNK_NAME));
|
||||
|
||||
return emitAtomOp(nameExpr->pn_atom, JSOP_DELNAME);
|
||||
return emitAtomOp(nameExpr->atom(), JSOP_DELNAME);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -6731,7 +6751,8 @@ BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode)
|
|||
}
|
||||
}
|
||||
|
||||
if (!poe.emitDelete(propExpr->key().pn_atom)) { // [Super]
|
||||
if (!poe.emitDelete(propExpr->key().atom())) {
|
||||
// // [Super]
|
||||
// // THIS
|
||||
// // [Other]
|
||||
// // SUCCEEDED
|
||||
|
|
@ -6884,7 +6905,7 @@ BytecodeEmitter::emitDeletePropertyInOptChain(
|
|||
}
|
||||
|
||||
JSOp delOp = sc->strict() ? JSOP_STRICTDELPROP : JSOP_DELPROP;
|
||||
if (!emitAtomOp(propExpr->pn_atom, delOp)) {
|
||||
if (!emitAtomOp(propExpr->key().atom(), delOp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -7034,7 +7055,7 @@ BytecodeEmitter::emitSelfHostedResumeGenerator(BinaryNode* callNode)
|
|||
|
||||
ParseNode* kindNode = valNode->pn_next;
|
||||
MOZ_ASSERT(kindNode->isKind(PNK_STRING));
|
||||
uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->pn_atom);
|
||||
uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->as<NameNode>().atom());
|
||||
MOZ_ASSERT(!kindNode->pn_next);
|
||||
|
||||
if (!emitCall(JSOP_RESUME, operand))
|
||||
|
|
@ -7472,7 +7493,7 @@ BytecodeEmitter::emitCalleeAndThis(
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!poe.emitGet(prop->key().pn_atom)) { // CALLEE THIS?
|
||||
if (!poe.emitGet(prop->key().atom())) { // CALLEE THIS?
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -7752,12 +7773,12 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
|
|||
ParseNode* key = propdef->as<BinaryNode>().left();
|
||||
bool isIndex = false;
|
||||
if (key->isKind(PNK_NUMBER)) {
|
||||
if (!emitNumberOp(key->pn_dval))
|
||||
if (!emitNumberOp(key->as<NumericLiteral>().value()))
|
||||
return false;
|
||||
isIndex = true;
|
||||
} else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) {
|
||||
// EmitClass took care of constructor already.
|
||||
if (type == ClassBody && key->pn_atom == cx->names().constructor &&
|
||||
if (type == ClassBody && key->as<NameNode>().atom() == cx->names().constructor &&
|
||||
!propdef->as<ClassMethod>().isStatic())
|
||||
{
|
||||
continue;
|
||||
|
|
@ -7787,10 +7808,11 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
|
|||
objp.set(nullptr);
|
||||
|
||||
if (propVal->isKind(PNK_FUNCTION) &&
|
||||
propVal->pn_funbox->needsHomeObject())
|
||||
propVal->as<CodeNode>().funbox()->needsHomeObject())
|
||||
{
|
||||
MOZ_ASSERT(propVal->pn_funbox->function()->allowSuperProperty());
|
||||
bool isAsync = propVal->pn_funbox->isAsync();
|
||||
FunctionBox* funbox = propVal->as<CodeNode>().funbox();
|
||||
MOZ_ASSERT(funbox->function()->allowSuperProperty());
|
||||
bool isAsync = funbox->isAsync();
|
||||
if (isAsync) {
|
||||
if (!emit1(JSOP_SWAP))
|
||||
return false;
|
||||
|
|
@ -7836,14 +7858,14 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
|
|||
MOZ_ASSERT(key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING));
|
||||
|
||||
uint32_t index;
|
||||
if (!makeAtomIndex(key->pn_atom, &index))
|
||||
if (!makeAtomIndex(key->as<NameNode>().atom(), &index))
|
||||
return false;
|
||||
|
||||
if (objp) {
|
||||
MOZ_ASSERT(type == ObjectLiteral);
|
||||
MOZ_ASSERT(!IsHiddenInitOp(op));
|
||||
MOZ_ASSERT(!objp->inDictionaryMode());
|
||||
Rooted<jsid> id(cx, AtomToId(key->pn_atom));
|
||||
Rooted<jsid> id(cx, AtomToId(key->as<NameNode>().atom()));
|
||||
if (!NativeDefineProperty(cx, objp, id, UndefinedHandleValue, nullptr, nullptr,
|
||||
JSPROP_ENUMERATE))
|
||||
{
|
||||
|
|
@ -7854,7 +7876,7 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
|
|||
}
|
||||
|
||||
if (propVal->isDirectRHSAnonFunction()) {
|
||||
RootedAtom keyName(cx, key->pn_atom);
|
||||
RootedAtom keyName(cx, key->as<NameNode>().atom());
|
||||
if (!setOrEmitSetFunName(propVal, keyName, prefixKind))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -8484,13 +8506,13 @@ BytecodeEmitter::emitClass(ClassNode* classNode)
|
|||
ParseNode* heritageExpression = classNode->heritage();
|
||||
ListNode* classMethods = classNode->methodList();
|
||||
|
||||
ParseNode* constructor = nullptr;
|
||||
CodeNode* constructor = nullptr;
|
||||
for (ParseNode* mn : classMethods->contents()) {
|
||||
ClassMethod& method = mn->as<ClassMethod>();
|
||||
ParseNode& methodName = method.name();
|
||||
if (!method.isStatic() &&
|
||||
(methodName.isKind(PNK_OBJECT_PROPERTY_NAME) || methodName.isKind(PNK_STRING)) &&
|
||||
methodName.pn_atom == cx->names().constructor)
|
||||
methodName.as<NameNode>().atom() == cx->names().constructor)
|
||||
{
|
||||
constructor = &method.method();
|
||||
break;
|
||||
|
|
@ -8533,7 +8555,7 @@ BytecodeEmitter::emitClass(ClassNode* classNode)
|
|||
if (constructor) {
|
||||
if (!emitFunction(constructor, !!heritageExpression))
|
||||
return false;
|
||||
if (constructor->pn_funbox->needsHomeObject()) {
|
||||
if (constructor->funbox()->needsHomeObject()) {
|
||||
if (!emit2(JSOP_INITHOMEOBJECT, 0))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -8547,7 +8569,7 @@ BytecodeEmitter::emitClass(ClassNode* classNode)
|
|||
if (!newSrcNote3(SRC_CLASS_SPAN, classStart, classEnd))
|
||||
return false;
|
||||
|
||||
JSAtom *name = names ? names->innerBinding()->pn_atom : cx->names().empty;
|
||||
JSAtom *name = names ? names->innerBinding()->as<NameNode>().atom() : cx->names().empty;
|
||||
if (heritageExpression) {
|
||||
if (!emitAtomOp(name, JSOP_DERIVEDCONSTRUCTOR))
|
||||
return false;
|
||||
|
|
@ -8618,7 +8640,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
|||
|
||||
switch (pn->getKind()) {
|
||||
case PNK_FUNCTION:
|
||||
if (!emitFunction(pn))
|
||||
if (!emitFunction(&pn->as<CodeNode>()))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
|
@ -8879,7 +8901,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!poe.emitGet(prop->key().pn_atom)) { // PROP
|
||||
if (!poe.emitGet(prop->key().atom())) { // PROP
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
|
@ -9004,12 +9026,12 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
|||
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_STRING:
|
||||
if (!emitAtomOp(pn->pn_atom, JSOP_STRING))
|
||||
if (!emitAtomOp(pn->as<NameNode>().atom(), JSOP_STRING))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PNK_NUMBER:
|
||||
if (!emitNumberOp(pn->pn_dval))
|
||||
if (!emitNumberOp(pn->as<NumericLiteral>().value()))
|
||||
return false;
|
||||
break;
|
||||
|
||||
|
|
@ -9281,7 +9303,7 @@ BytecodeEmitter::emitOptionalDotExpression(
|
|||
}
|
||||
}
|
||||
|
||||
if (!poe.emitGet(prop->key().pn_atom)) {
|
||||
if (!poe.emitGet(prop->key().atom())) {
|
||||
// [stack] PROP
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
|||
MOZ_MUST_USE bool emitScript(ParseNode* body);
|
||||
|
||||
// Emit function code for the tree rooted at body.
|
||||
MOZ_MUST_USE bool emitFunctionScript(ParseNode* body);
|
||||
MOZ_MUST_USE bool emitFunctionScript(CodeNode* funNode);
|
||||
|
||||
// If op is JOF_TYPESET (see the type barriers comment in TypeInference.h),
|
||||
// reserve a type set to store its result.
|
||||
|
|
@ -508,7 +508,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
|
|||
MOZ_MUST_USE bool emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2, JSOp op);
|
||||
MOZ_MUST_USE bool emitRegExp(uint32_t index);
|
||||
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(ParseNode* pn, bool needsProto = false);
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(CodeNode* funNode, bool needsProto = false);
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitObject(ListNode* objNode);
|
||||
|
||||
MOZ_MUST_USE bool replaceNewInitWithNewObject(JSObject* obj, ptrdiff_t offset);
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
|
|||
// that we preserve an unreachable function declaration node against
|
||||
// dead-code removal.
|
||||
case PNK_FUNCTION:
|
||||
MOZ_ASSERT(node->isArity(PN_CODE));
|
||||
MOZ_ASSERT(node->is<CodeNode>());
|
||||
*result = false;
|
||||
return true;
|
||||
|
||||
|
|
@ -151,7 +151,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
|
|||
return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().right(), result);
|
||||
|
||||
case PNK_LABEL:
|
||||
return ContainsHoistedDeclaration(cx, node->pn_expr, result);
|
||||
return ContainsHoistedDeclaration(cx, node->as<LabeledStatement>().statement(), result);
|
||||
|
||||
// Statements with more complicated structures.
|
||||
|
||||
|
|
@ -283,13 +283,13 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
|
|||
|
||||
case PNK_LEXICALSCOPE: {
|
||||
MOZ_ASSERT(node->isArity(PN_SCOPE));
|
||||
ParseNode* expr = node->pn_expr;
|
||||
ParseNode* expr = node->scopeBody();
|
||||
|
||||
if (expr->isKind(PNK_FOR) || expr->isKind(PNK_FUNCTION))
|
||||
return ContainsHoistedDeclaration(cx, expr, result);
|
||||
|
||||
MOZ_ASSERT(expr->isKind(PNK_STATEMENTLIST));
|
||||
return ListContainsHoistedDeclaration(cx, &node->pn_expr->as<ListNode>(), result);
|
||||
return ListContainsHoistedDeclaration(cx, &node->scopeBody()->as<ListNode>(), result);
|
||||
}
|
||||
|
||||
// List nodes with all non-null children.
|
||||
|
|
@ -426,21 +426,24 @@ FoldType(ExclusiveContext* cx, ParseNode* pn, ParseNodeKind kind)
|
|||
case PNK_NUMBER:
|
||||
if (pn->isKind(PNK_STRING)) {
|
||||
double d;
|
||||
if (!StringToNumber(cx, pn->pn_atom, &d))
|
||||
if (!StringToNumber(cx, pn->as<NameNode>().atom(), &d))
|
||||
return false;
|
||||
pn->pn_dval = d;
|
||||
pn->setKind(PNK_NUMBER);
|
||||
pn->setArity(PN_NUMBER);
|
||||
pn->setOp(JSOP_DOUBLE);
|
||||
pn->as<NumericLiteral>().setValue(d);
|
||||
}
|
||||
break;
|
||||
|
||||
case PNK_STRING:
|
||||
if (pn->isKind(PNK_NUMBER)) {
|
||||
pn->pn_atom = NumberToAtom(cx, pn->pn_dval);
|
||||
if (!pn->pn_atom)
|
||||
JSAtom* atom = NumberToAtom(cx, pn->as<NumericLiteral>().value());
|
||||
if (!atom)
|
||||
return false;
|
||||
pn->setKind(PNK_STRING);
|
||||
pn->setArity(PN_NAME);
|
||||
pn->setOp(JSOP_STRING);
|
||||
pn->as<NameNode>().setAtom(atom);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -485,13 +488,13 @@ Boolish(ParseNode* pn, bool isNullish = false)
|
|||
{
|
||||
switch (pn->getKind()) {
|
||||
case PNK_NUMBER: {
|
||||
bool isNonZeroNumber = (pn->pn_dval != 0 && !IsNaN(pn->pn_dval));
|
||||
bool isNonZeroNumber = (pn->as<NumericLiteral>().value() != 0 && !IsNaN(pn->as<NumericLiteral>().value()));
|
||||
return (isNullish || isNonZeroNumber) ? Truthy : Falsy;
|
||||
}
|
||||
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING: {
|
||||
bool isNonZeroLengthString = (pn->pn_atom->length() > 0);
|
||||
bool isNonZeroLengthString = (pn->as<NameNode>().atom()->length() > 0);
|
||||
return (isNullish || isNonZeroLengthString) ? Truthy : Falsy;
|
||||
}
|
||||
|
||||
|
|
@ -588,9 +591,9 @@ FoldTypeOfExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>&
|
|||
parser.prepareNodeForMutation(node);
|
||||
|
||||
node->setKind(PNK_STRING);
|
||||
node->setArity(PN_NULLARY);
|
||||
node->setArity(PN_NAME);
|
||||
node->setOp(JSOP_NOP);
|
||||
node->pn_atom = result;
|
||||
node->as<NameNode>().setAtom(result);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -676,7 +679,7 @@ FoldNot(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
|
|||
ParseNode* expr = node->kid();
|
||||
|
||||
if (expr->isKind(PNK_NUMBER)) {
|
||||
double d = expr->pn_dval;
|
||||
double d = expr->as<NumericLiteral>().value();
|
||||
|
||||
parser.prepareNodeForMutation(node);
|
||||
if (d == 0 || IsNaN(d)) {
|
||||
|
|
@ -713,7 +716,7 @@ FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandl
|
|||
|
||||
if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) {
|
||||
double d = expr->isKind(PNK_NUMBER)
|
||||
? expr->pn_dval
|
||||
? expr->as<NumericLiteral>().value()
|
||||
: double(expr->isKind(PNK_TRUE));
|
||||
|
||||
if (node->isKind(PNK_BITNOT))
|
||||
|
|
@ -725,9 +728,9 @@ FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandl
|
|||
|
||||
parser.prepareNodeForMutation(node);
|
||||
node->setKind(PNK_NUMBER);
|
||||
node->setArity(PN_NUMBER);
|
||||
node->setOp(JSOP_DOUBLE);
|
||||
node->setArity(PN_NULLARY);
|
||||
node->pn_dval = d;
|
||||
node->as<NumericLiteral>().setValue(d);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1011,20 +1014,19 @@ FoldIf(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& pars
|
|||
}
|
||||
|
||||
static bool
|
||||
FoldFunction(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
|
||||
FoldFunction(ExclusiveContext* cx, CodeNode* node, Parser<FullParseHandler>& parser,
|
||||
bool inGenexpLambda)
|
||||
{
|
||||
MOZ_ASSERT(node->isKind(PNK_FUNCTION));
|
||||
MOZ_ASSERT(node->isArity(PN_CODE));
|
||||
|
||||
// Don't constant-fold inside "use asm" code, as this could create a parse
|
||||
// tree that doesn't type-check as asm.js.
|
||||
if (node->pn_funbox->useAsmOrInsideUseAsm())
|
||||
if (node->funbox()->useAsmOrInsideUseAsm())
|
||||
return true;
|
||||
|
||||
// Note: pn_body is null for lazily-parsed functions.
|
||||
if (ParseNode*& functionBody = node->pn_body) {
|
||||
if (!Fold(cx, &functionBody, parser, node->pn_funbox->isGenexpLambda))
|
||||
if (node->body()) {
|
||||
if (!Fold(cx, node->unsafeBodyReference(), parser, node->funbox()->isGenexpLambda))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1074,14 +1076,11 @@ ComputeBinary(ParseNodeKind kind, double left, double right)
|
|||
}
|
||||
|
||||
static bool
|
||||
FoldModule(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser)
|
||||
FoldModule(ExclusiveContext* cx, CodeNode* node, Parser<FullParseHandler>& parser)
|
||||
{
|
||||
MOZ_ASSERT(node->isKind(PNK_MODULE));
|
||||
MOZ_ASSERT(node->isArity(PN_CODE));
|
||||
|
||||
ParseNode*& moduleBody = node->pn_body;
|
||||
MOZ_ASSERT(moduleBody);
|
||||
return Fold(cx, &moduleBody, parser, false);
|
||||
MOZ_ASSERT(node->body());
|
||||
return Fold(cx, node->unsafeBodyReference(), parser, false);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1122,7 +1121,7 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl
|
|||
if (!next || !next->isKind(PNK_NUMBER))
|
||||
break;
|
||||
|
||||
double d = ComputeBinary(kind, elem->pn_dval, next->pn_dval);
|
||||
double d = ComputeBinary(kind, elem->as<NumericLiteral>().value(), next->as<NumericLiteral>().value());
|
||||
|
||||
ParseNode* afterNext = next->pn_next;
|
||||
parser.freeTree(next);
|
||||
|
|
@ -1130,9 +1129,9 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl
|
|||
elem->pn_next = next;
|
||||
|
||||
elem->setKind(PNK_NUMBER);
|
||||
elem->setArity(PN_NUMBER);
|
||||
elem->setOp(JSOP_DOUBLE);
|
||||
elem->setArity(PN_NULLARY);
|
||||
elem->pn_dval = d;
|
||||
elem->as<NumericLiteral>().setValue(d);
|
||||
|
||||
node->unsafeDecrementCount();
|
||||
}
|
||||
|
|
@ -1141,11 +1140,11 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl
|
|||
MOZ_ASSERT(node->head() == elem);
|
||||
MOZ_ASSERT(elem->isKind(PNK_NUMBER));
|
||||
|
||||
double d = elem->pn_dval;
|
||||
double d = elem->as<NumericLiteral>().value();
|
||||
node->setKind(PNK_NUMBER);
|
||||
node->setArity(PN_NULLARY);
|
||||
node->setArity(PN_NUMBER);
|
||||
node->setOp(JSOP_DOUBLE);
|
||||
node->pn_dval = d;
|
||||
node->as<NumericLiteral>().setValue(d);
|
||||
|
||||
parser.freeTree(elem);
|
||||
}
|
||||
|
|
@ -1186,13 +1185,14 @@ FoldExponentiation(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandler
|
|||
if (!base->isKind(PNK_NUMBER) || !exponent->isKind(PNK_NUMBER))
|
||||
return true;
|
||||
|
||||
double d1 = base->pn_dval, d2 = exponent->pn_dval;
|
||||
double d1 = base->as<NumericLiteral>().value();
|
||||
double d2 = exponent->as<NumericLiteral>().value();
|
||||
|
||||
parser.prepareNodeForMutation(node);
|
||||
node->setKind(PNK_NUMBER);
|
||||
node->setArity(PN_NULLARY);
|
||||
node->setArity(PN_NUMBER);
|
||||
node->setOp(JSOP_DOUBLE);
|
||||
node->pn_dval = ecmaPow(d1, d2);
|
||||
node->as<NumericLiteral>().setValue(ecmaPow(d1, d2));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1312,20 +1312,21 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
|
|||
ParseNode* key = &elem->key();
|
||||
PropertyName* name = nullptr;
|
||||
if (key->isKind(PNK_STRING)) {
|
||||
JSAtom* atom = key->pn_atom;
|
||||
JSAtom* atom = key->as<NameNode>().atom();
|
||||
uint32_t index;
|
||||
|
||||
if (atom->isIndex(&index)) {
|
||||
// Optimization 1: We have something like expr["100"]. This is
|
||||
// equivalent to expr[100] which is faster.
|
||||
key->setKind(PNK_NUMBER);
|
||||
key->setArity(PN_NUMBER);
|
||||
key->setOp(JSOP_DOUBLE);
|
||||
key->pn_dval = index;
|
||||
key->as<NumericLiteral>().setValue(index);
|
||||
} else {
|
||||
name = atom->asPropertyName();
|
||||
}
|
||||
} else if (key->isKind(PNK_NUMBER)) {
|
||||
double number = key->pn_dval;
|
||||
double number = key->as<NumericLiteral>().value();
|
||||
if (number != ToUint32(number)) {
|
||||
// Optimization 2: We have something like expr[3.14]. The number
|
||||
// isn't an array index, so it converts to a string ("3.14"),
|
||||
|
|
@ -1343,7 +1344,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
|
|||
|
||||
// Optimization 3: We have expr["foo"] where foo is not an index. Convert
|
||||
// to a property access (like expr.foo) that optimizes better downstream.
|
||||
ParseNode* nameNode = parser.handler.newPropertyName(name, key->pn_pos);
|
||||
NameNode* nameNode = parser.handler.newPropertyName(name, key->pn_pos);
|
||||
if (!nameNode)
|
||||
return false;
|
||||
ParseNode* dottedAccess;
|
||||
|
|
@ -1397,7 +1398,9 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par
|
|||
if (!next->isKind(PNK_NUMBER))
|
||||
break;
|
||||
|
||||
current->pn_dval += next->pn_dval;
|
||||
NumericLiteral* num = ¤t->as<NumericLiteral>();
|
||||
|
||||
num->setValue(num->value() + next->as<NumericLiteral>().value());
|
||||
current->pn_next = next->pn_next;
|
||||
parser.freeTree(next);
|
||||
next = current->pn_next;
|
||||
|
|
@ -1442,7 +1445,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par
|
|||
// and replace them all with that fresh string.
|
||||
MOZ_ASSERT(current->isKind(PNK_STRING));
|
||||
|
||||
combination = current->pn_atom;
|
||||
combination = current->as<NameNode>().atom();
|
||||
|
||||
do {
|
||||
// Try folding the next operand to a string.
|
||||
|
|
@ -1454,7 +1457,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par
|
|||
break;
|
||||
|
||||
// Add this string to the combination and remove the node.
|
||||
tmp = next->pn_atom;
|
||||
tmp = next->as<NameNode>().atom();
|
||||
combination = ConcatStrings<CanGC>(cx, combination, tmp);
|
||||
if (!combination)
|
||||
return false;
|
||||
|
|
@ -1471,7 +1474,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par
|
|||
combination = AtomizeString(cx, combination);
|
||||
if (!combination)
|
||||
return false;
|
||||
current->pn_atom = &combination->asAtom();
|
||||
current->as<NameNode>().setAtom(&combination->asAtom());
|
||||
|
||||
|
||||
// If we're out of nodes, we're done.
|
||||
|
|
@ -1624,16 +1627,15 @@ FoldDottedProperty(ExclusiveContext* cx, PropertyAccessBase* prop, Parser<FullPa
|
|||
}
|
||||
|
||||
static bool
|
||||
FoldName(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
|
||||
FoldName(ExclusiveContext* cx, NameNode* nameNode, Parser<FullParseHandler>& parser,
|
||||
bool inGenexpLambda)
|
||||
{
|
||||
MOZ_ASSERT(node->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(node->isArity(PN_NAME));
|
||||
MOZ_ASSERT(nameNode->isKind(PNK_NAME));
|
||||
|
||||
if (!node->pn_expr)
|
||||
if (!nameNode->initializer())
|
||||
return true;
|
||||
|
||||
return Fold(cx, &node->pn_expr, parser, inGenexpLambda);
|
||||
return Fold(cx, nameNode->unsafeInitializerReference(), parser, inGenexpLambda);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1648,31 +1650,41 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
|
||||
switch (pn->getKind()) {
|
||||
case PNK_NOP:
|
||||
case PNK_REGEXP:
|
||||
case PNK_STRING:
|
||||
case PNK_TRUE:
|
||||
case PNK_FALSE:
|
||||
case PNK_NULL:
|
||||
case PNK_RAW_UNDEFINED:
|
||||
case PNK_ELISION:
|
||||
case PNK_NUMBER:
|
||||
case PNK_DEBUGGER:
|
||||
case PNK_BREAK:
|
||||
case PNK_CONTINUE:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_GENERATOR:
|
||||
case PNK_EXPORT_BATCH_SPEC:
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_POSHOLDER:
|
||||
MOZ_ASSERT(pn->isArity(PN_NULLARY));
|
||||
return true;
|
||||
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
MOZ_ASSERT(pn->is<NameNode>());
|
||||
return true;
|
||||
|
||||
case PNK_REGEXP:
|
||||
MOZ_ASSERT(pn->is<RegExpLiteral>());
|
||||
return true;
|
||||
|
||||
case PNK_NUMBER:
|
||||
MOZ_ASSERT(pn->is<NumericLiteral>());
|
||||
return true;
|
||||
|
||||
case PNK_SUPERBASE:
|
||||
case PNK_TYPEOFNAME: {
|
||||
#ifdef DEBUG
|
||||
UnaryNode* node = &pn->as<UnaryNode>();
|
||||
MOZ_ASSERT(node->kid()->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!node->kid()->expr());
|
||||
NameNode* nameNode = &node->kid()->as<NameNode>();
|
||||
MOZ_ASSERT(nameNode->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!nameNode->initializer());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1747,10 +1759,10 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
return FoldLogical(cx, pnp, parser, inGenexpLambda);
|
||||
|
||||
case PNK_FUNCTION:
|
||||
return FoldFunction(cx, pn, parser, inGenexpLambda);
|
||||
return FoldFunction(cx, &pn->as<CodeNode>(), parser, inGenexpLambda);
|
||||
|
||||
case PNK_MODULE:
|
||||
return FoldModule(cx, pn, parser);
|
||||
return FoldModule(cx, &pn->as<CodeNode>(), parser);
|
||||
|
||||
case PNK_SUB:
|
||||
case PNK_STAR:
|
||||
|
|
@ -1932,8 +1944,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
return FoldForHead(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);
|
||||
|
||||
case PNK_LABEL:
|
||||
MOZ_ASSERT(pn->isArity(PN_NAME));
|
||||
return Fold(cx, &pn->pn_expr, parser, inGenexpLambda);
|
||||
return Fold(cx, pn->as<LabeledStatement>().unsafeStatementReference(), parser, inGenexpLambda);
|
||||
|
||||
case PNK_PROPERTYNAME:
|
||||
MOZ_CRASH("unreachable, handled by ::Dot");
|
||||
|
|
@ -1949,7 +1960,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
return Fold(cx, &pn->pn_u.scope.body, parser, inGenexpLambda);
|
||||
|
||||
case PNK_NAME:
|
||||
return FoldName(cx, pn, parser, inGenexpLambda);
|
||||
return FoldName(cx, &pn->as<NameNode>(), parser, inGenexpLambda);
|
||||
|
||||
case PNK_LIMIT: // invalid sentinel value
|
||||
MOZ_CRASH("invalid node kind");
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
void prepareNodeForMutation(ParseNode* pn) { return allocator.prepareNodeForMutation(pn); }
|
||||
const Token& currentToken() { return tokenStream.currentToken(); }
|
||||
|
||||
ParseNode* newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx)
|
||||
NameNodeType newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx)
|
||||
{
|
||||
return new_<NameNode>(PNK_NAME, JSOP_GETNAME, name, pos);
|
||||
}
|
||||
|
|
@ -143,28 +143,24 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return new_<UnaryNode>(PNK_COMPUTED_NAME, JSOP_NOP, pos, expr);
|
||||
}
|
||||
|
||||
ParseNode* newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NullaryNode>(PNK_OBJECT_PROPERTY_NAME, JSOP_NOP, pos, atom);
|
||||
NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NameNode>(PNK_OBJECT_PROPERTY_NAME, JSOP_NOP, atom, pos);
|
||||
}
|
||||
|
||||
ParseNode* newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) {
|
||||
ParseNode* pn = new_<NullaryNode>(PNK_NUMBER, pos);
|
||||
if (!pn)
|
||||
return nullptr;
|
||||
pn->initNumber(value, decimalPoint);
|
||||
return pn;
|
||||
NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) {
|
||||
return new_<NumericLiteral>(value, decimalPoint, pos);
|
||||
}
|
||||
|
||||
ParseNode* newBooleanLiteral(bool cond, const TokenPos& pos) {
|
||||
return new_<BooleanLiteral>(cond, pos);
|
||||
}
|
||||
|
||||
ParseNode* newStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NullaryNode>(PNK_STRING, JSOP_NOP, pos, atom);
|
||||
NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NameNode>(PNK_STRING, JSOP_NOP, atom, pos);
|
||||
}
|
||||
|
||||
ParseNode* newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NullaryNode>(PNK_TEMPLATE_STRING, JSOP_NOP, pos, atom);
|
||||
NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
return new_<NameNode>(PNK_TEMPLATE_STRING, JSOP_NOP, atom, pos);
|
||||
}
|
||||
|
||||
CallSiteNodeType newCallSiteObject(uint32_t begin) {
|
||||
|
|
@ -211,7 +207,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
// Specifically, a Boxer has a .newObjectBox(T) method that accepts a
|
||||
// Rooted<RegExpObject*> argument and returns an ObjectBox*.
|
||||
template <class Boxer>
|
||||
ParseNode* newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) {
|
||||
RegExpLiteralType newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) {
|
||||
ObjectBox* objbox = boxer.newObjectBox(reobj);
|
||||
if (!objbox)
|
||||
return null();
|
||||
|
|
@ -421,11 +417,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool addShorthand(ListNodeType literal, ParseNode* name, ParseNode* expr) {
|
||||
MOZ_MUST_USE bool addShorthand(ListNodeType literal, NameNodeType name, NameNodeType expr) {
|
||||
MOZ_ASSERT(literal->isKind(PNK_OBJECT));
|
||||
MOZ_ASSERT(name->isKind(PNK_OBJECT_PROPERTY_NAME));
|
||||
MOZ_ASSERT(expr->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(name->pn_atom == expr->pn_atom);
|
||||
MOZ_ASSERT(name->atom() == expr->atom());
|
||||
|
||||
literal->setHasNonConstInitializer();
|
||||
BinaryNode* propdef = newBinary(PNK_SHORTHAND, name, expr, JSOP_INITPROP);
|
||||
|
|
@ -446,7 +442,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node key, Node fn,
|
||||
MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node key, CodeNodeType funNode,
|
||||
JSOp op)
|
||||
{
|
||||
MOZ_ASSERT(key->isKind(PNK_NUMBER) ||
|
||||
|
|
@ -455,14 +451,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
key->isKind(PNK_COMPUTED_NAME));
|
||||
literal->setHasNonConstInitializer();
|
||||
|
||||
ParseNode* propdef = newBinary(PNK_COLON, key, fn, op);
|
||||
ParseNode* propdef = newBinary(PNK_COLON, key, funNode, op);
|
||||
if (!propdef)
|
||||
return false;
|
||||
literal->append(propdef);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType methodList, Node key, Node fn,
|
||||
MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType methodList, Node key, CodeNodeType funNode,
|
||||
JSOp op, bool isStatic)
|
||||
{
|
||||
MOZ_ASSERT(methodList->isKind(PNK_CLASSMETHODLIST));
|
||||
|
|
@ -471,7 +467,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
key->isKind(PNK_STRING) ||
|
||||
key->isKind(PNK_COMPUTED_NAME));
|
||||
|
||||
ClassMethod* classMethod = new_<ClassMethod>(key, fn, op, isStatic);
|
||||
ClassMethod* classMethod = new_<ClassMethod>(key, funNode, op, isStatic);
|
||||
if (!classMethod)
|
||||
return false;
|
||||
methodList->append(classMethod);
|
||||
|
|
@ -679,7 +675,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
expr, body);
|
||||
}
|
||||
|
||||
ParseNode* newLabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin) {
|
||||
LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) {
|
||||
return new_<LabeledStatement>(label, stmt, begin);
|
||||
}
|
||||
|
||||
|
|
@ -698,11 +694,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return new_<DebuggerStatement>(pos);
|
||||
}
|
||||
|
||||
ParseNode* newPropertyName(PropertyName* name, const TokenPos& pos) {
|
||||
NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) {
|
||||
return new_<NameNode>(PNK_PROPERTYNAME, JSOP_NOP, name, pos);
|
||||
}
|
||||
|
||||
PropertyAccessType newPropertyAccess(Node expr, Node key) {
|
||||
PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
|
||||
return new_<PropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end);
|
||||
}
|
||||
|
||||
|
|
@ -710,7 +706,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return new_<PropertyByValue>(lhs, index, lhs->pn_pos.begin, end);
|
||||
}
|
||||
|
||||
ParseNode* newOptionalPropertyAccess(ParseNode* expr, ParseNode* key) {
|
||||
ParseNode* newOptionalPropertyAccess(Node expr, NameNodeType key) {
|
||||
return new_<OptionalPropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end);
|
||||
}
|
||||
|
||||
|
|
@ -722,8 +718,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
ParseNode* catchBinding, ParseNode* catchGuard,
|
||||
ParseNode* catchBody);
|
||||
|
||||
inline MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(ParseNode* funcpn,
|
||||
ParseNode* pn);
|
||||
inline MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(CodeNodeType funNode,
|
||||
Node defaultValue);
|
||||
inline void setLastFunctionFormalParameterDestructuring(ParseNode* funcpn, ParseNode* pn);
|
||||
|
||||
void checkAndSetIsDirectRHSAnonFunction(ParseNode* pn) {
|
||||
|
|
@ -731,44 +727,44 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
pn->setDirectRHSAnonFunction(true);
|
||||
}
|
||||
|
||||
ParseNode* newFunctionStatement() {
|
||||
CodeNodeType newFunctionStatement() {
|
||||
return new_<CodeNode>(PNK_FUNCTION, JSOP_NOP, pos());
|
||||
}
|
||||
|
||||
ParseNode* newFunctionExpression() {
|
||||
CodeNodeType newFunctionExpression() {
|
||||
return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA, pos());
|
||||
}
|
||||
|
||||
ParseNode* newArrowFunction() {
|
||||
CodeNodeType newArrowFunction() {
|
||||
return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA_ARROW, pos());
|
||||
}
|
||||
|
||||
bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) {
|
||||
bool setComprehensionLambdaBody(CodeNodeType funNode, ListNodeType body) {
|
||||
MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
|
||||
ParseNode* paramsBody = newList(PNK_PARAMSBODY, body);
|
||||
ListNode* paramsBody = newList(PNK_PARAMSBODY, body);
|
||||
if (!paramsBody)
|
||||
return false;
|
||||
setFunctionFormalParametersAndBody(pn, paramsBody);
|
||||
setFunctionFormalParametersAndBody(funNode, paramsBody);
|
||||
return true;
|
||||
}
|
||||
void setFunctionFormalParametersAndBody(ParseNode* pn, ParseNode* kid) {
|
||||
MOZ_ASSERT_IF(kid, kid->isKind(PNK_PARAMSBODY));
|
||||
pn->pn_body = kid;
|
||||
void setFunctionFormalParametersAndBody(CodeNodeType funNode, ListNodeType paramsBody) {
|
||||
MOZ_ASSERT_IF(paramsBody, paramsBody->isKind(PNK_PARAMSBODY));
|
||||
funNode->setBody(paramsBody);
|
||||
}
|
||||
void setFunctionBox(ParseNode* pn, FunctionBox* funbox) {
|
||||
MOZ_ASSERT(pn->isKind(PNK_FUNCTION));
|
||||
pn->pn_funbox = funbox;
|
||||
funbox->functionNode = pn;
|
||||
void setFunctionBox(CodeNodeType funNode, FunctionBox* funbox) {
|
||||
MOZ_ASSERT(funNode->isKind(PNK_FUNCTION));
|
||||
funNode->setFunbox(funbox);
|
||||
funbox->functionNode = funNode;
|
||||
}
|
||||
void addFunctionFormalParameter(ParseNode* pn, ParseNode* argpn) {
|
||||
addList(/* list = */ &pn->pn_body->as<ListNode>(), /* child = */ argpn);
|
||||
void addFunctionFormalParameter(CodeNodeType funNode, Node argpn) {
|
||||
addList(/* list = */ funNode->body(), /* child = */ argpn);
|
||||
}
|
||||
void setFunctionBody(ParseNode* fn, ParseNode* body) {
|
||||
MOZ_ASSERT(fn->pn_body->isKind(PNK_PARAMSBODY));
|
||||
addList(/* list = */ &fn->pn_body->as<ListNode>(), /* child = */ body);
|
||||
void setFunctionBody(CodeNodeType funNode, Node body) {
|
||||
MOZ_ASSERT(funNode->body()->isKind(PNK_PARAMSBODY));
|
||||
addList(/* list = */ funNode->body(), /* child = */ body);
|
||||
}
|
||||
|
||||
ParseNode* newModule() {
|
||||
CodeNodeType newModule() {
|
||||
return new_<CodeNode>(PNK_MODULE, JSOP_NOP, pos());
|
||||
}
|
||||
|
||||
|
|
@ -827,7 +823,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return node->isKind(PNK_SUPERBASE);
|
||||
}
|
||||
|
||||
inline MOZ_MUST_USE bool finishInitializerAssignment(ParseNode* pn, ParseNode* init);
|
||||
inline MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode, Node init);
|
||||
|
||||
void setBeginPosition(ParseNode* pn, ParseNode* oth) {
|
||||
setBeginPosition(pn, oth->pn_pos.begin);
|
||||
|
|
@ -909,12 +905,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
void setListHasNonConstInitializer(ListNodeType literal) {
|
||||
literal->setHasNonConstInitializer();
|
||||
}
|
||||
MOZ_MUST_USE ParseNode* parenthesize(ParseNode* pn) {
|
||||
pn->setInParens(true);
|
||||
return pn;
|
||||
template <typename NodeType>
|
||||
MOZ_MUST_USE NodeType parenthesize(NodeType node) {
|
||||
node->setInParens(true);
|
||||
return node;
|
||||
}
|
||||
MOZ_MUST_USE ParseNode* setLikelyIIFE(ParseNode* pn) {
|
||||
return parenthesize(pn);
|
||||
template <typename NodeType>
|
||||
MOZ_MUST_USE NodeType setLikelyIIFE(NodeType node) {
|
||||
return parenthesize(node);
|
||||
}
|
||||
void setInDirectivePrologue(UnaryNodeType exprStmt) {
|
||||
exprStmt->setIsDirectivePrologueMember();
|
||||
|
|
@ -933,11 +931,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
}
|
||||
|
||||
bool isArgumentsAnyParentheses(ParseNode* node, ExclusiveContext* cx) {
|
||||
return node->isKind(PNK_NAME) && node->pn_atom == cx->names().arguments;
|
||||
return node->isKind(PNK_NAME) && node->as<NameNode>().atom() == cx->names().arguments;
|
||||
}
|
||||
|
||||
bool isEvalAnyParentheses(ParseNode* node, ExclusiveContext* cx) {
|
||||
return node->isKind(PNK_NAME) && node->pn_atom == cx->names().eval;
|
||||
return node->isKind(PNK_NAME) && node->as<NameNode>().atom() == cx->names().eval;
|
||||
}
|
||||
|
||||
const char* nameIsArgumentsEvalAnyParentheses(ParseNode* node, ExclusiveContext* cx) {
|
||||
|
|
@ -954,7 +952,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
bool isAsyncKeyword(ParseNode* node, ExclusiveContext* cx) {
|
||||
return node->isKind(PNK_NAME) &&
|
||||
node->pn_pos.begin + strlen("async") == node->pn_pos.end &&
|
||||
node->pn_atom == cx->names().async;
|
||||
node->as<NameNode>().atom() == cx->names().async;
|
||||
}
|
||||
|
||||
bool isCall(ParseNode* pn) {
|
||||
|
|
@ -1016,9 +1014,10 @@ FullParseHandler::addCatchBlock(ListNodeType catchList, ParseNode* lexicalScope,
|
|||
}
|
||||
|
||||
inline bool
|
||||
FullParseHandler::setLastFunctionFormalParameterDefault(ParseNode* funcpn, ParseNode* defaultValue)
|
||||
FullParseHandler::setLastFunctionFormalParameterDefault(CodeNodeType funNode, Node defaultValue)
|
||||
{
|
||||
ListNode* body = &funcpn->pn_body->as<ListNode>();
|
||||
MOZ_ASSERT(funNode->isKind(PNK_FUNCTION));
|
||||
ListNode* body = funNode->body();
|
||||
ParseNode* arg = body->last();
|
||||
ParseNode* pn = newBinary(PNK_ASSIGN, arg, defaultValue, JSOP_NOP);
|
||||
if (!pn)
|
||||
|
|
@ -1032,13 +1031,16 @@ FullParseHandler::setLastFunctionFormalParameterDefault(ParseNode* funcpn, Parse
|
|||
}
|
||||
|
||||
inline bool
|
||||
FullParseHandler::finishInitializerAssignment(ParseNode* pn, ParseNode* init)
|
||||
FullParseHandler::finishInitializerAssignment(NameNodeType nameNode, Node init)
|
||||
{
|
||||
pn->pn_expr = init;
|
||||
pn->setOp(JSOP_SETNAME);
|
||||
MOZ_ASSERT(nameNode->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!nameNode->isInParens());
|
||||
|
||||
nameNode->setInitializer(init);
|
||||
nameNode->setOp(JSOP_SETNAME);
|
||||
|
||||
/* The declarator's position must include the initializer. */
|
||||
pn->pn_pos.end = init->pn_pos.end;
|
||||
nameNode->pn_pos.end = init->pn_pos.end;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,12 +79,12 @@ class NameResolver
|
|||
return false;
|
||||
if (!*foundName)
|
||||
return true;
|
||||
return appendPropertyReference(prop->right()->pn_atom);
|
||||
return appendPropertyReference(prop->right()->as<NameNode>().atom());
|
||||
}
|
||||
|
||||
case PNK_NAME:
|
||||
*foundName = true;
|
||||
return buf->append(n->pn_atom);
|
||||
return buf->append(n->as<NameNode>().atom());
|
||||
|
||||
case PNK_THIS:
|
||||
*foundName = true;
|
||||
|
|
@ -105,7 +105,7 @@ class NameResolver
|
|||
|
||||
case PNK_NUMBER:
|
||||
*foundName = true;
|
||||
return appendNumber(n->pn_dval);
|
||||
return appendNumber(n->as<NumericLiteral>().value());
|
||||
|
||||
default:
|
||||
/* We're confused as to what to call this function. */
|
||||
|
|
@ -190,11 +190,10 @@ class NameResolver
|
|||
* listed, then it is skipped. Otherwise an intelligent name is guessed to
|
||||
* assign to the function's displayAtom field.
|
||||
*/
|
||||
bool resolveFun(ParseNode* pn, HandleAtom prefix, MutableHandleAtom retAtom) {
|
||||
MOZ_ASSERT(pn != nullptr);
|
||||
MOZ_ASSERT(pn->isKind(PNK_FUNCTION));
|
||||
MOZ_ASSERT(pn->isArity(PN_CODE));
|
||||
RootedFunction fun(cx, pn->pn_funbox->function());
|
||||
bool resolveFun(CodeNode* funNode, HandleAtom prefix, MutableHandleAtom retAtom) {
|
||||
MOZ_ASSERT(funNode != nullptr);
|
||||
MOZ_ASSERT(funNode->isKind(PNK_FUNCTION));
|
||||
RootedFunction fun(cx, funNode->funbox()->function());
|
||||
|
||||
StringBuffer buf(cx);
|
||||
this->buf = &buf;
|
||||
|
|
@ -246,10 +245,10 @@ class NameResolver
|
|||
if (node->isKind(PNK_COLON) || node->isKind(PNK_SHORTHAND)) {
|
||||
ParseNode* left = node->as<BinaryNode>().left();
|
||||
if (left->isKind(PNK_OBJECT_PROPERTY_NAME) || left->isKind(PNK_STRING)) {
|
||||
if (!appendPropertyReference(left->pn_atom))
|
||||
if (!appendPropertyReference(left->as<NameNode>().atom()))
|
||||
return false;
|
||||
} else if (left->isKind(PNK_NUMBER)) {
|
||||
if (!appendNumericPropertyReference(left->pn_dval))
|
||||
if (!appendNumericPropertyReference(left->as<NumericLiteral>().value()))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(left->isKind(PNK_COMPUTED_NAME));
|
||||
|
|
@ -360,10 +359,10 @@ class NameResolver
|
|||
if (cur == nullptr)
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT((cur->isKind(PNK_FUNCTION) || cur->isKind(PNK_MODULE)) == cur->isArity(PN_CODE));
|
||||
MOZ_ASSERT((cur->isKind(PNK_FUNCTION) || cur->isKind(PNK_MODULE)) == cur->is<CodeNode>());
|
||||
if (cur->isKind(PNK_FUNCTION)) {
|
||||
RootedAtom prefix2(cx);
|
||||
if (!resolveFun(cur, prefix, &prefix2))
|
||||
if (!resolveFun(&cur->as<CodeNode>(), prefix, &prefix2))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
|
@ -383,29 +382,39 @@ class NameResolver
|
|||
// Nodes with no children that might require name resolution need no
|
||||
// further work.
|
||||
case PNK_NOP:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_REGEXP:
|
||||
case PNK_TRUE:
|
||||
case PNK_FALSE:
|
||||
case PNK_NULL:
|
||||
case PNK_RAW_UNDEFINED:
|
||||
case PNK_ELISION:
|
||||
case PNK_GENERATOR:
|
||||
case PNK_NUMBER:
|
||||
case PNK_BREAK:
|
||||
case PNK_CONTINUE:
|
||||
case PNK_DEBUGGER:
|
||||
case PNK_EXPORT_BATCH_SPEC:
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_POSHOLDER:
|
||||
MOZ_ASSERT(cur->isArity(PN_NULLARY));
|
||||
break;
|
||||
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
MOZ_ASSERT(cur->is<NameNode>());
|
||||
break;
|
||||
|
||||
case PNK_REGEXP:
|
||||
MOZ_ASSERT(cur->is<RegExpLiteral>());
|
||||
break;
|
||||
|
||||
case PNK_NUMBER:
|
||||
MOZ_ASSERT(cur->is<NumericLiteral>());
|
||||
break;
|
||||
|
||||
|
||||
case PNK_TYPEOFNAME:
|
||||
case PNK_SUPERBASE:
|
||||
MOZ_ASSERT(cur->as<UnaryNode>().kid()->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!cur->as<UnaryNode>().kid()->expr());
|
||||
MOZ_ASSERT(!cur->as<UnaryNode>().kid()->as<NameNode>().initializer());
|
||||
break;
|
||||
|
||||
case PNK_NEWTARGET: {
|
||||
|
|
@ -612,14 +621,14 @@ class NameResolver
|
|||
#ifdef DEBUG
|
||||
if (classNode->names()) {
|
||||
ClassNames* names = classNode->names();
|
||||
if (ParseNode* outerBinding = names->outerBinding()) {
|
||||
if (NameNode* outerBinding = names->outerBinding()) {
|
||||
MOZ_ASSERT(outerBinding->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!outerBinding->expr());
|
||||
MOZ_ASSERT(!outerBinding->initializer());
|
||||
}
|
||||
|
||||
ParseNode* innerBinding = names->innerBinding();
|
||||
NameNode* innerBinding = names->innerBinding();
|
||||
MOZ_ASSERT(innerBinding->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!innerBinding->expr());
|
||||
MOZ_ASSERT(!innerBinding->initializer());
|
||||
}
|
||||
#endif
|
||||
if (ParseNode* heritage = classNode->heritage()) {
|
||||
|
|
@ -799,9 +808,9 @@ class NameResolver
|
|||
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->left()->as<NameNode>().initializer());
|
||||
MOZ_ASSERT(spec->right()->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(!spec->right()->expr());
|
||||
MOZ_ASSERT(!spec->right()->as<NameNode>().initializer());
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
|
@ -832,15 +841,15 @@ class NameResolver
|
|||
}
|
||||
|
||||
case PNK_LABEL:
|
||||
MOZ_ASSERT(cur->isArity(PN_NAME));
|
||||
if (!resolve(cur->expr(), prefix))
|
||||
if (!resolve(cur->as<LabeledStatement>().statement(), prefix))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case PNK_NAME:
|
||||
MOZ_ASSERT(cur->isArity(PN_NAME));
|
||||
if (!resolve(cur->expr(), prefix))
|
||||
return false;
|
||||
if (ParseNode* init = cur->as<NameNode>().initializer()) {
|
||||
if (!resolve(init, prefix))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case PNK_LEXICALSCOPE:
|
||||
|
|
@ -851,9 +860,10 @@ class NameResolver
|
|||
|
||||
case PNK_FUNCTION:
|
||||
case PNK_MODULE:
|
||||
MOZ_ASSERT(cur->isArity(PN_CODE));
|
||||
if (!resolve(cur->pn_body, prefix))
|
||||
return false;
|
||||
if (ParseNode* body = cur->as<CodeNode>().body()) {
|
||||
if (!resolve(body, prefix))
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
// Kinds that should be handled by parent node resolution.
|
||||
|
|
|
|||
|
|
@ -17,17 +17,12 @@ inline PropertyName*
|
|||
ParseNode::name() const
|
||||
{
|
||||
MOZ_ASSERT(isKind(PNK_FUNCTION) || isKind(PNK_NAME));
|
||||
JSAtom* atom = isKind(PNK_FUNCTION) ? pn_funbox->function()->explicitName() : pn_atom;
|
||||
JSAtom* atom = isKind(PNK_FUNCTION)
|
||||
? as<CodeNode>().funbox()->function()->explicitName()
|
||||
: as<NameNode>().atom();
|
||||
return atom->asPropertyName();
|
||||
}
|
||||
|
||||
inline JSAtom*
|
||||
ParseNode::atom() const
|
||||
{
|
||||
MOZ_ASSERT(isKind(PNK_STRING));
|
||||
return pn_atom;
|
||||
}
|
||||
|
||||
} /* namespace frontend */
|
||||
} /* namespace js */
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class NodeStack {
|
|||
enum class PushResult { Recyclable, CleanUpLater };
|
||||
|
||||
static PushResult
|
||||
PushCodeNodeChildren(ParseNode* node, NodeStack* stack)
|
||||
PushCodeNodeChildren(CodeNode* node, NodeStack* stack)
|
||||
{
|
||||
MOZ_ASSERT(node->isArity(PN_CODE));
|
||||
|
||||
|
|
@ -108,29 +108,27 @@ PushCodeNodeChildren(ParseNode* node, NodeStack* stack)
|
|||
*
|
||||
* In fact, we can't recycle the parse node yet, either: it may appear
|
||||
* on a method list, and reusing the node would corrupt that. Instead,
|
||||
* we clear its pn_funbox pointer to mark it as deleted;
|
||||
* we clear its funbox pointer to mark it as deleted;
|
||||
* CleanFunctionList recycles it as well.
|
||||
*
|
||||
* We do recycle the nodes around it, though, so we must clear pointers
|
||||
* to them to avoid leaving dangling references where someone can find
|
||||
* them.
|
||||
*/
|
||||
node->pn_funbox = nullptr;
|
||||
if (node->pn_body)
|
||||
stack->push(node->pn_body);
|
||||
node->pn_body = nullptr;
|
||||
node->setFunbox(nullptr);
|
||||
if (node->body())
|
||||
stack->push(node->body());
|
||||
node->setBody(nullptr);
|
||||
|
||||
return PushResult::CleanUpLater;
|
||||
}
|
||||
|
||||
static PushResult
|
||||
PushNameNodeChildren(ParseNode* node, NodeStack* stack)
|
||||
PushNameNodeChildren(NameNode* node, NodeStack* stack)
|
||||
{
|
||||
MOZ_ASSERT(node->isArity(PN_NAME));
|
||||
|
||||
if (node->pn_expr)
|
||||
stack->push(node->pn_expr);
|
||||
node->pn_expr = nullptr;
|
||||
if (node->initializer())
|
||||
stack->push(node->initializer());
|
||||
node->setInitializer(nullptr);
|
||||
return PushResult::Recyclable;
|
||||
}
|
||||
|
||||
|
|
@ -179,25 +177,34 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
|||
// Trivial nodes that refer to no nodes, are referred to by nothing
|
||||
// but their parents, are never used, and are never a definition.
|
||||
case PNK_NOP:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_REGEXP:
|
||||
case PNK_TRUE:
|
||||
case PNK_FALSE:
|
||||
case PNK_NULL:
|
||||
case PNK_RAW_UNDEFINED:
|
||||
case PNK_ELISION:
|
||||
case PNK_GENERATOR:
|
||||
case PNK_NUMBER:
|
||||
case PNK_BREAK:
|
||||
case PNK_CONTINUE:
|
||||
case PNK_DEBUGGER:
|
||||
case PNK_EXPORT_BATCH_SPEC:
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_POSHOLDER:
|
||||
MOZ_ASSERT(pn->isArity(PN_NULLARY));
|
||||
return PushResult::Recyclable;
|
||||
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
MOZ_ASSERT(pn->is<NameNode>());
|
||||
return PushResult::Recyclable;
|
||||
|
||||
case PNK_REGEXP:
|
||||
MOZ_ASSERT(pn->is<RegExpLiteral>());
|
||||
return PushResult::Recyclable;
|
||||
|
||||
case PNK_NUMBER:
|
||||
MOZ_ASSERT(pn->is<NumericLiteral>());
|
||||
return PushResult::Recyclable;
|
||||
|
||||
// Nodes with a single non-null child.
|
||||
case PNK_TYPEOFNAME:
|
||||
case PNK_TYPEOFEXPR:
|
||||
|
|
@ -489,14 +496,14 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
|||
case PNK_LABEL:
|
||||
case PNK_NAME:
|
||||
case PNK_PROPERTYNAME:
|
||||
return PushNameNodeChildren(pn, stack);
|
||||
return PushNameNodeChildren(&pn->as<NameNode>(), stack);
|
||||
|
||||
case PNK_LEXICALSCOPE:
|
||||
return PushScopeNodeChildren(pn, stack);
|
||||
|
||||
case PNK_FUNCTION:
|
||||
case PNK_MODULE:
|
||||
return PushCodeNodeChildren(pn, stack);
|
||||
return PushCodeNodeChildren(&pn->as<CodeNode>(), stack);
|
||||
|
||||
case PNK_LIMIT: // invalid sentinel value
|
||||
MOZ_CRASH("invalid node kind");
|
||||
|
|
@ -656,33 +663,37 @@ ParseNode::dump(int indent)
|
|||
switch (pn_arity) {
|
||||
case PN_NULLARY:
|
||||
((NullaryNode*) this)->dump();
|
||||
break;
|
||||
return;
|
||||
case PN_UNARY:
|
||||
as<UnaryNode>().dump(indent);
|
||||
break;
|
||||
return;
|
||||
case PN_BINARY:
|
||||
as<BinaryNode>().dump(indent);
|
||||
break;
|
||||
return;
|
||||
case PN_TERNARY:
|
||||
as<TernaryNode>().dump(indent);
|
||||
break;
|
||||
return;
|
||||
case PN_CODE:
|
||||
((CodeNode*) this)->dump(indent);
|
||||
break;
|
||||
as<CodeNode>().dump(indent);
|
||||
return;
|
||||
case PN_LIST:
|
||||
as<ListNode>().dump(indent);
|
||||
break;
|
||||
return;
|
||||
case PN_NAME:
|
||||
((NameNode*) this)->dump(indent);
|
||||
break;
|
||||
as<NameNode>().dump(indent);
|
||||
return;
|
||||
case PN_NUMBER:
|
||||
as<NumericLiteral>().dump(indent);
|
||||
return;
|
||||
case PN_REGEXP:
|
||||
as<RegExpLiteral>().dump(indent);
|
||||
return;
|
||||
case PN_SCOPE:
|
||||
((LexicalScopeNode*) this)->dump(indent);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "#<BAD NODE %p, kind=%u, arity=%u>",
|
||||
(void*) this, unsigned(getKind()), unsigned(pn_arity));
|
||||
break;
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "#<BAD NODE %p, kind=%u, arity=%u>",
|
||||
(void*) this, unsigned(getKind()), unsigned(pn_arity));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -694,27 +705,32 @@ NullaryNode::dump()
|
|||
case PNK_NULL: fprintf(stderr, "#null"); break;
|
||||
case PNK_RAW_UNDEFINED: fprintf(stderr, "#undefined"); break;
|
||||
|
||||
case PNK_NUMBER: {
|
||||
ToCStringBuf cbuf;
|
||||
const char* cstr = NumberToCString(nullptr, &cbuf, pn_dval);
|
||||
if (!IsFinite(pn_dval))
|
||||
fputc('#', stderr);
|
||||
if (cstr)
|
||||
fprintf(stderr, "%s", cstr);
|
||||
else
|
||||
fprintf(stderr, "%g", pn_dval);
|
||||
break;
|
||||
}
|
||||
|
||||
case PNK_STRING:
|
||||
pn_atom->dumpCharsNoNewline();
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "(%s)", parseNodeNames[getKind()]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NumericLiteral::dump(int indent)
|
||||
{
|
||||
ToCStringBuf cbuf;
|
||||
const char* cstr = NumberToCString(nullptr, &cbuf, value());
|
||||
if (!IsFinite(value())) {
|
||||
fprintf(stderr, "#");
|
||||
}
|
||||
if (cstr) {
|
||||
fprintf(stderr, "%s", cstr);
|
||||
} else {
|
||||
fprintf(stderr, "%g", value());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegExpLiteral::dump(int indent)
|
||||
{
|
||||
fprintf(stderr, "(%s)", parseNodeNames[size_t(getKind())]);
|
||||
}
|
||||
|
||||
void
|
||||
UnaryNode::dump(int indent)
|
||||
{
|
||||
|
|
@ -772,7 +788,7 @@ CodeNode::dump(int indent)
|
|||
const char* name = parseNodeNames[getKind()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(pn_body, indent);
|
||||
DumpParseTree(body(), indent);
|
||||
fprintf(stderr, ")");
|
||||
}
|
||||
|
||||
|
|
@ -813,29 +829,53 @@ DumpName(const CharT* s, size_t len)
|
|||
void
|
||||
NameNode::dump(int indent)
|
||||
{
|
||||
if (isKind(PNK_NAME) || isKind(PNK_PROPERTYNAME)) {
|
||||
if (!pn_atom) {
|
||||
switch (getKind()) {
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
case PNK_OBJECT_PROPERTY_NAME: {
|
||||
atom()->dumpCharsNoNewline();
|
||||
return;
|
||||
}
|
||||
|
||||
case PNK_NAME:
|
||||
case PNK_PROPERTYNAME: {
|
||||
if (!atom()) {
|
||||
fprintf(stderr, "#<null name>");
|
||||
} else if (getOp() == JSOP_GETARG && pn_atom->length() == 0) {
|
||||
} else if (getOp() == JSOP_GETARG && atom()->length() == 0) {
|
||||
// Dump destructuring parameter.
|
||||
fprintf(stderr, "(#<zero-length name> ");
|
||||
DumpParseTree(expr(), indent + 21);
|
||||
static const char ZeroLengthPrefix[] = "(#<zero-length name> ";
|
||||
fprintf(stderr, ZeroLengthPrefix);
|
||||
DumpParseTree(initializer(), indent + strlen(ZeroLengthPrefix));
|
||||
fputc(')', stderr);
|
||||
} else {
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
if (pn_atom->hasLatin1Chars())
|
||||
DumpName(pn_atom->latin1Chars(nogc), pn_atom->length());
|
||||
if (atom()->hasLatin1Chars())
|
||||
DumpName(atom()->latin1Chars(nogc), atom()->length());
|
||||
else
|
||||
DumpName(pn_atom->twoByteChars(nogc), pn_atom->length());
|
||||
DumpName(atom()->twoByteChars(nogc), atom()->length());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const char* name = parseNodeNames[getKind()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(expr(), indent);
|
||||
fprintf(stderr, ")");
|
||||
case PNK_LABEL: {
|
||||
const char* name = parseNodeNames[getKind()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
atom()->dumpCharsNoNewline();
|
||||
indent += strlen(name) + atom()->length() + 2;
|
||||
DumpParseTree(initializer(), indent);
|
||||
fprintf(stderr, ")");
|
||||
return;
|
||||
}
|
||||
|
||||
default: {
|
||||
const char* name = parseNodeNames[getKind()];
|
||||
fprintf(stderr, "(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(initializer(), indent);
|
||||
fprintf(stderr, ")");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -920,7 +960,8 @@ js::frontend::IsAnonymousFunctionDefinition(ParseNode* pn)
|
|||
// 14.1.12 (FunctionExpression).
|
||||
// 14.4.8 (GeneratorExpression).
|
||||
// 14.6.8 (AsyncFunctionExpression)
|
||||
if (pn->isKind(PNK_FUNCTION) && !pn->pn_funbox->function()->explicitName())
|
||||
if (pn->isKind(PNK_FUNCTION) &&
|
||||
!pn->as<CodeNode>().funbox()->function()->explicitName())
|
||||
return true;
|
||||
|
||||
// 14.5.8 (ClassExpression)
|
||||
|
|
|
|||
|
|
@ -221,21 +221,21 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
|
||||
/*
|
||||
* <Definitions>
|
||||
* PNK_FUNCTION name pn_funbox: ptr to js::FunctionBox holding function
|
||||
* object containing arg and var properties. We
|
||||
* create the function object at parse (not emit)
|
||||
* time to specialize arg and var bytecodes early.
|
||||
* pn_body: PNK_PARAMSBODY, ordinarily;
|
||||
* PNK_LEXICALSCOPE for implicit function in genexpr
|
||||
* PNK_FUNCTION (CodeNode)
|
||||
* funbox: ptr to js::FunctionBox holding function object containing arg and
|
||||
* var properties. We create the function object at parse (not emit)
|
||||
* time to specialize arg and var bytecodes early.
|
||||
* body: PNK_PARAMSBODY or null for lazily-parsed function, ordinarily;
|
||||
* PNK_LEXICALSCOPE for implicit function in genexpr
|
||||
* PNK_PARAMSBODY (ListNode)
|
||||
* head: list of formal parameters with
|
||||
* * Name node with non-empty name for SingleNameBinding without
|
||||
* Initializer
|
||||
* * Assign node for SingleNameBinding with Initializer
|
||||
* * Name node with empty name for destructuring
|
||||
* pn_expr: Array or Object for BindingPattern without
|
||||
* Initializer, Assign for BindingPattern with
|
||||
* Initializer
|
||||
* expr: Array or Object for BindingPattern without
|
||||
* Initializer, Assign for BindingPattern with
|
||||
* Initializer
|
||||
* followed by either:
|
||||
* * StatementList node for function body statements
|
||||
* * Return for expression closure
|
||||
|
|
@ -259,6 +259,9 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
* PNK_CLASSMETHOD (ClassMethod)
|
||||
* name: propertyName
|
||||
* method: methodDefinition
|
||||
* PNK_MODULE (CodeNode)
|
||||
* funbox: ?
|
||||
* body: ?
|
||||
*
|
||||
* <Statements>
|
||||
* PNK_STATEMENTLIST (ListNode)
|
||||
|
|
@ -310,31 +313,29 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
* kid2: null or PNK_CATCHLIST list
|
||||
* kid3: null or finally block
|
||||
* PNK_CATCHLIST list pn_head: list of PNK_LEXICALSCOPE nodes, one per
|
||||
* catch-block, each with pn_expr pointing
|
||||
* catch-block, each with scopeBody pointing
|
||||
* to a PNK_CATCH node
|
||||
* PNK_CATCH (TernaryNode)
|
||||
* kid1: PNK_NAME, PNK_ARRAY, or PNK_OBJECT catch binding node (PNK_ARRAY or PNK_OBJECT if destructuring)
|
||||
or null if optional catch binding
|
||||
* kid2: null or the catch guard expression
|
||||
* kid3: catch block statements
|
||||
* PNK_BREAK name pn_atom: label or null
|
||||
* PNK_CONTINUE name pn_atom: label or null
|
||||
* PNK_BREAK (BreakStatement)
|
||||
* atom: label or null
|
||||
* PNK_CONTINUE (ContinueStatement)
|
||||
* atom: label or null
|
||||
* 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
|
||||
* pn_used: false
|
||||
* pn_atom: variable name
|
||||
* pn_expr: initializer or null
|
||||
* atom: variable name
|
||||
* expr: initializer or null
|
||||
* or
|
||||
* pn_used: true
|
||||
* pn_atom: variable name
|
||||
* pn_lexdef: def node
|
||||
* atom: variable name
|
||||
* each assignment node has
|
||||
* left: Name with pn_used true and
|
||||
* pn_lexdef (NOT pn_expr) set
|
||||
* left: pattern
|
||||
* right: initializer
|
||||
* count: N > 0
|
||||
* PNK_RETURN (UnaryNode)
|
||||
|
|
@ -343,7 +344,11 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
* kid: expr
|
||||
* prologue: true if Directive Prologue member in original source, not
|
||||
* introduced via constant folding or other tree rewriting
|
||||
* PNK_LABEL name pn_atom: label, pn_expr: labeled statement
|
||||
* PNK_NOP (NullaryNode)
|
||||
* (no fields)
|
||||
* PNK_LABEL (LabeledStatement)
|
||||
* atom: label
|
||||
* expr: labeled statement
|
||||
* PNK_IMPORT (BinaryNode)
|
||||
* left: PNK_IMPORT_SPEC_LIST import specifiers
|
||||
* right: PNK_STRING module specifier
|
||||
|
|
@ -434,7 +439,8 @@ 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_PROPERTYNAME name pn_atom: property being accessed
|
||||
* PNK_PROPERTYNAME (NameNode)
|
||||
* atom: property name 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 '.'
|
||||
|
|
@ -472,17 +478,20 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
* ES6 ComputedPropertyName.
|
||||
* kid: the AssignmentExpression inside the square brackets
|
||||
* pn_kid: the AssignmentExpression inside the square brackets
|
||||
* PNK_NAME, name pn_atom: name, string, or object atom
|
||||
* PNK_STRING pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT
|
||||
* If JSOP_GETNAME, pn_op may be JSOP_*ARG or JSOP_*VAR
|
||||
* telling const-ness and static analysis results
|
||||
* PNK_NAME (NameNode)
|
||||
* atom: name, or object atom
|
||||
* pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT
|
||||
* If JSOP_GETNAME, pn_op may be JSOP_*ARG or JSOP_*VAR telling
|
||||
* const-ness and static analysis results
|
||||
* PNK_STRING (NameNode)
|
||||
* atom: string
|
||||
* PNK_TEMPLATE_STRING_LIST (ListNode)
|
||||
* head: list of alternating expr and template strings
|
||||
* TemplateString [, expression, TemplateString]+
|
||||
* there's at least one expression. If the template literal contains
|
||||
* no ${}-delimited expression, it's parsed as a single TemplateString
|
||||
* PNK_TEMPLATE_STRING pn_atom: template string atom
|
||||
nullary pn_op: JSOP_NOP
|
||||
* PNK_TEMPLATE_STRING (NameNode)
|
||||
* atom: template string atom
|
||||
* PNK_TAGGED_TEMPLATE (BinaryNode)
|
||||
* left: tag expression
|
||||
* right: Arguments, with the first being the call site object, then
|
||||
|
|
@ -493,8 +502,10 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
* Array [, cooked TemplateString]+
|
||||
* where the Array is
|
||||
* [raw TemplateString]+
|
||||
* PNK_REGEXP nullary pn_objbox: RegExp model object
|
||||
* PNK_NUMBER dval pn_dval: double value of numeric literal
|
||||
* PNK_REGEXP (RegExpLiteral)
|
||||
* regexp: RegExp model object
|
||||
* PNK_NUMBER (NumericLiteral)
|
||||
* value: double value of numeric literal
|
||||
* PNK_TRUE, nullary pn_op: JSOp bytecode
|
||||
* PNK_FALSE,
|
||||
* PNK_NULL,
|
||||
|
|
@ -528,13 +539,15 @@ IsTypeofKind(ParseNodeKind kind)
|
|||
*/
|
||||
enum ParseNodeArity
|
||||
{
|
||||
PN_NULLARY, /* 0 kids, only pn_atom/pn_dval/etc. */
|
||||
PN_NULLARY, /* 0 kids */
|
||||
PN_UNARY, /* one kid, plus a couple of scalars */
|
||||
PN_BINARY, /* two kids, plus a couple of scalars */
|
||||
PN_TERNARY, /* three kids */
|
||||
PN_CODE, /* module or function definition node */
|
||||
PN_LIST, /* generic singly linked list */
|
||||
PN_NAME, /* name, label, or regexp */
|
||||
PN_NAME, /* name, label, string */
|
||||
PN_NUMBER, /* numeric literal */
|
||||
PN_REGEXP, /* regexp literal */
|
||||
PN_SCOPE /* lexical scope */
|
||||
};
|
||||
|
||||
|
|
@ -549,9 +562,18 @@ enum ParseNodeArity
|
|||
macro(PropertyByValue, PropertyByValueType, asPropertyByValue) \
|
||||
macro(SwitchStatement, SwitchStatementType, asSwitchStatement) \
|
||||
\
|
||||
macro(CodeNode, CodeNodeType, asCode) \
|
||||
\
|
||||
macro(ListNode, ListNodeType, asList) \
|
||||
macro(CallSiteNode, CallSiteNodeType, asCallSite) \
|
||||
\
|
||||
macro(NameNode, NameNodeType, asName) \
|
||||
macro(LabeledStatement, LabeledStatementType, asLabeledStatement) \
|
||||
\
|
||||
macro(NumericLiteral, NumericLiteralType, asNumericLiteral) \
|
||||
\
|
||||
macro(RegExpLiteral, RegExpLiteralType, asRegExpLiteral) \
|
||||
\
|
||||
macro(TernaryNode, TernaryNodeType, asTernary) \
|
||||
macro(ClassNode, ClassNodeType, asClass) \
|
||||
macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression) \
|
||||
|
|
@ -683,19 +705,30 @@ class ParseNode
|
|||
bool prologue; /* directive prologue member */
|
||||
} unary;
|
||||
struct { /* name, labeled statement, etc. */
|
||||
union {
|
||||
JSAtom* atom; /* lexical name or label atom */
|
||||
ObjectBox* objbox; /* regexp object */
|
||||
FunctionBox* funbox; /* function object */
|
||||
};
|
||||
ParseNode* expr; /* module or function body, var
|
||||
initializer, or argument default */
|
||||
private:
|
||||
friend class NameNode;
|
||||
JSAtom* atom; /* lexical name or label atom */
|
||||
ParseNode* initOrStmt; /* var initializer, argument default,
|
||||
* or label statement target */
|
||||
} name;
|
||||
struct {
|
||||
private:
|
||||
friend class RegExpLiteral;
|
||||
ObjectBox* objbox;
|
||||
} regexp;
|
||||
struct {
|
||||
private:
|
||||
friend class CodeNode;
|
||||
FunctionBox* funbox; /* function object */
|
||||
ParseNode* body; /* module or function body */
|
||||
} code;
|
||||
struct {
|
||||
LexicalScope::Data* bindings;
|
||||
ParseNode* body;
|
||||
} scope;
|
||||
struct {
|
||||
private:
|
||||
friend class NumericLiteral;
|
||||
double value; /* aligned numeric literal value */
|
||||
DecimalPoint decimalPoint; /* Whether the number has a decimal point */
|
||||
} number;
|
||||
|
|
@ -705,15 +738,6 @@ class ParseNode
|
|||
} loopControl;
|
||||
} pn_u;
|
||||
|
||||
#define pn_objbox pn_u.name.objbox
|
||||
#define pn_funbox pn_u.name.funbox
|
||||
#define pn_body pn_u.name.expr
|
||||
#define pn_atom pn_u.name.atom
|
||||
#define pn_objbox pn_u.name.objbox
|
||||
#define pn_expr pn_u.name.expr
|
||||
#define pn_dval pn_u.number.value
|
||||
|
||||
|
||||
public:
|
||||
/*
|
||||
* If |left| is a list of the given kind/left-associative op, append
|
||||
|
|
@ -724,12 +748,6 @@ class ParseNode
|
|||
FullParseHandler* handler, ParseContext* pc);
|
||||
|
||||
inline PropertyName* name() const;
|
||||
inline JSAtom* atom() const;
|
||||
|
||||
ParseNode* expr() const {
|
||||
MOZ_ASSERT(pn_arity == PN_NAME || pn_arity == PN_CODE);
|
||||
return pn_expr;
|
||||
}
|
||||
|
||||
bool isEmptyScope() const {
|
||||
MOZ_ASSERT(pn_arity == PN_SCOPE);
|
||||
|
|
@ -753,18 +771,6 @@ class ParseNode
|
|||
pn_u.scope.body = body;
|
||||
}
|
||||
|
||||
bool functionIsHoisted() const {
|
||||
MOZ_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION);
|
||||
MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr
|
||||
isOp(JSOP_LAMBDA_ARROW) || // arrow function
|
||||
isOp(JSOP_DEFFUN) || // non-body-level function statement
|
||||
isOp(JSOP_NOP) || // body-level function stmt in global code
|
||||
isOp(JSOP_GETLOCAL) || // body-level function stmt in function code
|
||||
isOp(JSOP_GETARG) || // body-level function redeclaring formal
|
||||
isOp(JSOP_INITLEXICAL)); // block-level function stmt
|
||||
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
|
||||
}
|
||||
|
||||
/* True if pn is a parsenode representing a literal constant. */
|
||||
bool isLiteral() const {
|
||||
return isKind(PNK_NUMBER) ||
|
||||
|
|
@ -778,13 +784,6 @@ class ParseNode
|
|||
// True iff this is a for-in/of loop variable declaration (var/let/const).
|
||||
bool isForLoopDeclaration() const;
|
||||
|
||||
void initNumber(double value, DecimalPoint decimalPoint) {
|
||||
MOZ_ASSERT(pn_arity == PN_NULLARY);
|
||||
MOZ_ASSERT(getKind() == PNK_NUMBER);
|
||||
pn_u.number.value = value;
|
||||
pn_u.number.decimalPoint = decimalPoint;
|
||||
}
|
||||
|
||||
enum AllowConstantObjects {
|
||||
DontAllowObjects = 0,
|
||||
AllowObjects,
|
||||
|
|
@ -827,20 +826,59 @@ struct NullaryNode : public ParseNode
|
|||
NullaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos)
|
||||
: ParseNode(kind, op, PN_NULLARY, pos) {}
|
||||
|
||||
// This constructor is for a few mad uses in the emitter. It populates
|
||||
// the pn_atom field even though that field belongs to a branch in pn_u
|
||||
// that nullary nodes shouldn't use -- bogus.
|
||||
NullaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, JSAtom* atom)
|
||||
: ParseNode(kind, op, PN_NULLARY, pos)
|
||||
{
|
||||
pn_atom = atom;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump();
|
||||
#endif
|
||||
};
|
||||
|
||||
class NameNode : public ParseNode
|
||||
{
|
||||
protected:
|
||||
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, ParseNode* initOrStmt, const TokenPos& pos)
|
||||
: ParseNode(kind, op, PN_NAME, pos)
|
||||
{
|
||||
pn_u.name.atom = atom;
|
||||
pn_u.name.initOrStmt = initOrStmt;
|
||||
}
|
||||
|
||||
public:
|
||||
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos)
|
||||
: ParseNode(kind, op, PN_NAME, pos)
|
||||
{
|
||||
pn_u.name.atom = atom;
|
||||
pn_u.name.initOrStmt = nullptr;
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
return node.isArity(PN_NAME);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
|
||||
JSAtom* atom() const {
|
||||
return pn_u.name.atom;
|
||||
}
|
||||
|
||||
ParseNode* initializer() const {
|
||||
return pn_u.name.initOrStmt;
|
||||
}
|
||||
|
||||
void setAtom(JSAtom* atom) {
|
||||
pn_u.name.atom = atom;
|
||||
}
|
||||
|
||||
void setInitializer(ParseNode* init) {
|
||||
pn_u.name.initOrStmt = init;
|
||||
}
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeInitializerReference() {
|
||||
return &pn_u.name.initOrStmt;
|
||||
}
|
||||
};
|
||||
|
||||
class UnaryNode : public ParseNode
|
||||
{
|
||||
public:
|
||||
|
|
@ -889,7 +927,7 @@ class UnaryNode : public ParseNode
|
|||
if (isKind(PNK_SEMI)) {
|
||||
ParseNode* expr = kid();
|
||||
if (expr && expr->isKind(PNK_STRING) && !expr->isInParens()) {
|
||||
return expr->pn_atom;
|
||||
return kid()->as<NameNode>().atom();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
|
@ -1378,8 +1416,9 @@ ParseNode::isForLoopDeclaration() const
|
|||
return false;
|
||||
}
|
||||
|
||||
struct CodeNode : public ParseNode
|
||||
class CodeNode : public ParseNode
|
||||
{
|
||||
public:
|
||||
CodeNode(ParseNodeKind kind, JSOp op, const TokenPos& pos)
|
||||
: ParseNode(kind, op, PN_CODE, pos)
|
||||
{
|
||||
|
|
@ -1388,32 +1427,85 @@ struct CodeNode : public ParseNode
|
|||
MOZ_ASSERT(op == JSOP_NOP || // statement, module
|
||||
op == JSOP_LAMBDA_ARROW || // arrow function
|
||||
op == JSOP_LAMBDA); // expression, method, comprehension, accessor, &c.
|
||||
MOZ_ASSERT(!pn_body);
|
||||
MOZ_ASSERT(!pn_objbox);
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct NameNode : public ParseNode
|
||||
{
|
||||
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos)
|
||||
: ParseNode(kind, op, PN_NAME, pos)
|
||||
{
|
||||
pn_atom = atom;
|
||||
pn_expr = nullptr;
|
||||
MOZ_ASSERT(!pn_u.code.body);
|
||||
MOZ_ASSERT(!pn_u.code.funbox);
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
return node.isArity(PN_NAME);
|
||||
bool match = node.isKind(PNK_FUNCTION) || node.isKind(PNK_MODULE);
|
||||
MOZ_ASSERT_IF(match, node.isArity(PN_CODE));
|
||||
return match;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
|
||||
FunctionBox* funbox() const {
|
||||
return pn_u.code.funbox;
|
||||
}
|
||||
|
||||
ListNode* body() const {
|
||||
return pn_u.code.body ? &pn_u.code.body->as<ListNode>() : nullptr;
|
||||
}
|
||||
|
||||
void setFunbox(FunctionBox* funbox) {
|
||||
pn_u.code.funbox = funbox;
|
||||
}
|
||||
|
||||
void setBody(ListNode* body) {
|
||||
pn_u.code.body = body;
|
||||
}
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeBodyReference() {
|
||||
return &pn_u.code.body;
|
||||
}
|
||||
|
||||
bool functionIsHoisted() const {
|
||||
MOZ_ASSERT(isKind(PNK_FUNCTION));
|
||||
MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda
|
||||
isOp(JSOP_LAMBDA_ARROW) || // arrow function
|
||||
isOp(JSOP_DEFFUN) || // non-body-level function statement
|
||||
isOp(JSOP_NOP) || // body-level function stmt in global code
|
||||
isOp(JSOP_GETLOCAL) || // body-level function stmt in function code
|
||||
isOp(JSOP_GETARG) || // body-level function redeclaring formal
|
||||
isOp(JSOP_INITLEXICAL)); // block-level function stmt
|
||||
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
|
||||
}
|
||||
};
|
||||
|
||||
class NumericLiteral : public ParseNode
|
||||
{
|
||||
public:
|
||||
NumericLiteral(double value, DecimalPoint decimalPoint, const TokenPos& pos)
|
||||
: ParseNode(PNK_NUMBER, JSOP_NOP, PN_NUMBER, pos)
|
||||
{
|
||||
pn_u.number.value = value;
|
||||
pn_u.number.decimalPoint = decimalPoint;
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
bool match = node.isKind(PNK_NUMBER);
|
||||
MOZ_ASSERT_IF(match, node.isArity(PN_NUMBER));
|
||||
return match;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
|
||||
double value() const {
|
||||
return pn_u.number.value;
|
||||
}
|
||||
|
||||
DecimalPoint decimalPoint() const {
|
||||
return pn_u.number.decimalPoint;
|
||||
}
|
||||
|
||||
void setValue(double v) {
|
||||
pn_u.number.value = v;
|
||||
}
|
||||
};
|
||||
|
||||
struct LexicalScopeNode : public ParseNode
|
||||
|
|
@ -1434,22 +1526,19 @@ struct LexicalScopeNode : public ParseNode
|
|||
#endif
|
||||
};
|
||||
|
||||
class LabeledStatement : public ParseNode
|
||||
class LabeledStatement : public NameNode
|
||||
{
|
||||
public:
|
||||
LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin)
|
||||
: ParseNode(PNK_LABEL, JSOP_NOP, PN_NAME, TokenPos(begin, stmt->pn_pos.end))
|
||||
{
|
||||
pn_atom = label;
|
||||
pn_expr = stmt;
|
||||
}
|
||||
: NameNode(PNK_LABEL, JSOP_NOP, label, stmt, TokenPos(begin, stmt->pn_pos.end))
|
||||
{ }
|
||||
|
||||
PropertyName* label() const {
|
||||
return pn_atom->asPropertyName();
|
||||
return atom()->asPropertyName();
|
||||
}
|
||||
|
||||
ParseNode* statement() const {
|
||||
return pn_expr;
|
||||
return initializer();
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
|
|
@ -1458,6 +1547,11 @@ class LabeledStatement : public ParseNode
|
|||
MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
|
||||
return match;
|
||||
}
|
||||
|
||||
// Methods used by FoldConstants.cpp.
|
||||
ParseNode** unsafeStatementReference() {
|
||||
return unsafeInitializerReference();
|
||||
}
|
||||
};
|
||||
|
||||
// Inside a switch statement, a CaseClause is a case-label and the subsequent
|
||||
|
|
@ -1597,44 +1691,52 @@ class ThisLiteral : public UnaryNode
|
|||
}
|
||||
};
|
||||
|
||||
class NullLiteral : public ParseNode
|
||||
class NullLiteral : public NullaryNode
|
||||
{
|
||||
public:
|
||||
explicit NullLiteral(const TokenPos& pos) : ParseNode(PNK_NULL, JSOP_NULL, PN_NULLARY, pos) { }
|
||||
explicit NullLiteral(const TokenPos& pos)
|
||||
: NullaryNode(PNK_NULL, JSOP_NULL, pos)
|
||||
{ }
|
||||
};
|
||||
|
||||
// This is only used internally, currently just for tagged templates.
|
||||
// It represents the value 'undefined' (aka `void 0`), like NullLiteral
|
||||
// represents the value 'null'.
|
||||
class RawUndefinedLiteral : public ParseNode
|
||||
class RawUndefinedLiteral : public NullaryNode
|
||||
{
|
||||
public:
|
||||
explicit RawUndefinedLiteral(const TokenPos& pos)
|
||||
: ParseNode(PNK_RAW_UNDEFINED, JSOP_UNDEFINED, PN_NULLARY, pos) { }
|
||||
: NullaryNode(PNK_RAW_UNDEFINED, JSOP_UNDEFINED, pos) { }
|
||||
};
|
||||
|
||||
class BooleanLiteral : public ParseNode
|
||||
class BooleanLiteral : public NullaryNode
|
||||
{
|
||||
public:
|
||||
BooleanLiteral(bool b, const TokenPos& pos)
|
||||
: ParseNode(b ? PNK_TRUE : PNK_FALSE, b ? JSOP_TRUE : JSOP_FALSE, PN_NULLARY, pos)
|
||||
: NullaryNode(b ? PNK_TRUE : PNK_FALSE, b ? JSOP_TRUE : JSOP_FALSE, pos)
|
||||
{ }
|
||||
};
|
||||
|
||||
class RegExpLiteral : public NullaryNode
|
||||
class RegExpLiteral : public ParseNode
|
||||
{
|
||||
public:
|
||||
RegExpLiteral(ObjectBox* reobj, const TokenPos& pos)
|
||||
: NullaryNode(PNK_REGEXP, JSOP_REGEXP, pos)
|
||||
: ParseNode(PNK_REGEXP, JSOP_REGEXP, PN_REGEXP, pos)
|
||||
{
|
||||
pn_objbox = reobj;
|
||||
pn_u.regexp.objbox = reobj;
|
||||
}
|
||||
|
||||
ObjectBox* objbox() const { return pn_objbox; }
|
||||
ObjectBox* objbox() const {
|
||||
return pn_u.regexp.objbox;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(int indent);
|
||||
#endif
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
bool match = node.isKind(PNK_REGEXP);
|
||||
MOZ_ASSERT_IF(match, node.isArity(PN_NULLARY));
|
||||
MOZ_ASSERT_IF(match, node.isArity(PN_REGEXP));
|
||||
MOZ_ASSERT_IF(match, node.isOp(JSOP_REGEXP));
|
||||
return match;
|
||||
}
|
||||
|
|
@ -1647,11 +1749,11 @@ class PropertyAccessBase : public BinaryNode
|
|||
* PropertyAccess nodes can have any expression/'super' as left-hand
|
||||
* side, but the name must be a PNK_PROPERTYNAME node.
|
||||
*/
|
||||
PropertyAccessBase(ParseNodeKind kind, ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end)
|
||||
PropertyAccessBase(ParseNodeKind kind, ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end)
|
||||
: BinaryNode(kind, JSOP_NOP, TokenPos(begin, end), lhs, name)
|
||||
{
|
||||
MOZ_ASSERT(lhs != nullptr);
|
||||
MOZ_ASSERT(name != nullptr);
|
||||
MOZ_ASSERT(lhs);
|
||||
MOZ_ASSERT(name);
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
|
|
@ -1666,8 +1768,8 @@ class PropertyAccessBase : public BinaryNode
|
|||
return *left();
|
||||
}
|
||||
|
||||
ParseNode& key() const {
|
||||
return *right();
|
||||
NameNode& key() const {
|
||||
return right()->as<NameNode>();
|
||||
}
|
||||
|
||||
// Method used by BytecodeEmitter::emitPropLHS for optimization.
|
||||
|
|
@ -1682,7 +1784,7 @@ class PropertyAccessBase : public BinaryNode
|
|||
}
|
||||
|
||||
PropertyName& name() const {
|
||||
return *right()->pn_atom->asPropertyName();
|
||||
return *right()->as<NameNode>().atom()->asPropertyName();
|
||||
}
|
||||
|
||||
bool isSuper() const {
|
||||
|
|
@ -1694,7 +1796,7 @@ class PropertyAccessBase : public BinaryNode
|
|||
class PropertyAccess : public PropertyAccessBase
|
||||
{
|
||||
public:
|
||||
PropertyAccess(ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end)
|
||||
PropertyAccess(ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end)
|
||||
: PropertyAccessBase(PNK_DOT, lhs, name, begin, end)
|
||||
{
|
||||
MOZ_ASSERT(lhs != nullptr);
|
||||
|
|
@ -1712,7 +1814,7 @@ class PropertyAccess : public PropertyAccessBase
|
|||
class OptionalPropertyAccess : public PropertyAccessBase
|
||||
{
|
||||
public:
|
||||
OptionalPropertyAccess(ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end)
|
||||
OptionalPropertyAccess(ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end)
|
||||
: PropertyAccessBase(PNK_OPTDOT, lhs, name, begin, end)
|
||||
{
|
||||
MOZ_ASSERT(lhs != nullptr);
|
||||
|
|
@ -1827,8 +1929,8 @@ class ClassMethod : public BinaryNode
|
|||
ParseNode& name() const {
|
||||
return *left();
|
||||
}
|
||||
ParseNode& method() const {
|
||||
return *right();
|
||||
CodeNode& method() const {
|
||||
return right()->as<CodeNode>();
|
||||
}
|
||||
bool isStatic() const {
|
||||
return pn_u.binary.isStatic;
|
||||
|
|
@ -1887,7 +1989,8 @@ class ClassNames : public BinaryNode
|
|||
{
|
||||
MOZ_ASSERT_IF(outerBinding, outerBinding->isKind(PNK_NAME));
|
||||
MOZ_ASSERT(innerBinding->isKind(PNK_NAME));
|
||||
MOZ_ASSERT_IF(outerBinding, innerBinding->pn_atom == outerBinding->pn_atom);
|
||||
MOZ_ASSERT_IF(outerBinding,
|
||||
innerBinding->as<NameNode>().atom() == outerBinding->as<NameNode>().atom());
|
||||
}
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
|
|
@ -1904,11 +2007,14 @@ class ClassNames : public BinaryNode
|
|||
* giving the methods access to the static members of the class even if
|
||||
* the outer binding has been overwritten.
|
||||
*/
|
||||
ParseNode* outerBinding() const {
|
||||
return left();
|
||||
NameNode* outerBinding() const {
|
||||
if (ParseNode* binding = left()) {
|
||||
return &binding->as<NameNode>();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
ParseNode* innerBinding() const {
|
||||
return right();
|
||||
NameNode* innerBinding() const {
|
||||
return &right()->as<NameNode>();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -2068,7 +2174,7 @@ static inline ParseNode*
|
|||
FunctionFormalParametersList(ParseNode* fn, unsigned* numFormals)
|
||||
{
|
||||
MOZ_ASSERT(fn->isKind(PNK_FUNCTION));
|
||||
ListNode* argsBody = &fn->pn_body->as<ListNode>();
|
||||
ListNode* argsBody = fn->as<CodeNode>().body();
|
||||
MOZ_ASSERT(argsBody->isKind(PNK_PARAMSBODY));
|
||||
*numFormals = argsBody->count();
|
||||
if (*numFormals > 0 &&
|
||||
|
|
|
|||
|
|
@ -907,7 +907,7 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
|
|||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox*
|
||||
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
|
||||
Parser<ParseHandler>::newFunctionBox(CodeNodeType funNode, JSFunction* fun, uint32_t toStringStart,
|
||||
Directives inheritedDirectives,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
bool tryAnnexB)
|
||||
|
|
@ -932,8 +932,8 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toString
|
|||
}
|
||||
|
||||
traceListHead = funbox;
|
||||
if (fn)
|
||||
handler.setFunctionBox(fn, funbox);
|
||||
if (funNode)
|
||||
handler.setFunctionBox(funNode, funbox);
|
||||
|
||||
if (tryAnnexB && !pc->addInnerFunctionBoxForAnnexB(funbox))
|
||||
return nullptr;
|
||||
|
|
@ -1124,7 +1124,7 @@ Parser<ParseHandler>::reportRedeclaration(HandlePropertyName name, DeclarationKi
|
|||
// forbid duplicates.)
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName name,
|
||||
Parser<ParseHandler>::notePositionalFormalParameter(CodeNodeType funNode, HandlePropertyName name,
|
||||
uint32_t beginPos,
|
||||
bool disallowDuplicateParams,
|
||||
bool* duplicatedParam)
|
||||
|
|
@ -1159,17 +1159,17 @@ Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName
|
|||
return false;
|
||||
}
|
||||
|
||||
Node paramNode = newName(name);
|
||||
NameNodeType paramNode = newName(name);
|
||||
if (!paramNode)
|
||||
return false;
|
||||
|
||||
handler.addFunctionFormalParameter(fn, paramNode);
|
||||
handler.addFunctionFormalParameter(funNode, paramNode);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(Node fn, Node destruct)
|
||||
Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(CodeNodeType funNode, Node destruct)
|
||||
{
|
||||
// Append an empty name to the positional formals vector to keep track of
|
||||
// argument slots when making FunctionScope::Data.
|
||||
|
|
@ -1178,7 +1178,7 @@ Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(Node fn, Node de
|
|||
return false;
|
||||
}
|
||||
|
||||
handler.addFunctionFormalParameter(fn, destruct);
|
||||
handler.addFunctionFormalParameter(funNode, destruct);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2215,7 +2215,7 @@ Parser<FullParseHandler>::globalBody(GlobalSharedContext* globalsc)
|
|||
}
|
||||
|
||||
template <>
|
||||
ParseNode*
|
||||
CodeNode*
|
||||
Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
|
@ -2228,8 +2228,8 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
|||
if (!varScope.init(pc))
|
||||
return nullptr;
|
||||
|
||||
Node mn = handler.newModule();
|
||||
if (!mn)
|
||||
CodeNodeType moduleNode = handler.newModule();
|
||||
if (!moduleNode)
|
||||
return null();
|
||||
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, true);
|
||||
|
|
@ -2239,7 +2239,7 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
|||
}
|
||||
|
||||
MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST));
|
||||
mn->pn_body = stmtList;
|
||||
moduleNode->setBody(&stmtList->as<ListNode>());
|
||||
|
||||
TokenKind tt;
|
||||
if (!tokenStream.getToken(&tt, TokenStream::Operand))
|
||||
|
|
@ -2285,11 +2285,11 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
|||
return nullptr;
|
||||
|
||||
modulesc->bindings = *bindings;
|
||||
return mn;
|
||||
return moduleNode;
|
||||
}
|
||||
|
||||
template <>
|
||||
SyntaxParseHandler::Node
|
||||
SyntaxParseHandler::CodeNodeType
|
||||
Parser<SyntaxParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
||||
{
|
||||
MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
|
||||
|
|
@ -2340,10 +2340,10 @@ Parser<ParseHandler>::declareFunctionThis()
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::newInternalDotName(HandlePropertyName name)
|
||||
{
|
||||
Node nameNode = newName(name);
|
||||
NameNodeType nameNode = newName(name);
|
||||
if (!nameNode)
|
||||
return null();
|
||||
if (!noteUsedName(name))
|
||||
|
|
@ -2352,14 +2352,14 @@ Parser<ParseHandler>::newInternalDotName(HandlePropertyName name)
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::newThisName()
|
||||
{
|
||||
return newInternalDotName(context->names().dotThis);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::newDotGeneratorName()
|
||||
{
|
||||
return newInternalDotName(context->names().dotGenerator);
|
||||
|
|
@ -2505,7 +2505,7 @@ GetYieldHandling(GeneratorKind generatorKind)
|
|||
}
|
||||
|
||||
template <>
|
||||
ParseNode*
|
||||
CodeNode*
|
||||
Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
||||
HandleScope enclosingScope,
|
||||
Maybe<uint32_t> parameterListEnd,
|
||||
|
|
@ -2542,16 +2542,16 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
tokenStream.ungetToken();
|
||||
}
|
||||
|
||||
Node fn = handler.newFunctionStatement();
|
||||
if (!fn)
|
||||
CodeNodeType funNode = handler.newFunctionStatement();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
ListNodeType argsbody = handler.newList(PNK_PARAMSBODY);
|
||||
if (!argsbody)
|
||||
return null();
|
||||
fn->pn_body = argsbody;
|
||||
funNode->setBody(argsbody);
|
||||
|
||||
FunctionBox* funbox = newFunctionBox(fn, fun, /* toStringStart = */ 0, inheritedDirectives,
|
||||
FunctionBox* funbox = newFunctionBox(funNode, fun, /* toStringStart = */ 0, inheritedDirectives,
|
||||
generatorKind, asyncKind, /* tryAnnexB = */ false);
|
||||
if (!funbox)
|
||||
return null();
|
||||
|
|
@ -2564,7 +2564,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction);
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, fn, Statement,
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, Statement,
|
||||
parameterListEnd, /* isStandaloneFunction = */ true))
|
||||
{
|
||||
return null();
|
||||
|
|
@ -2577,10 +2577,12 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
return null();
|
||||
}
|
||||
|
||||
if (!FoldConstants(context, &fn, this))
|
||||
ParseNode* node = funNode;
|
||||
if (!FoldConstants(context, &node, this))
|
||||
return null();
|
||||
funNode = &node->as<CodeNode>();
|
||||
|
||||
return fn;
|
||||
return funNode;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
|
|
@ -2745,7 +2747,7 @@ Parser<ParseHandler>::functionBody(InHandling inHandling, YieldHandling yieldHan
|
|||
MOZ_ASSERT_IF(!pc->isAsync(), type == StatementListBody);
|
||||
if (!declareDotGeneratorName())
|
||||
return null();
|
||||
Node generator = newDotGeneratorName();
|
||||
NameNodeType generator = newDotGeneratorName();
|
||||
if (!generator)
|
||||
return null();
|
||||
if (!handler.prependInitialYield(handler.asList(body), generator))
|
||||
|
|
@ -2953,7 +2955,7 @@ Parser<ParseHandler>::prefixAccessorName(PropertyType propType, HandleAtom propA
|
|||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
|
||||
Node funcpn)
|
||||
CodeNodeType funNode)
|
||||
{
|
||||
FunctionBox* funbox = pc->functionBox();
|
||||
|
||||
|
|
@ -3013,7 +3015,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
ListNodeType argsbody = handler.newList(PNK_PARAMSBODY);
|
||||
if (!argsbody)
|
||||
return false;
|
||||
handler.setFunctionFormalParametersAndBody(funcpn, argsbody);
|
||||
handler.setFunctionFormalParametersAndBody(funNode, argsbody);
|
||||
|
||||
bool hasArguments = false;
|
||||
if (parenFreeArrow) {
|
||||
|
|
@ -3092,7 +3094,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
if (!destruct)
|
||||
return false;
|
||||
|
||||
if (!noteDestructuredPositionalFormalParameter(funcpn, destruct))
|
||||
if (!noteDestructuredPositionalFormalParameter(funNode, destruct))
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
|
@ -3111,7 +3113,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
if (!name)
|
||||
return false;
|
||||
|
||||
if (!notePositionalFormalParameter(funcpn, name, pos().begin,
|
||||
if (!notePositionalFormalParameter(funNode, name, pos().begin,
|
||||
disallowDuplicateParams, &duplicatedParam))
|
||||
{
|
||||
return false;
|
||||
|
|
@ -3160,7 +3162,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
Node def_expr = assignExprWithoutYieldOrAwait(yieldHandling);
|
||||
if (!def_expr)
|
||||
return false;
|
||||
if (!handler.setLastFunctionFormalParameterDefault(funcpn, def_expr))
|
||||
if (!handler.setLastFunctionFormalParameterDefault(funNode, def_expr))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3214,7 +3216,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||
|
||||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toStringStart,
|
||||
Parser<FullParseHandler>::skipLazyInnerFunction(CodeNode* funNode, uint32_t toStringStart,
|
||||
FunctionSyntaxKind kind, bool tryAnnexB)
|
||||
{
|
||||
// When a lazily-parsed function is called, we only fully parse (and emit)
|
||||
|
|
@ -3224,7 +3226,7 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toString
|
|||
|
||||
RootedFunction fun(context, handler.nextLazyInnerFunction());
|
||||
MOZ_ASSERT(!fun->isLegacyGenerator());
|
||||
FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, Directives(/* strict = */ false),
|
||||
FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, Directives(/* strict = */ false),
|
||||
fun->generatorKind(), fun->asyncKind(), tryAnnexB);
|
||||
if (!funbox)
|
||||
return false;
|
||||
|
|
@ -3261,7 +3263,7 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toString
|
|||
|
||||
template <>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::skipLazyInnerFunction(Node pn, uint32_t toStringStart,
|
||||
Parser<SyntaxParseHandler>::skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart,
|
||||
FunctionSyntaxKind kind, bool tryAnnexB)
|
||||
{
|
||||
MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing");
|
||||
|
|
@ -3314,11 +3316,11 @@ template <typename ParseHandler>
|
|||
typename ParseHandler::ListNodeType
|
||||
Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling)
|
||||
{
|
||||
Node pn = noSubstitutionUntaggedTemplate();
|
||||
if (!pn)
|
||||
NameNodeType literal = noSubstitutionUntaggedTemplate();
|
||||
if (!literal)
|
||||
return null();
|
||||
|
||||
ListNodeType nodeList = handler.newList(PNK_TEMPLATE_STRING_LIST, pn);
|
||||
ListNodeType nodeList = handler.newList(PNK_TEMPLATE_STRING_LIST, literal);
|
||||
if (!nodeList)
|
||||
return null();
|
||||
|
||||
|
|
@ -3327,18 +3329,18 @@ Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling)
|
|||
if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt))
|
||||
return null();
|
||||
|
||||
pn = noSubstitutionUntaggedTemplate();
|
||||
if (!pn)
|
||||
literal = noSubstitutionUntaggedTemplate();
|
||||
if (!literal)
|
||||
return null();
|
||||
|
||||
handler.addList(nodeList, pn);
|
||||
handler.addList(nodeList, literal);
|
||||
} while (tt == TOK_TEMPLATE_HEAD);
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHandling inHandling,
|
||||
typename ParseHandler::CodeNodeType
|
||||
Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, CodeNodeType funNode, InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
HandleAtom funName, FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
|
|
@ -3350,9 +3352,10 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand
|
|||
// functions, which are also lazy. Instead, their free variables and
|
||||
// source extents are recorded and may be skipped.
|
||||
if (handler.canSkipLazyInnerFunctions()) {
|
||||
if (!skipLazyInnerFunction(pn, toStringStart, kind, tryAnnexB))
|
||||
if (!skipLazyInnerFunction(funNode, toStringStart, kind, tryAnnexB))
|
||||
return null();
|
||||
return pn;
|
||||
|
||||
return funNode;
|
||||
}
|
||||
|
||||
RootedObject proto(context);
|
||||
|
|
@ -3383,8 +3386,8 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand
|
|||
// reparse a function due to failed syntax parsing and encountering new
|
||||
// "use foo" directives.
|
||||
while (true) {
|
||||
if (trySyntaxParseInnerFunction(pn, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, directives,
|
||||
if (trySyntaxParseInnerFunction(funNode, fun, toStringStart, inHandling, yieldHandling,
|
||||
kind, generatorKind, asyncKind, tryAnnexB, directives,
|
||||
&newDirectives))
|
||||
{
|
||||
break;
|
||||
|
|
@ -3402,16 +3405,16 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand
|
|||
|
||||
tokenStream.seek(start);
|
||||
|
||||
// functionFormalParametersAndBody may have already set pn->pn_body before failing.
|
||||
handler.setFunctionFormalParametersAndBody(pn, null());
|
||||
// functionFormalParametersAndBody may have already set body before failing.
|
||||
handler.setFunctionFormalParametersAndBody(funNode, null());
|
||||
}
|
||||
|
||||
return pn;
|
||||
return funNode;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunction fun,
|
||||
Parser<FullParseHandler>::trySyntaxParseInnerFunction(CodeNode* funNode, HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
|
|
@ -3428,7 +3431,7 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct
|
|||
// parse to avoid the overhead of a lazy syntax-only parse. Although
|
||||
// the prediction may be incorrect, IIFEs are common enough that it
|
||||
// pays off for lots of code.
|
||||
if (pn->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction)
|
||||
if (funNode->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction)
|
||||
break;
|
||||
|
||||
Parser<SyntaxParseHandler>* parser = handler.syntaxParser;
|
||||
|
|
@ -3443,10 +3446,10 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct
|
|||
if (!parser->tokenStream.seek(position, tokenStream))
|
||||
return false;
|
||||
|
||||
// Make a FunctionBox before we enter the syntax parser, because |pn|
|
||||
// Make a FunctionBox before we enter the syntax parser, because |funNode|
|
||||
// still expects a FunctionBox to be attached to it during BCE, and
|
||||
// the syntax parser cannot attach one to it.
|
||||
FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives,
|
||||
FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, inheritedDirectives,
|
||||
generatorKind, asyncKind, tryAnnexB);
|
||||
if (!funbox)
|
||||
return false;
|
||||
|
|
@ -3475,18 +3478,18 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct
|
|||
return false;
|
||||
|
||||
// Update the end position of the parse node.
|
||||
pn->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||
funNode->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||
return true;
|
||||
} while (false);
|
||||
|
||||
// We failed to do a syntax parse above, so do the full parse.
|
||||
return innerFunction(pn, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
return innerFunction(funNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(Node pn, HandleFunction fun,
|
||||
Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(CodeNodeType funNode, HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
|
|
@ -3498,13 +3501,13 @@ Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(Node pn, HandleFunction
|
|||
Directives* newDirectives)
|
||||
{
|
||||
// This is already a syntax parser, so just parse the inner function.
|
||||
return innerFunction(pn, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
return innerFunction(funNode, pc, fun, toStringStart, inHandling, yieldHandling, kind,
|
||||
generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox,
|
||||
Parser<ParseHandler>::innerFunction(CodeNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind, Directives inheritedDirectives,
|
||||
|
|
@ -3520,7 +3523,7 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox*
|
|||
if (!funpc.init())
|
||||
return false;
|
||||
|
||||
if (!functionFormalParametersAndBody(inHandling, yieldHandling, pn, kind))
|
||||
if (!functionFormalParametersAndBody(inHandling, yieldHandling, funNode, kind))
|
||||
return false;
|
||||
|
||||
return leaveInnerFunction(outerpc);
|
||||
|
|
@ -3528,7 +3531,7 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox*
|
|||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
|
||||
Parser<ParseHandler>::innerFunction(CodeNodeType funNode, ParseContext* outerpc, HandleFunction fun,
|
||||
uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind,
|
||||
|
|
@ -3541,13 +3544,13 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFuncti
|
|||
// parser. In that case, outerpc is a ParseContext from the full parser
|
||||
// instead of the current top of the stack of the syntax parser.
|
||||
|
||||
FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives,
|
||||
FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, inheritedDirectives,
|
||||
generatorKind, asyncKind, tryAnnexB);
|
||||
if (!funbox)
|
||||
return false;
|
||||
funbox->initWithEnclosingParseContext(outerpc, kind);
|
||||
|
||||
return innerFunction(pn, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind,
|
||||
return innerFunction(funNode, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind,
|
||||
inheritedDirectives, newDirectives);
|
||||
}
|
||||
|
||||
|
|
@ -3562,7 +3565,7 @@ Parser<ParseHandler>::appendToCallSiteObj(CallSiteNodeType callSiteObj)
|
|||
JSAtom* atom = tokenStream.getRawTemplateStringAtom();
|
||||
if (!atom)
|
||||
return false;
|
||||
Node rawNode = handler.newTemplateStringLiteral(atom, pos());
|
||||
NameNodeType rawNode = handler.newTemplateStringLiteral(atom, pos());
|
||||
if (!rawNode)
|
||||
return false;
|
||||
|
||||
|
|
@ -3571,19 +3574,19 @@ Parser<ParseHandler>::appendToCallSiteObj(CallSiteNodeType callSiteObj)
|
|||
}
|
||||
|
||||
template <>
|
||||
ParseNode*
|
||||
CodeNode*
|
||||
Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict,
|
||||
GeneratorKind generatorKind,
|
||||
FunctionAsyncKind asyncKind)
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
||||
Node pn = handler.newFunctionStatement();
|
||||
if (!pn)
|
||||
CodeNodeType funNode = handler.newFunctionStatement();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
Directives directives(strict);
|
||||
FunctionBox* funbox = newFunctionBox(pn, fun, /* toStringStart = */ 0, directives,
|
||||
FunctionBox* funbox = newFunctionBox(funNode, fun, /* toStringStart = */ 0, directives,
|
||||
generatorKind, asyncKind, /* tryAnnexB = */ false);
|
||||
if (!funbox)
|
||||
return null();
|
||||
|
|
@ -3594,14 +3597,14 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
|
|||
if (!funpc.init())
|
||||
return null();
|
||||
|
||||
// Our tokenStream has no current token, so pn's position is garbage.
|
||||
// Our tokenStream has no current token, so funNode's position is garbage.
|
||||
// Substitute the position of the first token in our source. If the function
|
||||
// is a not-async arrow, use TokenStream::Operand to keep
|
||||
// verifyConsistentModifier from complaining (we will use
|
||||
// TokenStream::Operand in functionArguments).
|
||||
TokenStream::Modifier modifier = (fun->isArrow() && asyncKind == SyncFunction)
|
||||
? TokenStream::Operand : TokenStream::None;
|
||||
if (!tokenStream.peekTokenPos(&pn->pn_pos, modifier))
|
||||
if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier))
|
||||
return null();
|
||||
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
|
|
@ -3617,22 +3620,24 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
|
|||
else if (fun->isArrow())
|
||||
syntaxKind = Arrow;
|
||||
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, pn, syntaxKind)) {
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, syntaxKind)) {
|
||||
MOZ_ASSERT(directives == newDirectives);
|
||||
return null();
|
||||
}
|
||||
|
||||
if (!FoldConstants(context, &pn, this))
|
||||
ParseNode* node = funNode;
|
||||
if (!FoldConstants(context, &node, this))
|
||||
return null();
|
||||
funNode = &node->as<CodeNode>();
|
||||
|
||||
return pn;
|
||||
return funNode;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
Node pn, FunctionSyntaxKind kind,
|
||||
CodeNodeType funNode, FunctionSyntaxKind kind,
|
||||
Maybe<uint32_t> parameterListEnd /* = Nothing() */,
|
||||
bool isStandaloneFunction /* = false */)
|
||||
{
|
||||
|
|
@ -3648,7 +3653,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
{
|
||||
bool asyncOrArrowInAsync = funbox->isAsync() || (kind == Arrow && awaitIsKeyword());
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync);
|
||||
if (!functionArguments(yieldHandling, kind, pn))
|
||||
if (!functionArguments(yieldHandling, kind, funNode))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3740,7 +3745,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
// We already use the correct await-handling at this point, therefore
|
||||
// we don't need call AutoAwaitIsKeyword here.
|
||||
|
||||
if (!checkBindingIdentifier(propertyName, handler.getPosition(pn).begin,
|
||||
if (!checkBindingIdentifier(propertyName, handler.getPosition(funNode).begin,
|
||||
nameYieldHandling))
|
||||
{
|
||||
return false;
|
||||
|
|
@ -3771,14 +3776,14 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
return false;
|
||||
|
||||
handler.setEndPosition(body, pos().begin);
|
||||
handler.setEndPosition(pn, pos().end);
|
||||
handler.setFunctionBody(pn, body);
|
||||
handler.setEndPosition(funNode, pos().end);
|
||||
handler.setFunctionBody(funNode, body);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::CodeNodeType
|
||||
Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHandling,
|
||||
DefaultHandling defaultHandling, FunctionAsyncKind asyncKind)
|
||||
{
|
||||
|
|
@ -3854,17 +3859,17 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa
|
|||
return null();
|
||||
}
|
||||
|
||||
Node pn = handler.newFunctionStatement();
|
||||
if (!pn)
|
||||
CodeNodeType funNode = handler.newFunctionStatement();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
|
||||
return functionDefinition(toStringStart, pn, InAllowed, newYieldHandling,
|
||||
name, Statement, generatorKind, asyncKind, tryAnnexB);
|
||||
return functionDefinition(toStringStart, funNode, InAllowed, newYieldHandling,
|
||||
name, Statement, generatorKind, asyncKind, tryAnnexB);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::CodeNodeType
|
||||
Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction invoked,
|
||||
FunctionAsyncKind asyncKind)
|
||||
{
|
||||
|
|
@ -3893,14 +3898,14 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv
|
|||
tokenStream.ungetToken();
|
||||
}
|
||||
|
||||
Node pn = handler.newFunctionExpression();
|
||||
if (!pn)
|
||||
CodeNodeType funNode = handler.newFunctionExpression();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
if (invoked)
|
||||
pn = handler.setLikelyIIFE(pn);
|
||||
funNode = handler.setLikelyIIFE(funNode);
|
||||
|
||||
return functionDefinition(toStringStart, pn, InAllowed, yieldHandling, name, Expression,
|
||||
return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, name, Expression,
|
||||
generatorKind, asyncKind);
|
||||
}
|
||||
|
||||
|
|
@ -4338,14 +4343,14 @@ Parser<ParseHandler>::bindingInitializer(Node lhs, DeclarationKind kind,
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling)
|
||||
{
|
||||
RootedPropertyName name(context, bindingIdentifier(yieldHandling));
|
||||
if (!name)
|
||||
return null();
|
||||
|
||||
Node binding = newName(name);
|
||||
NameNodeType binding = newName(name);
|
||||
if (!binding || !noteDeclaredName(name, kind, pos()))
|
||||
return null();
|
||||
|
||||
|
|
@ -4442,18 +4447,18 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y
|
|||
// for |var {x: x, y: y} = o|.
|
||||
MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
|
||||
|
||||
Node binding = bindingIdentifier(kind, yieldHandling);
|
||||
NameNodeType binding = bindingIdentifier(kind, yieldHandling);
|
||||
if (!binding)
|
||||
return null();
|
||||
|
||||
if (!handler.addShorthand(literal, propName, binding))
|
||||
if (!handler.addShorthand(literal, handler.asName(propName), binding))
|
||||
return null();
|
||||
} else if (propType == PropertyType::CoverInitializedName) {
|
||||
// Handle e.g., |var {x=1, y=2} = o| as destructuring
|
||||
// shorthand with default values.
|
||||
MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt));
|
||||
|
||||
Node binding = bindingIdentifier(kind, yieldHandling);
|
||||
NameNodeType binding = bindingIdentifier(kind, yieldHandling);
|
||||
if (!binding)
|
||||
return null();
|
||||
|
||||
|
|
@ -4717,7 +4722,7 @@ Parser<ParseHandler>::declarationPattern(Node decl, DeclarationKind declKind, To
|
|||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::initializerInNameDeclaration(Node decl, Node binding,
|
||||
Parser<ParseHandler>::initializerInNameDeclaration(Node decl, NameNodeType binding,
|
||||
Handle<PropertyName*> name,
|
||||
DeclarationKind declKind,
|
||||
bool initialDeclaration,
|
||||
|
|
@ -4803,7 +4808,7 @@ Parser<ParseHandler>::initializerInNameDeclaration(Node decl, Node binding,
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::declarationName(Node decl, DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind, Node* forInOrOfExpression)
|
||||
|
|
@ -4819,7 +4824,7 @@ Parser<ParseHandler>::declarationName(Node decl, DeclarationKind declKind, Token
|
|||
if (!name)
|
||||
return null();
|
||||
|
||||
Node binding = newName(name);
|
||||
NameNodeType binding = newName(name);
|
||||
if (!binding)
|
||||
return null();
|
||||
|
||||
|
|
@ -5025,13 +5030,13 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
|
|||
if (!bindingAtom)
|
||||
return false;
|
||||
|
||||
Node bindingName = newName(bindingAtom);
|
||||
NameNodeType bindingName = newName(bindingAtom);
|
||||
if (!bindingName)
|
||||
return false;
|
||||
if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos()))
|
||||
return false;
|
||||
|
||||
Node importNameNode = newName(importName, importNamePos);
|
||||
NameNodeType importNameNode = newName(importName, importNamePos);
|
||||
if (!importNameNode)
|
||||
return false;
|
||||
|
||||
|
|
@ -5060,7 +5065,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
|
|||
|
||||
MUST_MATCH_TOKEN_FUNC_OR(TokenKindIsPossibleIdentifierName, JSMSG_NO_BINDING_NAME, false);
|
||||
|
||||
Node importName = newName(context->names().star);
|
||||
NameNodeType importName = newName(context->names().star);
|
||||
if (!importName)
|
||||
return false;
|
||||
|
||||
|
|
@ -5071,7 +5076,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy
|
|||
RootedPropertyName bindingName(context, importedBinding());
|
||||
if (!bindingName)
|
||||
return false;
|
||||
Node bindingNameNode = newName(bindingName);
|
||||
NameNodeType bindingNameNode = newName(bindingName);
|
||||
if (!bindingNameNode)
|
||||
return false;
|
||||
if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos()))
|
||||
|
|
@ -5171,7 +5176,7 @@ Parser<FullParseHandler>::importDeclaration()
|
|||
MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
|
||||
}
|
||||
|
||||
Node moduleSpec = stringLiteral();
|
||||
NameNodeType moduleSpec = stringLiteral();
|
||||
if (!moduleSpec)
|
||||
return null();
|
||||
|
||||
|
|
@ -5295,7 +5300,7 @@ bool
|
|||
Parser<FullParseHandler>::checkExportedNamesForDeclaration(ParseNode* node)
|
||||
{
|
||||
if (node->isKind(PNK_NAME)) {
|
||||
if (!checkExportedName(node->pn_atom))
|
||||
if (!checkExportedName(node->as<NameNode>().atom()))
|
||||
return false;
|
||||
} else if (node->isKind(PNK_ARRAY)) {
|
||||
if (!checkExportedNamesForArrayBinding(&node->as<ListNode>()))
|
||||
|
|
@ -5344,14 +5349,14 @@ Parser<SyntaxParseHandler>::checkExportedNamesForDeclarationList(ListNodeType no
|
|||
|
||||
template<>
|
||||
bool
|
||||
Parser<FullParseHandler>::checkExportedNameForClause(ParseNode* node)
|
||||
Parser<FullParseHandler>::checkExportedNameForClause(NameNodeType nameNode)
|
||||
{
|
||||
return checkExportedName(node->pn_atom);
|
||||
return checkExportedName(nameNode->atom());
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::checkExportedNameForClause(Node node)
|
||||
Parser<SyntaxParseHandler>::checkExportedNameForClause(NameNodeType nameNode)
|
||||
{
|
||||
MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
|
||||
return false;
|
||||
|
|
@ -5359,14 +5364,14 @@ Parser<SyntaxParseHandler>::checkExportedNameForClause(Node node)
|
|||
|
||||
template<>
|
||||
bool
|
||||
Parser<FullParseHandler>::checkExportedNameForFunction(ParseNode* node)
|
||||
Parser<FullParseHandler>::checkExportedNameForFunction(CodeNodeType funNode)
|
||||
{
|
||||
return checkExportedName(node->pn_funbox->function()->explicitName());
|
||||
return checkExportedName(funNode->funbox()->function()->explicitName());
|
||||
}
|
||||
|
||||
template<>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::checkExportedNameForFunction(Node node)
|
||||
Parser<SyntaxParseHandler>::checkExportedNameForFunction(CodeNodeType funNode)
|
||||
{
|
||||
MOZ_ALWAYS_FALSE(abortIfSyntaxParser());
|
||||
return false;
|
||||
|
|
@ -5377,7 +5382,7 @@ bool
|
|||
Parser<FullParseHandler>::checkExportedNameForClass(ClassNode* classNode)
|
||||
{
|
||||
MOZ_ASSERT(classNode->names());
|
||||
return checkExportedName(classNode->names()->innerBinding()->pn_atom);
|
||||
return checkExportedName(classNode->names()->innerBinding()->atom());
|
||||
}
|
||||
|
||||
template<>
|
||||
|
|
@ -5432,7 +5437,7 @@ Parser<ParseHandler>::exportFrom(uint32_t begin, Node specList)
|
|||
|
||||
MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
|
||||
|
||||
Node moduleSpec = stringLiteral();
|
||||
NameNodeType moduleSpec = stringLiteral();
|
||||
if (!moduleSpec)
|
||||
return null();
|
||||
|
||||
|
|
@ -5484,7 +5489,7 @@ Parser<FullParseHandler>::checkLocalExportNames(ListNode* node)
|
|||
ParseNode* name = next->as<BinaryNode>().left();
|
||||
MOZ_ASSERT(name->isKind(PNK_NAME));
|
||||
|
||||
RootedPropertyName ident(context, name->pn_atom->asPropertyName());
|
||||
RootedPropertyName ident(context, name->as<NameNode>().atom()->asPropertyName());
|
||||
if (!checkLocalExportName(ident, name->pn_pos.begin))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -5528,7 +5533,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
|
|||
return null();
|
||||
}
|
||||
|
||||
Node bindingName = newName(tokenStream.currentName());
|
||||
NameNodeType bindingName = newName(tokenStream.currentName());
|
||||
if (!bindingName)
|
||||
return null();
|
||||
|
||||
|
|
@ -5538,7 +5543,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
|
|||
if (foundAs)
|
||||
MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifierName, JSMSG_NO_EXPORT_NAME);
|
||||
|
||||
Node exportName = newName(tokenStream.currentName());
|
||||
NameNodeType exportName = newName(tokenStream.currentName());
|
||||
if (!exportName)
|
||||
return null();
|
||||
|
||||
|
|
@ -5640,7 +5645,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
|
|||
if (!kid)
|
||||
return null();
|
||||
|
||||
if (!checkExportedNameForFunction(kid))
|
||||
if (!checkExportedNameForFunction(handler.asCode(kid)))
|
||||
return null();
|
||||
|
||||
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
|
||||
|
|
@ -5762,7 +5767,7 @@ Parser<ParseHandler>::exportDefaultAssignExpr(uint32_t begin)
|
|||
return null();
|
||||
|
||||
RootedPropertyName name(context, context->names().starDefaultStar);
|
||||
Node nameNode = newName(name);
|
||||
NameNodeType nameNode = newName(name);
|
||||
if (!nameNode)
|
||||
return null();
|
||||
if (!noteDeclaredName(name, DeclarationKind::Const, pos()))
|
||||
|
|
@ -6894,7 +6899,7 @@ Parser<ParseHandler>::labeledItem(YieldHandling yieldHandling)
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::LabeledStatementType
|
||||
Parser<ParseHandler>::labeledStatement(YieldHandling yieldHandling)
|
||||
{
|
||||
RootedPropertyName label(context, labelIdentifier(yieldHandling));
|
||||
|
|
@ -7390,15 +7395,15 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling,
|
|||
// Calling toString on constructors need to return the source text for
|
||||
// the entire class. The end offset is unknown at this point in
|
||||
// parsing and will be amended when class parsing finishes below.
|
||||
Node fn = methodDefinition(isConstructor ? classStartOffset : nameOffset,
|
||||
propType, funName);
|
||||
if (!fn)
|
||||
CodeNodeType funNode = methodDefinition(isConstructor ? classStartOffset : nameOffset,
|
||||
propType, funName);
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(fn);
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(funNode);
|
||||
|
||||
JSOp op = JSOpFromPropertyType(propType);
|
||||
if (!handler.addClassMethodDefinition(classMethods, propName, fn, op, isStatic))
|
||||
if (!handler.addClassMethodDefinition(classMethods, propName, funNode, op, isStatic))
|
||||
return null();
|
||||
}
|
||||
|
||||
|
|
@ -7418,7 +7423,7 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling,
|
|||
if (!noteDeclaredName(name, DeclarationKind::Const, namePos))
|
||||
return null();
|
||||
|
||||
Node innerName = newName(name, namePos);
|
||||
NameNodeType innerName = newName(name, namePos);
|
||||
if (!innerName)
|
||||
return null();
|
||||
|
||||
|
|
@ -7432,7 +7437,7 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling,
|
|||
innerScope.reset();
|
||||
innerScopeStmt.reset();
|
||||
|
||||
Node outerName = null();
|
||||
NameNodeType outerName = null();
|
||||
if (classContext == ClassStatement) {
|
||||
// The outer name is mutable.
|
||||
if (!noteDeclaredName(name, DeclarationKind::Let, namePos))
|
||||
|
|
@ -8387,11 +8392,11 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
|||
}
|
||||
}
|
||||
|
||||
Node pn = handler.newArrowFunction();
|
||||
if (!pn)
|
||||
CodeNodeType funNode = handler.newArrowFunction();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
Node arrowFunc = functionDefinition(toStringStart, pn, inHandling, yieldHandling, nullptr,
|
||||
Node arrowFunc = functionDefinition(toStringStart, funNode, inHandling, yieldHandling, nullptr,
|
||||
Arrow, NotGenerator, asyncKind);
|
||||
if (!arrowFunc)
|
||||
return null();
|
||||
|
|
@ -8784,7 +8789,7 @@ template <typename ParseHandler>
|
|||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin)
|
||||
{
|
||||
Node genfn = handler.newFunctionExpression();
|
||||
CodeNodeType genfn = handler.newFunctionExpression();
|
||||
if (!genfn)
|
||||
return null();
|
||||
|
||||
|
|
@ -9235,7 +9240,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
|||
handler.setOp(lhs, JSOP_SPREADNEW);
|
||||
}
|
||||
} else if (tt == TOK_SUPER) {
|
||||
Node thisName = newThisName();
|
||||
NameNodeType thisName = newThisName();
|
||||
if (!thisName)
|
||||
return null();
|
||||
lhs = handler.newSuperBase(thisName, pos());
|
||||
|
|
@ -9301,7 +9306,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
|||
if (isSpread)
|
||||
handler.setOp(nextMember, JSOP_SPREADSUPERCALL);
|
||||
|
||||
Node thisName = newThisName();
|
||||
NameNodeType thisName = newThisName();
|
||||
if (!thisName)
|
||||
return null();
|
||||
|
||||
|
|
@ -9336,14 +9341,14 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::newName(PropertyName* name)
|
||||
{
|
||||
return newName(name, pos());
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::newName(PropertyName* name, TokenPos pos)
|
||||
{
|
||||
return handler.newName(name, pos, context);
|
||||
|
|
@ -9360,7 +9365,7 @@ Parser<ParseHandler>::memberPropertyAccess(
|
|||
error(JSMSG_BAD_SUPERPROP, "property");
|
||||
return null();
|
||||
}
|
||||
Node name = handler.newPropertyName(field, pos());
|
||||
NameNodeType name = handler.newPropertyName(field, pos());
|
||||
if (!name)
|
||||
return null();
|
||||
if (optionalKind == OptionalKind::Optional) {
|
||||
|
|
@ -9624,21 +9629,21 @@ Parser<ParseHandler>::bindingIdentifier(YieldHandling yieldHandling)
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::identifierReference(Handle<PropertyName*> name)
|
||||
{
|
||||
Node pn = newName(name);
|
||||
if (!pn)
|
||||
NameNodeType id = newName(name);
|
||||
if (!id)
|
||||
return null();
|
||||
|
||||
if (!noteUsedName(name))
|
||||
return null();
|
||||
|
||||
return pn;
|
||||
return id;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::stringLiteral()
|
||||
{
|
||||
return handler.newStringLiteral(stopStringCompression(), pos());
|
||||
|
|
@ -9657,7 +9662,7 @@ Parser<ParseHandler>::noSubstitutionTaggedTemplate()
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::NameNodeType
|
||||
Parser<ParseHandler>::noSubstitutionUntaggedTemplate()
|
||||
{
|
||||
if (!tokenStream.checkForInvalidTemplateEscapeError())
|
||||
|
|
@ -9680,7 +9685,7 @@ JSAtom * Parser<ParseHandler>::stopStringCompression() {
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::RegExpLiteralType
|
||||
Parser<ParseHandler>::newRegExp()
|
||||
{
|
||||
MOZ_ASSERT(!options().selfHostingMode);
|
||||
|
|
@ -9700,7 +9705,7 @@ Parser<ParseHandler>::newRegExp()
|
|||
template <typename ParseHandler>
|
||||
void
|
||||
Parser<ParseHandler>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
|
||||
PossibleError* possibleError)
|
||||
PossibleError* possibleError)
|
||||
{
|
||||
// Return early if a pending destructuring error is already present.
|
||||
if (possibleError->hasPendingDestructuringError())
|
||||
|
|
@ -10193,14 +10198,14 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
|
|||
if (!name)
|
||||
return null();
|
||||
|
||||
Node nameExpr = identifierReference(name);
|
||||
NameNodeType nameExpr = identifierReference(name);
|
||||
if (!nameExpr)
|
||||
return null();
|
||||
|
||||
if (possibleError)
|
||||
checkDestructuringAssignmentTarget(nameExpr, namePos, possibleError);
|
||||
|
||||
if (!handler.addShorthand(literal, propName, nameExpr))
|
||||
if (!handler.addShorthand(literal, handler.asName(propName), nameExpr))
|
||||
return null();
|
||||
} else if (propType == PropertyType::CoverInitializedName) {
|
||||
/*
|
||||
|
|
@ -10269,14 +10274,14 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
|
|||
}
|
||||
}
|
||||
|
||||
Node fn = methodDefinition(namePos.begin, propType, funName);
|
||||
if (!fn)
|
||||
CodeNodeType funNode = methodDefinition(namePos.begin, propType, funName);
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(fn);
|
||||
handler.checkAndSetIsDirectRHSAnonFunction(funNode);
|
||||
|
||||
JSOp op = JSOpFromPropertyType(propType);
|
||||
if (!handler.addObjectMethodDefinition(literal, propName, fn, op))
|
||||
if (!handler.addObjectMethodDefinition(literal, propName, funNode, op))
|
||||
return null();
|
||||
|
||||
if (possibleError) {
|
||||
|
|
@ -10304,7 +10309,7 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError*
|
|||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
typename ParseHandler::CodeNodeType
|
||||
Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType propType,
|
||||
HandleAtom funName)
|
||||
{
|
||||
|
|
@ -10357,11 +10362,11 @@ Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType prop
|
|||
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
|
||||
Node pn = handler.newFunctionExpression();
|
||||
if (!pn)
|
||||
CodeNodeType funNode = handler.newFunctionExpression();
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
return functionDefinition(toStringStart, pn, InAllowed, yieldHandling, funName,
|
||||
return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, funName,
|
||||
kind, generatorKind, asyncKind);
|
||||
}
|
||||
|
||||
|
|
@ -10515,7 +10520,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling
|
|||
case TOK_THIS: {
|
||||
if (pc->isFunctionBox())
|
||||
pc->functionBox()->usesThis = true;
|
||||
Node thisName = null();
|
||||
NameNodeType thisName = null();
|
||||
if (pc->sc()->thisBinding() == ThisBinding::Function) {
|
||||
thisName = newThisName();
|
||||
if (!thisName)
|
||||
|
|
|
|||
|
|
@ -1085,7 +1085,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
* cx->tempLifoAlloc.
|
||||
*/
|
||||
ObjectBox* newObjectBox(JSObject* obj);
|
||||
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
|
||||
FunctionBox* newFunctionBox(CodeNodeType funNode, JSFunction* fun, uint32_t toStringStart,
|
||||
Directives directives,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
bool tryAnnexB);
|
||||
|
|
@ -1105,9 +1105,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
|
||||
JSAtom* stopStringCompression();
|
||||
|
||||
Node stringLiteral();
|
||||
NameNodeType stringLiteral();
|
||||
Node noSubstitutionTaggedTemplate();
|
||||
Node noSubstitutionUntaggedTemplate();
|
||||
NameNodeType noSubstitutionUntaggedTemplate();
|
||||
ListNodeType templateLiteral(YieldHandling yieldHandling);
|
||||
bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt);
|
||||
bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
|
||||
|
|
@ -1115,8 +1115,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
TokenKind* ttp);
|
||||
bool checkStatementsEOF();
|
||||
|
||||
inline Node newName(PropertyName* name);
|
||||
inline Node newName(PropertyName* name, TokenPos pos);
|
||||
inline NameNodeType newName(PropertyName* name);
|
||||
inline NameNodeType newName(PropertyName* name, TokenPos pos);
|
||||
|
||||
inline bool abortIfSyntaxParser();
|
||||
|
||||
|
|
@ -1138,23 +1138,23 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
ListNodeType globalBody(GlobalSharedContext* globalsc);
|
||||
|
||||
// Parse a module.
|
||||
Node moduleBody(ModuleSharedContext* modulesc);
|
||||
CodeNodeType moduleBody(ModuleSharedContext* modulesc);
|
||||
|
||||
// Parse a function, used for the Function, GeneratorFunction, and
|
||||
// AsyncFunction constructors.
|
||||
Node standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
|
||||
mozilla::Maybe<uint32_t> parameterListEnd,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
CodeNodeType standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
|
||||
mozilla::Maybe<uint32_t> parameterListEnd,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
|
||||
// Parse a function, given only its arguments and body. Used for lazily
|
||||
// parsed functions.
|
||||
Node standaloneLazyFunction(HandleFunction fun, bool strict,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
|
||||
CodeNodeType standaloneLazyFunction(HandleFunction fun, bool strict,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
|
||||
|
||||
// Parse an inner function given an enclosing ParseContext and a
|
||||
// FunctionBox for the inner function.
|
||||
bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart,
|
||||
bool innerFunction(CodeNodeType funNode, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
|
|
@ -1162,7 +1162,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
// Parse a function's formal parameters and its body assuming its function
|
||||
// ParseContext is already on the stack.
|
||||
bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
|
||||
Node pn, FunctionSyntaxKind kind,
|
||||
CodeNodeType funNode, FunctionSyntaxKind kind,
|
||||
mozilla::Maybe<uint32_t> parameterListEnd = mozilla::Nothing(),
|
||||
bool isStandaloneFunction = false);
|
||||
|
||||
|
|
@ -1188,11 +1188,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
* Some parsers have two versions: an always-inlined version (with an 'i'
|
||||
* suffix) and a never-inlined version (with an 'n' suffix).
|
||||
*/
|
||||
Node functionStmt(uint32_t toStringStart,
|
||||
YieldHandling yieldHandling, DefaultHandling defaultHandling,
|
||||
FunctionAsyncKind asyncKind = SyncFunction);
|
||||
Node functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked,
|
||||
FunctionAsyncKind asyncKind = SyncFunction);
|
||||
CodeNodeType functionStmt(uint32_t toStringStart,
|
||||
YieldHandling yieldHandling, DefaultHandling defaultHandling,
|
||||
FunctionAsyncKind asyncKind = SyncFunction);
|
||||
CodeNodeType functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked,
|
||||
FunctionAsyncKind asyncKind = SyncFunction);
|
||||
|
||||
ListNodeType statementList(YieldHandling yieldHandling);
|
||||
|
||||
|
|
@ -1222,7 +1222,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
|
||||
Node variableStatement(YieldHandling yieldHandling);
|
||||
|
||||
Node labeledStatement(YieldHandling yieldHandling);
|
||||
LabeledStatementType labeledStatement(YieldHandling yieldHandling);
|
||||
Node labeledItem(YieldHandling yieldHandling);
|
||||
|
||||
TernaryNodeType ifStatement(YieldHandling yieldHandling);
|
||||
|
|
@ -1295,16 +1295,16 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
Node declarationPattern(Node decl, DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
|
||||
Node declarationName(Node decl, DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
|
||||
NameNodeType declarationName(Node decl, DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
|
||||
|
||||
// Having parsed a name (not found in a destructuring pattern) declared by
|
||||
// a declaration, with the current token being the '=' separating the name
|
||||
// from its initializer, parse and bind that initializer -- and possibly
|
||||
// consume trailing in/of and subsequent expression, if so directed by
|
||||
// |forHeadKind|.
|
||||
bool initializerInNameDeclaration(Node decl, Node binding, Handle<PropertyName*> name,
|
||||
bool initializerInNameDeclaration(Node decl, NameNodeType binding, Handle<PropertyName*> name,
|
||||
DeclarationKind declKind, bool initialDeclaration,
|
||||
YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression);
|
||||
|
|
@ -1346,19 +1346,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
bool tryNewTarget(BinaryNodeType* newTarget);
|
||||
bool checkAndMarkSuperScope();
|
||||
|
||||
Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
|
||||
CodeNodeType methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
|
||||
|
||||
/*
|
||||
* Additional JS parsers.
|
||||
*/
|
||||
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
|
||||
Node funcpn);
|
||||
CodeNodeType funNode);
|
||||
|
||||
Node functionDefinition(uint32_t toStringStart, Node pn,
|
||||
InHandling inHandling, YieldHandling yieldHandling, HandleAtom name,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
bool tryAnnexB = false);
|
||||
CodeNodeType functionDefinition(uint32_t toStringStart, CodeNodeType funNode,
|
||||
InHandling inHandling, YieldHandling yieldHandling, HandleAtom name,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
bool tryAnnexB = false);
|
||||
|
||||
// Parse a function body. Pass StatementListBody if the body is a list of
|
||||
// statements; pass ExpressionBody if the body is a single expression.
|
||||
|
|
@ -1393,8 +1393,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
bool checkExportedNamesForDeclaration(Node node);
|
||||
bool checkExportedNamesForDeclarationList(ListNodeType node);
|
||||
|
||||
bool checkExportedNameForClause(Node node);
|
||||
bool checkExportedNameForFunction(Node node);
|
||||
bool checkExportedNameForClause(NameNodeType funNode);
|
||||
bool checkExportedNameForFunction(CodeNodeType funNode);
|
||||
bool checkExportedNameForClass(ClassNodeType classNode);
|
||||
|
||||
enum ClassContext { ClassStatement, ClassExpression };
|
||||
|
|
@ -1427,7 +1427,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
return bindingIdentifier(YieldIsName);
|
||||
}
|
||||
|
||||
Node identifierReference(Handle<PropertyName*> name);
|
||||
NameNodeType identifierReference(Handle<PropertyName*> name);
|
||||
|
||||
bool matchLabel(YieldHandling yieldHandling, MutableHandle<PropertyName*> label);
|
||||
|
||||
|
|
@ -1444,19 +1444,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
bool hasUsedFunctionSpecialName(HandlePropertyName name);
|
||||
bool declareFunctionArgumentsObject();
|
||||
bool declareFunctionThis();
|
||||
Node newInternalDotName(HandlePropertyName name);
|
||||
Node newThisName();
|
||||
Node newDotGeneratorName();
|
||||
NameNodeType newInternalDotName(HandlePropertyName name);
|
||||
NameNodeType newThisName();
|
||||
NameNodeType newDotGeneratorName();
|
||||
bool declareDotGeneratorName();
|
||||
|
||||
bool skipLazyInnerFunction(Node pn, uint32_t toStringStart, FunctionSyntaxKind kind,
|
||||
bool skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart, FunctionSyntaxKind kind,
|
||||
bool tryAnnexB);
|
||||
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart,
|
||||
bool innerFunction(CodeNodeType funNode, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, uint32_t toStringStart,
|
||||
bool trySyntaxParseInnerFunction(CodeNodeType funNode, HandleFunction fun, uint32_t toStringStart,
|
||||
InHandling inHandling, YieldHandling yieldHandling,
|
||||
FunctionSyntaxKind kind,
|
||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
|
|
@ -1489,9 +1489,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
|
||||
void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos,
|
||||
uint32_t prevPos);
|
||||
bool notePositionalFormalParameter(Node fn, HandlePropertyName name, uint32_t beginPos,
|
||||
bool notePositionalFormalParameter(CodeNodeType funNode, HandlePropertyName name, uint32_t beginPos,
|
||||
bool disallowDuplicateParams, bool* duplicatedParam);
|
||||
bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct);
|
||||
bool noteDestructuredPositionalFormalParameter(CodeNodeType funNode, Node destruct);
|
||||
mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
|
||||
DeclarationKind kind);
|
||||
bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
|
||||
|
|
@ -1522,12 +1522,12 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
UnaryNodeType computedPropertyName(YieldHandling yieldHandling,
|
||||
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType literal);
|
||||
ListNodeType arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
Node newRegExp();
|
||||
RegExpLiteralType newRegExp();
|
||||
|
||||
ListNodeType objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
|
||||
|
||||
BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
|
||||
Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
|
||||
NameNodeType bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
|
||||
Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
|
||||
TokenKind tt);
|
||||
ListNodeType objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
|
||||
|
|
@ -1538,7 +1538,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
|
||||
PossibleError* possibleError);
|
||||
|
||||
Node newNumber(const Token& tok) {
|
||||
NumericLiteralType newNumber(const Token& tok) {
|
||||
return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
void initWithEnclosingScope(Scope* enclosingScope);
|
||||
|
||||
public:
|
||||
ParseNode* functionNode; /* back pointer used by asm.js for error messages */
|
||||
CodeNode* functionNode; /* back pointer used by asm.js for error messages */
|
||||
uint32_t bufStart;
|
||||
uint32_t bufEnd;
|
||||
uint32_t startLine;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
|
||||
void trace(JSTracer* trc) {}
|
||||
|
||||
Node newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) {
|
||||
NameNodeType newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) {
|
||||
lastAtom = name;
|
||||
if (name == cx->names().arguments)
|
||||
return NodeUnparenthesizedArgumentsName;
|
||||
|
|
@ -219,20 +219,20 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return NodeGeneric;
|
||||
}
|
||||
|
||||
Node newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
|
||||
NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) {
|
||||
return NodeUnparenthesizedName;
|
||||
}
|
||||
|
||||
Node newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return NodeGeneric; }
|
||||
NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return NodeGeneric; }
|
||||
Node newBooleanLiteral(bool cond, const TokenPos& pos) { return NodeGeneric; }
|
||||
|
||||
Node newStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
lastAtom = atom;
|
||||
lastStringPos = pos;
|
||||
return NodeUnparenthesizedString;
|
||||
}
|
||||
|
||||
Node newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +247,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
Node newRawUndefinedLiteral(const TokenPos& pos) { return NodeGeneric; }
|
||||
|
||||
template <class Boxer>
|
||||
Node newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; }
|
||||
RegExpLiteralType newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; }
|
||||
|
||||
ConditionalExpressionType newConditional(Node cond, Node thenExpr, Node elseExpr) {
|
||||
return NodeGeneric;
|
||||
|
|
@ -322,10 +322,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
|
||||
MOZ_MUST_USE bool addPrototypeMutation(ListNodeType literal, uint32_t begin, Node expr) { return true; }
|
||||
MOZ_MUST_USE bool addPropertyDefinition(ListNodeType literal, Node name, Node expr) { return true; }
|
||||
MOZ_MUST_USE bool addShorthand(ListNodeType literal, Node name, Node expr) { return true; }
|
||||
MOZ_MUST_USE bool addShorthand(ListNodeType literal, NameNodeType name, NameNodeType expr) { return true; }
|
||||
MOZ_MUST_USE bool addSpreadProperty(ListNodeType literal, uint32_t begin, Node inner) { return true; }
|
||||
MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node name, Node fn, JSOp op) { return true; }
|
||||
MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType literal, Node name, Node fn, JSOp op, bool isStatic) { return true; }
|
||||
MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node name, CodeNodeType funNode, JSOp op) { return true; }
|
||||
MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType literal, Node name, CodeNodeType funNode, JSOp op, bool isStatic) { return true; }
|
||||
UnaryNodeType newYieldExpression(uint32_t begin, Node value) { return NodeGeneric; }
|
||||
UnaryNodeType newYieldStarExpression(uint32_t begin, Node value) { return NodeGeneric; }
|
||||
UnaryNodeType newAwaitExpression(uint32_t begin, Node value) { return NodeGeneric; }
|
||||
|
|
@ -370,7 +370,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
UnaryNodeType newReturnStatement(Node expr, const TokenPos& pos) { return NodeReturn; }
|
||||
BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
|
||||
|
||||
Node newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) {
|
||||
LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
|
|
@ -380,16 +380,16 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
}
|
||||
Node newDebuggerStatement(const TokenPos& pos) { return NodeGeneric; }
|
||||
|
||||
Node newPropertyName(PropertyName* name, const TokenPos& pos) {
|
||||
NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) {
|
||||
lastAtom = name;
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
PropertyAccessType newPropertyAccess(Node expr, Node key) {
|
||||
PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
|
||||
return NodeDottedProperty;
|
||||
}
|
||||
|
||||
Node newOptionalPropertyAccess(Node expr, Node key) {
|
||||
Node newOptionalPropertyAccess(Node expr, NameNodeType key) {
|
||||
return NodeOptionalDottedProperty;
|
||||
}
|
||||
|
||||
|
|
@ -400,19 +400,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
MOZ_MUST_USE bool addCatchBlock(ListNodeType catchList, Node letBlock, Node catchBinding,
|
||||
Node catchGuard, Node catchBody) { return true; }
|
||||
|
||||
MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(Node funcpn, Node pn) { return true; }
|
||||
MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(CodeNodeType funNode, Node pn) { return true; }
|
||||
|
||||
void checkAndSetIsDirectRHSAnonFunction(Node pn) {}
|
||||
|
||||
Node newFunctionStatement() { return NodeFunctionDefinition; }
|
||||
Node newFunctionExpression() { return NodeFunctionDefinition; }
|
||||
Node newArrowFunction() { return NodeFunctionDefinition; }
|
||||
CodeNodeType newFunctionStatement() { return NodeFunctionDefinition; }
|
||||
CodeNodeType newFunctionExpression() { return NodeFunctionDefinition; }
|
||||
CodeNodeType newArrowFunction() { return NodeFunctionDefinition; }
|
||||
|
||||
bool setComprehensionLambdaBody(Node pn, Node body) { return true; }
|
||||
void setFunctionFormalParametersAndBody(Node pn, Node kid) {}
|
||||
void setFunctionBody(Node pn, Node kid) {}
|
||||
void setFunctionBox(Node pn, FunctionBox* funbox) {}
|
||||
void addFunctionFormalParameter(Node pn, Node argpn) {}
|
||||
bool setComprehensionLambdaBody(CodeNodeType funNode, ListNodeType body) { return true; }
|
||||
void setFunctionFormalParametersAndBody(CodeNodeType funNode, ListNodeType paramsBody) {}
|
||||
void setFunctionBody(CodeNodeType funNode, Node body) {}
|
||||
void setFunctionBox(CodeNodeType funNode, FunctionBox* funbox) {}
|
||||
void addFunctionFormalParameter(CodeNodeType funNode, Node argpn) {}
|
||||
|
||||
ForNodeType newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags) {
|
||||
return NodeGeneric;
|
||||
|
|
@ -438,7 +438,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
return NodeGeneric;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool finishInitializerAssignment(Node pn, Node init) { return true; }
|
||||
MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode, Node init) { return true; }
|
||||
|
||||
void setBeginPosition(Node pn, Node oth) {}
|
||||
void setBeginPosition(Node pn, uint32_t begin) {}
|
||||
|
|
@ -587,8 +587,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
// to the unparenthesized form: return |node| unchanged.
|
||||
return node;
|
||||
}
|
||||
MOZ_MUST_USE Node setLikelyIIFE(Node pn) {
|
||||
return pn; // Remain in syntax-parse mode.
|
||||
template <typename NodeType>
|
||||
MOZ_MUST_USE NodeType setLikelyIIFE(NodeType node) {
|
||||
return node; // Remain in syntax-parse mode.
|
||||
}
|
||||
void setInDirectivePrologue(UnaryNodeType exprStmt) {}
|
||||
|
||||
|
|
|
|||
|
|
@ -617,15 +617,13 @@ LabeledStatementStatement(ParseNode* pn)
|
|||
static double
|
||||
NumberNodeValue(ParseNode* pn)
|
||||
{
|
||||
MOZ_ASSERT(pn->isKind(PNK_NUMBER));
|
||||
return pn->pn_dval;
|
||||
return pn->as<NumericLiteral>().value();
|
||||
}
|
||||
|
||||
static bool
|
||||
NumberNodeHasFrac(ParseNode* pn)
|
||||
{
|
||||
MOZ_ASSERT(pn->isKind(PNK_NUMBER));
|
||||
return pn->pn_u.number.decimalPoint == HasDecimal;
|
||||
return pn->as<NumericLiteral>().decimalPoint() == HasDecimal;
|
||||
}
|
||||
|
||||
static ParseNode*
|
||||
|
|
@ -653,26 +651,25 @@ ElemIndex(ParseNode* pn)
|
|||
}
|
||||
|
||||
static inline JSFunction*
|
||||
FunctionObject(ParseNode* fn)
|
||||
FunctionObject(CodeNode* funNode)
|
||||
{
|
||||
MOZ_ASSERT(fn->isKind(PNK_FUNCTION));
|
||||
MOZ_ASSERT(fn->isArity(PN_CODE));
|
||||
return fn->pn_funbox->function();
|
||||
MOZ_ASSERT(funNode->isKind(PNK_FUNCTION));
|
||||
return funNode->funbox()->function();
|
||||
}
|
||||
|
||||
static inline PropertyName*
|
||||
FunctionName(ParseNode* fn)
|
||||
FunctionName(CodeNode* funNode)
|
||||
{
|
||||
if (JSAtom* name = FunctionObject(fn)->explicitName())
|
||||
if (JSAtom* name = FunctionObject(funNode)->explicitName())
|
||||
return name->asPropertyName();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
FunctionStatementList(ParseNode* fn)
|
||||
FunctionStatementList(CodeNode* funNode)
|
||||
{
|
||||
MOZ_ASSERT(fn->pn_body->isKind(PNK_PARAMSBODY));
|
||||
ParseNode* last = fn->pn_body->as<ListNode>().last();
|
||||
MOZ_ASSERT(funNode->body()->isKind(PNK_PARAMSBODY));
|
||||
ParseNode* last = funNode->body()->as<ListNode>().last();
|
||||
MOZ_ASSERT(last->isKind(PNK_LEXICALSCOPE));
|
||||
MOZ_ASSERT(last->isEmptyScope());
|
||||
ParseNode* body = last->scopeBody();
|
||||
|
|
@ -693,7 +690,7 @@ ObjectNormalFieldName(ExclusiveContext* cx, ParseNode* pn)
|
|||
{
|
||||
MOZ_ASSERT(IsNormalObjectField(cx, pn));
|
||||
MOZ_ASSERT(BinaryLeft(pn)->isKind(PNK_OBJECT_PROPERTY_NAME));
|
||||
return BinaryLeft(pn)->pn_atom->asPropertyName();
|
||||
return BinaryLeft(pn)->as<NameNode>().atom()->asPropertyName();
|
||||
}
|
||||
|
||||
static inline ParseNode*
|
||||
|
|
@ -706,7 +703,7 @@ ObjectNormalFieldInitializer(ExclusiveContext* cx, ParseNode* pn)
|
|||
static inline ParseNode*
|
||||
MaybeInitializer(ParseNode* pn)
|
||||
{
|
||||
return pn->expr();
|
||||
return pn->as<NameNode>().initializer();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -727,7 +724,7 @@ IsIgnoredDirective(ExclusiveContext* cx, ParseNode* pn)
|
|||
return pn->isKind(PNK_SEMI) &&
|
||||
UnaryKid(pn) &&
|
||||
UnaryKid(pn)->isKind(PNK_STRING) &&
|
||||
IsIgnoredDirectiveName(cx, UnaryKid(pn)->pn_atom);
|
||||
IsIgnoredDirectiveName(cx, UnaryKid(pn)->as<NameNode>().atom());
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -1620,7 +1617,7 @@ class MOZ_STACK_CLASS ModuleValidator
|
|||
|
||||
ExclusiveContext* cx_;
|
||||
AsmJSParser& parser_;
|
||||
ParseNode* moduleFunctionNode_;
|
||||
CodeNode* moduleFunctionNode_;
|
||||
PropertyName* moduleFunctionName_;
|
||||
PropertyName* globalArgumentName_;
|
||||
PropertyName* importArgumentName_;
|
||||
|
|
@ -1699,7 +1696,7 @@ class MOZ_STACK_CLASS ModuleValidator
|
|||
}
|
||||
|
||||
public:
|
||||
ModuleValidator(ExclusiveContext* cx, AsmJSParser& parser, ParseNode* moduleFunctionNode)
|
||||
ModuleValidator(ExclusiveContext* cx, AsmJSParser& parser, CodeNode* moduleFunctionNode)
|
||||
: cx_(cx),
|
||||
parser_(parser),
|
||||
moduleFunctionNode_(moduleFunctionNode),
|
||||
|
|
@ -1742,8 +1739,8 @@ class MOZ_STACK_CLASS ModuleValidator
|
|||
if (!asmJSMetadata_)
|
||||
return false;
|
||||
|
||||
asmJSMetadata_->toStringStart = moduleFunctionNode_->pn_funbox->toStringStart;
|
||||
asmJSMetadata_->srcStart = moduleFunctionNode_->pn_body->pn_pos.begin;
|
||||
asmJSMetadata_->toStringStart = moduleFunctionNode_->funbox()->toStringStart;
|
||||
asmJSMetadata_->srcStart = moduleFunctionNode_->body()->pn_pos.begin;
|
||||
asmJSMetadata_->srcBodyStart = parser_.tokenStream.currentToken().pos.end;
|
||||
asmJSMetadata_->strict = parser_.pc->sc()->strict() &&
|
||||
!parser_.pc->sc()->hasExplicitUseStrict();
|
||||
|
|
@ -3231,14 +3228,15 @@ CheckModuleLevelName(ModuleValidator& m, ParseNode* usepn, PropertyName* name)
|
|||
}
|
||||
|
||||
static bool
|
||||
CheckFunctionHead(ModuleValidator& m, ParseNode* fn)
|
||||
CheckFunctionHead(ModuleValidator& m, CodeNode* funNode)
|
||||
{
|
||||
if (fn->pn_funbox->hasRest())
|
||||
return m.fail(fn, "rest args not allowed");
|
||||
if (fn->pn_funbox->isExprBody())
|
||||
return m.fail(fn, "expression closures not allowed");
|
||||
if (fn->pn_funbox->hasDestructuringArgs)
|
||||
return m.fail(fn, "destructuring args not allowed");
|
||||
FunctionBox* funbox = funNode->funbox();
|
||||
MOZ_ASSERT(!funbox->isExprBody());
|
||||
|
||||
if (funbox->hasRest())
|
||||
return m.fail(funNode, "rest args not allowed");
|
||||
if (funbox->hasDestructuringArgs)
|
||||
return m.fail(funNode, "destructuring args not allowed");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3270,15 +3268,15 @@ CheckModuleArgument(ModuleValidator& m, ParseNode* arg, PropertyName** name)
|
|||
}
|
||||
|
||||
static bool
|
||||
CheckModuleArguments(ModuleValidator& m, ParseNode* fn)
|
||||
CheckModuleArguments(ModuleValidator& m, CodeNode* funNode)
|
||||
{
|
||||
unsigned numFormals;
|
||||
ParseNode* arg1 = FunctionFormalParametersList(fn, &numFormals);
|
||||
ParseNode* arg1 = FunctionFormalParametersList(funNode, &numFormals);
|
||||
ParseNode* arg2 = arg1 ? NextNode(arg1) : nullptr;
|
||||
ParseNode* arg3 = arg2 ? NextNode(arg2) : nullptr;
|
||||
|
||||
if (numFormals > 3)
|
||||
return m.fail(fn, "asm.js modules takes at most 3 argument");
|
||||
return m.fail(funNode, "asm.js modules takes at most 3 argument");
|
||||
|
||||
PropertyName* arg1Name = nullptr;
|
||||
if (arg1 && !CheckModuleArgument(m, arg1, &arg1Name))
|
||||
|
|
@ -7030,7 +7028,7 @@ CheckStatement(FunctionValidator& f, ParseNode* stmt)
|
|||
}
|
||||
|
||||
static bool
|
||||
ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
||||
ParseFunction(ModuleValidator& m, CodeNode** funNodeOut, unsigned* line)
|
||||
{
|
||||
TokenStream& tokenStream = m.tokenStream();
|
||||
|
||||
|
|
@ -7048,8 +7046,8 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
|||
if (!name)
|
||||
return false;
|
||||
|
||||
ParseNode* fn = m.parser().handler.newFunctionStatement();
|
||||
if (!fn)
|
||||
CodeNode* funNode = m.parser().handler.newFunctionStatement();
|
||||
if (!funNode)
|
||||
return false;
|
||||
|
||||
RootedFunction& fun = m.dummyFunction();
|
||||
|
|
@ -7058,7 +7056,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
|||
|
||||
ParseContext* outerpc = m.parser().pc;
|
||||
Directives directives(outerpc);
|
||||
FunctionBox* funbox = m.parser().newFunctionBox(fn, fun, toStringStart, directives, NotGenerator,
|
||||
FunctionBox* funbox = m.parser().newFunctionBox(funNode, fun, toStringStart, directives, NotGenerator,
|
||||
SyncFunction, /* tryAnnexB = */ false);
|
||||
if (!funbox)
|
||||
return false;
|
||||
|
|
@ -7069,17 +7067,17 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
|||
if (!funpc.init())
|
||||
return false;
|
||||
|
||||
if (!m.parser().functionFormalParametersAndBody(InAllowed, YieldIsName, fn, Statement)) {
|
||||
if (!m.parser().functionFormalParametersAndBody(InAllowed, YieldIsName, funNode, Statement)) {
|
||||
if (tokenStream.hadError() || directives == newDirectives)
|
||||
return false;
|
||||
|
||||
return m.fail(fn, "encountered new directive in function");
|
||||
return m.fail(funNode, "encountered new directive in function");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!tokenStream.hadError());
|
||||
MOZ_ASSERT(directives == newDirectives);
|
||||
|
||||
*fnOut = fn;
|
||||
*funNodeOut = funNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -7090,19 +7088,19 @@ CheckFunction(ModuleValidator& m)
|
|||
// the backing LifoAlloc after parsing/compiling each function.
|
||||
AsmJSParser::Mark mark = m.parser().mark();
|
||||
|
||||
ParseNode* fn = nullptr;
|
||||
CodeNode* funNode = nullptr;
|
||||
unsigned line = 0;
|
||||
if (!ParseFunction(m, &fn, &line))
|
||||
if (!ParseFunction(m, &funNode, &line))
|
||||
return false;
|
||||
|
||||
if (!CheckFunctionHead(m, fn))
|
||||
if (!CheckFunctionHead(m, funNode))
|
||||
return false;
|
||||
|
||||
FunctionValidator f(m, fn);
|
||||
if (!f.init(FunctionName(fn), line))
|
||||
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
||||
FunctionValidator f(m, funNode);
|
||||
if (!f.init(FunctionName(funNode), line))
|
||||
return m.fail(funNode, "internal compiler failure (probably out of memory)");
|
||||
|
||||
ParseNode* stmtIter = ListHead(FunctionStatementList(fn));
|
||||
ParseNode* stmtIter = ListHead(FunctionStatementList(funNode));
|
||||
|
||||
if (!CheckProcessingDirectives(m, &stmtIter))
|
||||
return false;
|
||||
|
|
@ -7125,16 +7123,16 @@ CheckFunction(ModuleValidator& m)
|
|||
return false;
|
||||
|
||||
ModuleValidator::Func* func = nullptr;
|
||||
if (!CheckFunctionSignature(m, fn, Sig(Move(args), f.returnedType()), FunctionName(fn), &func))
|
||||
if (!CheckFunctionSignature(m, funNode, Sig(Move(args), f.returnedType()), FunctionName(funNode), &func))
|
||||
return false;
|
||||
|
||||
if (func->defined())
|
||||
return m.failName(fn, "function '%s' already defined", FunctionName(fn));
|
||||
return m.failName(funNode, "function '%s' already defined", FunctionName(funNode));
|
||||
|
||||
func->define(fn);
|
||||
func->define(funNode);
|
||||
|
||||
if (!f.finish(func->index()))
|
||||
return m.fail(fn, "internal compiler failure (probably out of memory)");
|
||||
return m.fail(funNode, "internal compiler failure (probably out of memory)");
|
||||
|
||||
// Release the parser's lifo memory only after the last use of a parse node.
|
||||
m.parser().release(mark);
|
||||
|
|
@ -7340,8 +7338,7 @@ CheckModule(ExclusiveContext* cx, AsmJSParser& parser, ParseNode* stmtList, unsi
|
|||
{
|
||||
int64_t before = PRMJ_Now();
|
||||
|
||||
ParseNode* moduleFunctionNode = parser.pc->functionBox()->functionNode;
|
||||
MOZ_ASSERT(moduleFunctionNode);
|
||||
CodeNode* moduleFunctionNode = parser.pc->functionBox()->functionNode;
|
||||
|
||||
ModuleValidator m(cx, parser, moduleFunctionNode);
|
||||
if (!m.init())
|
||||
|
|
@ -8297,7 +8294,7 @@ class ModuleCharsForStore : ModuleChars
|
|||
isFunCtor_ = parser.pc->isStandaloneFunctionBody();
|
||||
if (isFunCtor_) {
|
||||
unsigned numArgs;
|
||||
ParseNode* functionNode = parser.pc->functionBox()->functionNode;
|
||||
CodeNode* functionNode = parser.pc->functionBox()->functionNode;
|
||||
ParseNode* arg = FunctionFormalParametersList(functionNode, &numArgs);
|
||||
for (unsigned i = 0; i < numArgs; i++, arg = arg->pn_next) {
|
||||
UniqueChars name = StringToNewUTF8CharsZ(nullptr, *arg->name());
|
||||
|
|
@ -8378,7 +8375,7 @@ class ModuleCharsForLookup : ModuleChars
|
|||
if (parseBegin + chars_.length() != parseLimit)
|
||||
return false;
|
||||
unsigned numArgs;
|
||||
ParseNode* functionNode = parser.pc->functionBox()->functionNode;
|
||||
CodeNode* functionNode = parser.pc->functionBox()->functionNode;
|
||||
ParseNode* arg = FunctionFormalParametersList(functionNode, &numArgs);
|
||||
if (funCtorArgs_.length() != numArgs)
|
||||
return false;
|
||||
|
|
@ -8539,7 +8536,7 @@ LookupAsmJSModuleInCache(ExclusiveContext* cx, AsmJSParser& parser, bool* loaded
|
|||
|
||||
// See AsmJSMetadata comment as well as ModuleValidator::init().
|
||||
asmJSMetadata->toStringStart = parser.pc->functionBox()->toStringStart;
|
||||
asmJSMetadata->srcStart = parser.pc->functionBox()->functionNode->pn_body->pn_pos.begin;
|
||||
asmJSMetadata->srcStart = parser.pc->functionBox()->functionNode->body()->pn_pos.begin;
|
||||
asmJSMetadata->srcBodyStart = parser.tokenStream.currentToken().pos.end;
|
||||
asmJSMetadata->strict = parser.pc->sc()->strict() && !parser.pc->sc()->hasExplicitUseStrict();
|
||||
asmJSMetadata->scriptSource.reset(parser.ss);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue