Bug 699227 - Change ParseNode::getKind() to use a type separate from TokenKind, for greater clarity. r=jorendorff

--HG--
extra : rebase_source : a7a0f9028f6094a29f013aafd1eeea4b22d08fa2
This commit is contained in:
Jeff Walden 2011-10-28 16:06:14 -07:00
Родитель 86a6e932ad
Коммит 3486aea238
13 изменённых файлов: 1606 добавлений и 1418 удалений

Просмотреть файл

@ -295,7 +295,7 @@ frontend::CompileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
goto out;
#if JS_HAS_XML_SUPPORT
if (!pn->isKind(TOK_SEMI) || !pn->pn_kid || !TreeTypeIsXML(pn->pn_kid->getKind()))
if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
onlyXML = false;
#endif
bce.freeTree(pn);
@ -403,8 +403,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
return false;
/* FIXME: make Function format the source for a function definition. */
tokenStream.mungeCurrentToken(TOK_NAME);
ParseNode *fn = FunctionNode::create(&funbce);
ParseNode *fn = FunctionNode::create(PNK_NAME, &funbce);
if (fn) {
fn->pn_body = NULL;
fn->pn_cookie.makeFree();
@ -451,7 +450,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
pn = NULL;
} else {
if (fn->pn_body) {
JS_ASSERT(fn->pn_body->isKind(TOK_ARGSBODY));
JS_ASSERT(fn->pn_body->isKind(PNK_ARGSBODY));
fn->pn_body->append(pn);
fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -52,30 +52,25 @@
using namespace js;
static ParseNode *
ContainsStmt(ParseNode *pn, TokenKind tt)
ContainsStmt(ParseNode *pn, ParseNodeKind kind)
{
ParseNode *pn2, *pnt;
if (!pn)
return NULL;
if (pn->isKind(tt))
if (pn->isKind(kind))
return pn;
switch (pn->getArity()) {
case PN_LIST:
for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
pnt = ContainsStmt(pn2, tt);
if (pnt)
for (ParseNode *pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) {
if (ParseNode *pnt = ContainsStmt(pn2, kind))
return pnt;
}
break;
case PN_TERNARY:
pnt = ContainsStmt(pn->pn_kid1, tt);
if (pnt)
if (ParseNode *pnt = ContainsStmt(pn->pn_kid1, kind))
return pnt;
pnt = ContainsStmt(pn->pn_kid2, tt);
if (pnt)
if (ParseNode *pnt = ContainsStmt(pn->pn_kid2, kind))
return pnt;
return ContainsStmt(pn->pn_kid3, tt);
return ContainsStmt(pn->pn_kid3, kind);
case PN_BINARY:
/*
* Limit recursion if pn is a binary expression, which can't contain a
@ -83,18 +78,17 @@ ContainsStmt(ParseNode *pn, TokenKind tt)
*/
if (!pn->isOp(JSOP_NOP))
return NULL;
pnt = ContainsStmt(pn->pn_left, tt);
if (pnt)
if (ParseNode *pnt = ContainsStmt(pn->pn_left, kind))
return pnt;
return ContainsStmt(pn->pn_right, tt);
return ContainsStmt(pn->pn_right, kind);
case PN_UNARY:
if (!pn->isOp(JSOP_NOP))
return NULL;
return ContainsStmt(pn->pn_kid, tt);
return ContainsStmt(pn->pn_kid, kind);
case PN_NAME:
return ContainsStmt(pn->maybeExpr(), tt);
return ContainsStmt(pn->maybeExpr(), kind);
case PN_NAMESET:
return ContainsStmt(pn->pn_tree, tt);
return ContainsStmt(pn->pn_tree, kind);
default:;
}
return NULL;
@ -105,30 +99,30 @@ ContainsStmt(ParseNode *pn, TokenKind tt)
* XXX handles only strings and numbers for now
*/
static JSBool
FoldType(JSContext *cx, ParseNode *pn, TokenKind type)
FoldType(JSContext *cx, ParseNode *pn, ParseNodeKind kind)
{
if (!pn->isKind(type)) {
switch (type) {
case TOK_NUMBER:
if (pn->isKind(TOK_STRING)) {
if (!pn->isKind(kind)) {
switch (kind) {
case PNK_NUMBER:
if (pn->isKind(PNK_STRING)) {
jsdouble d;
if (!ToNumber(cx, StringValue(pn->pn_atom), &d))
return JS_FALSE;
pn->pn_dval = d;
pn->setKind(TOK_NUMBER);
pn->setKind(PNK_NUMBER);
pn->setOp(JSOP_DOUBLE);
}
break;
case TOK_STRING:
if (pn->isKind(TOK_NUMBER)) {
case PNK_STRING:
if (pn->isKind(PNK_NUMBER)) {
JSString *str = js_NumberToString(cx, pn->pn_dval);
if (!str)
return JS_FALSE;
pn->pn_atom = js_AtomizeString(cx, str);
if (!pn->pn_atom)
return JS_FALSE;
pn->setKind(TOK_STRING);
pn->setKind(PNK_STRING);
pn->setOp(JSOP_STRING);
}
break;
@ -151,7 +145,7 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
jsdouble d, d2;
int32 i, j;
JS_ASSERT(pn1->isKind(TOK_NUMBER) && pn2->isKind(TOK_NUMBER));
JS_ASSERT(pn1->isKind(PNK_NUMBER) && pn2->isKind(PNK_NUMBER));
d = pn1->pn_dval;
d2 = pn2->pn_dval;
switch (op) {
@ -216,7 +210,7 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
tc->freeTree(pn1);
if (pn2 != pn)
tc->freeTree(pn2);
pn->setKind(TOK_NUMBER);
pn->setKind(PNK_NUMBER);
pn->setOp(JSOP_DOUBLE);
pn->setArity(PN_NULLARY);
pn->pn_dval = d;
@ -228,61 +222,58 @@ FoldBinaryNumeric(JSContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
static JSBool
FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
{
TokenKind tt;
ParseNode **pnp, *pn1, *pn2;
JSString *accum, *str;
uint32 i, j;
JS_ASSERT(pn->isArity(PN_LIST));
tt = pn->getKind();
pnp = &pn->pn_head;
pn1 = *pnp;
accum = NULL;
str = NULL;
ParseNodeKind kind = pn->getKind();
ParseNode **pnp = &pn->pn_head;
ParseNode *pn1 = *pnp;
JSString *accum = NULL;
JSString *str = NULL;
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
if (tt == TOK_XMLETAGO)
if (kind == PNK_XMLETAGO)
accum = cx->runtime->atomState.etagoAtom;
else if (tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC)
else if (kind == PNK_XMLSTAGO || kind == PNK_XMLPTAGC)
accum = cx->runtime->atomState.stagoAtom;
}
/*
* GC Rooting here is tricky: for most of the loop, |accum| is safe via
* the newborn string root. However, when |pn2->pn_type| is TOK_XMLCDATA,
* TOK_XMLCOMMENT, or TOK_XMLPI it is knocked out of the newborn root.
* the newborn string root. However, when |pn2->getKind()| is PNK_XMLCDATA,
* PNK_XMLCOMMENT, or PNK_XMLPI it is knocked out of the newborn root.
* Therefore, we have to add additonal protection from GC nesting under
* js_ConcatStrings.
*/
ParseNode *pn2;
uint32 i, j;
for (pn2 = pn1, i = j = 0; pn2; pn2 = pn2->pn_next, i++) {
/* The parser already rejected end-tags with attributes. */
JS_ASSERT(tt != TOK_XMLETAGO || i == 0);
JS_ASSERT(kind != PNK_XMLETAGO || i == 0);
switch (pn2->getKind()) {
case TOK_XMLATTR:
case PNK_XMLATTR:
if (!accum)
goto cantfold;
/* FALL THROUGH */
case TOK_XMLNAME:
case TOK_XMLSPACE:
case TOK_XMLTEXT:
case TOK_STRING:
case PNK_XMLNAME:
case PNK_XMLSPACE:
case PNK_XMLTEXT:
case PNK_STRING:
if (pn2->isArity(PN_LIST))
goto cantfold;
str = pn2->pn_atom;
break;
case TOK_XMLCDATA:
case PNK_XMLCDATA:
str = js_MakeXMLCDATAString(cx, pn2->pn_atom);
if (!str)
return JS_FALSE;
break;
case TOK_XMLCOMMENT:
case PNK_XMLCOMMENT:
str = js_MakeXMLCommentString(cx, pn2->pn_atom);
if (!str)
return JS_FALSE;
break;
case TOK_XMLPI:
case PNK_XMLPI:
str = js_MakeXMLPIString(cx, pn2->pn_pitarget, pn2->pn_pidata);
if (!str)
return JS_FALSE;
@ -291,7 +282,7 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
cantfold:
default:
JS_ASSERT(*pnp == pn1);
if ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) &&
if ((kind == PNK_XMLSTAGO || kind == PNK_XMLPTAGC) &&
(i & 1) ^ (j & 1)) {
#ifdef DEBUG_brendanXXX
printf("1: %d, %d => ", i, j);
@ -306,7 +297,7 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
pn1 = tc->freeTree(pn1);
--pn->pn_count;
}
pn1->setKind(TOK_XMLTEXT);
pn1->setKind(PNK_XMLTEXT);
pn1->setOp(JSOP_STRING);
pn1->setArity(PN_NULLARY);
pn1->pn_atom = js_AtomizeString(cx, accum);
@ -324,7 +315,7 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
if (accum) {
{
AutoStringRooter tvr(cx, accum);
str = ((tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC) && i != 0)
str = ((kind == PNK_XMLSTAGO || kind == PNK_XMLPTAGC) && i != 0)
? js_AddAttributePart(cx, i & 1, accum, str)
: js_ConcatStrings(cx, accum, str);
}
@ -343,9 +334,9 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
if (accum) {
str = NULL;
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
if (tt == TOK_XMLPTAGC)
if (kind == PNK_XMLPTAGC)
str = cx->runtime->atomState.ptagcAtom;
else if (tt == TOK_XMLSTAGO || tt == TOK_XMLETAGO)
else if (kind == PNK_XMLSTAGO || kind == PNK_XMLETAGO)
str = cx->runtime->atomState.tagcAtom;
}
if (str) {
@ -359,7 +350,7 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
pn1 = tc->freeTree(pn1);
--pn->pn_count;
}
pn1->setKind(TOK_XMLTEXT);
pn1->setKind(PNK_XMLTEXT);
pn1->setOp(JSOP_STRING);
pn1->setArity(PN_NULLARY);
pn1->pn_atom = js_AtomizeString(cx, accum);
@ -374,13 +365,13 @@ FoldXMLConstants(JSContext *cx, ParseNode *pn, TreeContext *tc)
* Only one node under pn, and it has been folded: move pn1 onto pn
* unless pn is an XML root (in which case we need it to tell the code
* generator to emit a JSOP_TOXML or JSOP_TOXMLLIST op). If pn is an
* XML root *and* it's a point-tag, rewrite it to TOK_XMLELEM to avoid
* XML root *and* it's a point-tag, rewrite it to PNK_XMLELEM to avoid
* extra "<" and "/>" bracketing at runtime.
*/
if (!(pn->pn_xflags & PNX_XMLROOT)) {
pn->become(pn1);
} else if (tt == TOK_XMLPTAGC) {
pn->setKind(TOK_XMLELEM);
} else if (kind == PNK_XMLPTAGC) {
pn->setKind(PNK_XMLELEM);
pn->setOp(JSOP_TOXML);
}
}
@ -412,7 +403,7 @@ Boolish(ParseNode *pn)
if (pn->pn_count != 1)
return Unknown;
ParseNode *pn2 = pn->pn_head;
if (!pn2->isKind(TOK_FUNCTION))
if (!pn2->isKind(PNK_FUNCTION))
return Unknown;
if (!(pn2->pn_funbox->tcflags & TCF_GENEXP_LAMBDA))
return Unknown;
@ -460,11 +451,11 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
case PN_LIST:
{
/* Propagate inCond through logical connectives. */
bool cond = inCond && (pn->isKind(TOK_OR) || pn->isKind(TOK_AND));
bool cond = inCond && (pn->isKind(PNK_OR) || pn->isKind(PNK_AND));
/* Don't fold a parenthesized call expression. See bug 537673. */
pn1 = pn2 = pn->pn_head;
if ((pn->isKind(TOK_LP) || pn->isKind(TOK_NEW)) && pn2->isInParens())
if ((pn->isKind(PNK_LP) || pn->isKind(PNK_NEW)) && pn2->isInParens())
pn2 = pn2->pn_next;
/* Save the list head in pn1 for later use. */
@ -480,12 +471,12 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pn1 = pn->pn_kid1;
pn2 = pn->pn_kid2;
pn3 = pn->pn_kid3;
if (pn1 && !FoldConstants(cx, pn1, tc, pn->isKind(TOK_IF)))
if (pn1 && !FoldConstants(cx, pn1, tc, pn->isKind(PNK_IF)))
return false;
if (pn2) {
if (!FoldConstants(cx, pn2, tc, pn->isKind(TOK_FORHEAD)))
if (!FoldConstants(cx, pn2, tc, pn->isKind(PNK_FORHEAD)))
return false;
if (pn->isKind(TOK_FORHEAD) && pn2->isOp(JSOP_TRUE)) {
if (pn->isKind(PNK_FORHEAD) && pn2->isOp(JSOP_TRUE)) {
tc->freeTree(pn2);
pn->pn_kid2 = NULL;
}
@ -499,7 +490,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pn2 = pn->pn_right;
/* Propagate inCond through logical connectives. */
if (pn->isKind(TOK_OR) || pn->isKind(TOK_AND)) {
if (pn->isKind(PNK_OR) || pn->isKind(PNK_AND)) {
if (!FoldConstants(cx, pn1, tc, inCond))
return false;
if (!FoldConstants(cx, pn2, tc, inCond))
@ -508,9 +499,9 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
}
/* First kid may be null (for default case in switch). */
if (pn1 && !FoldConstants(cx, pn1, tc, pn->isKind(TOK_WHILE)))
if (pn1 && !FoldConstants(cx, pn1, tc, pn->isKind(PNK_WHILE)))
return false;
if (!FoldConstants(cx, pn2, tc, pn->isKind(TOK_DO)))
if (!FoldConstants(cx, pn2, tc, pn->isKind(PNK_DO)))
return false;
break;
@ -526,7 +517,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
* null. This assumption does not hold true for other unary
* expressions.
*/
if (pn->isOp(JSOP_TYPEOF) && !pn1->isKind(TOK_NAME))
if (pn->isOp(JSOP_TYPEOF) && !pn1->isKind(PNK_NAME))
pn->setOp(JSOP_TYPEOFEXPR);
if (pn1 && !FoldConstants(cx, pn1, tc, pn->isOp(JSOP_NOT)))
@ -560,26 +551,26 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
}
switch (pn->getKind()) {
case TOK_IF:
if (ContainsStmt(pn2, TOK_VAR) || ContainsStmt(pn3, TOK_VAR))
case PNK_IF:
if (ContainsStmt(pn2, PNK_VAR) || ContainsStmt(pn3, PNK_VAR))
break;
/* FALL THROUGH */
case TOK_HOOK:
case PNK_HOOK:
/* Reduce 'if (C) T; else E' into T for true C, E for false. */
switch (pn1->getKind()) {
case TOK_NUMBER:
case PNK_NUMBER:
if (pn1->pn_dval == 0 || JSDOUBLE_IS_NaN(pn1->pn_dval))
pn2 = pn3;
break;
case TOK_STRING:
case PNK_STRING:
if (pn1->pn_atom->length() == 0)
pn2 = pn3;
break;
case TOK_TRUE:
case PNK_TRUE:
break;
case TOK_FALSE:
case TOK_NULL:
case PNK_FALSE:
case PNK_NULL:
pn2 = pn3;
break;
default:
@ -595,15 +586,15 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
if (pn2 && !pn2->isDefn())
pn->become(pn2);
if (!pn2 || (pn->isKind(TOK_SEMI) && !pn->pn_kid)) {
if (!pn2 || (pn->isKind(PNK_SEMI) && !pn->pn_kid)) {
/*
* False condition and no else, or an empty then-statement was
* moved up over pn. Either way, make pn an empty block (not an
* empty statement, which does not decompile, even when labeled).
* NB: pn must be a TOK_IF as TOK_HOOK can never have a null kid
* NB: pn must be a PNK_IF as PNK_HOOK can never have a null kid
* or an empty statement for a child.
*/
pn->setKind(TOK_LC);
pn->setKind(PNK_LC);
pn->setArity(PN_LIST);
pn->makeEmpty();
}
@ -612,8 +603,8 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
tc->freeTree(pn3);
break;
case TOK_OR:
case TOK_AND:
case PNK_OR:
case PNK_AND:
if (inCond) {
if (pn->isArity(PN_LIST)) {
ParseNode **pnp = &pn->pn_head;
@ -624,7 +615,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pnp = &pn1->pn_next;
continue;
}
if ((t == Truthy) == pn->isKind(TOK_OR)) {
if ((t == Truthy) == pn->isKind(PNK_OR)) {
for (pn2 = pn1->pn_next; pn2; pn2 = pn3) {
pn3 = pn2->pn_next;
tc->freeTree(pn2);
@ -633,7 +624,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pn1->pn_next = NULL;
break;
}
JS_ASSERT((t == Truthy) == pn->isKind(TOK_AND));
JS_ASSERT((t == Truthy) == pn->isKind(PNK_AND));
if (pn->pn_count == 1)
break;
*pnp = pn1->pn_next;
@ -657,11 +648,11 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
} else {
Truthiness t = Boolish(pn1);
if (t != Unknown) {
if ((t == Truthy) == pn->isKind(TOK_OR)) {
if ((t == Truthy) == pn->isKind(PNK_OR)) {
tc->freeTree(pn2);
pn->become(pn1);
} else {
JS_ASSERT((t == Truthy) == pn->isKind(TOK_AND));
JS_ASSERT((t == Truthy) == pn->isKind(PNK_AND));
tc->freeTree(pn1);
pn->become(pn2);
}
@ -670,16 +661,16 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
}
break;
case TOK_SUBASSIGN:
case TOK_BITORASSIGN:
case TOK_BITXORASSIGN:
case TOK_BITANDASSIGN:
case TOK_LSHASSIGN:
case TOK_RSHASSIGN:
case TOK_URSHASSIGN:
case TOK_MULASSIGN:
case TOK_DIVASSIGN:
case TOK_MODASSIGN:
case PNK_SUBASSIGN:
case PNK_BITORASSIGN:
case PNK_BITXORASSIGN:
case PNK_BITANDASSIGN:
case PNK_LSHASSIGN:
case PNK_RSHASSIGN:
case PNK_URSHASSIGN:
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
/*
* Compound operators such as *= should be subject to folding, in case
* the left-hand side is constant, and so that the decompiler produces
@ -689,10 +680,10 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
*/
goto do_binary_op;
case TOK_ADDASSIGN:
case PNK_ADDASSIGN:
JS_ASSERT(pn->isOp(JSOP_ADD));
/* FALL THROUGH */
case TOK_PLUS:
case PNK_PLUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
if (pn->isArity(PN_LIST)) {
@ -710,10 +701,10 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
/* Ok, we're concatenating: convert non-string constant operands. */
size_t length = 0;
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
if (!FoldType(cx, pn2, TOK_STRING))
if (!FoldType(cx, pn2, PNK_STRING))
return false;
/* XXX fold only if all operands convert to string */
if (!pn2->isKind(TOK_STRING))
if (!pn2->isKind(PNK_STRING))
return true;
length += pn2->pn_atom->length();
}
@ -742,7 +733,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pn->pn_atom = js_AtomizeString(cx, str);
if (!pn->pn_atom)
return false;
pn->setKind(TOK_STRING);
pn->setKind(PNK_STRING);
pn->setOp(JSOP_STRING);
pn->setArity(PN_NULLARY);
break;
@ -750,12 +741,12 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
/* Handle a binary string concatenation. */
JS_ASSERT(pn->isArity(PN_BINARY));
if (pn1->isKind(TOK_STRING) || pn2->isKind(TOK_STRING)) {
if (pn1->isKind(PNK_STRING) || pn2->isKind(PNK_STRING)) {
JSString *left, *right, *str;
if (!FoldType(cx, !pn1->isKind(TOK_STRING) ? pn1 : pn2, TOK_STRING))
if (!FoldType(cx, !pn1->isKind(PNK_STRING) ? pn1 : pn2, PNK_STRING))
return false;
if (!pn1->isKind(TOK_STRING) || !pn2->isKind(TOK_STRING))
if (!pn1->isKind(PNK_STRING) || !pn2->isKind(PNK_STRING))
return true;
left = pn1->pn_atom;
right = pn2->pn_atom;
@ -765,7 +756,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
pn->pn_atom = js_AtomizeString(cx, str);
if (!pn->pn_atom)
return false;
pn->setKind(TOK_STRING);
pn->setKind(PNK_STRING);
pn->setOp(JSOP_STRING);
pn->setArity(PN_NULLARY);
tc->freeTree(pn1);
@ -776,26 +767,26 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
/* Can't concatenate string literals, let's try numbers. */
goto do_binary_op;
case TOK_MINUS:
case PNK_MINUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
/* FALL THROUGH */
case TOK_STAR:
case TOK_LSH:
case TOK_RSH:
case TOK_URSH:
case TOK_DIV:
case TOK_MOD:
case PNK_STAR:
case PNK_LSH:
case PNK_RSH:
case PNK_URSH:
case PNK_DIV:
case PNK_MOD:
do_binary_op:
if (pn->isArity(PN_LIST)) {
JS_ASSERT(pn->pn_count > 2);
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
if (!FoldType(cx, pn2, TOK_NUMBER))
if (!FoldType(cx, pn2, PNK_NUMBER))
return false;
}
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
/* XXX fold only if all operands convert to number */
if (!pn2->isKind(TOK_NUMBER))
if (!pn2->isKind(PNK_NUMBER))
break;
}
if (!pn2) {
@ -813,23 +804,23 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
}
} else {
JS_ASSERT(pn->isArity(PN_BINARY));
if (!FoldType(cx, pn1, TOK_NUMBER) ||
!FoldType(cx, pn2, TOK_NUMBER)) {
if (!FoldType(cx, pn1, PNK_NUMBER) ||
!FoldType(cx, pn2, PNK_NUMBER)) {
return false;
}
if (pn1->isKind(TOK_NUMBER) && pn2->isKind(TOK_NUMBER)) {
if (pn1->isKind(PNK_NUMBER) && pn2->isKind(PNK_NUMBER)) {
if (!FoldBinaryNumeric(cx, pn->getOp(), pn1, pn2, pn, tc))
return false;
}
}
break;
case TOK_TYPEOF:
case TOK_VOID:
case TOK_NOT:
case TOK_BITNOT:
case PNK_TYPEOF:
case PNK_VOID:
case PNK_NOT:
case PNK_BITNOT:
unary_plusminus:
if (pn1->isKind(TOK_NUMBER)) {
if (pn1->isKind(PNK_NUMBER)) {
jsdouble d;
/* Operate on one numeric constant. */
@ -848,32 +839,32 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
case JSOP_NOT:
if (d == 0 || JSDOUBLE_IS_NaN(d)) {
pn->setKind(TOK_TRUE);
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
} else {
pn->setKind(TOK_FALSE);
pn->setKind(PNK_FALSE);
pn->setOp(JSOP_FALSE);
}
pn->setArity(PN_NULLARY);
/* FALL THROUGH */
default:
/* Return early to dodge the common TOK_NUMBER code. */
/* Return early to dodge the common PNK_NUMBER code. */
return true;
}
pn->setKind(TOK_NUMBER);
pn->setKind(PNK_NUMBER);
pn->setOp(JSOP_DOUBLE);
pn->setArity(PN_NULLARY);
pn->pn_dval = d;
tc->freeTree(pn1);
} else if (pn1->isKind(TOK_TRUE) || pn1->isKind(TOK_FALSE)) {
} else if (pn1->isKind(PNK_TRUE) || pn1->isKind(PNK_FALSE)) {
if (pn->isOp(JSOP_NOT)) {
pn->become(pn1);
if (pn->isKind(TOK_TRUE)) {
pn->setKind(TOK_FALSE);
if (pn->isKind(PNK_TRUE)) {
pn->setKind(PNK_FALSE);
pn->setOp(JSOP_FALSE);
} else {
pn->setKind(TOK_TRUE);
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
}
tc->freeTree(pn1);
@ -882,21 +873,21 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
break;
#if JS_HAS_XML_SUPPORT
case TOK_XMLELEM:
case TOK_XMLLIST:
case TOK_XMLPTAGC:
case TOK_XMLSTAGO:
case TOK_XMLETAGO:
case TOK_XMLNAME:
case PNK_XMLELEM:
case PNK_XMLLIST:
case PNK_XMLPTAGC:
case PNK_XMLSTAGO:
case PNK_XMLETAGO:
case PNK_XMLNAME:
if (pn->isArity(PN_LIST)) {
JS_ASSERT(pn->isKind(TOK_XMLLIST) || pn->pn_count != 0);
JS_ASSERT(pn->isKind(PNK_XMLLIST) || pn->pn_count != 0);
if (!FoldXMLConstants(cx, pn, tc))
return false;
}
break;
case TOK_AT:
if (pn1->isKind(TOK_XMLNAME)) {
case PNK_AT:
if (pn1->isKind(PNK_XMLNAME)) {
Value v = StringValue(pn1->pn_atom);
if (!js_ToAttributeName(cx, &v))
return false;
@ -906,7 +897,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
if (!xmlbox)
return false;
pn->setKind(TOK_XMLNAME);
pn->setKind(PNK_XMLNAME);
pn->setOp(JSOP_OBJECT);
pn->setArity(PN_NULLARY);
pn->pn_objbox = xmlbox;
@ -929,10 +920,10 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
*/
tc->parser->allocator.prepareNodeForMutation(pn);
if (t == Truthy) {
pn->setKind(TOK_TRUE);
pn->setKind(PNK_TRUE);
pn->setOp(JSOP_TRUE);
} else {
pn->setKind(TOK_FALSE);
pn->setKind(PNK_FALSE);
pn->setOp(JSOP_FALSE);
}
pn->setArity(PN_NULLARY);

Просмотреть файл

@ -50,14 +50,14 @@ inline bool
ParseNode::isConstant()
{
switch (pn_type) {
case TOK_NUMBER:
case TOK_STRING:
case TOK_NULL:
case TOK_FALSE:
case TOK_TRUE:
case PNK_NUMBER:
case PNK_STRING:
case PNK_NULL:
case PNK_FALSE:
case PNK_TRUE:
return true;
case TOK_RB:
case TOK_RC:
case PNK_RB:
case PNK_RC:
return isOp(JSOP_NEWINIT) && !(pn_xflags & PNX_NONCONST);
default:
return false;

Просмотреть файл

@ -84,7 +84,7 @@ ParseNode::become(ParseNode *pn2)
* If any pointers are pointing to pn2, change them to point to this
* instead, since pn2 will be cleared and probably recycled.
*/
if (this->isKind(TOK_FUNCTION) && isArity(PN_FUNC)) {
if (this->isKind(PNK_FUNCTION) && isArity(PN_FUNC)) {
/* Function node: fix up the pn_funbox->node back-pointer. */
JS_ASSERT(pn_funbox->node == pn2);
pn_funbox->node = this;
@ -101,7 +101,7 @@ ParseNode::become(ParseNode *pn2)
void
ParseNode::clear()
{
pn_type = TOK_EOF;
pn_type = PNK_LIMIT;
setOp(JSOP_NOP);
pn_used = pn_defn = false;
pn_arity = PN_NULLARY;
@ -384,20 +384,20 @@ ParseNodeAllocator::allocNode()
/* used only by static create methods of subclasses */
ParseNode *
ParseNode::create(ParseNodeArity arity, TreeContext *tc)
ParseNode::create(ParseNodeKind kind, ParseNodeArity arity, TreeContext *tc)
{
Parser *parser = tc->parser;
const Token &tok = parser->tokenStream.currentToken();
return parser->new_<ParseNode>(tok.type, JSOP_NOP, arity, tok.pos);
return parser->new_<ParseNode>(kind, JSOP_NOP, arity, tok.pos);
}
ParseNode *
ParseNode::append(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right)
ParseNode::append(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right)
{
if (!left || !right)
return NULL;
JS_ASSERT(left->isKind(tt) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC));
JS_ASSERT(left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC));
if (left->pn_arity != PN_LIST) {
ParseNode *pn1 = left->pn_left, *pn2 = left->pn_right;
@ -405,23 +405,23 @@ ParseNode::append(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right)
left->pn_parens = false;
left->initList(pn1);
left->append(pn2);
if (tt == TOK_PLUS) {
if (pn1->isKind(TOK_STRING))
if (kind == PNK_PLUS) {
if (pn1->isKind(PNK_STRING))
left->pn_xflags |= PNX_STRCAT;
else if (!pn1->isKind(TOK_NUMBER))
else if (!pn1->isKind(PNK_NUMBER))
left->pn_xflags |= PNX_CANTFOLD;
if (pn2->isKind(TOK_STRING))
if (pn2->isKind(PNK_STRING))
left->pn_xflags |= PNX_STRCAT;
else if (!pn2->isKind(TOK_NUMBER))
else if (!pn2->isKind(PNK_NUMBER))
left->pn_xflags |= PNX_CANTFOLD;
}
}
left->append(right);
left->pn_pos.end = right->pn_pos.end;
if (tt == TOK_PLUS) {
if (right->isKind(TOK_STRING))
if (kind == PNK_PLUS) {
if (right->isKind(PNK_STRING))
left->pn_xflags |= PNX_STRCAT;
else if (!right->isKind(TOK_NUMBER))
else if (!right->isKind(PNK_NUMBER))
left->pn_xflags |= PNX_CANTFOLD;
}
@ -429,7 +429,7 @@ ParseNode::append(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right)
}
ParseNode *
ParseNode::newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right,
ParseNode::newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
TreeContext *tc)
{
if (!left || !right)
@ -439,8 +439,8 @@ ParseNode::newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *
* Flatten a left-associative (left-heavy) tree of a given operator into
* a list, to reduce js_FoldConstants and js_EmitTree recursion.
*/
if (left->isKind(tt) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC))
return append(tt, op, left, right);
if (left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC))
return append(kind, op, left, right);
/*
* Fold constant addition immediately, to conserve node space and, what's
@ -449,9 +449,9 @@ ParseNode::newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *
* generated for expressions such as 1 + 2 + "pt" (which should evaluate
* to "3pt", not "12pt").
*/
if (tt == TOK_PLUS &&
left->isKind(TOK_NUMBER) &&
right->isKind(TOK_NUMBER) &&
if (kind == PNK_PLUS &&
left->isKind(PNK_NUMBER) &&
right->isKind(PNK_NUMBER) &&
tc->parser->foldConstants)
{
left->pn_dval += right->pn_dval;
@ -460,13 +460,13 @@ ParseNode::newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *
return left;
}
return tc->parser->new_<BinaryNode>(tt, op, left, right);
return tc->parser->new_<BinaryNode>(kind, op, left, right);
}
NameNode *
NameNode::create(JSAtom *atom, TreeContext *tc)
NameNode::create(ParseNodeKind kind, JSAtom *atom, TreeContext *tc)
{
ParseNode *pn = ParseNode::create(PN_NAME, tc);
ParseNode *pn = ParseNode::create(kind, PN_NAME, tc);
if (pn) {
pn->pn_atom = atom;
((NameNode *)pn)->initCommon(tc);
@ -619,13 +619,13 @@ js::CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
#if JS_HAS_DESTRUCTURING
if (opn->isArity(PN_LIST)) {
JS_ASSERT(opn->isKind(TOK_RB) || opn->isKind(TOK_RC));
JS_ASSERT(opn->isKind(PNK_RB) || opn->isKind(PNK_RC));
pn->makeEmpty();
for (ParseNode *opn2 = opn->pn_head; opn2; opn2 = opn2->pn_next) {
ParseNode *pn2;
if (opn->isKind(TOK_RC)) {
if (opn->isKind(PNK_RC)) {
JS_ASSERT(opn2->isArity(PN_BINARY));
JS_ASSERT(opn2->isKind(TOK_COLON));
JS_ASSERT(opn2->isKind(PNK_COLON));
ParseNode *tag = CloneParseTree(opn2->pn_left, tc);
if (!tag)
@ -634,9 +634,9 @@ js::CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
if (!target)
return NULL;
pn2 = tc->parser->new_<BinaryNode>(TOK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
pn2 = tc->parser->new_<BinaryNode>(PNK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
} else if (opn2->isArity(PN_NULLARY)) {
JS_ASSERT(opn2->isKind(TOK_COMMA));
JS_ASSERT(opn2->isKind(PNK_COMMA));
pn2 = CloneParseTree(opn2, tc);
} else {
pn2 = CloneLeftHandSide(opn2, tc);
@ -652,7 +652,7 @@ js::CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
#endif
JS_ASSERT(opn->isArity(PN_NAME));
JS_ASSERT(opn->isKind(TOK_NAME));
JS_ASSERT(opn->isKind(PNK_NAME));
/* If opn is a definition or use, make pn a use. */
pn->pn_u.name = opn->pn_u.name;

Просмотреть файл

@ -53,81 +53,219 @@ namespace js {
* not a concrete syntax tree in all respects (for example, || and && are left
* associative, but (A && B && C) translates into the right-associated tree
* <A && <B && C>> so that code generation can emit a left-associative branch
* around <B && C> when A is false). Nodes are labeled by token type, with a
* JSOp secondary label when needed:
* around <B && C> when A is false). Nodes are labeled by kind, with a
* secondary JSOp label when needed.
*
* The long comment after this enum block describes the kinds in detail.
*/
enum ParseNodeKind {
PNK_SEMI,
PNK_COMMA,
PNK_HOOK,
PNK_COLON,
PNK_OR,
PNK_AND,
PNK_BITOR,
PNK_BITXOR,
PNK_BITAND,
PNK_PLUS,
PNK_MINUS,
PNK_STAR,
PNK_DIV,
PNK_MOD,
PNK_INC,
PNK_DEC,
PNK_DOT,
PNK_LB,
PNK_RB,
PNK_LC,
PNK_RC,
PNK_LP,
PNK_RP,
PNK_NAME,
PNK_NUMBER,
PNK_STRING,
PNK_REGEXP,
PNK_TRUE,
PNK_FALSE,
PNK_NULL,
PNK_THIS,
PNK_FUNCTION,
PNK_IF,
PNK_ELSE,
PNK_SWITCH,
PNK_CASE,
PNK_DEFAULT,
PNK_WHILE,
PNK_DO,
PNK_FOR,
PNK_BREAK,
PNK_CONTINUE,
PNK_IN,
PNK_VAR,
PNK_WITH,
PNK_RETURN,
PNK_NEW,
PNK_DELETE,
PNK_DEFSHARP,
PNK_USESHARP,
PNK_TRY,
PNK_CATCH,
PNK_CATCHLIST,
PNK_FINALLY,
PNK_THROW,
PNK_INSTANCEOF,
PNK_DEBUGGER,
PNK_XMLSTAGO,
PNK_XMLETAGO,
PNK_XMLPTAGC,
PNK_XMLTAGC,
PNK_XMLNAME,
PNK_XMLATTR,
PNK_XMLSPACE,
PNK_XMLTEXT,
PNK_XMLCOMMENT,
PNK_XMLCDATA,
PNK_XMLPI,
PNK_AT,
PNK_DBLCOLON,
PNK_ANYNAME,
PNK_DBLDOT,
PNK_FILTER,
PNK_XMLELEM,
PNK_XMLLIST,
PNK_YIELD,
PNK_ARRAYCOMP,
PNK_ARRAYPUSH,
PNK_LEXICALSCOPE,
PNK_LET,
PNK_SEQ,
PNK_FORHEAD,
PNK_ARGSBODY,
PNK_UPVARS,
/*
* The following parse node kinds occupy contiguous ranges to enable easy
* range-testing.
*/
/* Equality operators. */
PNK_STRICTEQ,
PNK_EQ,
PNK_STRICTNE,
PNK_NE,
/* Unary operators. */
PNK_TYPEOF,
PNK_VOID,
PNK_NOT,
PNK_BITNOT,
/* Relational operators (< <= > >=). */
PNK_LT,
PNK_LE,
PNK_GT,
PNK_GE,
/* Shift operators (<< >> >>>). */
PNK_LSH,
PNK_RSH,
PNK_URSH,
/* Assignment operators (= += -= etc.). */
PNK_ASSIGN,
PNK_ASSIGNMENT_START = PNK_ASSIGN,
PNK_ADDASSIGN,
PNK_SUBASSIGN,
PNK_BITORASSIGN,
PNK_BITXORASSIGN,
PNK_BITANDASSIGN,
PNK_LSHASSIGN,
PNK_RSHASSIGN,
PNK_URSHASSIGN,
PNK_MULASSIGN,
PNK_DIVASSIGN,
PNK_MODASSIGN,
PNK_ASSIGNMENT_LAST = PNK_MODASSIGN,
PNK_LIMIT /* domain size */
};
/*
* Label Variant Members
* ----- ------- -------
* <Definitions>
* TOK_FUNCTION name pn_funbox: ptr to js::FunctionBox holding function
* PNK_FUNCTION name pn_funbox: ptr to js::FunctionBox holding function
* object containing arg and var properties. We
* create the function object at parse (not emit)
* time to specialize arg and var bytecodes early.
* pn_body: TOK_UPVARS if the function's source body
* depends on outer names, else TOK_ARGSBODY
* if formal parameters, else TOK_LC node for
* function body statements, else TOK_RETURN
* for expression closure, else TOK_SEQ for
* pn_body: PNK_UPVARS if the function's source body
* depends on outer names, else PNK_ARGSBODY
* if formal parameters, else PNK_LC node for
* function body statements, else PNK_RETURN
* for expression closure, else PNK_SEQ for
* expression closure with destructured
* formal parameters
* pn_cookie: static level and var index for function
* pn_dflags: PND_* definition/use flags (see below)
* pn_blockid: block id number
* TOK_ARGSBODY list list of formal parameters followed by TOK_LC node
* PNK_ARGSBODY list list of formal parameters followed by PNK_LC node
* for function body statements as final element
* pn_count: 1 + number of formal parameters
* TOK_UPVARS nameset pn_names: lexical dependencies (js::Definitions)
* PNK_UPVARS nameset pn_names: lexical dependencies (js::Definitions)
* defined in enclosing scopes, or ultimately not
* defined (free variables, either global property
* references or reference errors).
* pn_tree: TOK_ARGSBODY or TOK_LC node
* pn_tree: PNK_ARGSBODY or PNK_LC node
*
* <Statements>
* TOK_LC list pn_head: list of pn_count statements
* TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null.
* PNK_LC list pn_head: list of pn_count statements
* PNK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null.
* In body of a comprehension or desugared generator
* expression, pn_kid2 is TOK_YIELD, TOK_ARRAYPUSH,
* or (if the push was optimized away) empty TOK_LC.
* TOK_SWITCH binary pn_left: discriminant
* pn_right: list of TOK_CASE nodes, with at most one
* TOK_DEFAULT node, or if there are let bindings
* expression, pn_kid2 is PNK_YIELD, PNK_ARRAYPUSH,
* or (if the push was optimized away) empty PNK_LC.
* PNK_SWITCH binary pn_left: discriminant
* pn_right: list of PNK_CASE nodes, with at most one
* PNK_DEFAULT node, or if there are let bindings
* in the top level of the switch body's cases, a
* TOK_LEXICALSCOPE node that contains the list of
* TOK_CASE nodes.
* TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT
* TOK_DEFAULT pn_right: TOK_LC node for this case's statements
* PNK_LEXICALSCOPE node that contains the list of
* PNK_CASE nodes.
* PNK_CASE, binary pn_left: case expr
* pn_right: PNK_LC node for this case's statements
* PNK_DEFAULT binary pn_left: null
* pn_right: PNK_LC node for this default's statements
* pn_val: constant value if lookup or table switch
* TOK_WHILE binary pn_left: cond, pn_right: body
* TOK_DO binary pn_left: body, pn_right: cond
* TOK_FOR binary pn_left: either
* for/in loop: a ternary TOK_IN node with
* pn_kid1: TOK_VAR to left of 'in', or NULL
* PNK_WHILE binary pn_left: cond, pn_right: body
* PNK_DO binary pn_left: body, pn_right: cond
* PNK_FOR binary pn_left: either
* for/in loop: a ternary PNK_IN node with
* pn_kid1: PNK_VAR to left of 'in', or NULL
* its pn_xflags may have PNX_POPVAR
* and PNX_FORINVAR bits set
* pn_kid2: TOK_NAME or destructuring expr
* pn_kid2: PNK_NAME or destructuring expr
* to left of 'in'; if pn_kid1, then this
* is a clone of pn_kid1->pn_head
* pn_kid3: object expr to right of 'in'
* for(;;) loop: a ternary TOK_RESERVED node with
* for(;;) loop: a ternary PNK_FORHEAD node with
* pn_kid1: init expr before first ';'
* pn_kid2: cond expr before second ';'
* pn_kid3: update expr after second ';'
* any kid may be null
* pn_right: body
* TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception
* TOK_TRY ternary pn_kid1: try block
* pn_kid2: null or TOK_RESERVED list of
* TOK_LEXICALSCOPE nodes, each with pn_expr pointing
* to a TOK_CATCH node
* PNK_THROW unary pn_op: JSOP_THROW, pn_kid: exception
* PNK_TRY ternary pn_kid1: try block
* pn_kid2: null or PNK_CATCHLIST list of
* PNK_LEXICALSCOPE nodes, each with pn_expr pointing
* to a PNK_CATCH node
* pn_kid3: null or finally block
* TOK_CATCH ternary pn_kid1: TOK_NAME, TOK_RB, or TOK_RC catch var node
* (TOK_RB or TOK_RC if destructuring)
* PNK_CATCH ternary pn_kid1: PNK_NAME, PNK_RB, or PNK_RC catch var node
* (PNK_RB or PNK_RC if destructuring)
* pn_kid2: null or the catch guard expression
* pn_kid3: catch block statements
* TOK_BREAK name pn_atom: label or null
* TOK_CONTINUE name pn_atom: label or null
* TOK_WITH binary pn_left: head expr, pn_right: body
* TOK_VAR list pn_head: list of TOK_NAME or TOK_ASSIGN nodes
* PNK_BREAK name pn_atom: label or null
* PNK_CONTINUE name pn_atom: label or null
* PNK_WITH binary pn_left: head expr, pn_right: body
* PNK_VAR list pn_head: list of PNK_NAME or PNK_ASSIGN nodes
* each name node has either
* pn_used: false
* pn_atom: variable name
@ -137,142 +275,142 @@ namespace js {
* pn_atom: variable name
* pn_lexdef: def node
* each assignment node has
* pn_left: TOK_NAME with pn_used true and
* pn_left: PNK_NAME with pn_used true and
* pn_lexdef (NOT pn_expr) set
* pn_right: initializer
* TOK_RETURN unary pn_kid: return expr or null
* TOK_SEMI unary pn_kid: expr or null statement
* PNK_RETURN unary pn_kid: return expr or null
* PNK_SEMI unary pn_kid: expr or null statement
* pn_prologue: true if Directive Prologue member
* in original source, not introduced via
* constant folding or other tree rewriting
* TOK_COLON name pn_atom: label, pn_expr: labeled statement
* PNK_COLON name pn_atom: label, pn_expr: labeled statement
*
* <Expressions>
* All left-associated binary trees of the same type are optimized into lists
* to avoid recursion when processing expression chains.
* TOK_COMMA list pn_head: list of pn_count comma-separated exprs
* TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue
* TOK_ADDASSIGN, binary pn_left: lvalue, pn_right: rvalue
* TOK_SUBASSIGN, pn_op: JSOP_ADD for +=, etc.
* TOK_BITORASSIGN,
* TOK_BITXORASSIGN,
* TOK_BITANDASSIGN,
* TOK_LSHASSIGN,
* TOK_RSHASSIGN,
* TOK_URSHASSIGN,
* TOK_MULASSIGN,
* TOK_DIVASSIGN,
* TOK_MODASSIGN
* TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else
* TOK_OR binary pn_left: first in || chain, pn_right: rest of chain
* TOK_AND binary pn_left: first in && chain, pn_right: rest of chain
* TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr
* TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr
* TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr
* PNK_COMMA list pn_head: list of pn_count comma-separated exprs
* PNK_ASSIGN binary pn_left: lvalue, pn_right: rvalue
* PNK_ADDASSIGN, binary pn_left: lvalue, pn_right: rvalue
* PNK_SUBASSIGN, pn_op: JSOP_ADD for +=, etc.
* PNK_BITORASSIGN,
* PNK_BITXORASSIGN,
* PNK_BITANDASSIGN,
* PNK_LSHASSIGN,
* PNK_RSHASSIGN,
* PNK_URSHASSIGN,
* PNK_MULASSIGN,
* PNK_DIVASSIGN,
* PNK_MODASSIGN
* PNK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else
* PNK_OR binary pn_left: first in || chain, pn_right: rest of chain
* PNK_AND binary pn_left: first in && chain, pn_right: rest of chain
* PNK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr
* PNK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr
* PNK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr
*
* TOK_EQ, binary pn_left: left-assoc EQ expr, pn_right: REL expr
* TOK_NE,
* TOK_STRICTEQ,
* TOK_STRICTNE
* TOK_LT, binary pn_left: left-assoc REL expr, pn_right: SH expr
* TOK_LE,
* TOK_GT,
* TOK_GE
* TOK_LSH, binary pn_left: left-assoc SH expr, pn_right: ADD expr
* TOK_RSH,
* TOK_URSH
* TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
* pn_xflags: if a left-associated binary TOK_PLUS
* PNK_EQ, binary pn_left: left-assoc EQ expr, pn_right: REL expr
* PNK_NE,
* PNK_STRICTEQ,
* PNK_STRICTNE
* PNK_LT, binary pn_left: left-assoc REL expr, pn_right: SH expr
* PNK_LE,
* PNK_GT,
* PNK_GE
* PNK_LSH, binary pn_left: left-assoc SH expr, pn_right: ADD expr
* PNK_RSH,
* PNK_URSH
* PNK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
* pn_xflags: if a left-associated binary PNK_PLUS
* tree has been flattened into a list (see above
* under <Expressions>), pn_xflags will contain
* PNX_STRCAT if at least one list element is a
* string literal (TOK_STRING); if such a list has
* string literal (PNK_STRING); if such a list has
* any non-string, non-number term, pn_xflags will
* contain PNX_CANTFOLD.
* pn_
* TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB
* TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
* TOK_DIV, pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
* TOK_MOD
* TOK_TYPEOF, unary pn_kid: UNARY expr
* TOK_VOID,
* TOK_NOT,
* TOK_BITNOT
* TOK_INC, unary pn_kid: MEMBER expr
* TOK_DEC
* TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN
* PNK_MINUS pn_op: JSOP_ADD, JSOP_SUB
* PNK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
* PNK_DIV, pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
* PNK_MOD
* PNK_TYPEOF, unary pn_kid: UNARY expr
* PNK_VOID,
* PNK_NOT,
* PNK_BITNOT
* PNK_INC, unary pn_kid: MEMBER expr
* PNK_DEC
* PNK_NEW list pn_head: list of ctor, arg1, arg2, ... argN
* pn_count: 1 + N (where N is number of args)
* ctor is a MEMBER expr
* TOK_DELETE unary pn_kid: MEMBER expr
* TOK_DOT, name pn_expr: MEMBER expr to left of .
* TOK_DBLDOT pn_atom: name to right of .
* TOK_LB binary pn_left: MEMBER expr to left of [
* PNK_DELETE unary pn_kid: MEMBER expr
* PNK_DOT, name pn_expr: MEMBER expr to left of .
* PNK_DBLDOT pn_atom: name to right of .
* PNK_LB binary pn_left: MEMBER expr to left of [
* pn_right: expr between [ and ]
* TOK_LP list pn_head: list of call, arg1, arg2, ... argN
* PNK_LP list pn_head: list of call, arg1, arg2, ... argN
* pn_count: 1 + N (where N is number of args)
* call is a MEMBER expr naming a callable object
* TOK_RB list pn_head: list of pn_count array element exprs
* [,,] holes are represented by TOK_COMMA nodes
* PNK_RB list pn_head: list of pn_count array element exprs
* [,,] holes are represented by PNK_COMMA nodes
* pn_xflags: PN_ENDCOMMA if extra comma at end
* TOK_RC list pn_head: list of pn_count binary TOK_COLON nodes
* TOK_COLON binary key-value pair in object initializer or
* PNK_RC list pn_head: list of pn_count binary PNK_COLON nodes
* PNK_COLON binary key-value pair in object initializer or
* destructuring lhs
* pn_left: property id, pn_right: value
* var {x} = object destructuring shorthand shares
* PN_NAME node for x on left and right of TOK_COLON
* node in TOK_RC's list, has PNX_DESTRUCT flag
* TOK_DEFSHARP unary pn_num: jsint value of n in #n=
* PN_NAME node for x on left and right of PNK_COLON
* node in PNK_RC's list, has PNX_DESTRUCT flag
* PNK_DEFSHARP unary pn_num: jsint value of n in #n=
* pn_kid: primary function, paren, name, object or
* array literal expressions
* TOK_USESHARP nullary pn_num: jsint value of n in #n#
* TOK_NAME, name pn_atom: name, string, or object atom
* TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or
* PNK_USESHARP nullary pn_num: jsint value of n in #n#
* PNK_NAME, name pn_atom: name, string, or object atom
* PNK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT, or
* JSOP_REGEXP
* TOK_REGEXP If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
* PNK_REGEXP If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR
* with pn_cookie telling (staticLevel, slot) (see
* jsscript.h's UPVAR macros) and pn_dflags telling
* const-ness and static analysis results
* TOK_NAME name If pn_used, TOK_NAME uses the lexdef member instead
* PNK_NAME name If pn_used, PNK_NAME uses the lexdef member instead
* of the expr member it overlays
* TOK_NUMBER dval pn_dval: double value of numeric literal
* TOK_TRUE, nullary pn_op: JSOp bytecode
* TOK_FALSE,
* TOK_NULL,
* TOK_THIS
* PNK_NUMBER dval pn_dval: double value of numeric literal
* PNK_TRUE, nullary pn_op: JSOp bytecode
* PNK_FALSE,
* PNK_NULL,
* PNK_THIS
*
* <E4X node descriptions>
* TOK_DEFAULT name pn_atom: default XML namespace string literal
* TOK_FILTER binary pn_left: container expr, pn_right: filter expr
* TOK_DBLDOT binary pn_left: container expr, pn_right: selector expr
* TOK_ANYNAME nullary pn_op: JSOP_ANYNAME
* PNK_DEFAULT name pn_atom: default XML namespace string literal
* PNK_FILTER binary pn_left: container expr, pn_right: filter expr
* PNK_DBLDOT binary pn_left: container expr, pn_right: selector expr
* PNK_ANYNAME nullary pn_op: JSOP_ANYNAME
* pn_atom: cx->runtime->atomState.starAtom
* TOK_AT unary pn_op: JSOP_TOATTRNAME; pn_kid attribute id/expr
* TOK_DBLCOLON binary pn_op: JSOP_QNAME
* pn_left: TOK_ANYNAME or TOK_NAME node
* pn_right: TOK_STRING "*" node, or expr within []
* PNK_AT unary pn_op: JSOP_TOATTRNAME; pn_kid attribute id/expr
* PNK_DBLCOLON binary pn_op: JSOP_QNAME
* pn_left: PNK_ANYNAME or PNK_NAME node
* pn_right: PNK_STRING "*" node, or expr within []
* name pn_op: JSOP_QNAMECONST
* pn_expr: TOK_ANYNAME or TOK_NAME left operand
* pn_expr: PNK_ANYNAME or PNK_NAME left operand
* pn_atom: name on right of ::
* TOK_XMLELEM list XML element node
* PNK_XMLELEM list XML element node
* pn_head: start tag, content1, ... contentN, end tag
* pn_count: 2 + N where N is number of content nodes
* N may be > x.length() if {expr} embedded
* After constant folding, these contents may be
* concatenated into string nodes.
* TOK_XMLLIST list XML list node
* PNK_XMLLIST list XML list node
* pn_head: content1, ... contentN
* TOK_XMLSTAGO, list XML start, end, and point tag contents
* TOK_XMLETAGO, pn_head: tag name or {expr}, ... XML attrs ...
* TOK_XMLPTAGC
* TOK_XMLNAME nullary pn_atom: XML name, with no {expr} embedded
* TOK_XMLNAME list pn_head: tag name or {expr}, ... name or {expr}
* TOK_XMLATTR, nullary pn_atom: attribute value string; pn_op: JSOP_STRING
* TOK_XMLCDATA,
* TOK_XMLCOMMENT
* TOK_XMLPI nullary pn_pitarget: XML processing instruction target
* PNK_XMLSTAGO, list XML start, end, and point tag contents
* PNK_XMLETAGO, pn_head: tag name or {expr}, ... XML attrs ...
* PNK_XMLPTAGC
* PNK_XMLNAME nullary pn_atom: XML name, with no {expr} embedded
* PNK_XMLNAME list pn_head: tag name or {expr}, ... name or {expr}
* PNK_XMLATTR, nullary pn_atom: attribute value string; pn_op: JSOP_STRING
* PNK_XMLCDATA,
* PNK_XMLCOMMENT
* PNK_XMLPI nullary pn_pitarget: XML processing instruction target
* pn_pidata: XML PI data, or null if no data
* TOK_XMLTEXT nullary pn_atom: marked-up text, or null if empty string
* TOK_LC unary {expr} in XML tag or content; pn_kid is expr
* PNK_XMLTEXT nullary pn_atom: marked-up text, or null if empty string
* PNK_LC unary {expr} in XML tag or content; pn_kid is expr
*
* So an XML tag with no {expr} and three attributes is a list with the form:
*
@ -287,10 +425,10 @@ namespace js {
* ((name1 {expr1}) (name2 {expr2} name3) {expr3})
*
* where () bracket a list with elements separated by spaces, and {expr} is a
* TOK_LC unary node with expr as its kid.
* PNK_LC unary node with expr as its kid.
*
* Thus, the attribute name/value pairs occupy successive odd and even list
* locations, where pn_head is the TOK_XMLNAME node at list location 0. The
* locations, where pn_head is the PNK_XMLNAME node at list location 0. The
* parser builds the same sort of structures for elements:
*
* <a x={x}>Hi there!<b y={y}>How are you?</b><answer>{x + y}</answer></a>
@ -303,14 +441,14 @@ namespace js {
*
* Label Variant Members
* ----- ------- -------
* TOK_LEXICALSCOPE name pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEXPR
* PNK_LEXICALSCOPE name pn_op: JSOP_LEAVEBLOCK or JSOP_LEAVEBLOCKEXPR
* pn_objbox: block object in ObjectBox holder
* pn_expr: block body
* TOK_ARRAYCOMP list pn_count: 1
* PNK_ARRAYCOMP list pn_count: 1
* pn_head: list of 1 element, which is block
* enclosing for loop(s) and optionally
* if-guarded TOK_ARRAYPUSH
* TOK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP
* if-guarded PNK_ARRAYPUSH
* PNK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP
* pn_kid: array comprehension expression
*/
enum ParseNodeArity {
@ -328,7 +466,7 @@ struct Definition;
struct ParseNode {
private:
uint32 pn_type : 16, /* TOK_* type, see frontend/TokenStream.h */
uint32 pn_type : 16, /* PNK_* type */
pn_op : 8, /* see JSOp enum and jsopcode.tbl */
pn_arity : 5, /* see ParseNodeArity enum */
pn_parens : 1, /* this expr was enclosed in parens */
@ -336,10 +474,11 @@ struct ParseNode {
pn_defn : 1; /* this node is a Definition */
public:
ParseNode(TokenKind type, JSOp op, ParseNodeArity arity)
: pn_type(type), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
ParseNode(ParseNodeKind kind, JSOp op, ParseNodeArity arity)
: pn_type(kind), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
pn_offset(0), pn_next(NULL), pn_link(NULL)
{
JS_ASSERT(kind < PNK_LIMIT);
pn_pos.begin.index = 0;
pn_pos.begin.lineno = 0;
pn_pos.end.index = 0;
@ -347,27 +486,51 @@ struct ParseNode {
memset(&pn_u, 0, sizeof pn_u);
}
ParseNode(TokenKind type, JSOp op, ParseNodeArity arity, const TokenPos &pos)
: pn_type(type), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
ParseNode(ParseNodeKind kind, JSOp op, ParseNodeArity arity, const TokenPos &pos)
: pn_type(kind), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
pn_pos(pos), pn_offset(0), pn_next(NULL), pn_link(NULL)
{
JS_ASSERT(kind < PNK_LIMIT);
memset(&pn_u, 0, sizeof pn_u);
}
JSOp getOp() const { return JSOp(pn_op); }
void setOp(JSOp op) { pn_op = op; }
bool isOp(JSOp op) const { return getOp() == op; }
TokenKind getKind() const { return TokenKind(pn_type); }
void setKind(TokenKind kind) { pn_type = kind; }
bool isKind(TokenKind kind) const { return getKind() == kind; }
ParseNodeKind getKind() const {
JS_ASSERT(pn_type < PNK_LIMIT);
return ParseNodeKind(pn_type);
}
void setKind(ParseNodeKind kind) {
JS_ASSERT(kind < PNK_LIMIT);
pn_type = kind;
}
bool isKind(ParseNodeKind kind) const { return getKind() == kind; }
ParseNodeArity getArity() const { return ParseNodeArity(pn_arity); }
bool isArity(ParseNodeArity a) const { return getArity() == a; }
void setArity(ParseNodeArity a) { pn_arity = a; }
bool isEquality() const { return TokenKindIsEquality(getKind()); }
bool isUnaryOp() const { return TokenKindIsUnaryOp(getKind()); }
bool isXMLNameOp() const { return TokenKindIsXML(getKind()); }
bool isAssignment() const { return TokenKindIsAssignment(getKind()); }
bool isXMLNameOp() const {
ParseNodeKind kind = getKind();
return kind == PNK_ANYNAME || kind == PNK_AT || kind == PNK_DBLCOLON;
}
bool isAssignment() const {
ParseNodeKind kind = getKind();
return PNK_ASSIGNMENT_START <= kind && kind <= PNK_ASSIGNMENT_LAST;
}
bool isXMLPropertyIdentifier() const {
ParseNodeKind kind = getKind();
return kind == PNK_ANYNAME || kind == PNK_AT || kind == PNK_DBLCOLON;
}
bool isXMLItem() const {
ParseNodeKind kind = getKind();
return kind == PNK_XMLCOMMENT || kind == PNK_XMLCDATA || kind == PNK_XMLPI ||
kind == PNK_XMLELEM || kind == PNK_XMLLIST;
}
/* Boolean attributes. */
bool isInParens() const { return pn_parens; }
@ -401,7 +564,7 @@ struct ParseNode {
ParseNode *left;
ParseNode *right;
Value *pval; /* switch case value */
uintN iflags; /* JSITER_* flags for TOK_FOR node */
uintN iflags; /* JSITER_* flags for PNK_FOR node */
} binary;
struct { /* one kid if unary */
ParseNode *kid;
@ -418,7 +581,7 @@ struct ParseNode {
};
union {
ParseNode *expr; /* function body, var initializer, or
base object of TOK_DOT */
base object of PNK_DOT */
Definition *lexdef; /* lexical definition for this use */
};
UpvarCookie cookie; /* upvar cookie with absolute frame
@ -482,7 +645,7 @@ struct ParseNode {
pn_next = pn_link = NULL;
}
static ParseNode *create(ParseNodeArity arity, TreeContext *tc);
static ParseNode *create(ParseNodeKind kind, ParseNodeArity arity, TreeContext *tc);
public:
/*
@ -490,7 +653,7 @@ struct ParseNode {
* kind and op, and op must be left-associative.
*/
static ParseNode *
append(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right);
append(ParseNodeKind tt, JSOp op, ParseNode *left, ParseNode *right);
/*
* Either append right to left, if left meets the conditions necessary to
@ -498,7 +661,8 @@ struct ParseNode {
* left.
*/
static ParseNode *
newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right, TreeContext *tc);
newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
TreeContext *tc);
/*
* The pn_expr and lexdef members are arms of an unsafe union. Unless you
@ -542,11 +706,11 @@ struct ParseNode {
#define PND_USE2DEF_FLAGS (PND_ASSIGNED | PND_FUNARG | PND_CLOSED)
/* PN_LIST pn_xflags bits. */
#define PNX_STRCAT 0x01 /* TOK_PLUS list has string term */
#define PNX_CANTFOLD 0x02 /* TOK_PLUS list has unfoldable term */
#define PNX_POPVAR 0x04 /* TOK_VAR last result needs popping */
#define PNX_FORINVAR 0x08 /* TOK_VAR is left kid of TOK_IN node,
which is left kid of TOK_FOR */
#define PNX_STRCAT 0x01 /* PNK_PLUS list has string term */
#define PNX_CANTFOLD 0x02 /* PNK_PLUS list has unfoldable term */
#define PNX_POPVAR 0x04 /* PNK_VAR last result needs popping */
#define PNX_FORINVAR 0x08 /* PNK_VAR is left kid of PNK_IN node,
which is left kid of PNK_FOR */
#define PNX_ENDCOMMA 0x10 /* array literal has comma at end */
#define PNX_XMLROOT 0x20 /* top-most node in XML literal tree */
#define PNX_GROUPINIT 0x40 /* var [a, b] = [c, d]; unit list */
@ -606,11 +770,11 @@ struct ParseNode {
/* True if pn is a parsenode representing a literal constant. */
bool isLiteral() const {
return isKind(TOK_NUMBER) ||
isKind(TOK_STRING) ||
isKind(TOK_TRUE) ||
isKind(TOK_FALSE) ||
isKind(TOK_NULL);
return isKind(PNK_NUMBER) ||
isKind(PNK_STRING) ||
isKind(PNK_TRUE) ||
isKind(PNK_FALSE) ||
isKind(PNK_NULL);
}
/*
@ -629,28 +793,28 @@ struct ParseNode {
* a directive.
*/
bool isStringExprStatement() const {
if (getKind() == TOK_SEMI) {
if (getKind() == PNK_SEMI) {
JS_ASSERT(pn_arity == PN_UNARY);
ParseNode *kid = pn_kid;
return kid && kid->getKind() == TOK_STRING && !kid->pn_parens;
return kid && kid->getKind() == PNK_STRING && !kid->pn_parens;
}
return false;
}
/*
* Return true if this node, known to be a string literal, could be the
* string of a directive in a Directive Prologue. Directive strings never
* contain escape sequences or line continuations.
* Return true if this node, known to be an unparenthesized string literal,
* could be the string of a directive in a Directive Prologue. Directive
* strings never contain escape sequences or line continuations.
*/
bool isEscapeFreeStringLiteral() const {
JS_ASSERT(pn_type == TOK_STRING && !pn_parens);
JSString *str = pn_atom;
JS_ASSERT(isKind(PNK_STRING) && !pn_parens);
/*
* If the string's length in the source code is its length as a value,
* accounting for the quotes, then it must not contain any escape
* sequences or line continuations.
*/
JSString *str = pn_atom;
return (pn_pos.begin.lineno == pn_pos.end.lineno &&
pn_pos.begin.index + str->length() + 2 == pn_pos.end.index);
}
@ -663,13 +827,13 @@ struct ParseNode {
* True if this node is a desugared generator expression.
*/
bool isGeneratorExpr() const {
if (getKind() == TOK_LP) {
if (getKind() == PNK_LP) {
ParseNode *callee = this->pn_head;
if (callee->getKind() == TOK_FUNCTION) {
ParseNode *body = (callee->pn_body->getKind() == TOK_UPVARS)
if (callee->getKind() == PNK_FUNCTION) {
ParseNode *body = (callee->pn_body->getKind() == PNK_UPVARS)
? callee->pn_body->pn_tree
: callee->pn_body;
if (body->getKind() == TOK_LEXICALSCOPE)
if (body->getKind() == PNK_LEXICALSCOPE)
return true;
}
}
@ -679,10 +843,10 @@ struct ParseNode {
ParseNode *generatorExpr() const {
JS_ASSERT(isGeneratorExpr());
ParseNode *callee = this->pn_head;
ParseNode *body = callee->pn_body->getKind() == TOK_UPVARS
ParseNode *body = callee->pn_body->getKind() == PNK_UPVARS
? callee->pn_body->pn_tree
: callee->pn_body;
JS_ASSERT(body->getKind() == TOK_LEXICALSCOPE);
JS_ASSERT(body->getKind() == PNK_LEXICALSCOPE);
return body->pn_expr;
}
#endif
@ -727,46 +891,46 @@ struct ParseNode {
};
struct NullaryNode : public ParseNode {
static inline NullaryNode *create(TreeContext *tc) {
return (NullaryNode *)ParseNode::create(PN_NULLARY, tc);
static inline NullaryNode *create(ParseNodeKind kind, TreeContext *tc) {
return (NullaryNode *)ParseNode::create(kind, PN_NULLARY, tc);
}
};
struct UnaryNode : public ParseNode {
UnaryNode(TokenKind type, JSOp op, const TokenPos &pos, ParseNode *kid)
: ParseNode(type, op, PN_UNARY, pos)
UnaryNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *kid)
: ParseNode(kind, op, PN_UNARY, pos)
{
pn_kid = kid;
}
static inline UnaryNode *create(TreeContext *tc) {
return (UnaryNode *)ParseNode::create(PN_UNARY, tc);
static inline UnaryNode *create(ParseNodeKind kind, TreeContext *tc) {
return (UnaryNode *)ParseNode::create(kind, PN_UNARY, tc);
}
};
struct BinaryNode : public ParseNode {
BinaryNode(TokenKind type, JSOp op, const TokenPos &pos, ParseNode *left, ParseNode *right)
: ParseNode(type, op, PN_BINARY, pos)
BinaryNode(ParseNodeKind kind, JSOp op, const TokenPos &pos, ParseNode *left, ParseNode *right)
: ParseNode(kind, op, PN_BINARY, pos)
{
pn_left = left;
pn_right = right;
}
BinaryNode(TokenKind type, JSOp op, ParseNode *left, ParseNode *right)
: ParseNode(type, op, PN_BINARY, TokenPos::box(left->pn_pos, right->pn_pos))
BinaryNode(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right)
: ParseNode(kind, op, PN_BINARY, TokenPos::box(left->pn_pos, right->pn_pos))
{
pn_left = left;
pn_right = right;
}
static inline BinaryNode *create(TreeContext *tc) {
return (BinaryNode *)ParseNode::create(PN_BINARY, tc);
static inline BinaryNode *create(ParseNodeKind kind, TreeContext *tc) {
return (BinaryNode *)ParseNode::create(kind, PN_BINARY, tc);
}
};
struct TernaryNode : public ParseNode {
TernaryNode(TokenKind type, JSOp op, ParseNode *kid1, ParseNode *kid2, ParseNode *kid3)
: ParseNode(type, op, PN_TERNARY,
TernaryNode(ParseNodeKind kind, JSOp op, ParseNode *kid1, ParseNode *kid2, ParseNode *kid3)
: ParseNode(kind, op, PN_TERNARY,
TokenPos::make((kid1 ? kid1 : kid2 ? kid2 : kid3)->pn_pos.begin,
(kid3 ? kid3 : kid2 ? kid2 : kid1)->pn_pos.end))
{
@ -775,38 +939,38 @@ struct TernaryNode : public ParseNode {
pn_kid3 = kid3;
}
static inline TernaryNode *create(TreeContext *tc) {
return (TernaryNode *)ParseNode::create(PN_TERNARY, tc);
static inline TernaryNode *create(ParseNodeKind kind, TreeContext *tc) {
return (TernaryNode *)ParseNode::create(kind, PN_TERNARY, tc);
}
};
struct ListNode : public ParseNode {
static inline ListNode *create(TreeContext *tc) {
return (ListNode *)ParseNode::create(PN_LIST, tc);
static inline ListNode *create(ParseNodeKind kind, TreeContext *tc) {
return (ListNode *)ParseNode::create(kind, PN_LIST, tc);
}
};
struct FunctionNode : public ParseNode {
static inline FunctionNode *create(TreeContext *tc) {
return (FunctionNode *)ParseNode::create(PN_FUNC, tc);
static inline FunctionNode *create(ParseNodeKind kind, TreeContext *tc) {
return (FunctionNode *)ParseNode::create(kind, PN_FUNC, tc);
}
};
struct NameNode : public ParseNode {
static NameNode *create(JSAtom *atom, TreeContext *tc);
static NameNode *create(ParseNodeKind kind, JSAtom *atom, TreeContext *tc);
inline void initCommon(TreeContext *tc);
};
struct NameSetNode : public ParseNode {
static inline NameSetNode *create(TreeContext *tc) {
return (NameSetNode *)ParseNode::create(PN_NAMESET, tc);
static inline NameSetNode *create(ParseNodeKind kind, TreeContext *tc) {
return (NameSetNode *)ParseNode::create(kind, PN_NAMESET, tc);
}
};
struct LexicalScopeNode : public ParseNode {
static inline LexicalScopeNode *create(TreeContext *tc) {
return (LexicalScopeNode *)ParseNode::create(PN_NAME, tc);
static inline LexicalScopeNode *create(ParseNodeKind kind, TreeContext *tc) {
return (LexicalScopeNode *)ParseNode::create(kind, PN_NAME, tc);
}
};
@ -817,7 +981,7 @@ CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
* js::Definition is a degenerate subtype of the PN_FUNC and PN_NAME variants
* of js::ParseNode, allocated only for function, var, const, and let
* declarations that define truly lexical bindings. This means that a child of
* a TOK_VAR list may be a Definition instead of a ParseNode. The pn_defn
* a PNK_VAR list may be a Definition instead of a ParseNode. The pn_defn
* bit is set for all Definitions, clear otherwise.
*
* In an upvars list, defn->resolve() is the outermost definition the
@ -861,7 +1025,7 @@ CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
* map x to dn via tc->decls;
* pn = dn;
* }
* insert pn into its parent TOK_VAR list;
* insert pn into its parent PNK_VAR list;
* } else {
* pn = allocate a ParseNode for this reference to x;
* dn = lookup x in tc's lexical scope chain;
@ -973,9 +1137,9 @@ struct Definition : public ParseNode
static const char *kindString(Kind kind);
Kind kind() {
if (getKind() == TOK_FUNCTION)
if (getKind() == PNK_FUNCTION)
return FUNCTION;
JS_ASSERT(getKind() == TOK_NAME);
JS_ASSERT(getKind() == PNK_NAME);
if (isOp(JSOP_NOP))
return UNKNOWN;
if (isOp(JSOP_GETARG))

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -141,6 +141,12 @@ struct Parser : private AutoGCRooter
return allocator.allocNode();
}
/*
* Create a parse node with the given kind and op using the current token's
* atom.
*/
ParseNode *atomNode(ParseNodeKind kind, JSOp op);
public:
ParseNode *freeTree(ParseNode *pn) { return allocator.freeTree(pn); }
void prepareNodeForMutation(ParseNode *pn) { return allocator.prepareNodeForMutation(pn); }
@ -218,9 +224,11 @@ struct Parser : private AutoGCRooter
ParseNode *functionDef(PropertyName *name, FunctionType type, FunctionSyntaxKind kind);
ParseNode *unaryOpExpr(ParseNodeKind kind, JSOp op);
ParseNode *condition();
ParseNode *comprehensionTail(ParseNode *kid, uintN blockid, bool isGenexp,
TokenKind type = TOK_SEMI, JSOp op = JSOP_NOP);
ParseNodeKind kind = PNK_SEMI, JSOp op = JSOP_NOP);
ParseNode *generatorExpr(ParseNode *kid);
JSBool argumentList(ParseNode *listNode);
ParseNode *bracketedExpr();
@ -236,9 +244,8 @@ struct Parser : private AutoGCRooter
ParseNode *qualifiedIdentifier();
ParseNode *attributeIdentifier();
ParseNode *xmlExpr(JSBool inTag);
ParseNode *xmlAtomNode();
ParseNode *xmlNameExpr();
ParseNode *xmlTagContent(TokenKind tagtype, JSAtom **namep);
ParseNode *xmlTagContent(ParseNodeKind tagkind, JSAtom **namep);
JSBool xmlElementContent(ParseNode *pn);
ParseNode *xmlElementOrList(JSBool allowList);
ParseNode *xmlElementOrListRoot(JSBool allowList);

Просмотреть файл

@ -194,7 +194,7 @@ FindFunArgs(FunctionBox *funbox, int level, FunctionBoxQueue *queue)
uintN skipmin = UpvarCookie::FREE_LEVEL;
ParseNode *pn = fn->pn_body;
if (pn->isKind(TOK_UPVARS)) {
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr &upvars = pn->pn_names;
JS_ASSERT(upvars->count() != 0);
@ -273,7 +273,7 @@ MarkFunArgs(JSContext *cx, FunctionBox *funbox, uint32 functionCount)
JS_ASSERT(fn->isFunArg());
ParseNode *pn = fn->pn_body;
if (pn->isKind(TOK_UPVARS)) {
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
@ -528,11 +528,11 @@ ConsiderUnbranding(FunctionBox *funbox)
#if JS_HAS_EXPR_CLOSURES
{
ParseNode *pn2 = funbox->node->pn_body;
if (pn2->isKind(TOK_UPVARS))
if (pn2->isKind(PNK_UPVARS))
pn2 = pn2->pn_tree;
if (pn2->isKind(TOK_ARGSBODY))
if (pn2->isKind(PNK_ARGSBODY))
pn2 = pn2->last();
if (!pn2->isKind(TOK_LC))
if (!pn2->isKind(PNK_LC))
returnsExpr = true;
}
#endif
@ -585,7 +585,7 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
bool hasUpvars = false;
bool canFlatten = true;
if (pn->isKind(TOK_UPVARS)) {
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
@ -630,13 +630,13 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
fn->setOp(JSOP_LAMBDA_FC);
break;
default:
/* js_EmitTree's case TOK_FUNCTION: will select op. */
/* js::frontend::EmitTree's PNK_FUNCTION case sets op. */
JS_ASSERT(fn->isOp(JSOP_NOP));
}
}
}
if (fun->kind() == JSFUN_INTERPRETED && pn->isKind(TOK_UPVARS)) {
if (fun->kind() == JSFUN_INTERPRETED && pn->isKind(PNK_UPVARS)) {
/*
* One or more upvars cannot be safely snapshot into a flat
* closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop

Просмотреть файл

@ -2282,14 +2282,8 @@ TokenKindToString(TokenKind tt)
case TOK_XMLELEM: return "TOK_XMLELEM";
case TOK_XMLLIST: return "TOK_XMLLIST";
case TOK_YIELD: return "TOK_YIELD";
case TOK_ARRAYCOMP: return "TOK_ARRAYCOMP";
case TOK_ARRAYPUSH: return "TOK_ARRAYPUSH";
case TOK_LEXICALSCOPE: return "TOK_LEXICALSCOPE";
case TOK_LET: return "TOK_LET";
case TOK_SEQ: return "TOK_SEQ";
case TOK_FORHEAD: return "TOK_FORHEAD";
case TOK_ARGSBODY: return "TOK_ARGSBODY";
case TOK_UPVARS: return "TOK_UPVARS";
case TOK_RESERVED: return "TOK_RESERVED";
case TOK_STRICT_RESERVED: return "TOK_STRICT_RESERVED";
case TOK_STRICTEQ: return "TOK_STRICTEQ";

Просмотреть файл

@ -136,17 +136,8 @@ enum TokenKind {
TOK_XMLELEM, /* XML element node type (no token) */
TOK_XMLLIST, /* XML list node type (no token) */
TOK_YIELD, /* yield from generator function */
TOK_ARRAYCOMP, /* array comprehension initialiser */
TOK_ARRAYPUSH, /* array push within comprehension */
TOK_LEXICALSCOPE, /* block scope AST node label */
TOK_LET, /* let keyword */
TOK_SEQ, /* synthetic sequence of statements, not a
block */
TOK_FORHEAD, /* head of for(;;)-style loop */
TOK_ARGSBODY, /* formal args in list + body at end */
TOK_UPVARS, /* lexical dependencies as JSAtomDefnMap of
definitions paired with a parse tree full
of uses of those names */
TOK_RESERVED, /* reserved keywords */
TOK_STRICT_RESERVED, /* reserved keywords in strict mode */
@ -163,13 +154,11 @@ enum TokenKind {
TOK_NE,
TOK_EQUALITY_LAST = TOK_NE,
/* Unary operation tokens, per TokenKindIsUnaryOp */
/* Unary operation tokens */
TOK_TYPEOF,
TOK_UNARYOP_START = TOK_TYPEOF,
TOK_VOID,
TOK_NOT,
TOK_BITNOT,
TOK_UNARYOP_LAST = TOK_BITNOT,
/* Relational ops (< <= > >=), per TokenKindIsRelational */
TOK_LT,
@ -201,7 +190,6 @@ enum TokenKind {
TOK_DIVASSIGN,
TOK_MODASSIGN,
TOK_ASSIGNMENT_LAST = TOK_MODASSIGN,
TOK_LIMIT /* domain size */
};
@ -212,12 +200,6 @@ TokenKindIsEquality(TokenKind tt)
return TOK_EQUALITY_START <= tt && tt <= TOK_EQUALITY_LAST;
}
inline bool
TokenKindIsUnaryOp(TokenKind tt)
{
return TOK_UNARYOP_START <= tt && tt <= TOK_UNARYOP_LAST;
}
inline bool
TokenKindIsXML(TokenKind tt)
{
@ -242,13 +224,6 @@ TokenKindIsAssignment(TokenKind tt)
return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST;
}
inline bool
TreeTypeIsXML(TokenKind tt)
{
return tt == TOK_XMLCOMMENT || tt == TOK_XMLCDATA || tt == TOK_XMLPI ||
tt == TOK_XMLELEM || tt == TOK_XMLLIST;
}
inline bool
TokenKindIsDecl(TokenKind tt)
{
@ -542,10 +517,6 @@ class TokenStream
return TokenKindIsEquality(currentToken().type);
}
bool isCurrentTokenUnaryOp() const {
return TokenKindIsUnaryOp(currentToken().type);
}
bool isCurrentTokenRelational() const {
return TokenKindIsRelational(currentToken().type);
}

Просмотреть файл

@ -1607,8 +1607,8 @@ class ASTSerializer
return StringValue(atom ? atom : cx->runtime->atomState.emptyAtom);
}
BinaryOperator binop(TokenKind tk, JSOp op);
UnaryOperator unop(TokenKind tk, JSOp op);
BinaryOperator binop(ParseNodeKind kind, JSOp op);
UnaryOperator unop(ParseNodeKind kind, JSOp op);
AssignmentOperator aop(JSOp op);
bool statements(ParseNode *pn, NodeVector &elts);
@ -1730,9 +1730,9 @@ ASTSerializer::aop(JSOp op)
}
UnaryOperator
ASTSerializer::unop(TokenKind tk, JSOp op)
ASTSerializer::unop(ParseNodeKind kind, JSOp op)
{
if (tk == TOK_DELETE)
if (kind == PNK_DELETE)
return UNOP_DELETE;
switch (op) {
@ -1755,52 +1755,52 @@ ASTSerializer::unop(TokenKind tk, JSOp op)
}
BinaryOperator
ASTSerializer::binop(TokenKind tk, JSOp op)
ASTSerializer::binop(ParseNodeKind kind, JSOp op)
{
switch (tk) {
case TOK_LSH:
switch (kind) {
case PNK_LSH:
return BINOP_LSH;
case TOK_RSH:
case PNK_RSH:
return BINOP_RSH;
case TOK_URSH:
case PNK_URSH:
return BINOP_URSH;
case TOK_LT:
case PNK_LT:
return BINOP_LT;
case TOK_LE:
case PNK_LE:
return BINOP_LE;
case TOK_GT:
case PNK_GT:
return BINOP_GT;
case TOK_GE:
case PNK_GE:
return BINOP_GE;
case TOK_EQ:
case PNK_EQ:
return BINOP_EQ;
case TOK_NE:
case PNK_NE:
return BINOP_NE;
case TOK_STRICTEQ:
case PNK_STRICTEQ:
return BINOP_STRICTEQ;
case TOK_STRICTNE:
case PNK_STRICTNE:
return BINOP_STRICTNE;
case TOK_PLUS:
case PNK_PLUS:
return BINOP_PLUS;
case TOK_MINUS:
case PNK_MINUS:
return BINOP_MINUS;
case TOK_STAR:
case PNK_STAR:
return BINOP_STAR;
case TOK_DIV:
case PNK_DIV:
return BINOP_DIV;
case TOK_MOD:
case PNK_MOD:
return BINOP_MOD;
case TOK_BITOR:
case PNK_BITOR:
return BINOP_BITOR;
case TOK_BITXOR:
case PNK_BITXOR:
return BINOP_BITXOR;
case TOK_BITAND:
case PNK_BITAND:
return BINOP_BITAND;
case TOK_IN:
case PNK_IN:
return BINOP_IN;
case TOK_INSTANCEOF:
case PNK_INSTANCEOF:
return BINOP_INSTANCEOF;
case TOK_DBLDOT:
case PNK_DBLDOT:
return BINOP_DBLDOT;
default:
return BINOP_ERR;
@ -1810,7 +1810,7 @@ ASTSerializer::binop(TokenKind tk, JSOp op)
bool
ASTSerializer::statements(ParseNode *pn, NodeVector &elts)
{
JS_ASSERT(pn->isKind(TOK_LC) && pn->isArity(PN_LIST));
JS_ASSERT(pn->isKind(PNK_LC) && pn->isArity(PN_LIST));
if (!elts.reserve(pn->pn_count))
return false;
@ -1860,7 +1860,7 @@ ASTSerializer::xmls(ParseNode *pn, NodeVector &elts)
bool
ASTSerializer::blockStatement(ParseNode *pn, Value *dst)
{
JS_ASSERT(pn->isKind(TOK_LC));
JS_ASSERT(pn->isKind(PNK_LC));
NodeVector stmts(cx);
return statements(pn, stmts) &&
@ -1887,17 +1887,17 @@ ASTSerializer::sourceElement(ParseNode *pn, Value *dst)
bool
ASTSerializer::declaration(ParseNode *pn, Value *dst)
{
JS_ASSERT(pn->isKind(TOK_FUNCTION) || pn->isKind(TOK_VAR) || pn->isKind(TOK_LET));
JS_ASSERT(pn->isKind(PNK_FUNCTION) || pn->isKind(PNK_VAR) || pn->isKind(PNK_LET));
switch (pn->getKind()) {
case TOK_FUNCTION:
case PNK_FUNCTION:
return function(pn, AST_FUNC_DECL, dst);
case TOK_VAR:
case PNK_VAR:
return variableDeclaration(pn, false, dst);
default:
JS_ASSERT(pn->isKind(TOK_LET));
JS_ASSERT(pn->isKind(PNK_LET));
return variableDeclaration(pn, true, dst);
}
}
@ -1905,7 +1905,7 @@ ASTSerializer::declaration(ParseNode *pn, Value *dst)
bool
ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst)
{
JS_ASSERT(let ? pn->isKind(TOK_LET) : pn->isKind(TOK_VAR));
JS_ASSERT(let ? pn->isKind(PNK_LET) : pn->isKind(PNK_VAR));
/* Later updated to VARDECL_CONST if we find a PND_CONST declarator. */
VarDeclKind kind = let ? VARDECL_LET : VARDECL_VAR;
@ -1936,17 +1936,17 @@ ASTSerializer::variableDeclaration(ParseNode *pn, bool let, Value *dst)
bool
ASTSerializer::variableDeclarator(ParseNode *pn, VarDeclKind *pkind, Value *dst)
{
/* A destructuring declarator is always a TOK_ASSIGN. */
JS_ASSERT(pn->isKind(TOK_NAME) || pn->isKind(TOK_ASSIGN));
/* A destructuring declarator is always a PNK_ASSIGN. */
JS_ASSERT(pn->isKind(PNK_NAME) || pn->isKind(PNK_ASSIGN));
ParseNode *pnleft;
ParseNode *pnright;
if (pn->isKind(TOK_NAME)) {
if (pn->isKind(PNK_NAME)) {
pnleft = pn;
pnright = pn->isUsed() ? NULL : pn->pn_expr;
} else {
JS_ASSERT(pn->isKind(TOK_ASSIGN));
JS_ASSERT(pn->isKind(PNK_ASSIGN));
pnleft = pn->pn_left;
pnright = pn->pn_right;
}
@ -2002,7 +2002,7 @@ ASTSerializer::switchStatement(ParseNode *pn, Value *dst)
ParseNode *listNode;
bool lexical;
if (pn->pn_right->isKind(TOK_LEXICALSCOPE)) {
if (pn->pn_right->isKind(PNK_LEXICALSCOPE)) {
listNode = pn->pn_right->pn_expr;
lexical = true;
} else {
@ -2071,9 +2071,9 @@ ASTSerializer::forInit(ParseNode *pn, Value *dst)
return true;
}
return pn->isKind(TOK_VAR)
return pn->isKind(PNK_VAR)
? variableDeclaration(pn, false, dst)
: pn->isKind(TOK_LET)
: pn->isKind(PNK_LET)
? variableDeclaration(pn, true, dst)
: expression(pn, dst);
}
@ -2083,16 +2083,16 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
{
JS_CHECK_RECURSION(cx, return false);
switch (pn->getKind()) {
case TOK_FUNCTION:
case TOK_VAR:
case TOK_LET:
case PNK_FUNCTION:
case PNK_VAR:
case PNK_LET:
return declaration(pn, dst);
case TOK_NAME:
case PNK_NAME:
LOCAL_ASSERT(pn->isUsed());
return statement(pn->pn_lexdef, dst);
case TOK_SEMI:
case PNK_SEMI:
if (pn->pn_kid) {
Value expr;
return expression(pn->pn_kid, &expr) &&
@ -2100,9 +2100,9 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
}
return builder.emptyStatement(&pn->pn_pos, dst);
case TOK_LEXICALSCOPE:
case PNK_LEXICALSCOPE:
pn = pn->pn_expr;
if (pn->isKind(TOK_LET)) {
if (pn->isKind(PNK_LET)) {
NodeVector dtors(cx);
Value stmt;
@ -2111,14 +2111,14 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
builder.letStatement(dtors, stmt, &pn->pn_pos, dst);
}
if (!pn->isKind(TOK_LC))
if (!pn->isKind(PNK_LC))
return statement(pn, dst);
/* FALL THROUGH */
case TOK_LC:
case PNK_LC:
return blockStatement(pn, dst);
case TOK_IF:
case PNK_IF:
{
Value test, cons, alt;
@ -2128,25 +2128,25 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
builder.ifStatement(test, cons, alt, &pn->pn_pos, dst);
}
case TOK_SWITCH:
case PNK_SWITCH:
return switchStatement(pn, dst);
case TOK_TRY:
case PNK_TRY:
return tryStatement(pn, dst);
case TOK_WITH:
case TOK_WHILE:
case PNK_WITH:
case PNK_WHILE:
{
Value expr, stmt;
return expression(pn->pn_left, &expr) &&
statement(pn->pn_right, &stmt) &&
(pn->isKind(TOK_WITH)
(pn->isKind(PNK_WITH)
? builder.withStatement(expr, stmt, &pn->pn_pos, dst)
: builder.whileStatement(expr, stmt, &pn->pn_pos, dst));
}
case TOK_DO:
case PNK_DO:
{
Value stmt, test;
@ -2155,7 +2155,7 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
builder.doWhileStatement(stmt, test, &pn->pn_pos, dst);
}
case TOK_FOR:
case PNK_FOR:
{
ParseNode *head = pn->pn_left;
@ -2165,13 +2165,13 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
bool isForEach = pn->pn_iflags & JSITER_FOREACH;
if (head->isKind(TOK_IN)) {
if (head->isKind(PNK_IN)) {
Value var, expr;
return (!head->pn_kid1
? pattern(head->pn_kid2, NULL, &var)
: variableDeclaration(head->pn_kid1,
head->pn_kid1->isKind(TOK_LET),
head->pn_kid1->isKind(PNK_LET),
&var)) &&
expression(head->pn_kid3, &expr) &&
builder.forInStatement(var, expr, stmt, isForEach, &pn->pn_pos, dst);
@ -2186,21 +2186,21 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
}
/* Synthesized by the parser when a for-in loop contains a variable initializer. */
case TOK_SEQ:
case PNK_SEQ:
{
LOCAL_ASSERT(pn->pn_count == 2);
ParseNode *prelude = pn->pn_head;
ParseNode *loop = prelude->pn_next;
LOCAL_ASSERT(prelude->isKind(TOK_VAR) && loop->isKind(TOK_FOR));
LOCAL_ASSERT(prelude->isKind(PNK_VAR) && loop->isKind(PNK_FOR));
Value var;
if (!variableDeclaration(prelude, false, &var))
return false;
ParseNode *head = loop->pn_left;
JS_ASSERT(head->isKind(TOK_IN));
JS_ASSERT(head->isKind(PNK_IN));
bool isForEach = loop->pn_iflags & JSITER_FOREACH;
@ -2211,18 +2211,18 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
builder.forInStatement(var, expr, stmt, isForEach, &pn->pn_pos, dst);
}
case TOK_BREAK:
case TOK_CONTINUE:
case PNK_BREAK:
case PNK_CONTINUE:
{
Value label;
return optIdentifier(pn->pn_atom, NULL, &label) &&
(pn->isKind(TOK_BREAK)
(pn->isKind(PNK_BREAK)
? builder.breakStatement(label, &pn->pn_pos, dst)
: builder.continueStatement(label, &pn->pn_pos, dst));
}
case TOK_COLON:
case PNK_COLON:
{
Value label, stmt;
@ -2231,22 +2231,22 @@ ASTSerializer::statement(ParseNode *pn, Value *dst)
builder.labeledStatement(label, stmt, &pn->pn_pos, dst);
}
case TOK_THROW:
case TOK_RETURN:
case PNK_THROW:
case PNK_RETURN:
{
Value arg;
return optExpression(pn->pn_kid, &arg) &&
(pn->isKind(TOK_THROW)
(pn->isKind(PNK_THROW)
? builder.throwStatement(arg, &pn->pn_pos, dst)
: builder.returnStatement(arg, &pn->pn_pos, dst));
}
case TOK_DEBUGGER:
case PNK_DEBUGGER:
return builder.debuggerStatement(&pn->pn_pos, dst);
#if JS_HAS_XML_SUPPORT
case TOK_DEFAULT:
case PNK_DEFAULT:
{
LOCAL_ASSERT(pn->isArity(PN_UNARY));
@ -2268,9 +2268,9 @@ ASTSerializer::leftAssociate(ParseNode *pn, Value *dst)
JS_ASSERT(pn->isArity(PN_LIST));
JS_ASSERT(pn->pn_count >= 1);
TokenKind tk = pn->getKind();
bool lor = tk == TOK_OR;
bool logop = lor || (tk == TOK_AND);
ParseNodeKind kind = pn->getKind();
bool lor = kind == PNK_OR;
bool logop = lor || (kind == PNK_AND);
ParseNode *head = pn->pn_head;
Value left;
@ -2306,7 +2306,7 @@ ASTSerializer::comprehensionBlock(ParseNode *pn, Value *dst)
ParseNode *in = pn->pn_left;
LOCAL_ASSERT(in && in->isKind(TOK_IN));
LOCAL_ASSERT(in && in->isKind(PNK_IN));
bool isForEach = pn->pn_iflags & JSITER_FOREACH;
@ -2319,12 +2319,12 @@ ASTSerializer::comprehensionBlock(ParseNode *pn, Value *dst)
bool
ASTSerializer::comprehension(ParseNode *pn, Value *dst)
{
LOCAL_ASSERT(pn->isKind(TOK_FOR));
LOCAL_ASSERT(pn->isKind(PNK_FOR));
NodeVector blocks(cx);
ParseNode *next = pn;
while (next->isKind(TOK_FOR)) {
while (next->isKind(PNK_FOR)) {
Value block;
if (!comprehensionBlock(next, &block) || !blocks.append(block))
return false;
@ -2333,17 +2333,17 @@ ASTSerializer::comprehension(ParseNode *pn, Value *dst)
Value filter = MagicValue(JS_SERIALIZE_NO_NODE);
if (next->isKind(TOK_IF)) {
if (next->isKind(PNK_IF)) {
if (!optExpression(next->pn_kid1, &filter))
return false;
next = next->pn_kid2;
} else if (next->isKind(TOK_LC) && next->pn_count == 0) {
} else if (next->isKind(PNK_LC) && next->pn_count == 0) {
/* FoldConstants optimized away the push. */
NodeVector empty(cx);
return builder.arrayExpression(empty, &pn->pn_pos, dst);
}
LOCAL_ASSERT(next->isKind(TOK_ARRAYPUSH));
LOCAL_ASSERT(next->isKind(PNK_ARRAYPUSH));
Value body;
@ -2354,12 +2354,12 @@ ASTSerializer::comprehension(ParseNode *pn, Value *dst)
bool
ASTSerializer::generatorExpression(ParseNode *pn, Value *dst)
{
LOCAL_ASSERT(pn->isKind(TOK_FOR));
LOCAL_ASSERT(pn->isKind(PNK_FOR));
NodeVector blocks(cx);
ParseNode *next = pn;
while (next->isKind(TOK_FOR)) {
while (next->isKind(PNK_FOR)) {
Value block;
if (!comprehensionBlock(next, &block) || !blocks.append(block))
return false;
@ -2368,14 +2368,14 @@ ASTSerializer::generatorExpression(ParseNode *pn, Value *dst)
Value filter = MagicValue(JS_SERIALIZE_NO_NODE);
if (next->isKind(TOK_IF)) {
if (next->isKind(PNK_IF)) {
if (!optExpression(next->pn_kid1, &filter))
return false;
next = next->pn_kid2;
}
LOCAL_ASSERT(next->isKind(TOK_SEMI) &&
next->pn_kid->isKind(TOK_YIELD) &&
LOCAL_ASSERT(next->isKind(PNK_SEMI) &&
next->pn_kid->isKind(PNK_YIELD) &&
next->pn_kid->pn_kid);
Value body;
@ -2389,17 +2389,17 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
{
JS_CHECK_RECURSION(cx, return false);
switch (pn->getKind()) {
case TOK_FUNCTION:
case PNK_FUNCTION:
return function(pn, AST_FUNC_EXPR, dst);
case TOK_COMMA:
case PNK_COMMA:
{
NodeVector exprs(cx);
return expressions(pn, exprs) &&
builder.sequenceExpression(exprs, &pn->pn_pos, dst);
}
case TOK_HOOK:
case PNK_HOOK:
{
Value test, cons, alt;
@ -2409,22 +2409,22 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.conditionalExpression(test, cons, alt, &pn->pn_pos, dst);
}
case TOK_OR:
case TOK_AND:
case PNK_OR:
case PNK_AND:
{
if (pn->isArity(PN_BINARY)) {
Value left, right;
return expression(pn->pn_left, &left) &&
expression(pn->pn_right, &right) &&
builder.logicalExpression(pn->isKind(TOK_OR), left, right, &pn->pn_pos, dst);
builder.logicalExpression(pn->isKind(PNK_OR), left, right, &pn->pn_pos, dst);
}
return leftAssociate(pn, dst);
}
case TOK_INC:
case TOK_DEC:
case PNK_INC:
case PNK_DEC:
{
bool incr = pn->isKind(TOK_INC);
bool incr = pn->isKind(PNK_INC);
bool prefix = pn->getOp() >= JSOP_INCNAME && pn->getOp() <= JSOP_DECELEM;
Value expr;
@ -2432,18 +2432,18 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.updateExpression(expr, incr, prefix, &pn->pn_pos, dst);
}
case TOK_ASSIGN:
case TOK_ADDASSIGN:
case TOK_SUBASSIGN:
case TOK_BITORASSIGN:
case TOK_BITXORASSIGN:
case TOK_BITANDASSIGN:
case TOK_LSHASSIGN:
case TOK_RSHASSIGN:
case TOK_URSHASSIGN:
case TOK_MULASSIGN:
case TOK_DIVASSIGN:
case TOK_MODASSIGN:
case PNK_ASSIGN:
case PNK_ADDASSIGN:
case PNK_SUBASSIGN:
case PNK_BITORASSIGN:
case PNK_BITXORASSIGN:
case PNK_BITANDASSIGN:
case PNK_LSHASSIGN:
case PNK_RSHASSIGN:
case PNK_URSHASSIGN:
case PNK_MULASSIGN:
case PNK_DIVASSIGN:
case PNK_MODASSIGN:
{
AssignmentOperator op = aop(pn->getOp());
LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT);
@ -2454,31 +2454,31 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.assignmentExpression(op, lhs, rhs, &pn->pn_pos, dst);
}
case TOK_PLUS:
case TOK_MINUS:
case PNK_PLUS:
case PNK_MINUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
/* FALL THROUGH */
case TOK_STRICTEQ:
case TOK_EQ:
case TOK_STRICTNE:
case TOK_NE:
case TOK_LT:
case TOK_LE:
case TOK_GT:
case TOK_GE:
case TOK_LSH:
case TOK_RSH:
case TOK_URSH:
case TOK_STAR:
case TOK_DIV:
case TOK_MOD:
case TOK_BITOR:
case TOK_BITXOR:
case TOK_BITAND:
case TOK_IN:
case TOK_INSTANCEOF:
case TOK_DBLDOT:
case PNK_STRICTEQ:
case PNK_EQ:
case PNK_STRICTNE:
case PNK_NE:
case PNK_LT:
case PNK_LE:
case PNK_GT:
case PNK_GE:
case PNK_LSH:
case PNK_RSH:
case PNK_URSH:
case PNK_STAR:
case PNK_DIV:
case PNK_MOD:
case PNK_BITOR:
case PNK_BITXOR:
case PNK_BITAND:
case PNK_IN:
case PNK_INSTANCEOF:
case PNK_DBLDOT:
if (pn->isArity(PN_BINARY)) {
BinaryOperator op = binop(pn->getKind(), pn->getOp());
LOCAL_ASSERT(op > BINOP_ERR && op < BINOP_LIMIT);
@ -2490,11 +2490,11 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
}
return leftAssociate(pn, dst);
case TOK_DELETE:
case TOK_TYPEOF:
case TOK_VOID:
case TOK_NOT:
case TOK_BITNOT:
case PNK_DELETE:
case PNK_TYPEOF:
case PNK_VOID:
case PNK_NOT:
case PNK_BITNOT:
unary_plusminus: {
UnaryOperator op = unop(pn->getKind(), pn->getOp());
LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT);
@ -2504,8 +2504,8 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.unaryExpression(op, expr, &pn->pn_pos, dst);
}
case TOK_NEW:
case TOK_LP:
case PNK_NEW:
case PNK_LP:
{
#ifdef JS_HAS_GENERATOR_EXPRS
if (pn->isGeneratorExpr())
@ -2529,12 +2529,12 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
args.infallibleAppend(arg);
}
return pn->isKind(TOK_NEW)
return pn->isKind(PNK_NEW)
? builder.newExpression(callee, args, &pn->pn_pos, dst)
: builder.callExpression(callee, args, &pn->pn_pos, dst);
}
case TOK_DOT:
case PNK_DOT:
{
Value expr, id;
return expression(pn->pn_expr, &expr) &&
@ -2542,7 +2542,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.memberExpression(false, expr, id, &pn->pn_pos, dst);
}
case TOK_LB:
case PNK_LB:
{
Value left, right;
return expression(pn->pn_left, &left) &&
@ -2550,14 +2550,14 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.memberExpression(true, left, right, &pn->pn_pos, dst);
}
case TOK_RB:
case PNK_RB:
{
NodeVector elts(cx);
if (!elts.reserve(pn->pn_count))
return false;
for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
if (next->isKind(TOK_COMMA)) {
if (next->isKind(PNK_COMMA)) {
elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
} else {
Value expr;
@ -2570,7 +2570,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
return builder.arrayExpression(elts, &pn->pn_pos, dst);
}
case TOK_RC:
case PNK_RC:
{
/* The parser notes any uninitialized properties by setting the PNX_DESTRUCT flag. */
if (pn->pn_xflags & PNX_DESTRUCT) {
@ -2591,45 +2591,45 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
return builder.objectExpression(elts, &pn->pn_pos, dst);
}
case TOK_NAME:
case PNK_NAME:
return identifier(pn, dst);
case TOK_THIS:
case PNK_THIS:
return builder.thisExpression(&pn->pn_pos, dst);
case TOK_STRING:
case TOK_REGEXP:
case TOK_NUMBER:
case TOK_TRUE:
case TOK_FALSE:
case TOK_NULL:
case PNK_STRING:
case PNK_REGEXP:
case PNK_NUMBER:
case PNK_TRUE:
case PNK_FALSE:
case PNK_NULL:
return literal(pn, dst);
case TOK_YIELD:
case PNK_YIELD:
{
Value arg;
return optExpression(pn->pn_kid, &arg) &&
builder.yieldExpression(arg, &pn->pn_pos, dst);
}
case TOK_DEFSHARP:
case PNK_DEFSHARP:
{
Value expr;
return expression(pn->pn_kid, &expr) &&
builder.graphExpression(pn->pn_num, expr, &pn->pn_pos, dst);
}
case TOK_USESHARP:
case PNK_USESHARP:
return builder.graphIndexExpression(pn->pn_num, &pn->pn_pos, dst);
case TOK_ARRAYCOMP:
case PNK_ARRAYCOMP:
/* NB: it's no longer the case that pn_count could be 2. */
LOCAL_ASSERT(pn->pn_count == 1);
LOCAL_ASSERT(pn->pn_head->isKind(TOK_LEXICALSCOPE));
LOCAL_ASSERT(pn->pn_head->isKind(PNK_LEXICALSCOPE));
return comprehension(pn->pn_head->pn_expr, dst);
case TOK_LEXICALSCOPE:
case PNK_LEXICALSCOPE:
{
pn = pn->pn_expr;
@ -2642,7 +2642,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
}
#ifdef JS_HAS_XML_SUPPORT
case TOK_ANYNAME:
case PNK_ANYNAME:
if (pn->isOp(JSOP_XMLNAME) ||
pn->isOp(JSOP_SETXMLNAME) ||
pn->isOp(JSOP_BINDXMLNAME))
@ -2651,7 +2651,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
}
return builder.xmlAnyName(&pn->pn_pos, dst);
case TOK_DBLCOLON:
case PNK_DBLCOLON:
{
if (pn->isOp(JSOP_XMLNAME) ||
pn->isOp(JSOP_SETXMLNAME) ||
@ -2680,7 +2680,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
return false;
}
if (pnleft->isKind(TOK_FUNCTION))
if (pnleft->isKind(PNK_FUNCTION))
return builder.xmlFunctionQualifiedIdentifier(right, computed, &pn->pn_pos, dst);
Value left;
@ -2688,7 +2688,7 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.xmlQualifiedIdentifier(left, right, computed, &pn->pn_pos, dst);
}
case TOK_AT:
case PNK_AT:
{
if (pn->isOp(JSOP_XMLNAME) ||
pn->isOp(JSOP_SETXMLNAME) ||
@ -2699,14 +2699,14 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
Value expr;
ParseNode *kid = pn->pn_kid;
bool computed = ((!kid->isKind(TOK_NAME) || !kid->isOp(JSOP_QNAMEPART)) &&
!kid->isKind(TOK_DBLCOLON) &&
!kid->isKind(TOK_ANYNAME));
bool computed = ((!kid->isKind(PNK_NAME) || !kid->isOp(JSOP_QNAMEPART)) &&
!kid->isKind(PNK_DBLCOLON) &&
!kid->isKind(PNK_ANYNAME));
return expression(kid, &expr) &&
builder.xmlAttributeSelector(expr, computed, &pn->pn_pos, dst);
}
case TOK_FILTER:
case PNK_FILTER:
{
Value left, right;
return expression(pn->pn_left, &left) &&
@ -2730,14 +2730,14 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
JS_CHECK_RECURSION(cx, return false);
switch (pn->getKind()) {
#ifdef JS_HAS_XML_SUPPORT
case TOK_LC:
case PNK_LC:
{
Value expr;
return expression(pn->pn_kid, &expr) &&
builder.xmlEscapeExpression(expr, &pn->pn_pos, dst);
}
case TOK_XMLELEM:
case PNK_XMLELEM:
{
NodeVector elts(cx);
if (!xmls(pn, elts))
@ -2745,7 +2745,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlElement(elts, &pn->pn_pos, dst);
}
case TOK_XMLLIST:
case PNK_XMLLIST:
{
NodeVector elts(cx);
if (!xmls(pn, elts))
@ -2753,7 +2753,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlList(elts, &pn->pn_pos, dst);
}
case TOK_XMLSTAGO:
case PNK_XMLSTAGO:
{
NodeVector elts(cx);
if (!xmls(pn, elts))
@ -2761,7 +2761,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlStartTag(elts, &pn->pn_pos, dst);
}
case TOK_XMLETAGO:
case PNK_XMLETAGO:
{
NodeVector elts(cx);
if (!xmls(pn, elts))
@ -2769,7 +2769,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlEndTag(elts, &pn->pn_pos, dst);
}
case TOK_XMLPTAGC:
case PNK_XMLPTAGC:
{
NodeVector elts(cx);
if (!xmls(pn, elts))
@ -2777,11 +2777,11 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
return builder.xmlPointTag(elts, &pn->pn_pos, dst);
}
case TOK_XMLTEXT:
case TOK_XMLSPACE:
case PNK_XMLTEXT:
case PNK_XMLSPACE:
return builder.xmlText(atomContents(pn->pn_atom), &pn->pn_pos, dst);
case TOK_XMLNAME:
case PNK_XMLNAME:
if (pn->isArity(PN_NULLARY))
return builder.xmlName(atomContents(pn->pn_atom), &pn->pn_pos, dst);
@ -2793,16 +2793,16 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
builder.xmlName(elts, &pn->pn_pos, dst);
}
case TOK_XMLATTR:
case PNK_XMLATTR:
return builder.xmlAttribute(atomContents(pn->pn_atom), &pn->pn_pos, dst);
case TOK_XMLCDATA:
case PNK_XMLCDATA:
return builder.xmlCdata(atomContents(pn->pn_atom), &pn->pn_pos, dst);
case TOK_XMLCOMMENT:
case PNK_XMLCOMMENT:
return builder.xmlComment(atomContents(pn->pn_atom), &pn->pn_pos, dst);
case TOK_XMLPI:
case PNK_XMLPI:
if (!pn->pn_pidata)
return builder.xmlPI(atomContents(pn->pn_pitarget), &pn->pn_pos, dst);
else
@ -2820,10 +2820,10 @@ ASTSerializer::xml(ParseNode *pn, Value *dst)
bool
ASTSerializer::propertyName(ParseNode *pn, Value *dst)
{
if (pn->isKind(TOK_NAME))
if (pn->isKind(PNK_NAME))
return identifier(pn, dst);
LOCAL_ASSERT(pn->isKind(TOK_STRING) || pn->isKind(TOK_NUMBER));
LOCAL_ASSERT(pn->isKind(PNK_STRING) || pn->isKind(PNK_NUMBER));
return literal(pn, dst);
}
@ -2860,11 +2860,11 @@ ASTSerializer::literal(ParseNode *pn, Value *dst)
{
Value val;
switch (pn->getKind()) {
case TOK_STRING:
case PNK_STRING:
val.setString(pn->pn_atom);
break;
case TOK_REGEXP:
case PNK_REGEXP:
{
JSObject *re1 = pn->pn_objbox ? pn->pn_objbox->object : NULL;
LOCAL_ASSERT(re1 && re1->isRegExp());
@ -2881,19 +2881,19 @@ ASTSerializer::literal(ParseNode *pn, Value *dst)
break;
}
case TOK_NUMBER:
case PNK_NUMBER:
val.setNumber(pn->pn_dval);
break;
case TOK_NULL:
case PNK_NULL:
val.setNull();
break;
case TOK_TRUE:
case PNK_TRUE:
val.setBoolean(true);
break;
case TOK_FALSE:
case PNK_FALSE:
val.setBoolean(false);
break;
@ -2907,14 +2907,14 @@ ASTSerializer::literal(ParseNode *pn, Value *dst)
bool
ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst)
{
JS_ASSERT(pn->isKind(TOK_RB));
JS_ASSERT(pn->isKind(PNK_RB));
NodeVector elts(cx);
if (!elts.reserve(pn->pn_count))
return false;
for (ParseNode *next = pn->pn_head; next; next = next->pn_next) {
if (next->isKind(TOK_COMMA)) {
if (next->isKind(PNK_COMMA)) {
elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE));
} else {
Value patt;
@ -2930,7 +2930,7 @@ ASTSerializer::arrayPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst)
bool
ASTSerializer::objectPattern(ParseNode *pn, VarDeclKind *pkind, Value *dst)
{
JS_ASSERT(pn->isKind(TOK_RC));
JS_ASSERT(pn->isKind(PNK_RC));
NodeVector elts(cx);
if (!elts.reserve(pn->pn_count))
@ -2957,13 +2957,13 @@ ASTSerializer::pattern(ParseNode *pn, VarDeclKind *pkind, Value *dst)
{
JS_CHECK_RECURSION(cx, return false);
switch (pn->getKind()) {
case TOK_RC:
case PNK_RC:
return objectPattern(pn, pkind, dst);
case TOK_RB:
case PNK_RB:
return arrayPattern(pn, pkind, dst);
case TOK_NAME:
case PNK_NAME:
if (pkind && (pn->pn_dflags & PND_CONST))
*pkind = VARDECL_CONST;
/* FALL THROUGH */
@ -3013,7 +3013,7 @@ ASTSerializer::function(ParseNode *pn, ASTType type, Value *dst)
NodeVector args(cx);
ParseNode *argsAndBody = pn->pn_body->isKind(TOK_UPVARS)
ParseNode *argsAndBody = pn->pn_body->isKind(PNK_UPVARS)
? pn->pn_body->pn_tree
: pn->pn_body;
@ -3029,7 +3029,7 @@ ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, Value *body)
ParseNode *pnbody;
/* Extract the args and body separately. */
if (pn->isKind(TOK_ARGSBODY)) {
if (pn->isKind(PNK_ARGSBODY)) {
pnargs = pn;
pnbody = pn->last();
} else {
@ -3042,30 +3042,30 @@ ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, Value *body)
/* Extract the destructuring assignments. */
if (pnbody->isArity(PN_LIST) && (pnbody->pn_xflags & PNX_DESTRUCT)) {
ParseNode *head = pnbody->pn_head;
LOCAL_ASSERT(head && head->isKind(TOK_SEMI));
LOCAL_ASSERT(head && head->isKind(PNK_SEMI));
pndestruct = head->pn_kid;
LOCAL_ASSERT(pndestruct && pndestruct->isKind(TOK_VAR));
LOCAL_ASSERT(pndestruct && pndestruct->isKind(PNK_VAR));
} else {
pndestruct = NULL;
}
/* Serialize the arguments and body. */
switch (pnbody->getKind()) {
case TOK_RETURN: /* expression closure, no destructured args */
case PNK_RETURN: /* expression closure, no destructured args */
return functionArgs(pn, pnargs, NULL, pnbody, args) &&
expression(pnbody->pn_kid, body);
case TOK_SEQ: /* expression closure with destructured args */
case PNK_SEQ: /* expression closure with destructured args */
{
ParseNode *pnstart = pnbody->pn_head->pn_next;
LOCAL_ASSERT(pnstart && pnstart->isKind(TOK_RETURN));
LOCAL_ASSERT(pnstart && pnstart->isKind(PNK_RETURN));
return functionArgs(pn, pnargs, pndestruct, pnbody, args) &&
expression(pnstart->pn_kid, body);
}
case TOK_LC: /* statement closure */
case PNK_LC: /* statement closure */
{
ParseNode *pnstart = (pnbody->pn_xflags & PNX_DESTRUCT)
? pnbody->pn_head->pn_next

Просмотреть файл

@ -1313,7 +1313,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
if (!js_EnterLocalRootScope(cx))
return NULL;
switch (pn->getKind()) {
case TOK_XMLELEM:
case PNK_XMLELEM:
length = inScopeNSes->length;
pn2 = pn->pn_head;
xml = ParseNodeToXML(parser, pn2, inScopeNSes, flags);
@ -1330,12 +1330,12 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
while ((pn2 = pn2->pn_next) != NULL) {
if (!pn2->pn_next) {
/* Don't append the end tag! */
JS_ASSERT(pn2->isKind(TOK_XMLETAGO));
JS_ASSERT(pn2->isKind(PNK_XMLETAGO));
break;
}
if ((flags & XSF_IGNORE_WHITESPACE) &&
n > 1 && pn2->isKind(TOK_XMLSPACE)) {
n > 1 && pn2->isKind(PNK_XMLSPACE)) {
--n;
continue;
}
@ -1370,7 +1370,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
XMLARRAY_TRUNCATE(cx, inScopeNSes, length);
break;
case TOK_XMLLIST:
case PNK_XMLLIST:
xml = js_NewXML(cx, JSXML_CLASS_LIST);
if (!xml)
goto fail;
@ -1386,7 +1386,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
* condition this on an XML.ignoreWhitespace setting when the list
* constructor is XMLList (note XML/XMLList unification hazard).
*/
if (pn2->isKind(TOK_XMLSPACE)) {
if (pn2->isKind(PNK_XMLSPACE)) {
--n;
continue;
}
@ -1408,11 +1408,11 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
xml->xml_kids.trim();
break;
case TOK_XMLSTAGO:
case TOK_XMLPTAGC:
case PNK_XMLSTAGO:
case PNK_XMLPTAGC:
length = inScopeNSes->length;
pn2 = pn->pn_head;
JS_ASSERT(pn2->isKind(TOK_XMLNAME));
JS_ASSERT(pn2->isKind(PNK_XMLNAME));
if (pn2->isArity(PN_LIST))
goto syntax;
@ -1429,7 +1429,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
size_t length;
const jschar *chars;
if (!pn2->isKind(TOK_XMLNAME) || !pn2->isArity(PN_NULLARY))
if (!pn2->isKind(PNK_XMLNAME) || !pn2->isArity(PN_NULLARY))
goto syntax;
/* Enforce "Well-formedness constraint: Unique Att Spec". */
@ -1449,7 +1449,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
JSAtom *atom = pn2->pn_atom;
pn2 = pn2->pn_next;
JS_ASSERT(pn2);
if (!pn2->isKind(TOK_XMLATTR))
if (!pn2->isKind(PNK_XMLATTR))
goto syntax;
chars = atom->chars();
@ -1546,7 +1546,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
pn2 = pn2->pn_next;
JS_ASSERT(pn2);
JS_ASSERT(pn2->isKind(TOK_XMLATTR));
JS_ASSERT(pn2->isKind(PNK_XMLATTR));
attr = js_NewXML(cx, JSXML_CLASS_ATTRIBUTE);
if (!attr)
@ -1559,22 +1559,22 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
}
/* Point tag closes its own namespace scope. */
if (pn->isKind(TOK_XMLPTAGC))
if (pn->isKind(PNK_XMLPTAGC))
XMLARRAY_TRUNCATE(cx, inScopeNSes, length);
break;
case TOK_XMLSPACE:
case TOK_XMLTEXT:
case TOK_XMLCDATA:
case TOK_XMLCOMMENT:
case TOK_XMLPI:
case PNK_XMLSPACE:
case PNK_XMLTEXT:
case PNK_XMLCDATA:
case PNK_XMLCOMMENT:
case PNK_XMLPI:
str = pn->pn_atom;
qn = NULL;
if (pn->isKind(TOK_XMLCOMMENT)) {
if (pn->isKind(PNK_XMLCOMMENT)) {
if (flags & XSF_IGNORE_COMMENTS)
goto skip_child;
xml_class = JSXML_CLASS_COMMENT;
} else if (pn->isKind(TOK_XMLPI)) {
} else if (pn->isKind(PNK_XMLPI)) {
if (IS_XML(str)) {
Value v = StringValue(str);
JSAutoByteString bytes;
@ -1603,7 +1603,7 @@ ParseNodeToXML(Parser *parser, ParseNode *pn, JSXMLArray *inScopeNSes, uintN fla
if (!xml)
goto fail;
xml->name = qn;
if (pn->isKind(TOK_XMLSPACE))
if (pn->isKind(PNK_XMLSPACE))
xml->xml_flags |= XMLF_WHITESPACE_TEXT;
xml->xml_value = str;
break;