This commit is contained in:
David Anderson 2010-03-11 11:41:14 -08:00
commit 05b6c5fc13
2 changed files with 233 additions and 167 deletions

View File

@ -495,6 +495,10 @@ RecycleFuncNameKids(JSParseNode *pn, JSTreeContext *tc)
}
}
/*
* Allocate a JSParseNode from tc's node freelist or, failing that, from cx's
* temporary arena.
*/
static JSParseNode *
NewOrRecycledNode(JSTreeContext *tc)
{
@ -569,24 +573,10 @@ NewOrRecycledNode(JSTreeContext *tc)
return pn;
}
static inline void
InitParseNode(JSParseNode *pn, JSTokenType type, JSOp op, JSParseNodeArity arity)
{
pn->pn_type = type;
pn->pn_op = op;
pn->pn_arity = arity;
pn->pn_parens = false;
JS_ASSERT(!pn->pn_used);
JS_ASSERT(!pn->pn_defn);
pn->pn_next = pn->pn_link = NULL;
}
/* used only by static create methods of subclasses */
/*
* Allocate a JSParseNode from tc's node freelist or, failing that, from cx's
* temporary arena.
*/
static JSParseNode *
NewParseNode(JSParseNodeArity arity, JSTreeContext *tc)
JSParseNode *
JSParseNode::create(JSParseNodeArity arity, JSTreeContext *tc)
{
JSParseNode *pn;
JSToken *tp;
@ -595,38 +585,14 @@ NewParseNode(JSParseNodeArity arity, JSTreeContext *tc)
if (!pn)
return NULL;
tp = &CURRENT_TOKEN(&tc->compiler->tokenStream);
InitParseNode(pn, tp->type, JSOP_NOP, arity);
pn->init(tp->type, JSOP_NOP, arity);
pn->pn_pos = tp->pos;
return pn;
}
static inline void
InitNameNodeCommon(JSParseNode *pn, JSTreeContext *tc)
{
pn->pn_expr = NULL;
pn->pn_cookie = FREE_UPVAR_COOKIE;
pn->pn_dflags = tc->atTopLevel() ? PND_TOPLEVEL : 0;
if (!tc->topStmt || tc->topStmt->type == STMT_BLOCK)
pn->pn_dflags |= PND_BLOCKCHILD;
pn->pn_blockid = tc->blockid();
}
static JSParseNode *
NewNameNode(JSContext *cx, JSAtom *atom, JSTreeContext *tc)
{
JSParseNode *pn;
pn = NewParseNode(PN_NAME, tc);
if (pn) {
pn->pn_atom = atom;
InitNameNodeCommon(pn, tc);
}
return pn;
}
static JSParseNode *
NewBinary(JSTokenType tt, JSOp op, JSParseNode *left, JSParseNode *right,
JSTreeContext *tc)
JSParseNode *
JSParseNode::newBinaryOrAppend(JSTokenType tt, JSOp op, JSParseNode *left, JSParseNode *right,
JSTreeContext *tc)
{
JSParseNode *pn, *pn1, *pn2;
@ -687,14 +653,42 @@ NewBinary(JSTokenType tt, JSOp op, JSParseNode *left, JSParseNode *right,
pn = NewOrRecycledNode(tc);
if (!pn)
return NULL;
InitParseNode(pn, tt, op, PN_BINARY);
pn->init(tt, op, PN_BINARY);
pn->pn_pos.begin = left->pn_pos.begin;
pn->pn_pos.end = right->pn_pos.end;
pn->pn_left = left;
pn->pn_right = right;
return pn;
return (BinaryNode *)pn;
}
namespace js {
inline void
NameNode::initCommon(JSTreeContext *tc)
{
pn_expr = NULL;
pn_cookie = FREE_UPVAR_COOKIE;
pn_dflags = tc->atTopLevel() ? PND_TOPLEVEL : 0;
if (!tc->topStmt || tc->topStmt->type == STMT_BLOCK)
pn_dflags |= PND_BLOCKCHILD;
pn_blockid = tc->blockid();
}
NameNode *
NameNode::create(JSAtom *atom, JSTreeContext *tc)
{
JSParseNode *pn;
pn = JSParseNode::create(PN_NAME, tc);
if (pn) {
pn->pn_atom = atom;
((NameNode *)pn)->initCommon(tc);
}
return (NameNode *)pn;
}
} /* namespace js */
#if JS_HAS_GETTER_SETTER
static JSTokenType
CheckGetterOrSetter(JSContext *cx, JSTokenStream *ts, JSTokenType tt)
@ -1260,8 +1254,7 @@ CheckStrictAssignment(JSContext *cx, JSTreeContext *tc, JSParseNode *lhs)
* pn is NULL.
*/
bool
CheckStrictBinding(JSContext *cx, JSTreeContext *tc, JSAtom *atom,
JSParseNode *pn)
CheckStrictBinding(JSContext *cx, JSTreeContext *tc, JSAtom *atom, JSParseNode *pn)
{
if (!tc->needStrictChecks())
return true;
@ -1359,7 +1352,7 @@ FunctionBody(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
if (CURRENT_TOKEN(ts).type == TOK_LC) {
pn = Statements(cx, ts, tc);
} else {
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (pn) {
pn->pn_kid = AssignExpr(cx, ts, tc);
if (!pn->pn_kid) {
@ -1405,8 +1398,7 @@ MakePlaceholder(JSParseNode *pn, JSTreeContext *tc)
if (!ale)
return NULL;
JSDefinition *dn = (JSDefinition *)
NewNameNode(tc->compiler->context, pn->pn_atom, tc);
JSDefinition *dn = (JSDefinition *)NameNode::create(pn->pn_atom, tc);
if (!dn)
return NULL;
@ -1588,7 +1580,7 @@ DefineArg(JSParseNode *pn, JSAtom *atom, uintN i, JSTreeContext *tc)
* but having TOK_NAME type and JSOP_NOP op. Insert it in a TOK_ARGSBODY
* list node returned via pn->pn_body.
*/
argpn = NewNameNode(tc->compiler->context, atom, tc);
argpn = NameNode::create(atom, tc);
if (!argpn)
return false;
JS_ASSERT(PN_TYPE(argpn) == TOK_NAME && PN_OP(argpn) == JSOP_NOP);
@ -1600,7 +1592,7 @@ DefineArg(JSParseNode *pn, JSAtom *atom, uintN i, JSTreeContext *tc)
argsbody = pn->pn_body;
if (!argsbody) {
argsbody = NewParseNode(PN_LIST, tc);
argsbody = ListNode::create(tc);
if (!argsbody)
return false;
argsbody->pn_type = TOK_ARGSBODY;
@ -1645,7 +1637,7 @@ JSCompiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *pr
/* FIXME: make Function format the source for a function definition. */
jsc.tokenStream.tokens[0].type = TOK_NAME;
JSParseNode *fn = NewParseNode(PN_FUNC, &funcg);
JSParseNode *fn = FunctionNode::create(&funcg);
if (fn) {
fn->pn_body = NULL;
fn->pn_cookie = FREE_UPVAR_COOKIE;
@ -2626,7 +2618,7 @@ LeaveFunction(JSParseNode *fn, JSTreeContext *funtc, JSTreeContext *tc,
if (funtc->lexdeps.count - foundCallee != 0) {
JSParseNode *body = fn->pn_body;
fn->pn_body = NewParseNode(PN_NAMESET, tc);
fn->pn_body = NameSetNode::create(tc);
if (!fn->pn_body)
return false;
@ -2663,7 +2655,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
#if JS_HAS_GETTER_SETTER
op = CURRENT_TOKEN(ts).t_op;
#endif
pn = NewParseNode(PN_FUNC, tc);
pn = FunctionNode::create(tc);
if (!pn)
return NULL;
pn->pn_body = NULL;
@ -2860,7 +2852,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
* anonymous positional parameter into the destructuring
* left-hand-side expression and accumulate it in list.
*/
rhs = NewNameNode(cx, cx->runtime->atomState.emptyAtom, &funtc);
rhs = NameNode::create(cx->runtime->atomState.emptyAtom, &funtc);
if (!rhs)
return NULL;
rhs->pn_type = TOK_NAME;
@ -2868,11 +2860,11 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
rhs->pn_cookie = MAKE_UPVAR_COOKIE(funtc.staticLevel, slot);
rhs->pn_dflags |= PND_BOUND;
item = NewBinary(TOK_ASSIGN, JSOP_NOP, lhs, rhs, &funtc);
item = JSParseNode::newBinaryOrAppend(TOK_ASSIGN, JSOP_NOP, lhs, rhs, &funtc);
if (!item)
return NULL;
if (!list) {
list = NewParseNode(PN_LIST, &funtc);
list = ListNode::create(&funtc);
if (!list)
return NULL;
list->pn_type = TOK_COMMA;
@ -2975,7 +2967,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (body->pn_arity != PN_LIST) {
JSParseNode *block;
block = NewParseNode(PN_LIST, tc);
block = ListNode::create(tc);
if (!block)
return NULL;
block->pn_type = TOK_SEQ;
@ -2985,7 +2977,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
body = block;
}
item = NewParseNode(PN_UNARY, tc);
item = UnaryNode::create(tc);
if (!item)
return NULL;
@ -3034,7 +3026,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
* Edition 3 would have it). Backward compatibility must trump all,
* unless JSOPTION_ANONFUNFIX is set.
*/
result = NewParseNode(PN_UNARY, tc);
result = UnaryNode::create(tc);
if (!result)
return NULL;
result->pn_type = TOK_SEMI;
@ -3135,7 +3127,7 @@ Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JS_CHECK_RECURSION(cx, return NULL);
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_LC;
@ -3444,7 +3436,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
JSParseNode *pnu = pn;
if (pn->pn_defn) {
pnu = NewNameNode(cx, atom, tc);
pnu = NameNode::create(atom, tc);
if (!pnu)
return JS_FALSE;
}
@ -3481,7 +3473,7 @@ BindVarOrConst(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
pn = ALE_DEFN(ale);
tc->lexdeps.rawRemove(tc->compiler, ale, hep);
} else {
JSParseNode *pn2 = NewNameNode(cx, atom, tc);
JSParseNode *pn2 = NameNode::create(atom, tc);
if (!pn2)
return JS_FALSE;
@ -4315,7 +4307,7 @@ ReturnOrYield(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
return NULL;
}
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
@ -4381,7 +4373,7 @@ PushLexicalScope(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JSObject *obj;
JSObjectBox *blockbox;
pn = NewParseNode(PN_NAME, tc);
pn = LexicalScopeNode::create(tc);
if (!pn)
return NULL;
@ -4416,7 +4408,7 @@ LetBlock(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSBool statement)
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LET);
/* Create the let binary node. */
pnlet = NewParseNode(PN_BINARY, tc);
pnlet = BinaryNode::create(tc);
if (!pnlet)
return NULL;
@ -4443,7 +4435,7 @@ LetBlock(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, JSBool statement)
* need to wrap the TOK_LET node in a TOK_SEMI node so that we pop
* the return value of the expression.
*/
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_SEMI;
@ -4522,7 +4514,7 @@ NewBindingNode(JSAtom *atom, JSTreeContext *tc, bool let = false)
}
/* Make a new node for this declarator name (or destructuring pattern). */
pn = NewNameNode(tc->compiler->context, atom, tc);
pn = NameNode::create(atom, tc);
if (!pn)
return NULL;
return pn;
@ -4638,7 +4630,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_IF:
/* An IF node has three kids: condition, then, and optional else. */
pn = NewParseNode(PN_TERNARY, tc);
pn = TernaryNode::create(tc);
if (!pn)
return NULL;
pn1 = Condition(cx, ts, tc);
@ -4672,7 +4664,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSParseNode *pn5, *saveBlock;
JSBool seenDefault = JS_FALSE;
pn = NewParseNode(PN_BINARY, tc);
pn = BinaryNode::create(tc);
if (!pn)
return NULL;
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH);
@ -4692,7 +4684,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1);
/* pn2 is a list of case nodes. The default case has pn_left == NULL */
pn2 = NewParseNode(PN_LIST, tc);
pn2 = ListNode::create(tc);
if (!pn2)
return NULL;
pn2->makeEmpty();
@ -4713,7 +4705,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
/* FALL THROUGH */
case TOK_CASE:
pn3 = NewParseNode(PN_BINARY, tc);
pn3 = BinaryNode::create(tc);
if (!pn3)
return NULL;
if (tt == TOK_CASE) {
@ -4739,7 +4731,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
}
MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
pn4 = NewParseNode(PN_LIST, tc);
pn4 = ListNode::create(tc);
if (!pn4)
return NULL;
pn4->pn_type = TOK_LC;
@ -4784,7 +4776,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
}
case TOK_WHILE:
pn = NewParseNode(PN_BINARY, tc);
pn = BinaryNode::create(tc);
if (!pn)
return NULL;
js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1);
@ -4801,7 +4793,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return pn;
case TOK_DO:
pn = NewParseNode(PN_BINARY, tc);
pn = BinaryNode::create(tc);
if (!pn)
return NULL;
js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1);
@ -4836,7 +4828,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#endif
/* A FOR node is binary, left is loop control and right is the body. */
pn = NewParseNode(PN_BINARY, tc);
pn = BinaryNode::create(tc);
if (!pn)
return NULL;
js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1);
@ -4972,7 +4964,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|| pn2->pn_type == TOK_ASSIGN
#endif
) {
pnseq = NewParseNode(PN_LIST, tc);
pnseq = ListNode::create(tc);
if (!pnseq)
return NULL;
pnseq->pn_type = TOK_SEQ;
@ -4984,7 +4976,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
* Hoist just the 'i' from 'for (let x = i in o)' to
* before the loop, glued together via pnseq.
*/
pn3 = NewParseNode(PN_UNARY, tc);
pn3 = UnaryNode::create(tc);
if (!pn3)
return NULL;
pn3->pn_type = TOK_SEMI;
@ -5030,7 +5022,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#endif
{
JS_ASSERT(pn2->pn_type == TOK_NAME);
pn1 = NewNameNode(cx, pn2->pn_atom, tc);
pn1 = NameNode::create(pn2->pn_atom, tc);
if (!pn1)
return NULL;
pn1->pn_type = TOK_NAME;
@ -5104,7 +5096,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
tc->topStmt = save;
#endif
pn2 = NewBinary(TOK_IN, JSOP_NOP, pn1, pn2, tc);
pn2 = JSParseNode::newBinaryOrAppend(TOK_IN, JSOP_NOP, pn1, pn2, tc);
if (!pn2)
return NULL;
pn->pn_left = pn2;
@ -5140,7 +5132,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
}
/* Build the FORHEAD node to use as the left kid of pn. */
pn4 = NewParseNode(PN_TERNARY, tc);
pn4 = TernaryNode::create(tc);
if (!pn4)
return NULL;
pn4->pn_type = TOK_FORHEAD;
@ -5203,7 +5195,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
*
* finally nodes are TOK_LC Statement lists.
*/
pn = NewParseNode(PN_TERNARY, tc);
pn = TernaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_op = JSOP_NOP;
@ -5220,7 +5212,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
catchList = NULL;
tt = js_GetToken(cx, ts);
if (tt == TOK_CATCH) {
catchList = NewParseNode(PN_LIST, tc);
catchList = ListNode::create(tc);
if (!catchList)
return NULL;
catchList->pn_type = TOK_RESERVED;
@ -5254,7 +5246,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
* where lhs is a name or a destructuring left-hand side.
* (the latter is legal only #ifdef JS_HAS_CATCH_GUARD)
*/
pn2 = NewParseNode(PN_TERNARY, tc);
pn2 = TernaryNode::create(tc);
if (!pn2)
return NULL;
pnblock->pn_expr = pn2;
@ -5349,7 +5341,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
}
case TOK_THROW:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
@ -5385,7 +5377,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL;
case TOK_BREAK:
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
if (!MatchLabel(cx, ts, pn))
@ -5418,7 +5410,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
break;
case TOK_CONTINUE:
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
if (!MatchLabel(cx, ts, pn))
@ -5476,7 +5468,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return NULL;
}
pn = NewParseNode(PN_BINARY, tc);
pn = BinaryNode::create(tc);
if (!pn)
return NULL;
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH);
@ -5606,7 +5598,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#endif
/* Create a new lexical scope node for these statements. */
pn1 = NewParseNode(PN_NAME, tc);
pn1 = LexicalScopeNode::create(tc);
if (!pn1)
return NULL;
@ -5662,7 +5654,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_EOL:
case TOK_SEMI:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_SEMI;
@ -5670,7 +5662,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#if JS_HAS_DEBUGGER_KEYWORD
case TOK_DEBUGGER:
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_DEBUGGER;
@ -5680,7 +5672,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
#if JS_HAS_XML_SUPPORT
case TOK_DEFAULT:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
if (!js_MatchToken(cx, ts, TOK_NAME) ||
@ -5757,7 +5749,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
return pn2;
}
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_SEMI;
@ -5846,7 +5838,7 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, bool inLetHead)
}
data.op = let ? JSOP_NOP : CURRENT_TOKEN(ts).t_op;
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
pn->pn_op = data.op;
@ -5904,7 +5896,7 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, bool inLetHead)
if (!init || !UndominateInitializers(pn2, init, tc))
return NULL;
pn2 = NewBinary(TOK_ASSIGN, JSOP_NOP, pn2, init, tc);
pn2 = JSParseNode::newBinaryOrAppend(TOK_ASSIGN, JSOP_NOP, pn2, init, tc);
if (!pn2)
return NULL;
pn->append(pn2);
@ -5999,7 +5991,7 @@ Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = AssignExpr(cx, ts, tc);
if (pn && js_MatchToken(cx, ts, TOK_COMMA)) {
pn2 = NewParseNode(PN_LIST, tc);
pn2 = ListNode::create(tc);
if (!pn2)
return NULL;
pn2->pn_pos.begin = pn->pn_pos.begin;
@ -6085,7 +6077,7 @@ AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
rhs = AssignExpr(cx, ts, tc);
if (!rhs || !CheckDestructuring(cx, NULL, pn, rhs, tc))
return NULL;
return NewBinary(TOK_ASSIGN, op, pn, rhs, tc);
return JSParseNode::newBinaryOrAppend(TOK_ASSIGN, op, pn, rhs, tc);
#endif
case TOK_LP:
if (!MakeSetCall(cx, pn, tc, JSMSG_BAD_LEFTSIDE_OF_ASS))
@ -6122,7 +6114,7 @@ AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
}
}
return NewBinary(TOK_ASSIGN, op, pn, rhs, tc);
return JSParseNode::newBinaryOrAppend(TOK_ASSIGN, op, pn, rhs, tc);
}
static JSParseNode *
@ -6134,7 +6126,7 @@ CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = OrExpr(cx, ts, tc);
if (pn && js_MatchToken(cx, ts, TOK_HOOK)) {
pn1 = pn;
pn = NewParseNode(PN_TERNARY, tc);
pn = TernaryNode::create(tc);
if (!pn)
return NULL;
/*
@ -6169,7 +6161,7 @@ OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = AndExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_OR))
pn = NewBinary(TOK_OR, JSOP_OR, pn, AndExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(TOK_OR, JSOP_OR, pn, AndExpr(cx, ts, tc), tc);
return pn;
}
@ -6180,7 +6172,7 @@ AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = BitOrExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_AND))
pn = NewBinary(TOK_AND, JSOP_AND, pn, BitOrExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(TOK_AND, JSOP_AND, pn, BitOrExpr(cx, ts, tc), tc);
return pn;
}
@ -6191,8 +6183,7 @@ BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = BitXorExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_BITOR)) {
pn = NewBinary(TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc),
tc);
pn = JSParseNode::newBinaryOrAppend(TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc), tc);
}
return pn;
}
@ -6204,8 +6195,8 @@ BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = BitAndExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) {
pn = NewBinary(TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
tc);
pn = JSParseNode::newBinaryOrAppend(TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc),
tc);
}
return pn;
}
@ -6217,7 +6208,7 @@ BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = EqExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_BITAND))
pn = NewBinary(TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc);
return pn;
}
@ -6230,7 +6221,7 @@ EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = RelExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_EQOP)) {
op = CURRENT_TOKEN(ts).t_op;
pn = NewBinary(TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc);
}
return pn;
}
@ -6260,7 +6251,7 @@ RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
js_MatchToken(cx, ts, TOK_INSTANCEOF))) {
tt = CURRENT_TOKEN(ts).type;
op = CURRENT_TOKEN(ts).t_op;
pn = NewBinary(tt, op, pn, ShiftExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(tt, op, pn, ShiftExpr(cx, ts, tc), tc);
}
/* Restore previous state of inForInit flag. */
tc->flags |= inForInitFlag;
@ -6277,7 +6268,7 @@ ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = AddExpr(cx, ts, tc);
while (pn && js_MatchToken(cx, ts, TOK_SHOP)) {
op = CURRENT_TOKEN(ts).t_op;
pn = NewBinary(TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc);
}
return pn;
}
@ -6295,7 +6286,7 @@ AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
js_MatchToken(cx, ts, TOK_MINUS))) {
tt = CURRENT_TOKEN(ts).type;
op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
pn = NewBinary(tt, op, pn, MulExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(tt, op, pn, MulExpr(cx, ts, tc), tc);
}
return pn;
}
@ -6313,7 +6304,7 @@ MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
js_MatchToken(cx, ts, TOK_DIVOP))) {
tt = CURRENT_TOKEN(ts).type;
op = CURRENT_TOKEN(ts).t_op;
pn = NewBinary(tt, op, pn, UnaryExpr(cx, ts, tc), tc);
pn = JSParseNode::newBinaryOrAppend(tt, op, pn, UnaryExpr(cx, ts, tc), tc);
}
return pn;
}
@ -6406,7 +6397,7 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_UNARYOP:
case TOK_PLUS:
case TOK_MINUS:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_UNARYOP; /* PLUS and MINUS are binary */
@ -6420,7 +6411,7 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
case TOK_INC:
case TOK_DEC:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn2 = MemberExpr(cx, ts, tc, JS_TRUE);
@ -6432,7 +6423,7 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
break;
case TOK_DELETE:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn2 = UnaryExpr(cx, ts, tc);
@ -6480,7 +6471,7 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
ts->flags &= ~TSF_OPERAND;
if (tt == TOK_INC || tt == TOK_DEC) {
(void) js_GetToken(cx, ts);
pn2 = NewParseNode(PN_UNARY, tc);
pn2 = UnaryNode::create(tc);
if (!pn2)
return NULL;
if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
@ -6674,8 +6665,7 @@ CompExprTransplanter::transplant(JSParseNode *pn)
if (dn->pn_pos >= root->pn_pos) {
tc->parent->lexdeps.remove(tc->compiler, atom);
} else {
JSDefinition *dn2 = (JSDefinition *)
NewNameNode(tc->compiler->context, dn->pn_atom, tc);
JSDefinition *dn2 = (JSDefinition *)NameNode::create(dn->pn_atom, tc);
if (!dn2)
return false;
@ -6793,7 +6783,7 @@ ComprehensionTail(JSParseNode *kid, uintN blockid, JSTreeContext *tc,
* index to count each block-local let-variable on the left-hand side
* of the IN.
*/
pn2 = NewParseNode(PN_BINARY, tc);
pn2 = BinaryNode::create(tc);
if (!pn2)
return NULL;
@ -6882,7 +6872,7 @@ ComprehensionTail(JSParseNode *kid, uintN blockid, JSTreeContext *tc,
default:;
}
pn2->pn_left = NewBinary(TOK_IN, JSOP_NOP, pn3, pn4, tc);
pn2->pn_left = JSParseNode::newBinaryOrAppend(TOK_IN, JSOP_NOP, pn3, pn4, tc);
if (!pn2->pn_left)
return NULL;
*pnp = pn2;
@ -6890,7 +6880,7 @@ ComprehensionTail(JSParseNode *kid, uintN blockid, JSTreeContext *tc,
} while (js_MatchToken(cx, ts, TOK_FOR));
if (js_MatchToken(cx, ts, TOK_IF)) {
pn2 = NewParseNode(PN_TERNARY, tc);
pn2 = TernaryNode::create(tc);
if (!pn2)
return NULL;
pn2->pn_kid1 = Condition(cx, ts, tc);
@ -6900,7 +6890,7 @@ ComprehensionTail(JSParseNode *kid, uintN blockid, JSTreeContext *tc,
pnp = &pn2->pn_kid2;
}
pn2 = NewParseNode(PN_UNARY, tc);
pn2 = UnaryNode::create(tc);
if (!pn2)
return NULL;
pn2->pn_type = type;
@ -6942,7 +6932,7 @@ GeneratorExpr(JSParseNode *pn, JSParseNode *kid, JSTreeContext *tc)
pn->pn_hidden = true;
/* Make a new node for the desugared generator function. */
JSParseNode *genfn = NewParseNode(PN_FUNC, tc);
JSParseNode *genfn = FunctionNode::create(tc);
if (!genfn)
return NULL;
genfn->pn_type = TOK_FUNCTION;
@ -6998,7 +6988,7 @@ GeneratorExpr(JSParseNode *pn, JSParseNode *kid, JSTreeContext *tc)
* Our result is a call expression that invokes the anonymous generator
* function object.
*/
JSParseNode *result = NewParseNode(PN_LIST, tc);
JSParseNode *result = ListNode::create(tc);
if (!result)
return NULL;
result->pn_type = TOK_LP;
@ -7039,7 +7029,7 @@ ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
#endif
#if JS_HAS_GENERATOR_EXPRS
if (js_MatchToken(cx, ts, TOK_FOR)) {
JSParseNode *pn = NewParseNode(PN_UNARY, tc);
JSParseNode *pn = UnaryNode::create(tc);
if (!pn)
return JS_FALSE;
argNode = GeneratorExpr(pn, argNode, tc);
@ -7095,7 +7085,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
tt = js_GetToken(cx, ts);
ts->flags &= ~TSF_OPERAND;
if (tt == TOK_NEW) {
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
pn2 = MemberExpr(cx, ts, tc, JS_FALSE);
@ -7137,7 +7127,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
while ((tt = js_GetToken(cx, ts)) > TOK_EOF) {
if (tt == TOK_DOT) {
pn2 = NewNameNode(cx, NULL, tc);
pn2 = NameNode::create(NULL, tc);
if (!pn2)
return NULL;
#if JS_HAS_XML_SUPPORT
@ -7185,7 +7175,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
#if JS_HAS_XML_SUPPORT
} else if (tt == TOK_DBLDOT) {
pn2 = NewParseNode(PN_BINARY, tc);
pn2 = BinaryNode::create(tc);
if (!pn2)
return NULL;
ts->flags |= TSF_OPERAND | TSF_KEYWORD_IS_NAME;
@ -7211,7 +7201,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
#endif
} else if (tt == TOK_LB) {
pn2 = NewParseNode(PN_BINARY, tc);
pn2 = BinaryNode::create(tc);
if (!pn2)
return NULL;
pn3 = Expr(cx, ts, tc);
@ -7250,7 +7240,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
pn2->pn_right = pn3;
} while (0);
} else if (allowCallSyntax && tt == TOK_LP) {
pn2 = NewParseNode(PN_LIST, tc);
pn2 = ListNode::create(tc);
if (!pn2)
return NULL;
pn2->pn_op = JSOP_CALL;
@ -7382,7 +7372,7 @@ PropertySelector(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
{
JSParseNode *pn;
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
if (pn->pn_type == TOK_STAR) {
@ -7407,7 +7397,7 @@ QualifiedSuffix(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
JSTokenType tt;
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_DBLCOLON);
pn2 = NewNameNode(cx, NULL, tc);
pn2 = NameNode::create(NULL, tc);
if (!pn2)
return NULL;
@ -7471,7 +7461,7 @@ AttributeIdentifier(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSTokenType tt;
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_AT);
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_op = JSOP_TOATTRNAME;
@ -7503,7 +7493,7 @@ XMLExpr(JSContext *cx, JSTokenStream *ts, JSBool inTag, JSTreeContext *tc)
uintN oldflag;
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_LC);
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
@ -7538,7 +7528,7 @@ XMLAtomNode(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
JSParseNode *pn;
JSToken *tp;
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
tp = &CURRENT_TOKEN(ts);
@ -7585,7 +7575,7 @@ XMLNameExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
pn = pn2;
} else {
if (!list) {
list = NewParseNode(PN_LIST, tc);
list = ListNode::create(tc);
if (!list)
return NULL;
list->pn_type = TOK_XMLNAME;
@ -7652,7 +7642,7 @@ XMLTagContent(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (!pn2)
return NULL;
if (!list) {
list = NewParseNode(PN_LIST, tc);
list = ListNode::create(tc);
if (!list)
return NULL;
list->pn_type = tagtype;
@ -7779,7 +7769,7 @@ XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JS_CHECK_RECURSION(cx, return NULL);
JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_XMLSTAGO);
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
@ -7828,7 +7818,7 @@ XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (!XML_FOLDABLE(pn2))
pn->pn_xflags |= PNX_CANTFOLD;
pn2 = pn;
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
}
@ -7876,7 +7866,7 @@ XMLElementOrList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
/* Make a TOK_XMLETAGO list with pn2 as its single child. */
JS_ASSERT(pn2->pn_type == TOK_XMLNAME || pn2->pn_type == TOK_LC);
list = NewParseNode(PN_LIST, tc);
list = ListNode::create(tc);
if (!list)
return NULL;
list->pn_type = TOK_XMLETAGO;
@ -8021,7 +8011,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
ts->flags |= TSF_KEYWORD_IS_NAME;
if (js_MatchToken(cx, ts, TOK_DBLCOLON)) {
ts->flags &= ~TSF_KEYWORD_IS_NAME;
pn2 = NewParseNode(PN_NULLARY, tc);
pn2 = NullaryNode::create(tc);
if (!pn2)
return NULL;
pn2->pn_type = TOK_FUNCTION;
@ -8042,7 +8032,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
JSBool matched;
jsuint index;
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_RB;
@ -8075,7 +8065,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
if (tt == TOK_COMMA) {
/* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */
js_MatchToken(cx, ts, TOK_COMMA);
pn2 = NewParseNode(PN_NULLARY, tc);
pn2 = NullaryNode::create(tc);
pn->pn_xflags |= PNX_HOLEY;
} else {
pn2 = AssignExpr(cx, ts, tc);
@ -8182,7 +8172,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
*/
JSAutoAtomList seen(tc->compiler);
pn = NewParseNode(PN_LIST, tc);
pn = ListNode::create(tc);
if (!pn)
return NULL;
pn->pn_type = TOK_RC;
@ -8197,7 +8187,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
ts->flags &= ~TSF_KEYWORD_IS_NAME;
switch (tt) {
case TOK_NUMBER:
pn3 = NewParseNode(PN_NULLARY, tc);
pn3 = NullaryNode::create(tc);
if (!pn3)
return NULL;
pn3->pn_dval = CURRENT_TOKEN(ts).t_dval;
@ -8225,7 +8215,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
goto property_name;
}
atom = CURRENT_TOKEN(ts).t_atom;
pn3 = NewNameNode(cx, atom, tc);
pn3 = NameNode::create(atom, tc);
if (!pn3)
return NULL;
@ -8233,14 +8223,14 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
CURRENT_TOKEN(ts).t_op = JSOP_NOP;
CURRENT_TOKEN(ts).type = TOK_FUNCTION;
pn2 = FunctionExpr(cx, ts, tc);
pn2 = NewBinary(TOK_COLON, op, pn3, pn2, tc);
pn2 = JSParseNode::newBinaryOrAppend(TOK_COLON, op, pn3, pn2, tc);
goto skip;
}
property_name:
#endif
case TOK_STRING:
atom = CURRENT_TOKEN(ts).t_atom;
pn3 = NewParseNode(PN_NULLARY, tc);
pn3 = NullaryNode::create(tc);
if (!pn3)
return NULL;
pn3->pn_atom = atom;
@ -8285,12 +8275,12 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
pnval = pn3;
if (pnval->pn_type == TOK_NAME) {
pnval->pn_arity = PN_NAME;
InitNameNodeCommon(pnval, tc);
((NameNode *)pnval)->initCommon(tc);
}
#endif
}
pn2 = NewBinary(TOK_COLON, op, pn3, pnval, tc);
pn2 = JSParseNode::newBinaryOrAppend(TOK_COLON, op, pn3, pnval, tc);
#if JS_HAS_GETTER_SETTER
skip:
#endif
@ -8361,7 +8351,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
#if JS_HAS_SHARP_VARS
case TOK_DEFSHARP:
pn = NewParseNode(PN_UNARY, tc);
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval;
@ -8387,7 +8377,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
case TOK_USESHARP:
/* Check for forward/dangling references at runtime, to allow eval. */
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
if (!tc->ensureSharpSlots())
@ -8439,7 +8429,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
case TOK_XMLCOMMENT:
case TOK_XMLPI:
#endif
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_atom = CURRENT_TOKEN(ts).t_atom;
@ -8452,7 +8442,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
break;
case TOK_NAME:
pn = NewNameNode(cx, CURRENT_TOKEN(ts).t_atom, tc);
pn = NameNode::create(CURRENT_TOKEN(ts).t_atom, tc);
if (!pn)
return NULL;
JS_ASSERT(CURRENT_TOKEN(ts).t_op == JSOP_NAME);
@ -8589,7 +8579,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
{
JSObject *obj;
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
@ -8613,7 +8603,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
}
case TOK_NUMBER:
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_op = JSOP_DOUBLE;
@ -8621,7 +8611,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
break;
case TOK_PRIMARY:
pn = NewParseNode(PN_NULLARY, tc);
pn = NullaryNode::create(tc);
if (!pn)
return NULL;
pn->pn_op = CURRENT_TOKEN(ts).t_op;
@ -8670,7 +8660,7 @@ ParenExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
return NULL;
}
if (!pn1) {
pn1 = NewParseNode(PN_UNARY, tc);
pn1 = UnaryNode::create(tc);
if (!pn1)
return NULL;
}

View File

@ -386,6 +386,23 @@ struct JSParseNode {
#define pn_dval pn_u.dval
#define pn_atom2 pn_u.apair.atom2
protected:
void inline init(JSTokenType type, JSOp op, JSParseNodeArity arity) {
pn_type = type;
pn_op = op;
pn_arity = arity;
pn_parens = false;
JS_ASSERT(!pn_used);
JS_ASSERT(!pn_defn);
pn_next = pn_link = NULL;
}
static JSParseNode *create(JSParseNodeArity arity, JSTreeContext *tc);
public:
static JSParseNode *newBinaryOrAppend(JSTokenType tt, JSOp op, JSParseNode *left,
JSParseNode *right, JSTreeContext *tc);
/*
* The pn_expr and lexdef members are arms of an unsafe union. Unless you
* know exactly what you're doing, use only the following methods to access
@ -505,6 +522,7 @@ struct JSParseNode {
JS_ASSERT(isDirectivePrologueMember());
JSParseNode *kid = pn_kid;
JSString *str = ATOM_TO_STRING(kid->pn_atom);
/*
* Directives must contain no EscapeSequences or LineContinuations.
* If the string's length in the source code is its length as a value,
@ -550,6 +568,64 @@ struct JSParseNode {
}
};
namespace js {
struct NullaryNode : public JSParseNode {
static inline NullaryNode *create(JSTreeContext *tc) {
return (NullaryNode *)JSParseNode::create(PN_NULLARY, tc);
}
};
struct UnaryNode : public JSParseNode {
static inline UnaryNode *create(JSTreeContext *tc) {
return (UnaryNode *)JSParseNode::create(PN_UNARY, tc);
}
};
struct BinaryNode : public JSParseNode {
static inline BinaryNode *create(JSTreeContext *tc) {
return (BinaryNode *)JSParseNode::create(PN_BINARY, tc);
}
};
struct TernaryNode : public JSParseNode {
static inline TernaryNode *create(JSTreeContext *tc) {
return (TernaryNode *)JSParseNode::create(PN_TERNARY, tc);
}
};
struct ListNode : public JSParseNode {
static inline ListNode *create(JSTreeContext *tc) {
return (ListNode *)JSParseNode::create(PN_LIST, tc);
}
};
struct FunctionNode : public JSParseNode {
static inline FunctionNode *create(JSTreeContext *tc) {
return (FunctionNode *)JSParseNode::create(PN_FUNC, tc);
}
};
struct NameNode : public JSParseNode {
static NameNode *create(JSAtom *atom, JSTreeContext *tc);
void inline initCommon(JSTreeContext *tc);
};
struct NameSetNode : public JSParseNode {
static inline NameSetNode *create(JSTreeContext *tc) {
return (NameSetNode *)JSParseNode::create(PN_NAMESET, tc);
}
};
struct LexicalScopeNode : public JSParseNode {
static inline LexicalScopeNode *create(JSTreeContext *tc) {
return (LexicalScopeNode *)JSParseNode::create(PN_NAME, tc);
}
};
} /* namespace js */
/*
* JSDefinition is a degenerate subtype of the PN_FUNC and PN_NAME variants of
* JSParseNode, allocated only for function, var, const, and let declarations