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:
Martok 2023-03-31 23:52:57 +02:00 committed by roytam1
commit ba730c488f
16 changed files with 994 additions and 796 deletions

View file

@ -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 {

View file

@ -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 = &paramsBody->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);

View file

@ -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))

View file

@ -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;
}

View file

@ -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);

View file

@ -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 = &current->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");

View file

@ -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;
}

View file

@ -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.

View file

@ -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 */

View file

@ -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)

View file

@ -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 &&

View file

@ -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)

View file

@ -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);
}

View file

@ -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;

View file

@ -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) {}

View file

@ -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);