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

View file

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

View file

@ -465,10 +465,10 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitNumberOp(double dval); 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(ParseNode* pn);
MOZ_MUST_USE bool emitGetFunctionThis(const mozilla::Maybe<uint32_t>& offset); 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 emitSetThis(BinaryNode* setThisNode);
MOZ_MUST_USE bool emitCheckDerivedClassConstructorReturn(); MOZ_MUST_USE bool emitCheckDerivedClassConstructorReturn();
@ -484,7 +484,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter
MOZ_MUST_USE bool emitCall(JSOp op, uint16_t argc, MOZ_MUST_USE bool emitCall(JSOp op, uint16_t argc,
const mozilla::Maybe<uint32_t>& sourceCoordOffset); const mozilla::Maybe<uint32_t>& sourceCoordOffset);
MOZ_MUST_USE bool emitCall(JSOp op, uint16_t argc, ParseNode* pn = nullptr); 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 emitLoopHead(ParseNode* nextpn, JumpTarget* top);
MOZ_MUST_USE bool emitLoopEntry(ParseNode* nextpn, JumpList entryJump); 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 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 emitDeclarationList(ListNode* declList);
MOZ_MUST_USE bool emitSingleDeclaration(ParseNode* declList, ParseNode* decl, 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 emitGetDotGeneratorInScope(EmitterScope& currentScope);
MOZ_MUST_USE bool emitInitialYield(ParseNode* pn); MOZ_MUST_USE bool emitInitialYield(UnaryNode* yieldNode);
MOZ_MUST_USE bool emitYield(ParseNode* pn); MOZ_MUST_USE bool emitYield(UnaryNode* yieldNode);
MOZ_MUST_USE bool emitYieldOp(JSOp op); MOZ_MUST_USE bool emitYieldOp(JSOp op);
MOZ_MUST_USE bool emitYieldStar(ParseNode* iter); MOZ_MUST_USE bool emitYieldStar(ParseNode* iter);
MOZ_MUST_USE bool emitAwaitInInnermostScope() { MOZ_MUST_USE bool emitAwaitInInnermostScope() {
return emitAwaitInScope(*innermostEmitterScope()); 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 emitAwaitInScope(EmitterScope& currentScope);
MOZ_MUST_USE bool emitPropLHS(PropertyAccess* prop); 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 emitAsyncWrapperLambda(unsigned index, bool isArrow);
MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow, MOZ_MUST_USE bool emitAsyncWrapper(unsigned index, bool needsHomeObject, bool isArrow,
bool isStarGenerator); 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 // 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 // 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 emitElemObjAndKey(PropertyByValue* elem, bool isSuper, ElemOpEmitter& eoe);
MOZ_MUST_USE bool emitElemOpBase(JSOp op); 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 emitCatch(TernaryNode* catchNode);
MOZ_MUST_USE bool emitIf(TernaryNode* ifNode); 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 emitTemplateString(ListNode* templateString);
MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs); MOZ_MUST_USE bool emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs);
MOZ_MUST_USE bool emitReturn(ParseNode* pn); MOZ_MUST_USE bool emitReturn(UnaryNode* returnNode);
MOZ_MUST_USE bool emitStatement(ParseNode* pn); MOZ_MUST_USE bool emitStatement(UnaryNode* exprStmt);
MOZ_MUST_USE bool emitStatementList(ListNode* stmtList); MOZ_MUST_USE bool emitStatementList(ListNode* stmtList);
MOZ_MUST_USE bool emitDeleteName(ParseNode* pn); MOZ_MUST_USE bool emitDeleteName(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteProperty(ParseNode* pn); MOZ_MUST_USE bool emitDeleteProperty(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteElement(ParseNode* pn); MOZ_MUST_USE bool emitDeleteElement(UnaryNode* deleteNode);
MOZ_MUST_USE bool emitDeleteExpression(ParseNode* pn); MOZ_MUST_USE bool emitDeleteExpression(UnaryNode* deleteNode);
// Optional methods which emit Optional Jump Target // Optional methods which emit Optional Jump Target
MOZ_MUST_USE bool emitOptionalChain(ParseNode* optionalChain, MOZ_MUST_USE bool emitOptionalChain(UnaryNode* optionalChain,
ValueUsage valueUsage); ValueUsage valueUsage);
MOZ_MUST_USE bool emitCalleeAndThisForOptionalChain(ParseNode* optionalChain, MOZ_MUST_USE bool emitCalleeAndThisForOptionalChain(UnaryNode* optionalChain,
ParseNode* callNode, ParseNode* callNode,
CallOrNewEmitter& cone); 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 // Optional methods which emit a shortCircuit jump. They need to be called by
// a method which emits an Optional Jump Target, see below. // a method which emits an Optional Jump Target, see below.
@ -729,16 +729,16 @@ struct MOZ_STACK_CLASS BytecodeEmitter
OptionalEmitter& oe); OptionalEmitter& oe);
// |op| must be JSOP_TYPEOF or JSOP_TYPEOFEXPR. // |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 emitRightAssociative(ListNode* node);
MOZ_MUST_USE bool emitLeftAssociative(ListNode* node); MOZ_MUST_USE bool emitLeftAssociative(ListNode* node);
MOZ_MUST_USE bool emitLogical(ListNode* node); MOZ_MUST_USE bool emitLogical(ListNode* node);
MOZ_MUST_USE bool emitSequenceExpr(ListNode* node, MOZ_MUST_USE bool emitSequenceExpr(ListNode* node,
ValueUsage valueUsage = ValueUsage::WantValue); 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, MOZ_MUST_USE bool emitConditionalExpression(ConditionalExpression& conditional,
ValueUsage valueUsage = ValueUsage::WantValue); ValueUsage valueUsage = ValueUsage::WantValue);

View file

@ -110,7 +110,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_SEMI: case PNK_SEMI:
case PNK_THROW: case PNK_THROW:
case PNK_RETURN: case PNK_RETURN:
MOZ_ASSERT(node->isArity(PN_UNARY)); MOZ_ASSERT(node->is<UnaryNode>());
*result = false; *result = false;
return true; return true;
@ -119,7 +119,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_INITIALYIELD: case PNK_INITIALYIELD:
case PNK_YIELD_STAR: case PNK_YIELD_STAR:
case PNK_YIELD: case PNK_YIELD:
MOZ_ASSERT(node->isArity(PN_UNARY)); MOZ_ASSERT(node->is<UnaryNode>());
*result = false; *result = false;
return true; return true;
@ -515,7 +515,7 @@ Boolish(ParseNode* pn, bool isNullish = false)
// |void| expressions, for good measure) and check that the nested // |void| expressions, for good measure) and check that the nested
// expression doesn't break this requirement before indicating falsity. // expression doesn't break this requirement before indicating falsity.
do { do {
pn = pn->pn_kid; pn = pn->as<UnaryNode>().kid();
} while (pn->isKind(PNK_VOID)); } while (pn->isKind(PNK_VOID));
return IsEffectless(pn) ? Falsy : Unknown; return IsEffectless(pn) ? Falsy : Unknown;
@ -561,16 +561,16 @@ FoldCondition(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler
} }
static bool static bool
FoldTypeOfExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldTypeOfExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_TYPEOFEXPR)); MOZ_ASSERT(node->isKind(PNK_TYPEOFEXPR));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid; if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
if (!Fold(cx, &expr, parser, inGenexpLambda))
return false; return false;
ParseNode* expr = node->kid();
// Constant-fold the entire |typeof| if given a constant with known type. // Constant-fold the entire |typeof| if given a constant with known type.
RootedPropertyName result(cx); RootedPropertyName result(cx);
if (expr->isKind(PNK_STRING) || expr->isKind(PNK_TEMPLATE_STRING)) if (expr->isKind(PNK_STRING) || expr->isKind(PNK_TEMPLATE_STRING))
@ -597,16 +597,16 @@ FoldTypeOfExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>&
} }
static bool static bool
FoldDeleteExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldDeleteExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_DELETEEXPR)); MOZ_ASSERT(node->isKind(PNK_DELETEEXPR));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid; if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
if (!Fold(cx, &expr, parser, inGenexpLambda))
return false; return false;
ParseNode* expr = node->kid();
// Expression deletion evaluates the expression, then evaluates to true. // Expression deletion evaluates the expression, then evaluates to true.
// For effectless expressions, eliminate the expression evaluation. // For effectless expressions, eliminate the expression evaluation.
if (IsEffectless(expr)) { if (IsEffectless(expr)) {
@ -620,17 +620,17 @@ FoldDeleteExpr(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>&
} }
static bool static bool
FoldDeleteElement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldDeleteElement(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_DELETEELEM)); MOZ_ASSERT(node->isKind(PNK_DELETEELEM));
MOZ_ASSERT(node->isArity(PN_UNARY)); MOZ_ASSERT(node->kid()->isKind(PNK_ELEM));
MOZ_ASSERT(node->pn_kid->isKind(PNK_ELEM));
ParseNode*& expr = node->pn_kid; if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
if (!Fold(cx, &expr, parser, inGenexpLambda))
return false; return false;
ParseNode* expr = node->kid();
// If we're deleting an element, but constant-folding converted our // If we're deleting an element, but constant-folding converted our
// element reference into a dotted property access, we must *also* // element reference into a dotted property access, we must *also*
// morph the node's kind. // morph the node's kind.
@ -645,38 +645,36 @@ FoldDeleteElement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler
} }
static bool static bool
FoldDeleteProperty(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldDeleteProperty(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_DELETEPROP)); MOZ_ASSERT(node->isKind(PNK_DELETEPROP));
MOZ_ASSERT(node->isArity(PN_UNARY)); MOZ_ASSERT(node->kid()->isKind(PNK_DOT));
MOZ_ASSERT(node->pn_kid->isKind(PNK_DOT));
ParseNode*& expr = node->pn_kid;
#ifdef DEBUG #ifdef DEBUG
ParseNodeKind oldKind = expr->getKind(); ParseNodeKind oldKind = node->kid()->getKind();
#endif #endif
if (!Fold(cx, &expr, parser, inGenexpLambda)) if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false; return false;
MOZ_ASSERT(expr->isKind(oldKind), MOZ_ASSERT(node->kid()->isKind(oldKind),
"kind should have remained invariant under folding"); "kind should have remained invariant under folding");
return true; return true;
} }
static bool static bool
FoldNot(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldNot(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_NOT)); MOZ_ASSERT(node->isKind(PNK_NOT));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid; if (!FoldCondition(cx, node->unsafeKidReference(), parser, inGenexpLambda))
if (!FoldCondition(cx, &expr, parser, inGenexpLambda))
return false; return false;
ParseNode* expr = node->kid();
if (expr->isKind(PNK_NUMBER)) { if (expr->isKind(PNK_NUMBER)) {
double d = expr->pn_dval; double d = expr->pn_dval;
@ -702,17 +700,17 @@ FoldNot(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser,
} }
static bool static bool
FoldUnaryArithmetic(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_BITNOT) || node->isKind(PNK_POS) || node->isKind(PNK_NEG), MOZ_ASSERT(node->isKind(PNK_BITNOT) || node->isKind(PNK_POS) || node->isKind(PNK_NEG),
"need a different method for this node kind"); "need a different method for this node kind");
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& expr = node->pn_kid; if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
if (!Fold(cx, &expr, parser, inGenexpLambda))
return false; return false;
ParseNode* expr = node->kid();
if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) { if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) {
double d = expr->isKind(PNK_NUMBER) double d = expr->isKind(PNK_NUMBER)
? expr->pn_dval ? expr->pn_dval
@ -736,22 +734,22 @@ FoldUnaryArithmetic(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandl
} }
static bool static bool
FoldIncrementDecrement(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldIncrementDecrement(ExclusiveContext* cx, UnaryNode* incDec, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_PREINCREMENT) || MOZ_ASSERT(incDec->isKind(PNK_PREINCREMENT) ||
node->isKind(PNK_POSTINCREMENT) || incDec->isKind(PNK_POSTINCREMENT) ||
node->isKind(PNK_PREDECREMENT) || incDec->isKind(PNK_PREDECREMENT) ||
node->isKind(PNK_POSTDECREMENT)); incDec->isKind(PNK_POSTDECREMENT));
MOZ_ASSERT(node->isArity(PN_UNARY));
ParseNode*& target = node->pn_kid; MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(incDec->kid(),
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(target, Parser<FullParseHandler>::PermitAssignmentToFunctionCalls)); Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
if (!Fold(cx, &target, parser, inGenexpLambda)) if (!Fold(cx, incDec->unsafeKidReference(), parser, inGenexpLambda))
return false; return false;
MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(target, Parser<FullParseHandler>::PermitAssignmentToFunctionCalls)); MOZ_ASSERT(parser.isValidSimpleAssignmentTarget(incDec->kid(),
Parser<FullParseHandler>::PermitAssignmentToFunctionCalls));
return true; return true;
} }
@ -1214,14 +1212,13 @@ FoldList(ExclusiveContext* cx, ListNode* list, Parser<FullParseHandler>& parser,
} }
static bool static bool
FoldReturn(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, FoldReturn(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser,
bool inGenexpLambda) bool inGenexpLambda)
{ {
MOZ_ASSERT(node->isKind(PNK_RETURN)); MOZ_ASSERT(node->isKind(PNK_RETURN));
MOZ_ASSERT(node->isArity(PN_UNARY));
if (ParseNode*& expr = node->pn_kid) { if (node->kid()) {
if (!Fold(cx, &expr, parser, inGenexpLambda)) if (!Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda))
return false; return false;
} }
@ -1368,7 +1365,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>&
// assertions during freeing, then free it. // assertions during freeing, then free it.
elem->setKind(PNK_TYPEOFEXPR); elem->setKind(PNK_TYPEOFEXPR);
elem->setArity(PN_UNARY); elem->setArity(PN_UNARY);
elem->pn_kid = key; *(elem->as<UnaryNode>().unsafeKidReference()) = key;
parser.freeTree(elem); parser.freeTree(elem);
return true; return true;
@ -1671,29 +1668,31 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return true; return true;
case PNK_SUPERBASE: case PNK_SUPERBASE:
case PNK_TYPEOFNAME: case PNK_TYPEOFNAME: {
MOZ_ASSERT(pn->isArity(PN_UNARY)); #ifdef DEBUG
MOZ_ASSERT(pn->pn_kid->isKind(PNK_NAME)); UnaryNode* node = &pn->as<UnaryNode>();
MOZ_ASSERT(!pn->pn_kid->expr()); MOZ_ASSERT(node->kid()->isKind(PNK_NAME));
MOZ_ASSERT(!node->kid()->expr());
#endif
return true; return true;
}
case PNK_TYPEOFEXPR: case PNK_TYPEOFEXPR:
return FoldTypeOfExpr(cx, pn, parser, inGenexpLambda); return FoldTypeOfExpr(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETENAME: { case PNK_DELETENAME: {
MOZ_ASSERT(pn->isArity(PN_UNARY)); MOZ_ASSERT(pn->as<UnaryNode>().kid()->isKind(PNK_NAME));
MOZ_ASSERT(pn->pn_kid->isKind(PNK_NAME));
return true; return true;
} }
case PNK_DELETEEXPR: case PNK_DELETEEXPR:
return FoldDeleteExpr(cx, pn, parser, inGenexpLambda); return FoldDeleteExpr(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETEELEM: case PNK_DELETEELEM:
return FoldDeleteElement(cx, pn, parser, inGenexpLambda); return FoldDeleteElement(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_DELETEPROP: case PNK_DELETEPROP:
return FoldDeleteProperty(cx, pn, parser, inGenexpLambda); return FoldDeleteProperty(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_CONDITIONAL: case PNK_CONDITIONAL:
MOZ_ASSERT((*pnp)->is<TernaryNode>()); MOZ_ASSERT((*pnp)->is<TernaryNode>());
@ -1704,18 +1703,18 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldIf(cx, pnp, parser, inGenexpLambda); return FoldIf(cx, pnp, parser, inGenexpLambda);
case PNK_NOT: case PNK_NOT:
return FoldNot(cx, pn, parser, inGenexpLambda); return FoldNot(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_BITNOT: case PNK_BITNOT:
case PNK_POS: case PNK_POS:
case PNK_NEG: case PNK_NEG:
return FoldUnaryArithmetic(cx, pn, parser, inGenexpLambda); return FoldUnaryArithmetic(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_PREINCREMENT: case PNK_PREINCREMENT:
case PNK_POSTINCREMENT: case PNK_POSTINCREMENT:
case PNK_PREDECREMENT: case PNK_PREDECREMENT:
case PNK_POSTDECREMENT: case PNK_POSTDECREMENT:
return FoldIncrementDecrement(cx, pn, parser, inGenexpLambda); return FoldIncrementDecrement(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_THROW: case PNK_THROW:
case PNK_ARRAYPUSH: case PNK_ARRAYPUSH:
@ -1724,8 +1723,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_SPREAD: case PNK_SPREAD:
case PNK_EXPORT: case PNK_EXPORT:
case PNK_VOID: case PNK_VOID:
MOZ_ASSERT(pn->isArity(PN_UNARY)); return Fold(cx, pn->as<UnaryNode>().unsafeKidReference(), parser, inGenexpLambda);
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda);
case PNK_EXPORT_DEFAULT: case PNK_EXPORT_DEFAULT:
case PNK_GENEXP: case PNK_GENEXP:
@ -1734,11 +1732,13 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
case PNK_DELETEOPTCHAIN: case PNK_DELETEOPTCHAIN:
case PNK_OPTCHAIN: case PNK_OPTCHAIN:
case PNK_SEMI: case PNK_SEMI:
case PNK_THIS: case PNK_THIS: {
MOZ_ASSERT(pn->isArity(PN_UNARY)); UnaryNode* node = &pn->as<UnaryNode>();
if (ParseNode*& expr = pn->pn_kid) ParseNode** expr = node->unsafeKidReference();
return Fold(cx, &expr, parser, inGenexpLambda); if (*expr)
return Fold(cx, expr, parser, inGenexpLambda);
return true; return true;
}
case PNK_COALESCE: case PNK_COALESCE:
case PNK_AND: case PNK_AND:
@ -1797,9 +1797,8 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
return FoldList(cx, &pn->as<ListNode>(), parser, inGenexpLambda); return FoldList(cx, &pn->as<ListNode>(), parser, inGenexpLambda);
case PNK_INITIALYIELD: { case PNK_INITIALYIELD: {
MOZ_ASSERT(pn->isArity(PN_UNARY));
#ifdef DEBUG #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->left()->isKind(PNK_NAME));
MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR)); MOZ_ASSERT(assignNode->right()->isKind(PNK_GENERATOR));
#endif #endif
@ -1807,18 +1806,18 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
} }
case PNK_YIELD_STAR: case PNK_YIELD_STAR:
MOZ_ASSERT(pn->isArity(PN_UNARY)); return Fold(cx, pn->as<UnaryNode>().unsafeKidReference(), parser, inGenexpLambda);
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda);
case PNK_YIELD: case PNK_YIELD:
case PNK_AWAIT: case PNK_AWAIT: {
MOZ_ASSERT(pn->isArity(PN_UNARY)); UnaryNode* node = &pn->as<UnaryNode>();
if (!pn->pn_kid) if (!node->kid())
return true; return true;
return Fold(cx, &pn->pn_kid, parser, inGenexpLambda); return Fold(cx, node->unsafeKidReference(), parser, inGenexpLambda);
}
case PNK_RETURN: case PNK_RETURN:
return FoldReturn(cx, pn, parser, inGenexpLambda); return FoldReturn(cx, &pn->as<UnaryNode>(), parser, inGenexpLambda);
case PNK_TRY: case PNK_TRY:
return FoldTry(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda); 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); 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); TokenPos pos(begin, end);
return new_<UnaryNode>(PNK_COMPUTED_NAME, JSOP_NOP, pos, expr); return new_<UnaryNode>(PNK_COMPUTED_NAME, JSOP_NOP, pos, expr);
} }
@ -195,7 +195,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
setEndPosition(callSiteObj, callSiteObj->rawNodes()); setEndPosition(callSiteObj, callSiteObj->rawNodes());
} }
ParseNode* newThisLiteral(const TokenPos& pos, ParseNode* thisName) { ThisLiteralType newThisLiteral(const TokenPos& pos, Node thisName) {
return new_<ThisLiteral>(pos, thisName); return new_<ThisLiteral>(pos, thisName);
} }
@ -222,7 +222,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<ConditionalExpression>(cond, thenExpr, elseExpr); 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)) { if (expr->isKind(PNK_NAME)) {
expr->setOp(JSOP_DELNAME); expr->setOp(JSOP_DELNAME);
return newUnary(PNK_DELETENAME, JSOP_NOP, begin, expr); 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); return newUnary(PNK_DELETEELEM, JSOP_NOP, begin, expr);
if (expr->isKind(PNK_OPTCHAIN)) { if (expr->isKind(PNK_OPTCHAIN)) {
ParseNode* kid = expr->pn_kid; ParseNode* kid = expr->as<UnaryNode>().kid();
// Handle property deletion explicitly. OptionalCall is handled // Handle property deletion explicitly. OptionalCall is handled
// via DeleteExpr. // via DeleteExpr.
if (kid->isKind(PNK_DOT) || if (kid->isKind(PNK_DOT) ||
@ -249,7 +249,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return newUnary(PNK_DELETEEXPR, JSOP_NOP, begin, expr); 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); TokenPos pos(begin, kid->pn_pos.end);
ParseNodeKind kind = kid->isKind(PNK_NAME) ? PNK_TYPEOFNAME : PNK_TYPEOFEXPR; ParseNodeKind kind = kid->isKind(PNK_NAME) ? PNK_TYPEOFNAME : PNK_TYPEOFEXPR;
return new_<UnaryNode>(kind, JSOP_NOP, pos, kid); return new_<UnaryNode>(kind, JSOP_NOP, pos, kid);
@ -259,17 +259,17 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return new_<NullaryNode>(kind, op, pos); 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); TokenPos pos(begin, kid ? kid->pn_pos.end : begin + 1);
return new_<UnaryNode>(kind, op, pos, kid); 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); TokenPos pos(begin, kid->pn_pos.end);
return new_<UnaryNode>(kind, JSOP_NOP, pos, kid); 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); TokenPos pos(begin, kid->pn_pos.end);
return new_<UnaryNode>(PNK_SPREAD, JSOP_NOP, pos, kid); return new_<UnaryNode>(PNK_SPREAD, JSOP_NOP, pos, kid);
} }
@ -387,7 +387,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
ParseNode* newPosHolder(const TokenPos& pos) { ParseNode* newPosHolder(const TokenPos& pos) {
return new_<NullaryNode>(PNK_POSHOLDER, 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); 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]]. // singleton objects will have Object.prototype as their [[Prototype]].
literal->setHasNonConstInitializer(); literal->setHasNonConstInitializer();
ParseNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr); UnaryNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr);
if (!mutation) if (!mutation)
return false; return false;
literal->append(mutation); literal->append(mutation);
@ -478,22 +478,22 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return true; return true;
} }
ParseNode* newInitialYieldExpression(uint32_t begin, ParseNode* gen) { UnaryNodeType newInitialYieldExpression(uint32_t begin, Node gen) {
TokenPos pos(begin, begin + 1); TokenPos pos(begin, begin + 1);
return new_<UnaryNode>(PNK_INITIALYIELD, JSOP_INITIALYIELD, pos, gen); 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); TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<UnaryNode>(PNK_YIELD, JSOP_YIELD, pos, value); 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); TokenPos pos(begin, value->pn_pos.end);
return new_<UnaryNode>(PNK_YIELD_STAR, JSOP_NOP, pos, value); 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); TokenPos pos(begin, value ? value->pn_pos.end : begin + 1);
return new_<UnaryNode>(PNK_AWAIT, JSOP_AWAIT, pos, value); return new_<UnaryNode>(PNK_AWAIT, JSOP_AWAIT, pos, value);
} }
@ -550,7 +550,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
if (!genInit) if (!genInit)
return false; return false;
ParseNode* initialYield = newInitialYieldExpression(yieldPos.begin, genInit); UnaryNode* initialYield = newInitialYieldExpression(yieldPos.begin, genInit);
if (!initialYield) if (!initialYield)
return false; return false;
@ -575,7 +575,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return pn; 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); 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); 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); MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr); 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); 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)); MOZ_ASSERT_IF(expr, pos.encloses(expr->pn_pos));
return new_<UnaryNode>(PNK_RETURN, JSOP_RETURN, pos, expr); 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); 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)); MOZ_ASSERT(pos.encloses(expr->pn_pos));
return new_<UnaryNode>(PNK_THROW, JSOP_THROW, pos, expr); return new_<UnaryNode>(PNK_THROW, JSOP_THROW, pos, expr);
} }
@ -820,7 +820,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
bool isStatementPermittedAfterReturnStatement(ParseNode *node) { bool isStatementPermittedAfterReturnStatement(ParseNode *node) {
ParseNodeKind kind = node->getKind(); ParseNodeKind kind = node->getKind();
return kind == PNK_FUNCTION || kind == PNK_VAR || kind == PNK_BREAK || kind == PNK_THROW || 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) { bool isSuperBase(ParseNode* node) {
@ -916,8 +916,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE ParseNode* setLikelyIIFE(ParseNode* pn) { MOZ_MUST_USE ParseNode* setLikelyIIFE(ParseNode* pn) {
return parenthesize(pn); return parenthesize(pn);
} }
void setInDirectivePrologue(ParseNode* pn) { void setInDirectivePrologue(UnaryNodeType exprStmt) {
pn->pn_prologue = true; exprStmt->setIsDirectivePrologueMember();
} }
bool isConstant(ParseNode* pn) { bool isConstant(ParseNode* pn) {
@ -966,9 +966,12 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
nullptr; nullptr;
} }
JSAtom* isStringExprStatement(ParseNode* pn, TokenPos* pos) { JSAtom* isStringExprStatement(ParseNode* pn, TokenPos* pos) {
if (JSAtom* atom = pn->isStringExprStatement()) { if (pn->is<UnaryNode>()) {
*pos = pn->pn_kid->pn_pos; UnaryNode* unary = &pn->as<UnaryNode>();
return atom; if (JSAtom* atom = unary->isStringExprStatement()) {
*pos = unary->kid()->pn_pos;
return atom;
}
} }
return nullptr; return nullptr;
} }

View file

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

View file

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

View file

@ -240,7 +240,8 @@ IsTypeofKind(ParseNodeKind kind)
* * StatementList node for function body statements * * StatementList node for function body statements
* * Return for expression closure * * Return for expression closure
* count: number of formal parameters + 1 * count: number of formal parameters + 1
* PNK_SPREAD unary pn_kid: expression being spread * PNK_SPREAD (UnaryNode)
* kid: expression being spread
* PNK_CLASS (ClassNode) * PNK_CLASS (ClassNode)
* kid1: PNK_CLASSNAMES for class name. can be null for anonymous class. * kid1: PNK_CLASSNAMES for class name. can be null for anonymous class.
* kid2: expression after `extends`. null if no expression * kid2: expression after `extends`. null if no expression
@ -302,6 +303,8 @@ IsTypeofKind(ParseNodeKind kind)
* kid1: init expr before first ';' or nullptr * kid1: init expr before first ';' or nullptr
* kid2: cond expr before second ';' or nullptr * kid2: cond expr before second ';' or nullptr
* kid3: update expr after second ';' or nullptr * kid3: update expr after second ';' or nullptr
* PNK_THROW (UnaryNode)
* kid: thrown exception
* PNK_TRY (TernaryNode) * PNK_TRY (TernaryNode)
* kid1: try block * kid1: try block
* kid2: null or PNK_CATCHLIST list * kid2: null or PNK_CATCHLIST list
@ -334,11 +337,12 @@ IsTypeofKind(ParseNodeKind kind)
* pn_lexdef (NOT pn_expr) set * pn_lexdef (NOT pn_expr) set
* right: initializer * right: initializer
* count: N > 0 * count: N > 0
* PNK_RETURN unary pn_kid: return expr or null * PNK_RETURN (UnaryNode)
* PNK_SEMI unary pn_kid: expr or null statement * kid: returned expression, or null if none
* pn_prologue: true if Directive Prologue member * PNK_SEMI (UnaryNode)
* in original source, not introduced via * kid: expr
* constant folding or other tree rewriting * 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_LABEL name pn_atom: label, pn_expr: labeled statement
* PNK_IMPORT (BinaryNode) * PNK_IMPORT (BinaryNode)
* left: PNK_IMPORT_SPEC_LIST import specifiers * left: PNK_IMPORT_SPEC_LIST import specifiers
@ -349,7 +353,8 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_IMPORT_SPEC (BinaryNode) * PNK_IMPORT_SPEC (BinaryNode)
* left: import name * left: import name
* right: local binding name * right: local binding name
* PNK_EXPORT unary pn_kid: declaration expression * PNK_EXPORT (UnaryNode)
* kid: declaration expression
* PNK_EXPORT_FROM (BinaryNode) * PNK_EXPORT_FROM (BinaryNode)
* left: PNK_EXPORT_SPEC_LIST export specifiers * left: PNK_EXPORT_SPEC_LIST export specifiers
* right: PNK_STRING module specifier * right: PNK_STRING module specifier
@ -397,29 +402,25 @@ IsTypeofKind(ParseNodeKind kind)
* ParseNode::appendOrCreateList). * ParseNode::appendOrCreateList).
* count: N >= 2 * count: N >= 2
* *
* PNK_POS, unary pn_kid: UNARY expr * PNK_POS, PNK_NEG, PNK_VOID, PNK_NOT, PNK_BITNOT,
* PNK_NEG * PNK_TYPEOFNAME, PNK_TYPEOFEXPR (UnaryNode)
* PNK_VOID, unary pn_kid: UNARY expr * kid: unary expr
* PNK_NOT, * PNK_PREINCREMENT, PNK_POSTINCREMENT,
* PNK_BITNOT, * PNK_PREDECREMENT, PNK_POSTDECREMENT (UnaryNode)
* PNK_AWAIT * kid: member expr
* PNK_TYPEOFNAME, unary pn_kid: UNARY expr
* PNK_TYPEOFEXPR
* PNK_PREINCREMENT, unary pn_kid: MEMBER expr
* PNK_POSTINCREMENT,
* PNK_PREDECREMENT,
* PNK_POSTDECREMENT
* PNK_NEW (BinaryNode) * PNK_NEW (BinaryNode)
* left: ctor expression on the left of the '(' * left: ctor expression on the left of the '('
* right: Arguments * right: Arguments
* PNK_DELETENAME unary pn_kid: PNK_NAME expr * PNK_DELETENAME, PNK_DELETEPROP, PNK_DELETEELEM,
* PNK_DELETEPROP unary pn_kid: PNK_DOT expr * PNK_DELETEEXPR (UnaryNode)
* PNK_DELETEELEM unary pn_kid: PNK_ELEM expr * kid: expression that's evaluated, then the overall delete evaluates to
* PNK_DELETEEXPR unary pn_kid: MEMBER expr that's evaluated, then the * true; can't be a kind for a more-specific ParseNodeKind::Delete*
* overall delete evaluates to true; can't be a kind * unless constant folding (or a similar parse tree manipulation) has
* for a more-specific PNK_DELETE* unless constant * occurred
* folding (or a similar parse tree manipulation) has * * DeleteName: PNK_NAME expr
* occurred * * DeleteProp: PNK_DOT expr
* * DeleteElem: PNK_ELEM expr
* * DeleteExpr: MEMBER expr
* PNK_DELETEOPTCHAIN unary pn_kid: MEMBER expr that's evaluated, then the * PNK_DELETEOPTCHAIN unary pn_kid: MEMBER expr that's evaluated, then the
* overall delete evaluates to true; If constant * overall delete evaluates to true; If constant
* folding occurs, PNK_ELEM may become PNK_DOT. * folding occurs, PNK_ELEM may become PNK_DOT.
@ -467,7 +468,9 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_SHORTHAND (BinaryNode) * PNK_SHORTHAND (BinaryNode)
* Same fields as Colon. This is used for object literal properties using * Same fields as Colon. This is used for object literal properties using
* shorthand ({x}). * 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 * pn_kid: the AssignmentExpression inside the square brackets
* PNK_NAME, name pn_atom: name, string, or object atom * PNK_NAME, name pn_atom: name, string, or object atom
* PNK_STRING pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT * PNK_STRING pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT
@ -497,8 +500,10 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_NULL, * PNK_NULL,
* PNK_RAW_UNDEFINED * PNK_RAW_UNDEFINED
* *
* PNK_THIS, unary pn_kid: '.this' Name if function `this`, else nullptr * PNK_THIS (UnaryNode)
* PNK_SUPERBASE unary pn_kid: '.this' Name * kid: '.this' Name if function `this`, else nullptr
* PNK_SUPERBASE (UnaryNode)
* kid: '.this' Name
* *
* PNK_SUPERCALL (BinaryNode) * PNK_SUPERCALL (BinaryNode)
* left: SuperBase * left: SuperBase
@ -509,9 +514,10 @@ IsTypeofKind(ParseNodeKind kind)
* PNK_LEXICALSCOPE scope pn_u.scope.bindings: scope bindings * PNK_LEXICALSCOPE scope pn_u.scope.bindings: scope bindings
* pn_u.scope.body: scope body * pn_u.scope.body: scope body
* PNK_GENERATOR nullary * PNK_GENERATOR nullary
* PNK_INITIALYIELD unary pn_kid: generator object * PNK_INITIALYIELD (UnaryNode)
* PNK_YIELD, unary pn_kid: expr or null * kid: generator object
* PNK_YIELD_STAR * PNK_YIELD, PNK_YIELD_STAR, PNK_AWAIT (UnaryNode)
* kid: expr or null
* PNK_ARRAYCOMP list pn_count: 1 * PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block * pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally * enclosing for loop(s) and optionally
@ -548,7 +554,9 @@ enum ParseNodeArity
\ \
macro(TernaryNode, TernaryNodeType, asTernary) \ macro(TernaryNode, TernaryNodeType, asTernary) \
macro(ClassNode, ClassNodeType, asClass) \ macro(ClassNode, ClassNodeType, asClass) \
macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression) macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression) \
macro(UnaryNode, UnaryNodeType, asUnary) \
macro(ThisLiteral, ThisLiteralType, asThisLiteral)
class LoopControlStatement; class LoopControlStatement;
class BreakStatement; class BreakStatement;
@ -669,9 +677,10 @@ class ParseNode
}; };
} binary; } binary;
struct { /* one kid if unary */ struct { /* one kid if unary */
private:
friend class UnaryNode;
ParseNode* kid; ParseNode* kid;
bool prologue; /* directive prologue member (as bool prologue; /* directive prologue member */
pn_prologue) */
} unary; } unary;
struct { /* name, labeled statement, etc. */ struct { /* name, labeled statement, etc. */
union { union {
@ -699,8 +708,6 @@ class ParseNode
#define pn_objbox pn_u.name.objbox #define pn_objbox pn_u.name.objbox
#define pn_funbox pn_u.name.funbox #define pn_funbox pn_u.name.funbox
#define pn_body pn_u.name.expr #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_atom pn_u.name.atom
#define pn_objbox pn_u.name.objbox #define pn_objbox pn_u.name.objbox
#define pn_expr pn_u.name.expr #define pn_expr pn_u.name.expr
@ -758,29 +765,6 @@ class ParseNode
return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN); 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. */ /* True if pn is a parsenode representing a literal constant. */
bool isLiteral() const { bool isLiteral() const {
return isKind(PNK_NUMBER) || return isKind(PNK_NUMBER) ||
@ -791,9 +775,6 @@ class ParseNode
isKind(PNK_RAW_UNDEFINED); 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). // True iff this is a for-in/of loop variable declaration (var/let/const).
bool isForLoopDeclaration() const; bool isForLoopDeclaration() const;
@ -860,12 +841,13 @@ struct NullaryNode : public ParseNode
#endif #endif
}; };
struct UnaryNode : public ParseNode class UnaryNode : public ParseNode
{ {
public:
UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, ParseNode* kid) UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, ParseNode* kid)
: ParseNode(kind, op, PN_UNARY, pos) : ParseNode(kind, op, PN_UNARY, pos)
{ {
pn_kid = kid; pn_u.unary.kid = kid;
} }
static bool test(const ParseNode& node) { static bool test(const ParseNode& node) {
@ -875,6 +857,48 @@ struct UnaryNode : public ParseNode
#ifdef DEBUG #ifdef DEBUG
void dump(int indent); void dump(int indent);
#endif #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 class BinaryNode : public ParseNode
@ -1565,6 +1589,12 @@ class ThisLiteral : public UnaryNode
ThisLiteral(const TokenPos& pos, ParseNode* thisName) ThisLiteral(const TokenPos& pos, ParseNode* thisName)
: UnaryNode(PNK_THIS, JSOP_NOP, pos, 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 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 * Recognize Directive Prologue members and directives. Assuming |pn| is a
* candidate for membership in a directive prologue, recognize directives and * 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 * 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: * 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 // directive in the future. We don't want to interfere with people
// taking advantage of directive-prologue-enabled features that appear // taking advantage of directive-prologue-enabled features that appear
// in other browsers first. // in other browsers first.
handler.setInDirectivePrologue(possibleDirective); handler.setInDirectivePrologue(handler.asUnary(possibleDirective));
if (directive == context->names().useStrict) { if (directive == context->names().useStrict) {
// Functions with non-simple parameter lists (destructuring, // Functions with non-simple parameter lists (destructuring,
@ -5229,7 +5229,7 @@ Parser<FullParseHandler>::checkExportedNamesForArrayBinding(ListNode* array)
ParseNode* binding; ParseNode* binding;
if (node->isKind(PNK_SPREAD)) if (node->isKind(PNK_SPREAD))
binding = node->pn_kid; binding = node->as<UnaryNode>().kid();
else if (node->isKind(PNK_ASSIGN)) else if (node->isKind(PNK_ASSIGN))
binding = node->as<AssignmentNode>().left(); binding = node->as<AssignmentNode>().left();
else else
@ -5264,10 +5264,10 @@ Parser<FullParseHandler>::checkExportedNamesForObjectBinding(ListNode* obj)
ParseNode* target; ParseNode* target;
if (node->isKind(PNK_SPREAD)) { if (node->isKind(PNK_SPREAD)) {
target = node->pn_kid; target = node->as<UnaryNode>().kid();
} else { } else {
if (node->isKind(PNK_MUTATEPROTO)) if (node->isKind(PNK_MUTATEPROTO))
target = node->pn_kid; target = node->as<UnaryNode>().kid();
else else
target = node->as<BinaryNode>().right(); target = node->as<BinaryNode>().right();
@ -5590,7 +5590,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
if (!checkLocalExportNames(kid)) if (!checkLocalExportNames(kid))
return null(); return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node) if (!node)
return null(); return null();
@ -5601,7 +5601,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportVariableStatement(uint32_t begin) Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
{ {
if (!abortIfSyntaxParser()) if (!abortIfSyntaxParser())
@ -5617,7 +5617,7 @@ Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
if (!checkExportedNamesForDeclarationList(kid)) if (!checkExportedNamesForDeclarationList(kid))
return null(); return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node) if (!node)
return null(); return null();
@ -5628,7 +5628,7 @@ Parser<ParseHandler>::exportVariableStatement(uint32_t begin)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin) Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
{ {
if (!abortIfSyntaxParser()) if (!abortIfSyntaxParser())
@ -5643,7 +5643,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
if (!checkExportedNameForFunction(kid)) if (!checkExportedNameForFunction(kid))
return null(); return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node) if (!node)
return null(); return null();
@ -5654,7 +5654,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportClassDeclaration(uint32_t begin) Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
{ {
if (!abortIfSyntaxParser()) if (!abortIfSyntaxParser())
@ -5669,7 +5669,7 @@ Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
if (!checkExportedNameForClass(kid)) if (!checkExportedNameForClass(kid))
return null(); return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node) if (!node)
return null(); return null();
@ -5680,7 +5680,7 @@ Parser<ParseHandler>::exportClassDeclaration(uint32_t begin)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind kind) Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind kind)
{ {
if (!abortIfSyntaxParser()) if (!abortIfSyntaxParser())
@ -5696,7 +5696,7 @@ Parser<ParseHandler>::exportLexicalDeclaration(uint32_t begin, DeclarationKind k
if (!checkExportedNamesForDeclarationList(kid)) if (!checkExportedNamesForDeclarationList(kid))
return null(); return null();
Node node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end));
if (!node) if (!node)
return null(); return null();
@ -5878,7 +5878,7 @@ Parser<ParseHandler>::exportDeclaration()
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::expressionStatement(YieldHandling yieldHandling, InvokedPrediction invoked) Parser<ParseHandler>::expressionStatement(YieldHandling yieldHandling, InvokedPrediction invoked)
{ {
tokenStream.ungetToken(); tokenStream.ungetToken();
@ -6635,7 +6635,7 @@ Parser<ParseHandler>::breakStatement(YieldHandling yieldHandling)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling) Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
{ {
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_RETURN)); MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_RETURN));
@ -6675,7 +6675,7 @@ Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
return null(); return null();
} }
Node pn = handler.newReturnStatement(exprNode, TokenPos(begin, pos().end)); UnaryNodeType pn = handler.newReturnStatement(exprNode, TokenPos(begin, pos().end));
if (!pn) if (!pn)
return null(); return null();
@ -6689,7 +6689,7 @@ Parser<ParseHandler>::returnStatement(YieldHandling yieldHandling)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::yieldExpression(InHandling inHandling) Parser<ParseHandler>::yieldExpression(InHandling inHandling)
{ {
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_YIELD)); MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_YIELD));
@ -6924,7 +6924,7 @@ Parser<ParseHandler>::labeledStatement(YieldHandling yieldHandling)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::throwStatement(YieldHandling yieldHandling) Parser<ParseHandler>::throwStatement(YieldHandling yieldHandling)
{ {
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_THROW)); MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_THROW));
@ -8540,7 +8540,7 @@ Parser<ParseHandler>::checkIncDecOperand(Node operand, uint32_t operandOffset)
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, Parser<ParseHandler>::unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op,
uint32_t begin) uint32_t begin)
{ {
@ -10065,7 +10065,7 @@ Parser<ParseHandler>::propertyName(YieldHandling yieldHandling,
} }
template <typename ParseHandler> template <typename ParseHandler>
typename ParseHandler::Node typename ParseHandler::UnaryNodeType
Parser<ParseHandler>::computedPropertyName(YieldHandling yieldHandling, Parser<ParseHandler>::computedPropertyName(YieldHandling yieldHandling,
const Maybe<DeclarationKind>& maybeDecl, const Maybe<DeclarationKind>& maybeDecl,
ListNodeType literal) ListNodeType literal)

View file

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

View file

@ -215,7 +215,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeUnparenthesizedName; return NodeUnparenthesizedName;
} }
Node newComputedName(Node expr, uint32_t start, uint32_t end) { UnaryNodeType newComputedName(Node expr, uint32_t start, uint32_t end) {
return NodeGeneric; return NodeGeneric;
} }
@ -242,7 +242,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
void addToCallSiteObject(CallSiteNodeType callSiteObj, Node rawNode, Node cookedNode) {} 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 newNullLiteral(const TokenPos& pos) { return NodeGeneric; }
Node newRawUndefinedLiteral(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 newElision() { return NodeGeneric; }
Node newDelete(uint32_t begin, Node expr) { UnaryNodeType newDelete(uint32_t begin, Node expr) {
return NodeUnparenthesizedUnary; return NodeUnparenthesizedUnary;
} }
Node newTypeof(uint32_t begin, Node kid) { UnaryNodeType newTypeof(uint32_t begin, Node kid) {
return NodeUnparenthesizedUnary; return NodeUnparenthesizedUnary;
} }
@ -267,15 +267,15 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
return NodeGeneric; 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; return NodeUnparenthesizedUnary;
} }
Node newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) { UnaryNodeType newUpdate(ParseNodeKind kind, uint32_t begin, Node kid) {
return NodeGeneric; return NodeGeneric;
} }
Node newSpread(uint32_t begin, Node kid) { UnaryNodeType newSpread(uint32_t begin, Node kid) {
return NodeGeneric; return NodeGeneric;
} }
@ -318,7 +318,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
BinaryNodeType newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; } BinaryNodeType newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; }
Node newPosHolder(const TokenPos& pos) { 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 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 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 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 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 addClassMethodDefinition(ListNodeType literal, Node name, Node fn, JSOp op, bool isStatic) { return true; }
Node newYieldExpression(uint32_t begin, Node value) { return NodeGeneric; } UnaryNodeType newYieldExpression(uint32_t begin, Node value) { return NodeGeneric; }
Node newYieldStarExpression(uint32_t begin, Node value) { return NodeGeneric; } UnaryNodeType newYieldStarExpression(uint32_t begin, Node value) { return NodeGeneric; }
Node newAwaitExpression(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; } Node newOptionalChain(uint32_t begin, Node value) { return NodeGeneric; }
// Statements // Statements
@ -339,7 +339,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE bool prependInitialYield(ListNodeType stmtList, Node genName) { return true; } MOZ_MUST_USE bool prependInitialYield(ListNodeType stmtList, Node genName) { return true; }
Node newEmptyStatement(const TokenPos& pos) { return NodeEmptyStatement; } Node newEmptyStatement(const TokenPos& pos) { return NodeEmptyStatement; }
Node newExportDeclaration(Node kid, const TokenPos& pos) { UnaryNodeType newExportDeclaration(Node kid, const TokenPos& pos) {
return NodeGeneric; return NodeGeneric;
} }
BinaryNodeType newExportFromDeclaration(uint32_t begin, Node exportSpecSet, Node moduleSpec) { 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; } 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; 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; } CaseClauseType newCaseOrDefault(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
Node newContinueStatement(PropertyName* label, const TokenPos& pos) { return NodeGeneric; } Node newContinueStatement(PropertyName* label, const TokenPos& pos) { return NodeGeneric; }
Node newBreakStatement(PropertyName* label, const TokenPos& pos) { return NodeBreak; } 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; } BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) { return NodeGeneric; }
Node newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) { Node newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) {
return NodeGeneric; 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) { Node newTryStatement(uint32_t begin, Node body, ListNodeType catchList, Node finallyBlock) {
return NodeGeneric; return NodeGeneric;
} }
@ -590,7 +590,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
MOZ_MUST_USE Node setLikelyIIFE(Node pn) { MOZ_MUST_USE Node setLikelyIIFE(Node pn) {
return pn; // Remain in syntax-parse mode. return pn; // Remain in syntax-parse mode.
} }
void setInDirectivePrologue(Node pn) {} void setInDirectivePrologue(UnaryNodeType exprStmt) {}
bool isConstant(Node pn) { return false; } bool isConstant(Node pn) { return false; }

View file

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