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; goto out;
#if JS_HAS_XML_SUPPORT #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; onlyXML = false;
#endif #endif
bce.freeTree(pn); bce.freeTree(pn);
@ -403,8 +403,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
return false; return false;
/* FIXME: make Function format the source for a function definition. */ /* FIXME: make Function format the source for a function definition. */
tokenStream.mungeCurrentToken(TOK_NAME); ParseNode *fn = FunctionNode::create(PNK_NAME, &funbce);
ParseNode *fn = FunctionNode::create(&funbce);
if (fn) { if (fn) {
fn->pn_body = NULL; fn->pn_body = NULL;
fn->pn_cookie.makeFree(); fn->pn_cookie.makeFree();
@ -451,7 +450,7 @@ frontend::CompileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
pn = NULL; pn = NULL;
} else { } else {
if (fn->pn_body) { 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->append(pn);
fn->pn_body->pn_pos = pn->pn_pos; fn->pn_body->pn_pos = pn->pn_pos;
pn = fn->pn_body; pn = fn->pn_body;

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

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

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

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

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

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

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

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

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

@ -141,6 +141,12 @@ struct Parser : private AutoGCRooter
return allocator.allocNode(); 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: public:
ParseNode *freeTree(ParseNode *pn) { return allocator.freeTree(pn); } ParseNode *freeTree(ParseNode *pn) { return allocator.freeTree(pn); }
void prepareNodeForMutation(ParseNode *pn) { return allocator.prepareNodeForMutation(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 *functionDef(PropertyName *name, FunctionType type, FunctionSyntaxKind kind);
ParseNode *unaryOpExpr(ParseNodeKind kind, JSOp op);
ParseNode *condition(); ParseNode *condition();
ParseNode *comprehensionTail(ParseNode *kid, uintN blockid, bool isGenexp, 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); ParseNode *generatorExpr(ParseNode *kid);
JSBool argumentList(ParseNode *listNode); JSBool argumentList(ParseNode *listNode);
ParseNode *bracketedExpr(); ParseNode *bracketedExpr();
@ -236,9 +244,8 @@ struct Parser : private AutoGCRooter
ParseNode *qualifiedIdentifier(); ParseNode *qualifiedIdentifier();
ParseNode *attributeIdentifier(); ParseNode *attributeIdentifier();
ParseNode *xmlExpr(JSBool inTag); ParseNode *xmlExpr(JSBool inTag);
ParseNode *xmlAtomNode();
ParseNode *xmlNameExpr(); ParseNode *xmlNameExpr();
ParseNode *xmlTagContent(TokenKind tagtype, JSAtom **namep); ParseNode *xmlTagContent(ParseNodeKind tagkind, JSAtom **namep);
JSBool xmlElementContent(ParseNode *pn); JSBool xmlElementContent(ParseNode *pn);
ParseNode *xmlElementOrList(JSBool allowList); ParseNode *xmlElementOrList(JSBool allowList);
ParseNode *xmlElementOrListRoot(JSBool allowList); ParseNode *xmlElementOrListRoot(JSBool allowList);

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

@ -194,7 +194,7 @@ FindFunArgs(FunctionBox *funbox, int level, FunctionBoxQueue *queue)
uintN skipmin = UpvarCookie::FREE_LEVEL; uintN skipmin = UpvarCookie::FREE_LEVEL;
ParseNode *pn = fn->pn_body; ParseNode *pn = fn->pn_body;
if (pn->isKind(TOK_UPVARS)) { if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr &upvars = pn->pn_names; AtomDefnMapPtr &upvars = pn->pn_names;
JS_ASSERT(upvars->count() != 0); JS_ASSERT(upvars->count() != 0);
@ -273,7 +273,7 @@ MarkFunArgs(JSContext *cx, FunctionBox *funbox, uint32 functionCount)
JS_ASSERT(fn->isFunArg()); JS_ASSERT(fn->isFunArg());
ParseNode *pn = fn->pn_body; ParseNode *pn = fn->pn_body;
if (pn->isKind(TOK_UPVARS)) { if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names; AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty()); JS_ASSERT(!upvars->empty());
@ -528,11 +528,11 @@ ConsiderUnbranding(FunctionBox *funbox)
#if JS_HAS_EXPR_CLOSURES #if JS_HAS_EXPR_CLOSURES
{ {
ParseNode *pn2 = funbox->node->pn_body; ParseNode *pn2 = funbox->node->pn_body;
if (pn2->isKind(TOK_UPVARS)) if (pn2->isKind(PNK_UPVARS))
pn2 = pn2->pn_tree; pn2 = pn2->pn_tree;
if (pn2->isKind(TOK_ARGSBODY)) if (pn2->isKind(PNK_ARGSBODY))
pn2 = pn2->last(); pn2 = pn2->last();
if (!pn2->isKind(TOK_LC)) if (!pn2->isKind(PNK_LC))
returnsExpr = true; returnsExpr = true;
} }
#endif #endif
@ -585,7 +585,7 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
bool hasUpvars = false; bool hasUpvars = false;
bool canFlatten = true; bool canFlatten = true;
if (pn->isKind(TOK_UPVARS)) { if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names; AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty()); JS_ASSERT(!upvars->empty());
@ -630,13 +630,13 @@ SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
fn->setOp(JSOP_LAMBDA_FC); fn->setOp(JSOP_LAMBDA_FC);
break; break;
default: 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)); 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 * One or more upvars cannot be safely snapshot into a flat
* closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop * 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_XMLELEM: return "TOK_XMLELEM";
case TOK_XMLLIST: return "TOK_XMLLIST"; case TOK_XMLLIST: return "TOK_XMLLIST";
case TOK_YIELD: return "TOK_YIELD"; 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_LEXICALSCOPE: return "TOK_LEXICALSCOPE";
case TOK_LET: return "TOK_LET"; 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_RESERVED: return "TOK_RESERVED";
case TOK_STRICT_RESERVED: return "TOK_STRICT_RESERVED"; case TOK_STRICT_RESERVED: return "TOK_STRICT_RESERVED";
case TOK_STRICTEQ: return "TOK_STRICTEQ"; case TOK_STRICTEQ: return "TOK_STRICTEQ";

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

@ -136,17 +136,8 @@ enum TokenKind {
TOK_XMLELEM, /* XML element node type (no token) */ TOK_XMLELEM, /* XML element node type (no token) */
TOK_XMLLIST, /* XML list node type (no token) */ TOK_XMLLIST, /* XML list node type (no token) */
TOK_YIELD, /* yield from generator function */ 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_LEXICALSCOPE, /* block scope AST node label */
TOK_LET, /* let keyword */ 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_RESERVED, /* reserved keywords */
TOK_STRICT_RESERVED, /* reserved keywords in strict mode */ TOK_STRICT_RESERVED, /* reserved keywords in strict mode */
@ -163,13 +154,11 @@ enum TokenKind {
TOK_NE, TOK_NE,
TOK_EQUALITY_LAST = TOK_NE, TOK_EQUALITY_LAST = TOK_NE,
/* Unary operation tokens, per TokenKindIsUnaryOp */ /* Unary operation tokens */
TOK_TYPEOF, TOK_TYPEOF,
TOK_UNARYOP_START = TOK_TYPEOF,
TOK_VOID, TOK_VOID,
TOK_NOT, TOK_NOT,
TOK_BITNOT, TOK_BITNOT,
TOK_UNARYOP_LAST = TOK_BITNOT,
/* Relational ops (< <= > >=), per TokenKindIsRelational */ /* Relational ops (< <= > >=), per TokenKindIsRelational */
TOK_LT, TOK_LT,
@ -202,7 +191,6 @@ enum TokenKind {
TOK_MODASSIGN, TOK_MODASSIGN,
TOK_ASSIGNMENT_LAST = TOK_MODASSIGN, TOK_ASSIGNMENT_LAST = TOK_MODASSIGN,
TOK_LIMIT /* domain size */ TOK_LIMIT /* domain size */
}; };
@ -212,12 +200,6 @@ TokenKindIsEquality(TokenKind tt)
return TOK_EQUALITY_START <= tt && tt <= TOK_EQUALITY_LAST; 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 inline bool
TokenKindIsXML(TokenKind tt) TokenKindIsXML(TokenKind tt)
{ {
@ -242,13 +224,6 @@ TokenKindIsAssignment(TokenKind tt)
return TOK_ASSIGNMENT_START <= tt && tt <= TOK_ASSIGNMENT_LAST; 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 inline bool
TokenKindIsDecl(TokenKind tt) TokenKindIsDecl(TokenKind tt)
{ {
@ -542,10 +517,6 @@ class TokenStream
return TokenKindIsEquality(currentToken().type); return TokenKindIsEquality(currentToken().type);
} }
bool isCurrentTokenUnaryOp() const {
return TokenKindIsUnaryOp(currentToken().type);
}
bool isCurrentTokenRelational() const { bool isCurrentTokenRelational() const {
return TokenKindIsRelational(currentToken().type); return TokenKindIsRelational(currentToken().type);
} }

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

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

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

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