diff --git a/js/src/jsparse.cpp b/js/src/jsparse.cpp index 4f279295dad..88c9b26380f 100644 --- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -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; @@ -1282,7 +1275,7 @@ CheckStrictBinding(JSContext *cx, JSTreeContext *tc, JSAtom *atom, * formals are legit given fun's strictness level, return true. Otherwise, * report an error and return false. Use pn for error position reporting, * unless we can find something more accurate in tc's decls. - * + * * In some cases the code to parse the argument list will already have noticed * the duplication; we could try to use that knowledge instead of re-checking * here. But since the strictness of the function's body determines what @@ -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; @@ -2028,7 +2020,7 @@ JSCompiler::markFunArgs(JSFunctionBox *funbox, uintN tcflags) * funarg if it is immediately applied. However, if its * name is used in an escaping function nested within * it, then it must become flagged as a funarg again. - * See bug 545980. + * See bug 545980. */ afunbox = funbox; uintN calleeLevel = UPVAR_FRAME_SKIP(lexdep->pn_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; @@ -2889,7 +2881,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, if (!DefineArg(pn, atom, fun->nargs, &funtc)) return NULL; #ifdef JS_HAS_DESTRUCTURING - /* + /* * ECMA-262 requires us to support duplicate parameter names, but if the * parameter list includes destructuring, we consider the code to have * opted in to higher standards, and forbid duplicates. We may see a @@ -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 @@ -8302,7 +8292,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, * In strict mode code, check for duplicate property names. Treat * getters and setters as distinct attributes of each property. A * plain old value conflicts with a getter or a setter. - */ + */ if (tc->needStrictChecks()) { unsigned attributesMask; if (op == JSOP_INITPROP) { @@ -8333,7 +8323,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, return NULL; ALE_SET_INDEX(ale, attributesMask); } - } + } tt = js_GetToken(cx, ts); if (tt == TOK_RC) @@ -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; } diff --git a/js/src/jsparse.h b/js/src/jsparse.h index 11fb854bcdb..793641d480d 100644 --- a/js/src/jsparse.h +++ b/js/src/jsparse.h @@ -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 @@ -481,7 +498,7 @@ struct JSParseNode { (PN_TYPE(this) == TOK_PRIMARY && PN_OP(this) != JSOP_THIS); } - /* + /* * True if this statement node could be a member of a Directive * Prologue. Note that the prologue may contain strings that * cannot themselves be directives; that's a stricter test. @@ -505,7 +522,8 @@ 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, * accounting for the quotes, then it qualifies. @@ -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