Issue #2173 - Add accessors to UnaryNode and subclasses

Based-on: m-c 1479659/4
This commit is contained in:
Martok 2023-03-27 08:38:11 +02:00 • committed by roytam1
commit 68a407c935
13 changed files with 502 additions and 473 deletions

View file

@ -1210,10 +1210,11 @@ ModuleBuilder::processExport(frontend::ParseNode* exportNode)
{
MOZ_ASSERT(exportNode->isKind(PNK_EXPORT) ||
exportNode->isKind(PNK_EXPORT_DEFAULT));
MOZ_ASSERT_IF(exportNode->isKind(PNK_EXPORT), exportNode->is<UnaryNode>());
bool isDefault = exportNode->isKind(PNK_EXPORT_DEFAULT);
ParseNode* kid = isDefault ? exportNode->as<BinaryNode>().left() : exportNode->pn_kid;
ParseNode* kid = isDefault
? exportNode->as<BinaryNode>().left()
: exportNode->as<UnaryNode>().kid();
if (isDefault && exportNode->as<BinaryNode>().right()) {
// This is an export default containing an expression.
@ -1321,7 +1322,7 @@ ModuleBuilder::processExportArrayBinding(frontend::ListNode* array)
continue;
if (node->isKind(PNK_SPREAD))
node = node->pn_kid;
node = node->as<UnaryNode>().kid();
else if (node->isKind(PNK_ASSIGN))
node = node->as<AssignmentNode>().left();
@ -1345,10 +1346,10 @@ ModuleBuilder::processExportObjectBinding(frontend::ListNode* obj)
ParseNode* target;
if (node->isKind(PNK_SPREAD)) {
target = node->pn_kid;
target = node->as<UnaryNode>().kid();
} else {
if (node->isKind(PNK_MUTATEPROTO))
target = node->pn_kid;
target = node->as<UnaryNode>().kid();
else
target = node->as<BinaryNode>().right();

View file

@ -2214,7 +2214,7 @@ ASTSerializer::exportDeclaration(ParseNode* exportNode, MutableHandleValue dst)
NodeVector elts(cx);
ParseNode* kid = exportNode->isKind(PNK_EXPORT)
? exportNode->pn_kid
? exportNode->as<UnaryNode>().kid()
: exportNode->as<BinaryNode>().left();
switch (ParseNodeKind kind = kid->getKind()) {
case PNK_EXPORT_SPEC_LIST: {
@ -2468,9 +2468,9 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return exportDeclaration(pn, dst);
case PNK_SEMI:
if (pn->pn_kid) {
if (pn->as<UnaryNode>().kid()) {
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
return expression(pn->as<UnaryNode>().kid(), &expr) &&
builder.expressionStatement(expr, &pn->pn_pos, dst);
}
return builder.emptyStatement(&pn->pn_pos, dst);
@ -2629,22 +2629,26 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
case PNK_THROW:
{
MOZ_ASSERT_IF(pn->pn_kid, pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* throwNode = &pn->as<UnaryNode>();
ParseNode* operand = throwNode->kid();
MOZ_ASSERT(throwNode->pn_pos.encloses(operand->pn_pos));
RootedValue arg(cx);
return optExpression(pn->pn_kid, &arg) &&
builder.throwStatement(arg, &pn->pn_pos, dst);
return expression(operand, &arg) &&
builder.throwStatement(arg, &throwNode->pn_pos, dst);
}
case PNK_RETURN:
{
MOZ_ASSERT_IF(pn->pn_kid, pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* returnNode = &pn->as<UnaryNode>();
ParseNode* operand = returnNode->kid();
MOZ_ASSERT_IF(operand, returnNode->pn_pos.encloses(operand->pn_pos));
RootedValue arg(cx);
return optExpression(pn->pn_kid, &arg) &&
builder.returnStatement(arg, &pn->pn_pos, dst);
return optExpression(operand, &arg) &&
builder.returnStatement(arg, &returnNode->pn_pos, dst);
}
case PNK_DEBUGGER:
@ -2865,7 +2869,7 @@ ASTSerializer::comprehension(ParseNode* pn, MutableHandleValue dst)
RootedValue body(cx);
return expression(next->pn_kid, &body) &&
return expression(next->as<UnaryNode>().kid(), &body) &&
builder.comprehensionExpression(body, blocks, filter, isLegacy, &pn->pn_pos, dst);
}
@ -2907,13 +2911,14 @@ ASTSerializer::generatorExpression(ParseNode* pn, MutableHandleValue dst)
}
}
LOCAL_ASSERT(next->isKind(PNK_SEMI) &&
next->pn_kid->isKind(PNK_YIELD) &&
next->pn_kid->pn_kid);
LOCAL_ASSERT(next->isKind(PNK_SEMI));
ParseNode* yieldNode = next->as<UnaryNode>().kid();
LOCAL_ASSERT(yieldNode->isKind(PNK_YIELD) &&
yieldNode->as<UnaryNode>().kid());
RootedValue body(cx);
return expression(next->pn_kid->pn_kid, &body) &&
return expression(yieldNode->as<UnaryNode>().kid(), &body) &&
builder.generatorExpression(body, blocks, filter, isLegacy, &pn->pn_pos, dst);
}
@ -2961,23 +2966,27 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_PREINCREMENT:
case PNK_PREDECREMENT:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* incDec = &pn->as<UnaryNode>();
ParseNode* operand = incDec->kid();
MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos));
bool inc = pn->isKind(PNK_PREINCREMENT);
bool inc = incDec->isKind(PNK_PREINCREMENT);
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
builder.updateExpression(expr, inc, true, &pn->pn_pos, dst);
return expression(operand, &expr) &&
builder.updateExpression(expr, inc, true, &incDec->pn_pos, dst);
}
case PNK_POSTINCREMENT:
case PNK_POSTDECREMENT:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* incDec = &pn->as<UnaryNode>();
ParseNode* operand = incDec->kid();
MOZ_ASSERT(incDec->pn_pos.encloses(operand->pn_pos));
bool inc = pn->isKind(PNK_POSTINCREMENT);
bool inc = incDec->isKind(PNK_POSTINCREMENT);
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
builder.updateExpression(expr, inc, false, &pn->pn_pos, dst);
return expression(operand, &expr) &&
builder.updateExpression(expr, inc, false, &incDec->pn_pos, dst);
}
case PNK_ASSIGN:
@ -3047,14 +3056,16 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_POS:
case PNK_AWAIT:
case PNK_NEG: {
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* unaryNode = &pn->as<UnaryNode>();
ParseNode* operand = unaryNode->kid();
MOZ_ASSERT(unaryNode->pn_pos.encloses(operand->pn_pos));
UnaryOperator op = unop(pn->getKind(), pn->getOp());
UnaryOperator op = unop(unaryNode->getKind(), unaryNode->getOp());
LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT);
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
builder.unaryExpression(op, expr, &pn->pn_pos, dst);
return expression(operand, &expr) &&
builder.unaryExpression(op, expr, &unaryNode->pn_pos, dst);
}
case PNK_GENEXP: {
@ -3073,13 +3084,13 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_DELETEOPTCHAIN: {
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
return expression(pn->as<UnaryNode>().kid(), &expr) &&
builder.deleteOptionalExpression(expr, &pn->pn_pos, dst);
}
case PNK_OPTCHAIN: {
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
return expression(pn->as<UnaryNode>().kid(), &expr) &&
builder.optionalExpression(expr, &pn->pn_pos, dst);
}
@ -3240,14 +3251,14 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_SPREAD:
{
RootedValue expr(cx);
return expression(pn->pn_kid, &expr) &&
return expression(pn->as<UnaryNode>().kid(), &expr) &&
builder.spreadExpression(expr, &pn->pn_pos, dst);
}
case PNK_COMPUTED_NAME:
{
RootedValue name(cx);
return expression(pn->pn_kid, &name) &&
return expression(pn->as<UnaryNode>().kid(), &name) &&
builder.computedName(name, &pn->pn_pos, dst);
}
@ -3307,20 +3318,24 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
case PNK_YIELD_STAR:
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* yieldNode = &pn->as<UnaryNode>();
ParseNode* operand = yieldNode->kid();
MOZ_ASSERT(yieldNode->pn_pos.encloses(operand->pn_pos));
RootedValue arg(cx);
return expression(pn->pn_kid, &arg) &&
builder.yieldExpression(arg, Delegating, &pn->pn_pos, dst);
return expression(operand, &arg) &&
builder.yieldExpression(arg, Delegating, &yieldNode->pn_pos, dst);
}
case PNK_YIELD:
{
MOZ_ASSERT_IF(pn->pn_kid, pn->pn_pos.encloses(pn->pn_kid->pn_pos));
UnaryNode* yieldNode = &pn->as<UnaryNode>();
ParseNode* operand = yieldNode->kid();
MOZ_ASSERT_IF(operand, yieldNode->pn_pos.encloses(operand->pn_pos));
RootedValue arg(cx);
return optExpression(pn->pn_kid, &arg) &&
builder.yieldExpression(arg, NotDelegating, &pn->pn_pos, dst);
return optExpression(operand, &arg) &&
builder.yieldExpression(arg, NotDelegating, &yieldNode->pn_pos, dst);
}
case PNK_ARRAYCOMP:
@ -3389,7 +3404,7 @@ ASTSerializer::property(ParseNode* pn, MutableHandleValue dst)
{
if (pn->isKind(PNK_MUTATEPROTO)) {
RootedValue val(cx);
return expression(pn->pn_kid, &val) &&
return expression(pn->as<UnaryNode>().kid(), &val) &&
builder.prototypeMutation(val, &pn->pn_pos, dst);
}
if (pn->isKind(PNK_SPREAD))
@ -3492,7 +3507,7 @@ ASTSerializer::arrayPattern(ListNode* array, MutableHandleValue dst)
} else if (item->isKind(PNK_SPREAD)) {
RootedValue target(cx);
RootedValue spread(cx);
if (!pattern(item->pn_kid, &target))
if (!pattern(item->as<UnaryNode>().kid(), &target))
return false;
if(!builder.spreadExpression(target, &item->pn_pos, &spread))
return false;
@ -3521,7 +3536,7 @@ ASTSerializer::objectPattern(ListNode* obj, MutableHandleValue dst)
if (propdef->isKind(PNK_SPREAD)) {
RootedValue target(cx);
RootedValue spread(cx);
if (!pattern(propdef->pn_kid, &target))
if (!pattern(propdef->as<UnaryNode>().kid(), &target))
return false;
if(!builder.spreadExpression(target, &propdef->pn_pos, &spread))
return false;
@ -3536,7 +3551,7 @@ ASTSerializer::objectPattern(ListNode* obj, MutableHandleValue dst)
RootedValue pname(cx, StringValue(cx->names().proto));
if (!builder.literal(pname, &propdef->pn_pos, &key))
return false;
target = propdef->pn_kid;
target = propdef->as<UnaryNode>().kid();
} else {
BinaryNode* prop = &propdef->as<BinaryNode>();
if (!propertyName(prop->left(), &key))
@ -3648,7 +3663,7 @@ ASTSerializer::functionArgsAndBody(ParseNode* pn, NodeVector& args, NodeVector&
switch (pnbody->getKind()) {
case PNK_RETURN: /* expression closure, no destructured args */
return functionArgs(pn, argsList, args, defaults, rest) &&
expression(pnbody->pn_kid, body);
expression(pnbody->as<UnaryNode>().kid(), body);
case PNK_STATEMENTLIST: /* statement closure */
{
@ -3665,7 +3680,7 @@ ASTSerializer::functionArgsAndBody(ParseNode* pn, NodeVector& args, NodeVector&
if (isAsync && isExpression) {
MOZ_ASSERT(firstNode->getKind() == PNK_RETURN);
return functionArgs(pn, argsList, args, defaults, rest) &&
expression(firstNode->pn_kid, body);
expression(firstNode->as<UnaryNode>().kid(), body);
}
return functionArgs(pn, argsList, args, defaults, rest) &&

View file

@ -1072,7 +1072,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// |this| can throw in derived class constructors, including nested arrow
// functions or eval.
case PNK_THIS:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = sc->needsThisTDZChecks();
return true;
@ -1101,8 +1101,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
case PNK_TYPEOFEXPR:
case PNK_VOID:
case PNK_NOT:
MOZ_ASSERT(pn->isArity(PN_UNARY));
return checkSideEffects(pn->pn_kid, answer);
return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
// Even if the name expression is effect-free, performing ToPropertyKey on
// it might not be effect-free:
@ -1116,13 +1115,13 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// Q.toString = () => { throw 17; };
// new Q; // new.target will be Q, ToPropertyKey(Q) throws 17
case PNK_COMPUTED_NAME:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
// Looking up or evaluating the associated name could throw.
case PNK_TYPEOFNAME:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1135,8 +1134,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// only produce a value, without affecting anything else.
case PNK_MUTATEPROTO:
case PNK_ARRAYPUSH:
MOZ_ASSERT(pn->isArity(PN_UNARY));
return checkSideEffects(pn->pn_kid, answer);
return checkSideEffects(pn->as<UnaryNode>().kid(), answer);
// Unary cases with obvious side effects.
case PNK_PREINCREMENT:
@ -1144,7 +1142,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
case PNK_PREDECREMENT:
case PNK_POSTDECREMENT:
case PNK_THROW:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1153,13 +1151,13 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
case PNK_BITNOT:
case PNK_POS:
case PNK_NEG:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
// This invokes the (user-controllable) iterator protocol.
case PNK_SPREAD:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1167,7 +1165,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
case PNK_YIELD_STAR:
case PNK_YIELD:
case PNK_AWAIT:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1176,21 +1174,19 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
case PNK_DELETEPROP:
case PNK_DELETEELEM:
case PNK_DELETEOPTCHAIN:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
// Deletion of a non-Reference expression has side effects only through
// evaluating the expression.
case PNK_DELETEEXPR: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
ParseNode* expr = pn->pn_kid;
ParseNode* expr = pn->as<UnaryNode>().kid();
return checkSideEffects(expr, answer);
}
case PNK_SEMI:
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (ParseNode* expr = pn->pn_kid)
if (ParseNode* expr = pn->as<UnaryNode>().kid())
return checkSideEffects(expr, answer);
*answer = false;
return true;
@ -1299,7 +1295,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
// Likewise.
case PNK_EXPORT:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1360,7 +1356,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
return true;
case PNK_OPTCHAIN:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->is<UnaryNode>());
*answer = true;
return true;
@ -1875,13 +1871,12 @@ BytecodeEmitter::emitPropLHS(PropertyAccess* prop)
}
bool
BytecodeEmitter::emitPropIncDec(ParseNode* pn)
BytecodeEmitter::emitPropIncDec(UnaryNode* incDec)
{
MOZ_ASSERT(pn->pn_kid->isKind(PNK_DOT));
PropertyAccess* prop = &pn->pn_kid->as<PropertyAccess>();
PropertyAccess* prop = &incDec->kid()->as<PropertyAccess>();
bool isSuper = prop->isSuper();
ParseNodeKind kind = pn->getKind();
ParseNodeKind kind = incDec->getKind();
PropOpEmitter poe(this,
kind == PNK_POSTINCREMENT ? PropOpEmitter::Kind::PostIncrement
: kind == PNK_PREINCREMENT ? PropOpEmitter::Kind::PreIncrement
@ -1894,7 +1889,7 @@ BytecodeEmitter::emitPropIncDec(ParseNode* pn)
return false;
}
if (isSuper) {
ParseNode* base = &prop->expression();
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -1910,12 +1905,12 @@ BytecodeEmitter::emitPropIncDec(ParseNode* pn)
}
bool
BytecodeEmitter::emitNameIncDec(ParseNode* incDec)
BytecodeEmitter::emitNameIncDec(UnaryNode* incDec)
{
MOZ_ASSERT(incDec->pn_kid->isKind(PNK_NAME));
MOZ_ASSERT(incDec->kid()->isKind(PNK_NAME));
ParseNodeKind kind = incDec->getKind();
NameNode* name = &incDec->pn_kid->as<NameNode>();
NameNode* name = &incDec->kid()->as<NameNode>();
NameOpEmitter noe(this, name->pn_atom,
kind == PNK_POSTINCREMENT ? NameOpEmitter::Kind::PostIncrement
: kind == PNK_PREINCREMENT ? NameOpEmitter::Kind::PreIncrement
@ -1945,7 +1940,7 @@ BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEm
if (!eoe.prepareForObj()) { //
return false;
}
ParseNode* base = &elem->expression();
UnaryNode* base = &elem->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -1976,11 +1971,11 @@ BytecodeEmitter::emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEm
}
bool
BytecodeEmitter::emitElemIncDec(ParseNode* pn)
BytecodeEmitter::emitElemIncDec(UnaryNode* incDec)
{
PropertyByValue* elemExpr = &pn->pn_kid->as<PropertyByValue>();
bool isSuper = elemExpr->isSuper();
ParseNodeKind kind = pn->getKind();
PropertyByValue* elem = &incDec->kid()->as<PropertyByValue>();
bool isSuper = elem->isSuper();
ParseNodeKind kind = incDec->getKind();
ElemOpEmitter eoe(this,
kind == PNK_POSTINCREMENT ? ElemOpEmitter::Kind::PostIncrement
: kind == PNK_PREINCREMENT ? ElemOpEmitter::Kind::PreIncrement
@ -1989,7 +1984,7 @@ BytecodeEmitter::emitElemIncDec(ParseNode* pn)
isSuper
? ElemOpEmitter::ObjKind::Super
: ElemOpEmitter::ObjKind::Other);
if (!emitElemObjAndKey(elemExpr, isSuper, eoe)) { // [Super]
if (!emitElemObjAndKey(elem, isSuper, eoe)) { // [Super]
// // THIS KEY
// // [Other]
// // OBJ KEY
@ -2003,16 +1998,15 @@ BytecodeEmitter::emitElemIncDec(ParseNode* pn)
}
bool
BytecodeEmitter::emitCallIncDec(ParseNode* incDec)
BytecodeEmitter::emitCallIncDec(UnaryNode* incDec)
{
MOZ_ASSERT(incDec->isKind(PNK_PREINCREMENT) ||
incDec->isKind(PNK_POSTINCREMENT) ||
incDec->isKind(PNK_PREDECREMENT) ||
incDec->isKind(PNK_POSTDECREMENT));
MOZ_ASSERT(incDec->pn_kid->isKind(PNK_CALL));
ParseNode* call = incDec->pn_kid;
ParseNode* call = incDec->kid();
MOZ_ASSERT(call->isKind(PNK_CALL));
if (!emitTree(call)) // CALLRESULT
return false;
if (!emit1(JSOP_POS)) // N
@ -2440,7 +2434,7 @@ BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target, size_t* emitted)
*emitted = 0;
if (target->isKind(PNK_SPREAD))
target = target->pn_kid;
target = target->as<UnaryNode>().kid();
else if (target->isKind(PNK_ASSIGN))
target = target->as<AssignmentNode>().left();
@ -2467,7 +2461,7 @@ BytecodeEmitter::emitDestructuringLHSRef(ParseNode* target, size_t* emitted)
return false;
}
if (isSuper) {
ParseNode* base = &prop->expression();
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS SUPERBASE
return false;
}
@ -2539,7 +2533,7 @@ BytecodeEmitter::emitSetOrInitializeDestructuring(ParseNode* target, Destructuri
// the matched value. Otherwise emit an lvalue bytecode sequence followed
// by an assignment op.
if (target->isKind(PNK_SPREAD))
target = target->pn_kid;
target = target->as<UnaryNode>().kid();
else if (target->isKind(PNK_ASSIGN))
target = target->as<AssignmentNode>().left();
if (target->isKind(PNK_ARRAY) || target->isKind(PNK_OBJECT)) {
@ -3317,10 +3311,10 @@ BytecodeEmitter::emitDestructuringOpsArray(ListNode* pattern, DestructuringFlavo
}
bool
BytecodeEmitter::emitComputedPropertyName(ParseNode* computedPropName)
BytecodeEmitter::emitComputedPropertyName(UnaryNode* computedPropName)
{
MOZ_ASSERT(computedPropName->isKind(PNK_COMPUTED_NAME));
return emitTree(computedPropName->pn_kid) && emit1(JSOP_TOID);
return emitTree(computedPropName->kid()) && emit1(JSOP_TOID);
}
bool
@ -3346,7 +3340,7 @@ BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern, DestructuringFlav
for (ParseNode* member : pattern->contents()) {
ParseNode* subpattern;
if (member->isKind(PNK_MUTATEPROTO) || member->isKind(PNK_SPREAD))
subpattern = member->pn_kid;
subpattern = member->as<UnaryNode>().kid();
else {
MOZ_ASSERT(member->isKind(PNK_COLON) ||
member->isKind(PNK_SHORTHAND));
@ -3422,7 +3416,7 @@ BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern, DestructuringFlav
return false;
needsGetElem = false;
} else {
if (!emitComputedPropertyName(key)) // ... *SET RHS *LREF RHS KEY
if (!emitComputedPropertyName(&key->as<UnaryNode>())) // ... *SET RHS *LREF RHS KEY
return false;
// Add the computed property key to the exclusion set.
@ -3753,7 +3747,7 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs)
return false;
}
if (isSuper) {
ParseNode* base = &prop->expression();
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS SUPERBASE
return false;
}
@ -6097,18 +6091,16 @@ BytecodeEmitter::emitGetFunctionThis(const mozilla::Maybe<uint32_t>& offset)
}
bool
BytecodeEmitter::emitGetThisForSuperBase(ParseNode* pn)
BytecodeEmitter::emitGetThisForSuperBase(UnaryNode* superBase)
{
MOZ_ASSERT(pn->isKind(PNK_SUPERBASE));
return emitGetFunctionThis(pn->pn_kid); // THIS
MOZ_ASSERT(superBase->isKind(PNK_SUPERBASE));
return emitGetFunctionThis(superBase->kid()); // THIS
}
bool
BytecodeEmitter::emitThisLiteral(ParseNode* pn)
BytecodeEmitter::emitThisLiteral(ThisLiteral* pn)
{
MOZ_ASSERT(pn->isKind(PNK_THIS));
if (ParseNode* thisName = pn->pn_kid)
if (ParseNode* thisName = pn->kid())
return emitGetFunctionThis(thisName); // THIS
if (sc->thisBinding() == ThisBinding::Module)
@ -6130,9 +6122,9 @@ BytecodeEmitter::emitCheckDerivedClassConstructorReturn()
}
bool
BytecodeEmitter::emitReturn(ParseNode* pn)
BytecodeEmitter::emitReturn(UnaryNode* returnNode)
{
if (!updateSourceCoordNotes(pn->pn_pos.begin))
if (!updateSourceCoordNotes(returnNode->pn_pos.begin))
return false;
bool needsIteratorResult = sc->isFunctionBox() && sc->asFunctionBox()->needsIteratorResult();
@ -6142,8 +6134,8 @@ BytecodeEmitter::emitReturn(ParseNode* pn)
}
/* Push a return value */
if (ParseNode* pn2 = pn->pn_kid) {
if (!emitTree(pn2))
if (ParseNode* expr = returnNode->kid()) {
if (!emitTree(expr))
return false;
bool isAsyncGenerator = sc->asFunctionBox()->isAsync() &&
@ -6232,9 +6224,9 @@ BytecodeEmitter::emitGetDotGeneratorInScope(EmitterScope& currentScope)
}
bool
BytecodeEmitter::emitInitialYield(ParseNode* pn)
BytecodeEmitter::emitInitialYield(UnaryNode* yieldNode)
{
if (!emitTree(pn->pn_kid))
if (!emitTree(yieldNode->kid()))
return false;
if (!emitYieldOp(JSOP_INITIALYIELD))
@ -6247,18 +6239,19 @@ BytecodeEmitter::emitInitialYield(ParseNode* pn)
}
bool
BytecodeEmitter::emitYield(ParseNode* pn)
BytecodeEmitter::emitYield(UnaryNode* yieldNode)
{
MOZ_ASSERT(sc->isFunctionBox());
MOZ_ASSERT(pn->getOp() == JSOP_YIELD);
MOZ_ASSERT(yieldNode->getOp() == JSOP_YIELD);
bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult();
if (needsIteratorResult) {
if (!emitPrepareIteratorResult())
return false;
}
if (pn->pn_kid) {
if (!emitTree(pn->pn_kid))
if (ParseNode* expr = yieldNode->kid()) {
if (!emitTree(expr))
return false;
} else {
if (!emit1(JSOP_UNDEFINED))
@ -6287,12 +6280,12 @@ BytecodeEmitter::emitYield(ParseNode* pn)
}
bool
BytecodeEmitter::emitAwaitInInnermostScope(ParseNode* pn)
BytecodeEmitter::emitAwaitInInnermostScope(UnaryNode* awaitNode)
{
MOZ_ASSERT(sc->isFunctionBox());
MOZ_ASSERT(pn->getOp() == JSOP_AWAIT);
MOZ_ASSERT(awaitNode->getOp() == JSOP_AWAIT);
if (!emitTree(pn->pn_kid))
if (!emitTree(awaitNode->kid()))
return false;
return emitAwaitInInnermostScope();
}
@ -6606,15 +6599,15 @@ BytecodeEmitter::emitStatementList(ListNode* stmtList)
}
bool
BytecodeEmitter::emitStatement(ParseNode* pn)
BytecodeEmitter::emitStatement(UnaryNode* exprStmt)
{
MOZ_ASSERT(pn->isKind(PNK_SEMI));
MOZ_ASSERT(exprStmt->isKind(PNK_SEMI));
ParseNode* pn2 = pn->pn_kid;
if (!pn2)
ParseNode* expr = exprStmt->kid();
if (!expr)
return true;
if (!updateSourceCoordNotes(pn->pn_pos.begin))
if (!updateSourceCoordNotes(exprStmt->pn_pos.begin))
return false;
/*
@ -6635,7 +6628,7 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
/* Don't eliminate expressions with side effects. */
if (!useful) {
if (!checkSideEffects(pn2, &useful))
if (!checkSideEffects(expr, &useful))
return false;
/*
@ -6654,16 +6647,16 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
if (useful) {
JSOp op = wantval ? JSOP_SETRVAL : JSOP_POP;
ValueUsage valueUsage = wantval ? ValueUsage::WantValue : ValueUsage::IgnoreValue;
MOZ_ASSERT_IF(pn2->isKind(PNK_ASSIGN), pn2->isOp(JSOP_NOP));
if (!emitTree(pn2, valueUsage))
MOZ_ASSERT_IF(expr->isKind(PNK_ASSIGN), expr->isOp(JSOP_NOP));
if (!emitTree(expr, valueUsage))
return false;
if (!emit1(op))
return false;
} else if (pn->isDirectivePrologueMember()) {
} else if (exprStmt->isDirectivePrologueMember()) {
// Don't complain about directive prologue members; just don't emit
// their code.
} else {
if (JSAtom* atom = pn->isStringExprStatement()) {
if (JSAtom* atom = exprStmt->isStringExprStatement()) {
// Warn if encountering a non-directive prologue member string
// expression statement, that is inconsistent with the current
// directive prologue. That is, a script *not* starting with
@ -6681,13 +6674,13 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
}
if (directive) {
if (!reportExtraWarning(pn2, JSMSG_CONTRARY_NONDIRECTIVE, directive))
if (!reportExtraWarning(expr, JSMSG_CONTRARY_NONDIRECTIVE, directive))
return false;
}
} else {
current->currentLine = parser->tokenStream.srcCoords.lineNum(pn2->pn_pos.begin);
current->currentLine = parser->tokenStream.srcCoords.lineNum(expr->pn_pos.begin);
current->lastColumn = 0;
if (!reportExtraWarning(pn2, JSMSG_USELESS_EXPR))
if (!reportExtraWarning(expr, JSMSG_USELESS_EXPR))
return false;
}
}
@ -6696,24 +6689,22 @@ BytecodeEmitter::emitStatement(ParseNode* pn)
}
bool
BytecodeEmitter::emitDeleteName(ParseNode* node)
BytecodeEmitter::emitDeleteName(UnaryNode* deleteNode)
{
MOZ_ASSERT(node->isKind(PNK_DELETENAME));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(deleteNode->isKind(PNK_DELETENAME));
ParseNode* nameExpr = node->pn_kid;
ParseNode* nameExpr = deleteNode->kid();
MOZ_ASSERT(nameExpr->isKind(PNK_NAME));
return emitAtomOp(nameExpr->pn_atom, JSOP_DELNAME);
}
bool
BytecodeEmitter::emitDeleteProperty(ParseNode* node)
BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode)
{
MOZ_ASSERT(node->isKind(PNK_DELETEPROP));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(deleteNode->isKind(PNK_DELETEPROP));
PropertyAccess* propExpr = &node->pn_kid->as<PropertyAccess>();
PropertyAccess* propExpr = &deleteNode->kid()->as<PropertyAccess>();
MOZ_ASSERT(propExpr->isKind(PNK_DOT));
PropOpEmitter poe(this,
@ -6727,7 +6718,7 @@ BytecodeEmitter::emitDeleteProperty(ParseNode* node)
// which could throw if |this| hasn't yet been set by a |super(...)|
// call or the super-base is not an object, before throwing a
// ReferenceError for attempting to delete a super-reference.
ParseNode* base = &propExpr->expression();
UnaryNode* base = &propExpr->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -6751,12 +6742,11 @@ BytecodeEmitter::emitDeleteProperty(ParseNode* node)
}
bool
BytecodeEmitter::emitDeleteElement(ParseNode* node)
BytecodeEmitter::emitDeleteElement(UnaryNode* deleteNode)
{
MOZ_ASSERT(node->isKind(PNK_DELETEELEM));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(deleteNode->isKind(PNK_DELETEELEM));
PropertyByValue* elemExpr = &node->pn_kid->as<PropertyByValue>();
PropertyByValue* elemExpr = &deleteNode->kid()->as<PropertyByValue>();
MOZ_ASSERT(elemExpr->isKind(PNK_ELEM));
bool isSuper = elemExpr->isSuper();
@ -6775,7 +6765,7 @@ BytecodeEmitter::emitDeleteElement(ParseNode* node)
return false;
}
ParseNode* base = &elemExpr->expression();
UnaryNode* base = &elemExpr->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -6801,12 +6791,11 @@ BytecodeEmitter::emitDeleteElement(ParseNode* node)
}
bool
BytecodeEmitter::emitDeleteExpression(ParseNode* node)
BytecodeEmitter::emitDeleteExpression(UnaryNode* deleteNode)
{
MOZ_ASSERT(node->isKind(PNK_DELETEEXPR));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(deleteNode->isKind(PNK_DELETEEXPR));
ParseNode* expression = node->pn_kid;
ParseNode* expression = deleteNode->kid();
// If useless, just emit JSOP_TRUE; otherwise convert |delete <expr>| to
// effectively |<expr>, true|.
@ -6825,13 +6814,13 @@ BytecodeEmitter::emitDeleteExpression(ParseNode* node)
}
bool
BytecodeEmitter::emitDeleteOptionalChain(ParseNode* deleteNode)
BytecodeEmitter::emitDeleteOptionalChain(UnaryNode* deleteNode)
{
MOZ_ASSERT(deleteNode->isKind(PNK_DELETEOPTCHAIN));
OptionalEmitter oe(this, stackDepth);
ParseNode* kid = deleteNode->pn_kid;
ParseNode* kid = deleteNode->kid();
switch (kid->getKind()) {
case PNK_ELEM:
case PNK_OPTELEM: {
@ -7226,7 +7215,7 @@ BytecodeEmitter::emitOptionalCalleeAndThis(
break;
}
case PNK_OPTCHAIN: {
return emitCalleeAndThisForOptionalChain(calleeNode, callNode, cone);
return emitCalleeAndThisForOptionalChain(&calleeNode->as<UnaryNode>(), callNode, cone);
}
default: {
MOZ_RELEASE_ASSERT(calleeNode->getKind() != PNK_SUPERBASE);
@ -7274,7 +7263,7 @@ BytecodeEmitter::emitOptionalCall(
CallOrNewEmitter cone(this, op,
isSpread && (argc == 1) &&
isRestParameter(argsList->head()->pn_kid)
isRestParameter(argsList->head()->as<UnaryNode>().kid())
? CallOrNewEmitter::ArgumentsKind::SingleSpreadRest
: CallOrNewEmitter::ArgumentsKind::Other,
valueUsage);
@ -7365,7 +7354,7 @@ BytecodeEmitter::emitArguments(ListNode* argsList, bool isCall, bool isSpread,
} else {
if (cone.wantSpreadOperand()) {
ParseNode* spreadNode = argsList->head();
if (!emitTree(spreadNode->pn_kid)) { // CALLEE THIS ARG0
if (!emitTree(spreadNode->as<UnaryNode>().kid())) { // CALLEE THIS ARG0
return false;
}
}
@ -7432,7 +7421,7 @@ BytecodeEmitter::emitCallOrNew(
JSOp op = callNode->getOp();
CallOrNewEmitter cone(this, op,
isSpread && (argc == 1) &&
isRestParameter(argsList->head()->pn_kid)
isRestParameter(argsList->head()->as<UnaryNode>().kid())
? CallOrNewEmitter::ArgumentsKind::SingleSpreadRest
: CallOrNewEmitter::ArgumentsKind::Other,
valueUsage);
@ -7474,7 +7463,7 @@ BytecodeEmitter::emitCalleeAndThis(
return false;
}
if (isSuper) {
ParseNode* base = &prop->expression();
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -7520,7 +7509,7 @@ BytecodeEmitter::emitCalleeAndThis(
}
break;
case PNK_OPTCHAIN:
return emitCalleeAndThisForOptionalChain(calleeNode, callNode, cone);
return emitCalleeAndThisForOptionalChain(&calleeNode->as<UnaryNode>(), callNode, cone);
default:
if (!cone.prepareForOtherCallee()) {
return false;
@ -7638,17 +7627,17 @@ BytecodeEmitter::emitSequenceExpr(ListNode* node,
// Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
// the comment on emitSwitch.
MOZ_NEVER_INLINE bool
BytecodeEmitter::emitIncOrDec(ParseNode* pn)
BytecodeEmitter::emitIncOrDec(UnaryNode* incDec)
{
switch (pn->pn_kid->getKind()) {
switch (incDec->kid()->getKind()) {
case PNK_DOT:
return emitPropIncDec(pn);
return emitPropIncDec(incDec);
case PNK_ELEM:
return emitElemIncDec(pn);
return emitElemIncDec(incDec);
case PNK_CALL:
return emitCallIncDec(pn);
return emitCallIncDec(incDec);
default:
return emitNameIncDec(pn);
return emitNameIncDec(incDec);
}
return true;
@ -7726,7 +7715,7 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
// involving "__proto__", performs [[Prototype]] mutation.
if (propdef->isKind(PNK_MUTATEPROTO)) {
MOZ_ASSERT(type == ObjectLiteral);
if (!emitTree(propdef->pn_kid))
if (!emitTree(propdef->as<UnaryNode>().kid()))
return false;
objp.set(nullptr);
if (!emit1(JSOP_MUTATEPROTO))
@ -7740,7 +7729,7 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
if (!emit1(JSOP_DUP))
return false;
if (!emitTree(propdef->pn_kid))
if (!emitTree(propdef->as<UnaryNode>().kid()))
return false;
if (!emitCopyDataProperties(CopyOption::Unfiltered))
@ -7774,7 +7763,8 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp,
continue;
}
} else {
if (!emitComputedPropertyName(key))
MOZ_ASSERT(key->isKind(PNK_COMPUTED_NAME));
if (!emitComputedPropertyName(&key->as<UnaryNode>()))
return false;
isIndex = true;
}
@ -8065,7 +8055,7 @@ BytecodeEmitter::emitArray(ParseNode* arrayHead, uint32_t count, JSOp op)
} else {
ParseNode* expr;
if (elem->isKind(PNK_SPREAD)) {
expr = elem->pn_kid;
expr = elem->as<UnaryNode>().kid();
if (emitterMode == BytecodeEmitter::SelfHosting &&
expr->isKind(PNK_CALL) &&
@ -8105,30 +8095,29 @@ BytecodeEmitter::emitArray(ParseNode* arrayHead, uint32_t count, JSOp op)
}
bool
BytecodeEmitter::emitUnary(ParseNode* pn)
BytecodeEmitter::emitUnary(UnaryNode* unaryNode)
{
if (!updateSourceCoordNotes(pn->pn_pos.begin))
if (!updateSourceCoordNotes(unaryNode->pn_pos.begin))
return false;
/* Unary op, including unary +/-. */
JSOp op = pn->getOp();
ParseNode* pn2 = pn->pn_kid;
JSOp op = unaryNode->getOp();
if (!emitTree(pn2))
if (!emitTree(unaryNode->kid()))
return false;
return emit1(op);
}
bool
BytecodeEmitter::emitTypeof(ParseNode* node, JSOp op)
BytecodeEmitter::emitTypeof(UnaryNode* typeofNode, JSOp op)
{
MOZ_ASSERT(op == JSOP_TYPEOF || op == JSOP_TYPEOFEXPR);
if (!updateSourceCoordNotes(node->pn_pos.begin))
if (!updateSourceCoordNotes(typeofNode->pn_pos.begin))
return false;
if (!emitTree(node->pn_kid))
if (!emitTree(typeofNode->kid()))
return false;
return emit1(op);
@ -8699,12 +8688,12 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case PNK_RETURN:
if (!emitReturn(pn))
if (!emitReturn(&pn->as<UnaryNode>()))
return false;
break;
case PNK_YIELD_STAR:
if (!emitYieldStar(pn->pn_kid))
if (!emitYieldStar(pn->as<UnaryNode>().kid()))
return false;
break;
@ -8714,17 +8703,17 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case PNK_INITIALYIELD:
if (!emitInitialYield(pn))
if (!emitInitialYield(&pn->as<UnaryNode>()))
return false;
break;
case PNK_YIELD:
if (!emitYield(pn))
if (!emitYield(&pn->as<UnaryNode>()))
return false;
break;
case PNK_AWAIT:
if (!emitAwaitInInnermostScope(pn))
if (!emitAwaitInInnermostScope(&pn->as<UnaryNode>()))
return false;
break;
@ -8734,7 +8723,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case PNK_SEMI:
if (!emitStatement(pn))
if (!emitStatement(&pn->as<UnaryNode>()))
return false;
break;
@ -8810,12 +8799,12 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case PNK_TYPEOFNAME:
if (!emitTypeof(pn, JSOP_TYPEOF))
if (!emitTypeof(&pn->as<UnaryNode>(), JSOP_TYPEOF))
return false;
break;
case PNK_TYPEOFEXPR:
if (!emitTypeof(pn, JSOP_TYPEOFEXPR))
if (!emitTypeof(&pn->as<UnaryNode>(), JSOP_TYPEOFEXPR))
return false;
break;
@ -8825,7 +8814,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
case PNK_BITNOT:
case PNK_POS:
case PNK_NEG:
if (!emitUnary(pn))
if (!emitUnary(&pn->as<UnaryNode>()))
return false;
break;
@ -8833,38 +8822,38 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
case PNK_PREDECREMENT:
case PNK_POSTINCREMENT:
case PNK_POSTDECREMENT:
if (!emitIncOrDec(pn))
if (!emitIncOrDec(&pn->as<UnaryNode>()))
return false;
break;
case PNK_DELETENAME:
if (!emitDeleteName(pn))
if (!emitDeleteName(&pn->as<UnaryNode>()))
return false;
break;
case PNK_DELETEPROP:
if (!emitDeleteProperty(pn))
if (!emitDeleteProperty(&pn->as<UnaryNode>()))
return false;
break;
case PNK_DELETEELEM:
if (!emitDeleteElement(pn))
if (!emitDeleteElement(&pn->as<UnaryNode>()))
return false;
break;
case PNK_DELETEEXPR:
if (!emitDeleteExpression(pn))
if (!emitDeleteExpression(&pn->as<UnaryNode>()))
return false;
break;
case PNK_DELETEOPTCHAIN:
if (!emitDeleteOptionalChain(pn)) {
if (!emitDeleteOptionalChain(&pn->as<UnaryNode>())) {
return false;
}
break;
case PNK_OPTCHAIN:
if (!emitOptionalChain(pn, valueUsage)) {
if (!emitOptionalChain(&pn->as<UnaryNode>(), valueUsage)) {
return false;
}
break;
@ -8881,7 +8870,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
}
if (isSuper) {
ParseNode* base = &prop->expression();
UnaryNode* base = &prop->expression().as<UnaryNode>();
if (!emitGetThisForSuperBase(base)) { // THIS
return false;
}
@ -8940,13 +8929,16 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
MOZ_ASSERT(sc->isModuleContext());
break;
case PNK_EXPORT:
case PNK_EXPORT: {
MOZ_ASSERT(sc->isModuleContext());
if (pn->pn_kid->getKind() != PNK_EXPORT_SPEC_LIST) {
if (!emitTree(pn->pn_kid))
UnaryNode* node = &pn->as<UnaryNode>();
ParseNode* decl = node->kid();
if (decl->getKind() != PNK_EXPORT_SPEC_LIST) {
if (!emitTree(decl))
return false;
}
break;
}
case PNK_EXPORT_DEFAULT: {
MOZ_ASSERT(sc->isModuleContext());
@ -8972,7 +8964,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
* under the array initialiser code generator for array comprehension
* special casing.
*/
if (!emitTree(pn->pn_kid))
if (!emitTree(pn->as<UnaryNode>().kid()))
return false;
if (!emitDupAt(this->stackDepth - 1 - arrayCompDepth))
return false;
@ -9035,7 +9027,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
break;
case PNK_THIS:
if (!emitThisLiteral(pn))
if (!emitThisLiteral(&pn->as<ThisLiteral>()))
return false;
break;
@ -9198,11 +9190,11 @@ BytecodeEmitter::emitOptionalTree(
// For example `(a?.b)()` and `(a?.b)?.()`.
bool
BytecodeEmitter::emitCalleeAndThisForOptionalChain(
ParseNode* optionalChain,
UnaryNode* optionalChain,
ParseNode* callNode,
CallOrNewEmitter& cone)
{
ParseNode* calleeNode = optionalChain->pn_kid;
ParseNode* calleeNode = optionalChain->kid();
// Create a new OptionalEmitter, in order to emit the right bytecode
// in isolation.
@ -9231,10 +9223,10 @@ BytecodeEmitter::emitCalleeAndThisForOptionalChain(
bool
BytecodeEmitter::emitOptionalChain(
ParseNode* optionalChain,
UnaryNode* optionalChain,
ValueUsage valueUsage)
{
ParseNode* expression = optionalChain->pn_kid;
ParseNode* expression = optionalChain->kid();
OptionalEmitter oe(this, stackDepth);
@ -9266,14 +9258,13 @@ BytecodeEmitter::emitOptionalDotExpression(
return false;
}
ParseNode* base = &prop->expression();
if (isSuper) {
if (!emitGetThisForSuperBase(base)) {
if (!emitGetThisForSuperBase(&prop->expression().as<UnaryNode>())) {
// [stack] OBJ
return false;
}
} else {
if (!emitOptionalTree(base, oe)) {
if (!emitOptionalTree(&prop->expression(), oe)) {
// [stack] OBJ
return false;
}
@ -9310,14 +9301,13 @@ BytecodeEmitter::emitOptionalElemExpression(
return false;
}
ParseNode* base = &elem->expression();
if (isSuper) {
if (!emitGetThisForSuperBase(base)) {
if (!emitGetThisForSuperBase(&elem->expression().as<UnaryNode>())) {
// [stack] OBJ
return false;
}
} else {
if (!emitOptionalTree(base, oe)) {
if (!emitOptionalTree(&elem->expression(), oe)) {
// [stack] OBJ
return false;
}

View file

@ -465,10 +465,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitNumberOp(double dval);
MOZ_MUST_USE bool emitThisLiteral(ParseNode* pn);
MOZ_MUST_USE bool emitThisLiteral(ThisLiteral* pn);
MOZ_MUST_USE bool emitGetFunctionThis(ParseNode* pn);
MOZ_MUST_USE bool emitGetFunctionThis(const mozilla::Maybe<uint32_t>& offset);
MOZ_MUST_USE bool emitGetThisForSuperBase(ParseNode* pn);
MOZ_MUST_USE bool emitGetThisForSuperBase(UnaryNode* superBase);
MOZ_MUST_USE bool emitSetThis(BinaryNode* setThisNode);
MOZ_MUST_USE bool emitCheckDerivedClassConstructorReturn();
@ -484,7 +484,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitCall(JSOp op, uint16_t argc,
const mozilla::Maybe<uint32_t>& sourceCoordOffset);
MOZ_MUST_USE bool emitCall(JSOp op, uint16_t argc, ParseNode* pn = nullptr);
MOZ_MUST_USE bool emitCallIncDec(ParseNode* incDec);
MOZ_MUST_USE bool emitCallIncDec(UnaryNode* incDec);
MOZ_MUST_USE bool emitLoopHead(ParseNode* nextpn, JumpTarget* top);
MOZ_MUST_USE bool emitLoopEntry(ParseNode* nextpn, JumpList entryJump);
@ -536,7 +536,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitTDZCheckIfNeeded(JSAtom* name, const NameLocation& loc);
MOZ_MUST_USE bool emitNameIncDec(ParseNode* incDec);
MOZ_MUST_USE bool emitNameIncDec(UnaryNode* incDec);
MOZ_MUST_USE bool emitDeclarationList(ListNode* declList);
MOZ_MUST_USE bool emitSingleDeclaration(ParseNode* declList, ParseNode* decl,
@ -555,23 +555,23 @@ struct MOZ_STACK_CLASS BytecodeEmitter
}
MOZ_MUST_USE bool emitGetDotGeneratorInScope(EmitterScope& currentScope);
MOZ_MUST_USE bool emitInitialYield(ParseNode* pn);
MOZ_MUST_USE bool emitYield(ParseNode* pn);
MOZ_MUST_USE bool emitInitialYield(UnaryNode* yieldNode);
MOZ_MUST_USE bool emitYield(UnaryNode* yieldNode);
MOZ_MUST_USE bool emitYieldOp(JSOp op);
MOZ_MUST_USE bool emitYieldStar(ParseNode* iter);
MOZ_MUST_USE bool emitAwaitInInnermostScope() {
return emitAwaitInScope(*innermostEmitterScope());
}
MOZ_MUST_USE bool emitAwaitInInnermostScope(ParseNode* pn);
MOZ_MUST_USE bool emitAwaitInInnermostScope(UnaryNode* awaitNode);
MOZ_MUST_USE bool emitAwaitInScope(EmitterScope& currentScope);
MOZ_MUST_USE bool emitPropLHS(PropertyAccess* prop);
MOZ_MUST_USE bool emitPropIncDec(ParseNode* pn);
MOZ_MUST_USE bool emitPropIncDec(UnaryNode* incDec);
MOZ_MUST_USE bool emitAsyncWrapperLambda(unsigned index, bool isArrow);
MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
bool isStarGenerator);
MOZ_MUST_USE bool emitComputedPropertyName(ParseNode* computedPropName);
MOZ_MUST_USE bool emitComputedPropertyName(UnaryNode* computedPropName);
// Emit bytecode to put operands for a JSOP_GETELEM/CALLELEM/SETELEM/DELELEM
// opcode onto the stack in the right order. In the case of SETELEM, the
@ -581,7 +581,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEmitter& eoe);
MOZ_MUST_USE bool emitElemOpBase(JSOp op);
MOZ_MUST_USE bool emitElemIncDec(ParseNode* pn);
MOZ_MUST_USE bool emitElemIncDec(UnaryNode* incDec);
MOZ_MUST_USE bool emitCatch(TernaryNode* catchNode);
MOZ_MUST_USE bool emitIf(TernaryNode* ifNode);
@ -695,22 +695,22 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitTemplateString(ListNode* templateString);
MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs);
MOZ_MUST_USE bool emitReturn(ParseNode* pn);
MOZ_MUST_USE bool emitStatement(ParseNode* pn);
MOZ_MUST_USE bool emitReturn(UnaryNode* returnNode);
MOZ_MUST_USE bool emitStatement(UnaryNode* exprStmt);
MOZ_MUST_USE bool emitStatementList(ListNode* stmtList);
MOZ_MUST_USE bool emitDeleteName(ParseNode* pn);
MOZ_MUST_USE bool emitDeleteProperty(ParseNode* pn);
MOZ_MUST_USE bool emitDeleteElement(ParseNode* pn);
MOZ_MUST_USE bool emitDeleteExpression(ParseNode* pn);
MOZ_MUST_USE bool emitDeleteName(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteProperty(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteElement(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteExpression(UnaryNode* deleteNode);
// Optional methods which emit Optional Jump Target
MOZ_MUST_USE bool emitOptionalChain(ParseNode* optionalChain,
MOZ_MUST_USE bool emitOptionalChain(UnaryNode* optionalChain,
ValueUsage valueUsage);
MOZ_MUST_USE bool emitCalleeAndThisForOptionalChain(ParseNode* optionalChain,
MOZ_MUST_USE bool emitCalleeAndThisForOptionalChain(UnaryNode* optionalChain,
ParseNode* callNode,
CallOrNewEmitter& cone);
MOZ_MUST_USE bool emitDeleteOptionalChain(ParseNode* deleteNode);
MOZ_MUST_USE bool emitDeleteOptionalChain(UnaryNode* deleteNode);
// Optional methods which emit a shortCircuit jump. They need to be called by
// a method which emits an Optional Jump Target, see below.
@ -729,16 +729,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
OptionalEmitter& oe);
// |op| must be JSOP_TYPEOF or JSOP_TYPEOFEXPR.
MOZ_MUST_USE bool emitTypeof(ParseNode* node, JSOp op);
MOZ_MUST_USE bool emitTypeof(UnaryNode* typeofNode, JSOp op);
MOZ_MUST_USE bool emitUnary(ParseNode* pn);
MOZ_MUST_USE bool emitUnary(UnaryNode* unaryNode);
MOZ_MUST_USE bool emitRightAssociative(ListNode* node);
MOZ_MUST_USE bool emitLeftAssociative(ListNode* node);
MOZ_MUST_USE bool emitLogical(ListNode* node);
MOZ_MUST_USE bool emitSequenceExpr(ListNode* node,
ValueUsage valueUsage = ValueUsage::WantValue);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitIncOrDec(ParseNode* pn);
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitIncOrDec(UnaryNode* incDec);
MOZ_MUST_USE bool emitConditionalExpression(ConditionalExpression& conditional,
ValueUsage valueUsage = ValueUsage::WantValue);

View file

@ -110,7 +110,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_SEMI:
case PNK_THROW:
case PNK_RETURN:
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(node->is<UnaryNode>());
*result = false;
return true;
@ -119,7 +119,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_INITIALYIELD:
case PNK_YIELD_STAR:
case PNK_YIELD:
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(node->is<UnaryNode>());
*result = false;
return true;
@ -515,7 +515,7 @@ Boolish(ParseNode* pn, bool isNullish = false)
// |void| expressions, for good measure) and check that the nested
// expression doesn't break this requirement before indicating falsity.
do {
pn = pn->pn_kid;
pn = pn->as<UnaryNode>().kid();
} while (pn->isKind(PNK_VOID));
return IsEffectless(pn) ? Falsy : Unknown;
@ -561,16 +561,16 @@ FoldCondition(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler
}
static bool
FoldTypeOfExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldTypeOfExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_TYPEOFEXPR));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = node->kid();
// Constant-fold the entire |typeof| if given a constant with known type.
RootedPropertyName result(cx);
if (expr->isKind(PNK_STRING) || expr->isKind(PNK_TEMPLATE_STRING))
@ -597,16 +597,16 @@ FoldTypeOfExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>&
}
static bool
FoldDeleteExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldDeleteExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_DELETEEXPR));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = node->kid();
// Expression deletion evaluates the expression, then evaluates to true.
// For effectless expressions, eliminate the expression evaluation.
if (IsEffectless(expr)) {
@ -620,17 +620,17 @@ FoldDeleteExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>&
}
static bool
FoldDeleteElement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldDeleteElement(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_DELETEELEM));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(node->pn_kid->isKind(PNK_ELEM));
MOZ_ASSERT(node->kid()->isKind(PNK_ELEM));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = node->kid();
// If we're deleting an element, but constant-folding converted our
// element reference into a dotted property access, we must *also*
// morph the node's kind.
@ -645,38 +645,36 @@ FoldDeleteElement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler
}
static bool
FoldDeleteProperty(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldDeleteProperty(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_DELETEPROP));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(node->pn_kid->isKind(PNK_DOT));
MOZ_ASSERT(node->kid()->isKind(PNK_DOT));
ParseNode*& expr = node->pn_kid;
#ifdef DEBUG
ParseNodeKind oldKind = expr->getKind();
ParseNodeKind oldKind = node->kid()->getKind();
#endif
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
MOZ_ASSERT(expr->isKind(oldKind),
MOZ_ASSERT(node->kid()->isKind(oldKind),
"kind should have remained invariant under folding");
return true;
}
static bool
FoldNot(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldNot(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_NOT));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!FoldCondition(cx, &expr, parser, inGenexpLambda))
if (!FoldCondition(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = node->kid();
if (expr->isKind(PNK_NUMBER)) {
double d = expr->pn_dval;
@ -702,17 +700,17 @@ FoldNot(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
}
static bool
FoldUnaryArithmetic(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_BITNOT) || node->isKind(PNK_POS) || node->isKind(PNK_NEG),
"need a different method for this node kind");
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid;
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
ParseNode* expr = node->kid();
if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) {
double d = expr->isKind(PNK_NUMBER)
? expr->pn_dval
@ -736,22 +734,22 @@ FoldUnaryArithmetic(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandl
}
static bool
FoldIncrementDecrement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldIncrementDecrement(ExclusiveContext* cx, UnaryNode* incDec, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_PREINCREMENT) ||
node->isKind(PNK_POSTINCREMENT) ||
node->isKind(PNK_PREDECREMENT) ||
node->isKind(PNK_POSTDECREMENT));
MOZ_ASSERT(node->isArity(PN_UNARY));
MOZ_ASSERT(incDec->isKind(PNK_PREINCREMENT) ||
incDec->isKind(PNK_POSTINCREMENT) ||
incDec->isKind(PNK_PREDECREMENT) ||
incDec->isKind(PNK_POSTDECREMENT));
ParseNode*& target = node->pn_kid;
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(target, Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(incDec->kid(),
Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
if (!Fold(cx, &target, parser, inGenexpLambda))
if (!Fold(cx, incDec->unsafeKidReference(), parser, inGenexpLambda))
return false;
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(target, Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(incDec->kid(),
Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
return true;
}
@ -1214,14 +1212,13 @@ FoldList(ExclusiveContext* cx, ListNode* list, Parser<FullParseHandler>& parser,
}
static bool
FoldReturn(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
FoldReturn(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda)
{
MOZ_ASSERT(node->isKind(PNK_RETURN));
MOZ_ASSERT(node->isArity(PN_UNARY));
if (ParseNode*& expr = node->pn_kid) {
if (!Fold(cx, &expr, parser, inGenexpLambda))
if (node->kid()) {
if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false;
}
@ -1368,7 +1365,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
// assertions during freeing, then free it.
elem->setKind(PNK_TYPEOFEXPR);
elem->setArity(PN_UNARY);
elem->pn_kid = key;
*(elem->as<UnaryNode>().unsafeKidReference()) = key;
parser.freeTree(elem);
return true;
@ -1671,29 +1668,31 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return true;
case PNK_SUPERBASE:
case PNK_TYPEOFNAME:
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->pn_kid->isKind(PNK_NAME));
MOZ_ASSERT(!pn->pn_kid->expr());
case PNK_TYPEOFNAME: {
#ifdef DEBUG
UnaryNode* node = &pn->as<UnaryNode>();
MOZ_ASSERT(node->kid()->isKind(PNK_NAME));
MOZ_ASSERT(!node->kid()->expr());
#endif
return true;
}
case PNK_TYPEOFEXPR:
return FoldTypeOfExpr(cx, pn, parser, inGenexpLambda);
return FoldTypeOfExpr(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETENAME: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
MOZ_ASSERT(pn->pn_kid->isKind(PNK_NAME));
MOZ_ASSERT(pn->as<UnaryNode>().kid()->isKind(PNK_NAME));
return true;
}
case PNK_DELETEEXPR:
return FoldDeleteExpr(cx, pn, parser, inGenexpLambda);
return FoldDeleteExpr(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETEELEM:
return FoldDeleteElement(cx, pn, parser, inGenexpLambda);
return FoldDeleteElement(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETEPROP:
return FoldDeleteProperty(cx, pn, parser, inGenexpLambda);
return FoldDeleteProperty(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_CONDITIONAL:
MOZ_ASSERT((*pnp)->is<TernaryNode>());
@ -1704,18 +1703,18 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldIf(cx, pnp, parser, inGenexpLambda);
case PNK_NOT:
return FoldNot(cx, pn, parser, inGenexpLambda);
return FoldNot(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_BITNOT:
case PNK_POS:
case PNK_NEG:
return FoldUnaryArithmetic(cx, pn, parser, inGenexpLambda);
return FoldUnaryArithmetic(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_PREINCREMENT:
case PNK_POSTINCREMENT:
case PNK_PREDECREMENT:
case PNK_POSTDECREMENT:
return FoldIncrementDecrement(cx, pn, parser, inGenexpLambda);
return FoldIncrementDecrement(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_THROW:
case PNK_ARRAYPUSH:
@ -1724,8 +1723,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_SPREAD:
case PNK_EXPORT:
case PNK_VOID:
MOZ_ASSERT(pn->isArity(PN_UNARY));
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda);
return Fold(cx, pn->as<UnaryNode>().unsafeKidReference(), parser, inGenexpLambda);
case PNK_EXPORT_DEFAULT:
case PNK_GENEXP:
@ -1734,11 +1732,13 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_DELETEOPTCHAIN:
case PNK_OPTCHAIN:
case PNK_SEMI:
case PNK_THIS:
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (ParseNode*& expr = pn->pn_kid)
return Fold(cx, &expr, parser, inGenexpLambda);
case PNK_THIS: {
UnaryNode* node = &pn->as<UnaryNode>();
ParseNode** expr = node->unsafeKidReference();
if (*expr)
return Fold(cx, expr, parser, inGenexpLambda);
return true;
}
case PNK_COALESCE:
case PNK_AND:
@ -1797,9 +1797,8 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldList(cx, &pn->as<ListNode>(), parser, inGenexpLambda);
case PNK_INITIALYIELD: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
#ifdef DEBUG
AssignmentNode* assignNode = &pn->pn_kid->as<AssignmentNode>();
AssignmentNode* assignNode = &pn->as<UnaryNode>().kid()->as<AssignmentNode>();
MOZ_ASSERT(assignNode->left()->isKind(PNK_NAME));
MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR));
#endif
@ -1807,18 +1806,18 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
}
case PNK_YIELD_STAR:
MOZ_ASSERT(pn->isArity(PN_UNARY));
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda);
return Fold(cx, pn->as<UnaryNode>().unsafeKidReference(), parser, inGenexpLambda);
case PNK_YIELD:
case PNK_AWAIT:
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (!pn->pn_kid)
case PNK_AWAIT: {
UnaryNode* node = &pn->as<UnaryNode>();
if (!node->kid())
return true;
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda);
return Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda);
}
case PNK_RETURN:
return FoldReturn(cx, pn, parser, inGenexpLambda);
return FoldReturn(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_TRY:
return FoldTry(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda);

View file

@ -138,7 +138,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<NameNode>(PNK_NAME, JSOP_GETNAME, name, pos);
}
ParseNode* newComputedName(ParseNode* expr, uint32_t begin, uint32_t end) {
UnaryNodeType newComputedName(Node expr, uint32_t begin, uint32_t end) {
TokenPos pos(begin, end);
return new_<UnaryNode>(PNK_COMPUTED_NAME, JSOP_NOP, pos, expr);
}
@ -195,7 +195,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
setEndPosition(callSiteObj, callSiteObj->rawNodes());
}
ParseNode* newThisLiteral(const TokenPos& pos, ParseNode* thisName) {
ThisLiteralType newThisLiteral(const TokenPos& pos, Node thisName) {
return new_<ThisLiteral>(pos, thisName);
}
@ -222,7 +222,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
}
ParseNode* newDelete(uint32_t begin, ParseNode* expr) {
UnaryNodeType newDelete(uint32_t begin, Node expr) {
if (expr->isKind(PNK_NAME)) {
expr->setOp(JSOP_DELNAME);
return newUnary(PNK_DELETENAME, JSOP_NOP, begin, expr);
@ -235,7 +235,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return newUnary(PNK_DELETEELEM, JSOP_NOP, begin, expr);
if (expr->isKind(PNK_OPTCHAIN)) {
ParseNode* kid = expr->pn_kid;
ParseNode* kid = expr->as<UnaryNode>().kid();
// Handle property deletion explicitly. OptionalCall is handled
// via DeleteExpr.
if (kid->isKind(PNK_DOT) ||
@ -249,7 +249,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return newUnary(PNK_DELETEEXPR, JSOP_NOP, begin, expr);
}
ParseNode* newTypeof(uint32_t begin, ParseNode* kid) {
UnaryNodeType newTypeof(uint32_t begin, Node kid) {
TokenPos pos(begin, kid->pn_pos.end);
ParseNodeKind kind = kid->isKind(PNK_NAME) ? PNK_TYPEOFNAME : PNK_TYPEOFEXPR;
return new_<UnaryNode>(kind, JSOP_NOP, pos, kid);
@ -259,17 +259,17 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<NullaryNode>(kind, op, pos);
}
ParseNode* newUnary(ParseNodeKind kind, JSOp op, uint32_t begin, ParseNode* kid) {
UnaryNodeType newUnary(ParseNodeKind kind, JSOp op, uint32_t begin, ParseNode* kid) {
TokenPos pos(begin, kid ? kid->pn_pos.end : begin + 1);
return new_<UnaryNode>(kind, op, pos, kid);
}
ParseNode* newUpdate(ParseNodeKind kind, uint32_t begin, ParseNode* kid) {
UnaryNodeType newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
TokenPos pos(begin, kid->pn_pos.end);
return new_<UnaryNode>(kind, JSOP_NOP, pos, kid);
}
ParseNode* newSpread(uint32_t begin, ParseNode* kid) {
UnaryNodeType newSpread(uint32_t begin, Node kid) {
TokenPos pos(begin, kid->pn_pos.end);
return new_<UnaryNode>(PNK_SPREAD, JSOP_NOP, pos, kid);
}
@ -387,7 +387,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
ParseNode* newPosHolder(const TokenPos& pos) {
return new_<NullaryNode>(PNK_POSHOLDER, pos);
}
ParseNode* newSuperBase(ParseNode* thisName, const TokenPos& pos) {
UnaryNodeType newSuperBase(Node thisName, const TokenPos& pos) {
return new_<UnaryNode>(PNK_SUPERBASE, JSOP_NOP, pos, thisName);
}
@ -396,7 +396,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
// singleton objects will have Object.prototype as their [[Prototype]].
literal->setHasNonConstInitializer();
ParseNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr);
UnaryNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr);
if (!mutation)
return false;
literal->append(mutation);
@ -478,22 +478,22 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return true;
}
ParseNode* newInitialYieldExpression(uint32_t begin, ParseNode* gen) {
UnaryNodeType newInitialYieldExpression(uint32_t begin, Node gen) {
TokenPos pos(begin, begin + 1);
return new_<UnaryNode>(PNK_INITIALYIELD, JSOP_INITIALYIELD, pos, gen);
}
ParseNode* newYieldExpression(uint32_t begin, ParseNode* value) {
UnaryNodeType newYieldExpression(uint32_t begin, Node value) {
TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<UnaryNode>(PNK_YIELD, JSOP_YIELD, pos, value);
}
ParseNode* newYieldStarExpression(uint32_t begin, ParseNode* value) {
UnaryNodeType newYieldStarExpression(uint32_t begin, Node value) {
TokenPos pos(begin, value->pn_pos.end);
return new_<UnaryNode>(PNK_YIELD_STAR, JSOP_NOP, pos, value);
}
ParseNode* newAwaitExpression(uint32_t begin, ParseNode* value) {
UnaryNodeType newAwaitExpression(uint32_t begin, Node value) {
TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<UnaryNode>(PNK_AWAIT, JSOP_AWAIT, pos, value);
}
@ -550,7 +550,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
if (!genInit)
return false;
ParseNode* initialYield = newInitialYieldExpression(yieldPos.begin, genInit);
UnaryNode* initialYield = newInitialYieldExpression(yieldPos.begin, genInit);
if (!initialYield)
return false;
@ -575,7 +575,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return pn;
}
ParseNode* newExportDeclaration(ParseNode* kid, const TokenPos& pos) {
UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
return new_<UnaryNode>(PNK_EXPORT, JSOP_NOP, pos, kid);
}
@ -597,7 +597,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<BinaryNode>(PNK_EXPORT_DEFAULT, JSOP_NOP, pos, kid, maybeBinding);
}
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
UnaryNodeType newExprStatement(Node expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);
}
@ -669,7 +669,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<BreakStatement>(label, pos);
}
ParseNode* newReturnStatement(ParseNode* expr, const TokenPos& pos) {
UnaryNodeType newReturnStatement(Node expr, const TokenPos& pos) {
MOZ_ASSERT_IF(expr, pos.encloses(expr->pn_pos));
return new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, pos, expr);
}
@ -683,7 +683,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<LabeledStatement>(label, stmt, begin);
}
ParseNode* newThrowStatement(ParseNode* expr, const TokenPos& pos) {
UnaryNodeType newThrowStatement(Node expr, const TokenPos& pos) {
MOZ_ASSERT(pos.encloses(expr->pn_pos));
return new_<UnaryNode>(PNK_THROW, JSOP_THROW, pos, expr);
}
@ -820,7 +820,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
bool isStatementPermittedAfterReturnStatement(ParseNode *node) {
ParseNodeKind kind = node->getKind();
return kind == PNK_FUNCTION || kind == PNK_VAR || kind == PNK_BREAK || kind == PNK_THROW ||
(kind == PNK_SEMI && !node->pn_kid);
(kind == PNK_SEMI && !node->as<UnaryNode>().kid());
}
bool isSuperBase(ParseNode* node) {
@ -916,8 +916,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE ParseNode* setLikelyIIFE(ParseNode* pn) {
return parenthesize(pn);
}
void setInDirectivePrologue(ParseNode* pn) {
pn->pn_prologue = true;
void setInDirectivePrologue(UnaryNodeType exprStmt) {
exprStmt->setIsDirectivePrologueMember();
}
bool isConstant(ParseNode* pn) {
@ -966,10 +966,13 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
nullptr;
}
JSAtom* isStringExprStatement(ParseNode* pn, TokenPos* pos) {
if (JSAtom* atom = pn->isStringExprStatement()) {
*pos = pn->pn_kid->pn_pos;
if (pn->is<UnaryNode>()) {
UnaryNode* unary = &pn->as<UnaryNode>();
if (JSAtom* atom = unary->isStringExprStatement()) {
*pos = unary->kid()->pn_pos;
return atom;
}
}
return nullptr;
}

View file

@ -404,9 +404,8 @@ class NameResolver
case PNK_TYPEOFNAME:
case PNK_SUPERBASE:
MOZ_ASSERT(cur->isArity(PN_UNARY));
MOZ_ASSERT(cur->pn_kid->isKind(PNK_NAME));
MOZ_ASSERT(!cur->pn_kid->expr());
MOZ_ASSERT(cur->as<UnaryNode>().kid()->isKind(PNK_NAME));
MOZ_ASSERT(!cur->as<UnaryNode>().kid()->expr());
break;
case PNK_NEWTARGET: {
@ -436,16 +435,14 @@ class NameResolver
case PNK_SPREAD:
case PNK_MUTATEPROTO:
case PNK_EXPORT:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (!resolve(cur->pn_kid, prefix))
if (!resolve(cur->as<UnaryNode>().kid(), prefix))
return false;
break;
// Nodes with a single nullable child.
case PNK_SEMI:
case PNK_THIS:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (ParseNode* expr = cur->pn_kid) {
if (ParseNode* expr = cur->as<UnaryNode>().kid()) {
if (!resolve(expr, prefix))
return false;
}
@ -515,7 +512,7 @@ class NameResolver
case PNK_INITIALYIELD: {
#ifdef DEBUG
AssignmentNode* assignNode = &cur->pn_kid->as<AssignmentNode>();
AssignmentNode* assignNode = &cur->as<UnaryNode>().kid()->as<AssignmentNode>();
MOZ_ASSERT(assignNode->left()->isKind(PNK_NAME));
MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR));
#endif
@ -523,23 +520,20 @@ class NameResolver
}
case PNK_YIELD_STAR:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (!resolve(cur->pn_kid, prefix))
if (!resolve(cur->as<UnaryNode>().kid(), prefix))
return false;
break;
case PNK_YIELD:
case PNK_AWAIT:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (cur->pn_kid) {
if (!resolve(cur->pn_kid, prefix))
if (ParseNode* expr = cur->as<UnaryNode>().kid()) {
if (!resolve(expr, prefix))
return false;
}
break;
case PNK_RETURN:
MOZ_ASSERT(cur->isArity(PN_UNARY));
if (ParseNode* returnValue = cur->pn_kid) {
if (ParseNode* returnValue = cur->as<UnaryNode>().kid()) {
if (!resolve(returnValue, prefix))
return false;
}

View file

@ -157,11 +157,9 @@ PushListNodeChildren(ListNode* node, NodeStack* stack)
}
static PushResult
PushUnaryNodeChild(ParseNode* node, NodeStack* stack)
PushUnaryNodeChild(UnaryNode* node, NodeStack* stack)
{
MOZ_ASSERT(node->isArity(PN_UNARY));
stack->push(node->pn_kid);
stack->push(node->kid());
return PushResult::Recyclable;
}
@ -223,16 +221,16 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_MUTATEPROTO:
case PNK_EXPORT:
case PNK_SUPERBASE:
return PushUnaryNodeChild(pn, stack);
return PushUnaryNodeChild(&pn->as<UnaryNode>(), stack);
// Nodes with a single nullable child.
case PNK_OPTCHAIN:
case PNK_DELETEOPTCHAIN:
case PNK_THIS:
case PNK_SEMI: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (pn->pn_kid)
stack->push(pn->pn_kid);
UnaryNode* un = &pn->as<UnaryNode>();
if (un->kid())
stack->push(un->kid());
return PushResult::Recyclable;
}
@ -297,14 +295,14 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
// The child is an assignment of a PNK_GENERATOR node to the
// '.generator' local, for a synthesized, prepended initial yield.
case PNK_INITIALYIELD: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
UnaryNode* un = &pn->as<UnaryNode>();
#ifdef DEBUG
MOZ_ASSERT(pn->pn_kid->isKind(PNK_ASSIGN));
BinaryNode* bn = &pn->pn_kid->as<BinaryNode>();
MOZ_ASSERT(un->kid()->isKind(PNK_ASSIGN));
BinaryNode* bn = &un->kid()->as<BinaryNode>();
MOZ_ASSERT(bn->left()->isKind(PNK_NAME) &&
bn->right()->isKind(PNK_GENERATOR));
#endif
stack->push(pn->pn_kid);
stack->push(un->kid());
return PushResult::Recyclable;
}
@ -312,18 +310,18 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_YIELD_STAR:
case PNK_YIELD:
case PNK_AWAIT: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (pn->pn_kid)
stack->push(pn->pn_kid);
UnaryNode* un = &pn->as<UnaryNode>();
if (un->kid())
stack->push(un->kid());
return PushResult::Recyclable;
}
// A return node's child is what you'd expect: the return expression,
// if any.
case PNK_RETURN: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
if (pn->pn_kid)
stack->push(pn->pn_kid);
UnaryNode* un = &pn->as<UnaryNode>();
if (un->kid())
stack->push(un->kid());
return PushResult::Recyclable;
}
@ -660,7 +658,7 @@ ParseNode::dump(int indent)
((NullaryNode*) this)->dump();
break;
case PN_UNARY:
((UnaryNode*) this)->dump(indent);
as<UnaryNode>().dump(indent);
break;
case PN_BINARY:
as<BinaryNode>().dump(indent);
@ -723,7 +721,7 @@ UnaryNode::dump(int indent)
const char* name = parseNodeNames[getKind()];
fprintf(stderr, "(%s ", name);
indent += strlen(name) + 2;
DumpParseTree(pn_kid, indent);
DumpParseTree(kid(), indent);
fprintf(stderr, ")");
}

View file

@ -240,7 +240,8 @@ IsTypeofKind(ParseNodeKind kind)
* * StatementList node for function body statements
* * Return for expression closure
* count: number of formal parameters + 1
* PNK_SPREAD unary pn_kid: expression being spread
* PNK_SPREAD (UnaryNode)
* kid: expression being spread
* PNK_CLASS (ClassNode)
* kid1: PNK_CLASSNAMES for class name. can be null for anonymous class.
* kid2: expression after `extends`. null if no expression
@ -302,6 +303,8 @@ IsTypeofKind(ParseNodeKind kind)
* kid1: init expr before first ';' or nullptr
* kid2: cond expr before second ';' or nullptr
* kid3: update expr after second ';' or nullptr
* PNK_THROW (UnaryNode)
* kid: thrown exception
* PNK_TRY (TernaryNode)
* kid1: try block
* kid2: null or PNK_CATCHLIST list
@ -334,11 +337,12 @@ IsTypeofKind(ParseNodeKind kind)
* pn_lexdef (NOT pn_expr) set
* right: initializer
* count: N > 0
* PNK_RETURN unary pn_kid: return expr or null
* PNK_SEMI unary pn_kid: expr or null statement
* pn_prologue: true if Directive Prologue member
* in original source, not introduced via
* constant folding or other tree rewriting
* PNK_RETURN (UnaryNode)
* kid: returned expression, or null if none
* PNK_SEMI (UnaryNode)
* 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_IMPORT (BinaryNode)
* left: PNK_IMPORT_SPEC_LIST import specifiers
@ -349,7 +353,8 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_IMPORT_SPEC (BinaryNode)
* left: import name
* right: local binding name
* PNK_EXPORT unary pn_kid: declaration expression
* PNK_EXPORT (UnaryNode)
* kid: declaration expression
* PNK_EXPORT_FROM (BinaryNode)
* left: PNK_EXPORT_SPEC_LIST export specifiers
* right: PNK_STRING module specifier
@ -397,29 +402,25 @@ IsTypeofKind(ParseNodeKind kind)
* ParseNode::appendOrCreateList).
* count: N >= 2
*
* PNK_POS, unary pn_kid: UNARY expr
* PNK_NEG
* PNK_VOID, unary pn_kid: UNARY expr
* PNK_NOT,
* PNK_BITNOT,
* PNK_AWAIT
* PNK_TYPEOFNAME, unary pn_kid: UNARY expr
* PNK_TYPEOFEXPR
* PNK_PREINCREMENT, unary pn_kid: MEMBER expr
* PNK_POSTINCREMENT,
* PNK_PREDECREMENT,
* PNK_POSTDECREMENT
* PNK_POS, PNK_NEG, PNK_VOID, PNK_NOT, PNK_BITNOT,
* PNK_TYPEOFNAME, PNK_TYPEOFEXPR (UnaryNode)
* kid: unary expr
* PNK_PREINCREMENT, PNK_POSTINCREMENT,
* PNK_PREDECREMENT, PNK_POSTDECREMENT (UnaryNode)
* kid: member expr
* PNK_NEW (BinaryNode)
* left: ctor expression on the left of the '('
* right: Arguments
* PNK_DELETENAME unary pn_kid: PNK_NAME expr
* PNK_DELETEPROP unary pn_kid: PNK_DOT expr
* PNK_DELETEELEM unary pn_kid: PNK_ELEM expr
* PNK_DELETEEXPR unary pn_kid: MEMBER expr that's evaluated, then the
* overall delete evaluates to true; can't be a kind
* for a more-specific PNK_DELETE* unless constant
* folding (or a similar parse tree manipulation) has
* PNK_DELETENAME, PNK_DELETEPROP, PNK_DELETEELEM,
* PNK_DELETEEXPR (UnaryNode)
* kid: expression that's evaluated, then the overall delete evaluates to
* true; can't be a kind for a more-specific ParseNodeKind::Delete*
* unless constant folding (or a similar parse tree manipulation) has
* occurred
* * DeleteName: PNK_NAME expr
* * DeleteProp: PNK_DOT expr
* * DeleteElem: PNK_ELEM expr
* * DeleteExpr: MEMBER expr
* PNK_DELETEOPTCHAIN unary pn_kid: MEMBER expr that's evaluated, then the
* overall delete evaluates to true; If constant
* folding occurs, PNK_ELEM may become PNK_DOT.
@ -467,7 +468,9 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_SHORTHAND (BinaryNode)
* Same fields as Colon. This is used for object literal properties using
* shorthand ({x}).
* PNK_COMPUTED_NAME unary ES6 ComputedPropertyName.
* PNK_COMPUTED_NAME (UnaryNode)
* 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
@ -497,8 +500,10 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_NULL,
* PNK_RAW_UNDEFINED
*
* PNK_THIS, unary pn_kid: '.this' Name if function `this`, else nullptr
* PNK_SUPERBASE unary pn_kid: '.this' Name
* PNK_THIS (UnaryNode)
* kid: '.this' Name if function `this`, else nullptr
* PNK_SUPERBASE (UnaryNode)
* kid: '.this' Name
*
* PNK_SUPERCALL (BinaryNode)
* left: SuperBase
@ -509,9 +514,10 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_LEXICALSCOPE scope pn_u.scope.bindings: scope bindings
* pn_u.scope.body: scope body
* PNK_GENERATOR nullary
* PNK_INITIALYIELD unary pn_kid: generator object
* PNK_YIELD, unary pn_kid: expr or null
* PNK_YIELD_STAR
* PNK_INITIALYIELD (UnaryNode)
* kid: generator object
* PNK_YIELD, PNK_YIELD_STAR, PNK_AWAIT (UnaryNode)
* kid: expr or null
* PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally
@ -548,7 +554,9 @@ enum ParseNodeArity
\
macro(TernaryNode, TernaryNodeType, asTernary) \
macro(ClassNode, ClassNodeType, asClass) \
macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression)
macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression) \
macro(UnaryNode, UnaryNodeType, asUnary) \
macro(ThisLiteral, ThisLiteralType, asThisLiteral)
class LoopControlStatement;
class BreakStatement;
@ -669,9 +677,10 @@ class ParseNode
};
} binary;
struct { /* one kid if unary */
private:
friend class UnaryNode;
ParseNode* kid;
bool prologue; /* directive prologue member (as
pn_prologue) */
bool prologue; /* directive prologue member */
} unary;
struct { /* name, labeled statement, etc. */
union {
@ -699,8 +708,6 @@ class ParseNode
#define pn_objbox pn_u.name.objbox
#define pn_funbox pn_u.name.funbox
#define pn_body pn_u.name.expr
#define pn_kid pn_u.unary.kid
#define pn_prologue pn_u.unary.prologue
#define pn_atom pn_u.name.atom
#define pn_objbox pn_u.name.objbox
#define pn_expr pn_u.name.expr
@ -758,29 +765,6 @@ class ParseNode
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN);
}
/*
* True if this statement node could be a member of a Directive Prologue: an
* expression statement consisting of a single string literal.
*
* This considers only the node and its children, not its context. After
* parsing, check the node's pn_prologue flag to see if it is indeed part of
* a directive prologue.
*
* Note that a Directive Prologue can contain statements that cannot
* themselves be directives (string literals that include escape sequences
* or escaped newlines, say). This member function returns true for such
* nodes; we use it to determine the extent of the prologue.
*/
JSAtom* isStringExprStatement() const {
if (getKind() == PNK_SEMI) {
MOZ_ASSERT(pn_arity == PN_UNARY);
ParseNode* kid = pn_kid;
if (kid && kid->getKind() == PNK_STRING && !kid->pn_parens)
return kid->pn_atom;
}
return nullptr;
}
/* True if pn is a parsenode representing a literal constant. */
bool isLiteral() const {
return isKind(PNK_NUMBER) ||
@ -791,9 +775,6 @@ class ParseNode
isKind(PNK_RAW_UNDEFINED);
}
/* Return true if this node appears in a Directive Prologue. */
bool isDirectivePrologueMember() const { return pn_prologue; }
// True iff this is a for-in/of loop variable declaration (var/let/const).
bool isForLoopDeclaration() const;
@ -860,12 +841,13 @@ struct NullaryNode : public ParseNode
#endif
};
struct UnaryNode : public ParseNode
class UnaryNode : public ParseNode
{
public:
UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, ParseNode* kid)
: ParseNode(kind, op, PN_UNARY, pos)
{
pn_kid = kid;
pn_u.unary.kid = kid;
}
static bool test(const ParseNode& node) {
@ -875,6 +857,48 @@ struct UnaryNode : public ParseNode
#ifdef DEBUG
void dump(int indent);
#endif
ParseNode* kid() const {
return pn_u.unary.kid;
}
/* Return true if this node appears in a Directive Prologue. */
bool isDirectivePrologueMember() const {
return pn_u.unary.prologue;
}
void setIsDirectivePrologueMember() {
pn_u.unary.prologue = true;
}
/*
* Non-null if this is a statement node which could be a member of a
* Directive Prologue: an expression statement consisting of a single
* string literal.
*
* This considers only the node and its children, not its context. After
* parsing, check the node's prologue flag to see if it is indeed part of
* a directive prologue.
*
* Note that a Directive Prologue can contain statements that cannot
* themselves be directives (string literals that include escape sequences
* or escaped newlines, say). This member function returns true for such
* nodes; we use it to determine the extent of the prologue.
*/
JSAtom* isStringExprStatement() const {
if (isKind(PNK_SEMI)) {
ParseNode* expr = kid();
if (expr && expr->isKind(PNK_STRING) && !expr->isInParens()) {
return expr->pn_atom;
}
}
return nullptr;
}
// Methods used by FoldConstants.cpp.
ParseNode** unsafeKidReference() {
return &pn_u.unary.kid;
}
};
class BinaryNode : public ParseNode
@ -1565,6 +1589,12 @@ class ThisLiteral : public UnaryNode
ThisLiteral(const TokenPos& pos, ParseNode* thisName)
: UnaryNode(PNK_THIS, JSOP_NOP, pos, thisName)
{ }
static bool test(const ParseNode& node) {
bool match = node.isKind(PNK_THIS);
MOZ_ASSERT_IF(match, node.is<UnaryNode>());
return match;
}
};
class NullLiteral : public ParseNode

View file

@ -3977,7 +3977,7 @@ Parser<FullParseHandler>::asmJS(ListNodeType list)
* Recognize Directive Prologue members and directives. Assuming |pn| is a
* candidate for membership in a directive prologue, recognize directives and
* set |pc|'s flags accordingly. If |pn| is indeed part of a prologue, set its
* |pn_prologue| flag.
* |prologue| flag.
*
* Note that the following is a strict mode function:
*
@ -4014,7 +4014,7 @@ Parser<ParseHandler>::maybeParseDirective(ListNodeType list, Node possibleDirect
// directive in the future. We don't want to interfere with people
// taking advantage of directive-prologue-enabled features that appear
// in other browsers first.
handler.setInDirectivePrologue(possibleDirective);
handler.setInDirectivePrologue(handler.asUnary(possibleDirective));
if (directive == context->names().useStrict) {
// Functions with non-simple parameter lists (destructuring,
@ -5229,7 +5229,7 @@ Parser<FullParseHandler>::checkExportedNamesForArrayBinding(ListNode* array)
ParseNode* binding;
if (node->isKind(PNK_SPREAD))
binding = node->pn_kid;
binding = node->as<UnaryNode>().kid();
else if (node->isKind(PNK_ASSIGN))
binding = node->as<AssignmentNode>().left();
else
@ -5264,10 +5264,10 @@ Parser<FullParseHandler>::checkExportedNamesForObjectBinding(ListNode* obj)
ParseNode* target;
if (node->isKind(PNK_SPREAD)) {
target = node->pn_kid;
target = node->as<UnaryNode>().kid();
} else {
if (node->isKind(PNK_MUTATEPROTO))
target = node->pn_kid;
target = node->as<UnaryNode>().kid();
else
target = node->as<BinaryNode>().right();
@ -5590,7 +5590,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
if (!checkLocalExportNames(kid))
return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5601,7 +5601,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5617,7 +5617,7 @@ Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
if (!checkExportedNamesForDeclarationList(kid))
return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5628,7 +5628,7 @@ Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5643,7 +5643,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
if (!checkExportedNameForFunction(kid))
return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5654,7 +5654,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
{
if (!abortIfSyntaxParser())
@ -5669,7 +5669,7 @@ Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
if (!checkExportedNameForClass(kid))
return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5680,7 +5680,7 @@ Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind kind)
{
if (!abortIfSyntaxParser())
@ -5696,7 +5696,7 @@ Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind k
if (!checkExportedNamesForDeclarationList(kid))
return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node)
return null();
@ -5878,7 +5878,7 @@ Parser<ParseHandler>::exportDeclaration()
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::expressionStatement(YieldHandling yieldHandling, InvokedPrediction invoked)
{
tokenStream.ungetToken();
@ -6635,7 +6635,7 @@ Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_RETURN));
@ -6675,7 +6675,7 @@ Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
return null();
}
Node pn = handler.newReturnStatement(exprNode, TokenPos(begin, pos().end));
UnaryNodeType pn = handler.newReturnStatement(exprNode, TokenPos(begin, pos().end));
if (!pn)
return null();
@ -6689,7 +6689,7 @@ Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::yieldExpression(InHandling inHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_YIELD));
@ -6924,7 +6924,7 @@ Parser<ParseHandler>::labeledStatement(YieldHandling yieldHandling)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::throwStatement(YieldHandling yieldHandling)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_THROW));
@ -8540,7 +8540,7 @@ Parser<ParseHandler>::checkIncDecOperand(Node operand, uint32_t operandOffset)
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op,
uint32_t begin)
{
@ -10065,7 +10065,7 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
}
template <typename ParseHandler>
typename ParseHandler::Node
typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::computedPropertyName(YieldHandling yieldHandling,
const Maybe<DeclarationKind>& maybeDecl,
ListNodeType literal)

View file

@ -1213,9 +1213,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
SwitchStatementType switchStatement(YieldHandling yieldHandling);
Node continueStatement(YieldHandling yieldHandling);
Node breakStatement(YieldHandling yieldHandling);
Node returnStatement(YieldHandling yieldHandling);
UnaryNodeType returnStatement(YieldHandling yieldHandling);
BinaryNodeType withStatement(YieldHandling yieldHandling);
Node throwStatement(YieldHandling yieldHandling);
UnaryNodeType throwStatement(YieldHandling yieldHandling);
TernaryNodeType tryStatement(YieldHandling yieldHandling);
Node catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
Node debuggerStatement();
@ -1244,10 +1244,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
BinaryNodeType exportBatch(uint32_t begin);
bool checkLocalExportNames(ListNodeType node);
Node exportClause(uint32_t begin);
Node exportFunctionDeclaration(uint32_t begin);
Node exportVariableStatement(uint32_t begin);
Node exportClassDeclaration(uint32_t begin);
Node exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
UnaryNodeType exportFunctionDeclaration(uint32_t begin);
UnaryNodeType exportVariableStatement(uint32_t begin);
UnaryNodeType exportClassDeclaration(uint32_t begin);
UnaryNodeType exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
BinaryNodeType exportDefaultFunctionDeclaration(uint32_t begin,
FunctionAsyncKind asyncKind = SyncFunction);
BinaryNodeType exportDefaultClassDeclaration(uint32_t begin);
@ -1255,7 +1255,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
BinaryNodeType exportDefault(uint32_t begin);
Node exportDeclaration();
Node expressionStatement(YieldHandling yieldHandling,
UnaryNodeType expressionStatement(YieldHandling yieldHandling,
InvokedPrediction invoked = PredictUninvoked);
// Declaration parsing. The main entrypoint is Parser::declarationList,
@ -1316,7 +1316,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
InvokedPrediction invoked = PredictUninvoked);
Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
Node yieldExpression(InHandling inHandling);
UnaryNodeType yieldExpression(InHandling inHandling);
Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError,
@ -1366,7 +1366,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
Node functionBody(InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
FunctionBodyType type);
Node unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, uint32_t begin);
UnaryNodeType unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, uint32_t begin);
Node condition(InHandling inHandling, YieldHandling yieldHandling);
@ -1519,7 +1519,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
Node propertyName(YieldHandling yieldHandling,
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
PropertyType* propType, MutableHandleAtom propAtom);
Node computedPropertyName(YieldHandling yieldHandling,
UnaryNodeType computedPropertyName(YieldHandling yieldHandling,
const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType literal);
ListNodeType arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
Node newRegExp();

View file

@ -215,7 +215,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeUnparenthesizedName;
}
Node newComputedName(Node expr, uint32_t start, uint32_t end) {
UnaryNodeType newComputedName(Node expr, uint32_t start, uint32_t end) {
return NodeGeneric;
}
@ -242,7 +242,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
void addToCallSiteObject(CallSiteNodeType callSiteObj, Node rawNode, Node cookedNode) {}
Node newThisLiteral(const TokenPos& pos, Node thisName) { return NodeGeneric; }
UnaryNodeType newThisLiteral(const TokenPos& pos, Node thisName) { return NodeGeneric; }
Node newNullLiteral(const TokenPos& pos) { return NodeGeneric; }
Node newRawUndefinedLiteral(const TokenPos& pos) { return NodeGeneric; }
@ -255,11 +255,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
Node newElision() { return NodeGeneric; }
Node newDelete(uint32_t begin, Node expr) {
UnaryNodeType newDelete(uint32_t begin, Node expr) {
return NodeUnparenthesizedUnary;
}
Node newTypeof(uint32_t begin, Node kid) {
UnaryNodeType newTypeof(uint32_t begin, Node kid) {
return NodeUnparenthesizedUnary;
}
@ -267,15 +267,15 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeGeneric;
}
Node newUnary(ParseNodeKind kind, JSOp op, uint32_t begin, Node kid) {
UnaryNodeType newUnary(ParseNodeKind kind, JSOp op, uint32_t begin, Node kid) {
return NodeUnparenthesizedUnary;
}
Node newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
UnaryNodeType newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
return NodeGeneric;
}
Node newSpread(uint32_t begin, Node kid) {
UnaryNodeType newSpread(uint32_t begin, Node kid) {
return NodeGeneric;
}
@ -318,7 +318,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
BinaryNodeType newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; }
Node newPosHolder(const TokenPos& pos) { return NodeGeneric; }
Node newSuperBase(Node thisName, const TokenPos& pos) { return NodeSuperBase; }
UnaryNodeType newSuperBase(Node thisName, const TokenPos& pos) { return NodeSuperBase; }
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; }
@ -326,9 +326,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
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; }
Node newYieldExpression(uint32_t begin, Node value) { return NodeGeneric; }
Node newYieldStarExpression(uint32_t begin, Node value) { return NodeGeneric; }
Node newAwaitExpression(uint32_t begin, Node value) { return NodeGeneric; }
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; }
Node newOptionalChain(uint32_t begin, Node value) { return NodeGeneric; }
// Statements
@ -339,7 +339,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE bool prependInitialYield(ListNodeType stmtList, Node genName) { return true; }
Node newEmptyStatement(const TokenPos& pos) { return NodeEmptyStatement; }
Node newExportDeclaration(Node kid, const TokenPos& pos) {
UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
return NodeGeneric;
}
BinaryNodeType newExportFromDeclaration(uint32_t begin, Node exportSpecSet, Node moduleSpec) {
@ -351,7 +351,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
BinaryNodeType newSetThis(Node thisName, Node value) { return value; }
Node newExprStatement(Node expr, uint32_t end) {
UnaryNodeType newExprStatement(Node expr, uint32_t end) {
return expr == NodeUnparenthesizedString ? NodeStringExprStatement : NodeGeneric;
}
@ -367,14 +367,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
Node newContinueStatement(PropertyName* label, const TokenPos& pos) { return NodeGeneric; }
Node newBreakStatement(PropertyName* label, const TokenPos& pos) { return NodeBreak; }
Node newReturnStatement(Node expr, const TokenPos& pos) { return NodeReturn; }
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) {
return NodeGeneric;
}
Node newThrowStatement(Node expr, const TokenPos& pos) { return NodeThrow; }
UnaryNodeType newThrowStatement(Node expr, const TokenPos& pos) { return NodeThrow; }
Node newTryStatement(uint32_t begin, Node body, ListNodeType catchList, Node finallyBlock) {
return NodeGeneric;
}
@ -590,7 +590,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE Node setLikelyIIFE(Node pn) {
return pn; // Remain in syntax-parse mode.
}
void setInDirectivePrologue(Node pn) {}
void setInDirectivePrologue(UnaryNodeType exprStmt) {}
bool isConstant(Node pn) { return false; }

View file

@ -401,8 +401,7 @@ NextNode(ParseNode* pn)
static inline ParseNode*
UnaryKid(ParseNode* pn)
{
MOZ_ASSERT(pn->isArity(PN_UNARY));
return pn->pn_kid;
return pn->as<UnaryNode>().kid();
}
static inline ParseNode*