Bug 872735, part 5 - Remove newNullary from the ParseHandler protocol. It is only used for array holes; replace it with a newElision method. Add PNK_ELISION to distinguish elisions from sequence expressions (which use PNK_COMMA). r=Waldo.

This commit is contained in:
Jason Orendorff 2013-06-14 16:30:40 -05:00
parent 46e13cc41f
commit 463f5d3324
7 changed files with 25 additions and 27 deletions

View File

@ -2688,7 +2688,7 @@ EmitDestructuringDecls(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp, Parse
if (pn->isKind(PNK_ARRAY)) {
for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
if (pn2->isKind(PNK_COMMA))
if (pn2->isKind(PNK_ELISION))
continue;
emitter = (pn2->isKind(PNK_NAME))
? EmitDestructuringDecl
@ -2908,8 +2908,8 @@ EmitDestructuringOpsHelper(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn,
JS_ASSERT(bce->stackDepth >= stackDepth + 1);
}
/* Nullary comma node makes a hole in the array destructurer. */
if (pn3->isKind(PNK_COMMA) && pn3->isArity(PN_NULLARY)) {
/* Elision node makes a hole in the array destructurer. */
if (pn3->isKind(PNK_ELISION)) {
JS_ASSERT(pn->isKind(PNK_ARRAY));
JS_ASSERT(pn2 == pn3);
if (Emit1(cx, bce, JSOP_POP) < 0)
@ -2984,7 +2984,7 @@ EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
}
/* MaybeEmitGroupAssignment won't call us if rhs is holey. */
JS_ASSERT(!(pn->isKind(PNK_COMMA) && pn->isArity(PN_NULLARY)));
JS_ASSERT(!pn->isKind(PNK_ELISION));
if (!EmitTree(cx, bce, pn))
return false;
++limit;
@ -3001,7 +3001,7 @@ EmitGroupAssignment(JSContext *cx, BytecodeEmitter *bce, JSOp prologOp,
if (!EmitUnaliasedVarOp(cx, JSOP_GETLOCAL, slot, bce))
return false;
if (pn->isKind(PNK_COMMA) && pn->isArity(PN_NULLARY)) {
if (pn->isKind(PNK_ELISION)) {
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
} else {
@ -5542,7 +5542,7 @@ EmitArray(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
if (nspread && !EmitNumberOp(cx, 0, bce))
return false;
for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
if (pn2->isKind(PNK_COMMA) && pn2->isArity(PN_NULLARY)) {
if (pn2->isKind(PNK_ELISION)) {
if (Emit1(cx, bce, JSOP_HOLE) < 0)
return false;
} else {

View File

@ -49,6 +49,10 @@ class FullParseHandler
LazyScript * const lazyOuterFunction_;
size_t lazyInnerFunctionIndex;
const TokenPos &pos() {
return tokenStream.currentToken().pos;
}
public:
/*
@ -100,7 +104,7 @@ class FullParseHandler
return dn;
}
ParseNode *newAtom(ParseNodeKind kind, JSAtom *atom, JSOp op = JSOP_NOP) {
ParseNode *pn = NullaryNode::create(kind, this);
ParseNode *pn = new_<NullaryNode>(kind, pos());
if (!pn)
return NULL;
pn->setOp(op);
@ -108,7 +112,7 @@ class FullParseHandler
return pn;
}
ParseNode *newNumber(double value, DecimalPoint decimalPoint = NoDecimal) {
ParseNode *pn = NullaryNode::create(PNK_NUMBER, this);
ParseNode *pn = new_<NullaryNode>(PNK_NUMBER, pos());
if (!pn)
return NULL;
pn->initNumber(value, decimalPoint);
@ -130,8 +134,8 @@ class FullParseHandler
return new_<ConditionalExpression>(cond, thenExpr, elseExpr);
}
ParseNode *newNullary(ParseNodeKind kind) {
return NullaryNode::create(kind, this);
ParseNode *newElision() {
return new_<NullaryNode>(PNK_ELISION, pos());
}
ParseNode *newUnary(ParseNodeKind kind, ParseNode *kid, JSOp op = JSOP_NOP) {

View File

@ -530,7 +530,7 @@ Parser<FullParseHandler>::cloneLeftHandSide(ParseNode *opn)
pn2 = handler.new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
} else if (opn2->isArity(PN_NULLARY)) {
JS_ASSERT(opn2->isKind(PNK_COMMA));
JS_ASSERT(opn2->isKind(PNK_ELISION));
pn2 = cloneParseTree(opn2);
} else {
pn2 = cloneLeftHandSide(opn2);

View File

@ -75,6 +75,7 @@ class UpvarCookie
F(DOT) \
F(ELEM) \
F(ARRAY) \
F(ELISION) \
F(STATEMENTLIST) \
F(LABEL) \
F(OBJECT) \
@ -359,7 +360,7 @@ enum ParseNodeKind
* PNK_GENEXP list Exactly like PNK_CALL, used for the implicit call
* in the desugaring of a generator-expression.
* PNK_ARRAY list pn_head: list of pn_count array element exprs
* [,,] holes are represented by PNK_COMMA nodes
* [,,] holes are represented by PNK_ELISION nodes
* pn_xflags: PN_ENDCOMMA if extra comma at end
* PNK_OBJECT list pn_head: list of pn_count binary PNK_COLON nodes
* PNK_COLON binary key-value pair in object initializer or
@ -728,11 +729,6 @@ struct ParseNode
/* Return true if this node appears in a Directive Prologue. */
bool isDirectivePrologueMember() const { return pn_prologue; }
#ifdef JS_HAS_DESTRUCTURING
/* Return true if this represents a hole in an array literal. */
bool isArrayHole() const { return isKind(PNK_COMMA) && isArity(PN_NULLARY); }
#endif
#ifdef JS_HAS_GENERATOR_EXPRS
ParseNode *generatorExpr() const {
JS_ASSERT(isKind(PNK_GENEXP));
@ -822,6 +818,9 @@ struct ParseNode
struct NullaryNode : public ParseNode
{
NullaryNode(ParseNodeKind kind, const TokenPos &pos)
: ParseNode(kind, JSOP_NOP, PN_NULLARY, pos) {}
static inline NullaryNode *create(ParseNodeKind kind, FullParseHandler *handler) {
return (NullaryNode *) ParseNode::create(kind, PN_NULLARY, handler);
}

View File

@ -3088,8 +3088,7 @@ Parser<FullParseHandler>::checkDestructuring(BindData<FullParseHandler> *data,
if (left->isKind(PNK_ARRAY)) {
for (ParseNode *pn = left->pn_head; pn; pn = pn->pn_next) {
/* Nullary comma is an elision; binary comma is an expression.*/
if (!pn->isArrayHole()) {
if (!pn->isKind(PNK_ELISION)) {
if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) {
ok = checkDestructuring(data, pn, false);
} else {
@ -6618,9 +6617,8 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
break;
if (tt == TOK_COMMA) {
/* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
tokenStream.matchToken(TOK_COMMA);
pn2 = handler.newNullary(PNK_COMMA);
pn2 = handler.newElision();
if (!pn2)
return null();
handler.setListFlag(pn, PNX_SPECIALARRAYINIT | PNX_NONCONST);

View File

@ -71,7 +71,7 @@ class SyntaxParseHandler
Node newNullLiteral(const TokenPos &pos) { return NodeGeneric; }
Node newConditional(Node cond, Node thenExpr, Node elseExpr) { return NodeGeneric; }
Node newNullary(ParseNodeKind kind) { return NodeGeneric; }
Node newElision() { return NodeGeneric; }
Node newUnary(ParseNodeKind kind, Node kid, JSOp op = JSOP_NOP) {
if (kind == PNK_SEMI && kid == NodeString)

View File

@ -2516,7 +2516,7 @@ ASTSerializer::expression(ParseNode *pn, MutableHandleValue dst)
for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
JS_ASSERT(pn->pn_pos.encloses(next->pn_pos));
if (next->isKind(PNK_COMMA) && next->pn_count == 0) {
if (next->isKind(PNK_ELISION)) {
elts.infallibleAppend(NullValue());
} else {
RootedValue expr(cx);
@ -2696,10 +2696,7 @@ ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, MutableHandleValu
return false;
for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
/* Comma expressions can't occur inside patterns, so no need to test pn_count. */
JS_ASSERT_IF(next->isKind(PNK_COMMA), next->pn_count == 0);
if (next->isKind(PNK_COMMA)) {
if (next->isKind(PNK_ELISION)) {
elts.infallibleAppend(NullValue());
} else {
RootedValue patt(cx);