mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 695752 - Part 2 - Add Parser::new_ methods for creatinng parse nodes. r=luke.
--HG-- extra : rebase_source : 9978265f81e72929f55a78da55250a431c64c041
This commit is contained in:
parent
30b9012a13
commit
b90a714b55
@ -59,6 +59,8 @@ JS_STATIC_ASSERT(pn_offsetof(pn_link) == pn_offsetof(dn_uses));
|
||||
|
||||
#undef pn_offsetof
|
||||
|
||||
namespace js {
|
||||
|
||||
void
|
||||
ParseNode::become(ParseNode *pn2)
|
||||
{
|
||||
@ -111,7 +113,6 @@ ParseNode::clear()
|
||||
pn_parens = false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
FunctionBox::joinable() const
|
||||
{
|
||||
@ -151,8 +152,6 @@ FunctionBox::shouldUnbrand(uintN methods, uintN slowMethods) const
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/* Add |node| to |parser|'s free node list. */
|
||||
void
|
||||
AddNodeToFreeList(ParseNode *pn, Parser *parser)
|
||||
@ -215,8 +214,6 @@ class NodeStack {
|
||||
ParseNode *top;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/*
|
||||
* Push the children of |pn| on |stack|. Return true if |pn| itself could be
|
||||
* safely recycled, or false if it must be cleaned later (pn_used and pn_defn
|
||||
@ -299,8 +296,6 @@ PushNodeChildren(ParseNode *pn, NodeStack *stack)
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Prepare |pn| to be mutated in place into a new kind of node. Recycle all
|
||||
* |pn|'s recyclable children (but not |pn| itself!), and disconnect it from
|
||||
@ -374,33 +369,24 @@ RecycleTree(ParseNode *pn, TreeContext *tc)
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a ParseNode from tc's node freelist or, failing that, from
|
||||
* Allocate a ParseNode from parser's node freelist or, failing that, from
|
||||
* cx's temporary arena.
|
||||
*/
|
||||
ParseNode *
|
||||
NewOrRecycledNode(TreeContext *tc)
|
||||
void *
|
||||
AllocNodeUninitialized(Parser *parser)
|
||||
{
|
||||
ParseNode *pn = tc->parser->nodeList;
|
||||
if (!pn) {
|
||||
JSContext *cx = tc->parser->context;
|
||||
pn = (ParseNode *) cx->tempLifoAlloc().alloc(sizeof (ParseNode));
|
||||
if (!pn)
|
||||
js_ReportOutOfMemory(cx);
|
||||
} else {
|
||||
tc->parser->nodeList = pn->pn_next;
|
||||
if (ParseNode *pn = parser->nodeList) {
|
||||
parser->nodeList = pn->pn_next;
|
||||
return pn;
|
||||
}
|
||||
|
||||
if (pn) {
|
||||
pn->setUsed(false);
|
||||
pn->setDefn(false);
|
||||
memset(&pn->pn_u, 0, sizeof pn->pn_u);
|
||||
pn->pn_next = NULL;
|
||||
}
|
||||
return pn;
|
||||
JSContext *cx = parser->context;
|
||||
void *p = cx->tempLifoAlloc().alloc(sizeof (ParseNode));
|
||||
if (!p)
|
||||
js_ReportOutOfMemory(cx);
|
||||
return p;
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
/* used only by static create methods of subclasses */
|
||||
|
||||
ParseNode *
|
||||
@ -414,12 +400,10 @@ ParseNode *
|
||||
ParseNode::create(ParseNodeArity arity, TokenKind type, JSOp op, const TokenPos &pos,
|
||||
TreeContext *tc)
|
||||
{
|
||||
ParseNode *pn = NewOrRecycledNode(tc);
|
||||
if (!pn)
|
||||
void *p = AllocNodeUninitialized(tc->parser);
|
||||
if (!p)
|
||||
return NULL;
|
||||
pn->init(type, op, arity);
|
||||
pn->pn_pos = pos;
|
||||
return pn;
|
||||
return new(p) ParseNode(type, op, arity, pos);
|
||||
}
|
||||
|
||||
ParseNode *
|
||||
@ -481,19 +465,9 @@ ParseNode::newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *
|
||||
return left;
|
||||
}
|
||||
|
||||
ParseNode *pn = NewOrRecycledNode(tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
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 tc->parser->new_<BinaryNode>(tt, op, left, right);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
NameNode *
|
||||
NameNode::create(JSAtom *atom, TreeContext *tc)
|
||||
{
|
||||
@ -511,6 +485,8 @@ const char js_argument_str[] = "argument";
|
||||
const char js_variable_str[] = "variable";
|
||||
const char js_unknown_str[] = "unknown";
|
||||
|
||||
namespace js {
|
||||
|
||||
const char *
|
||||
Definition::kindString(Kind kind)
|
||||
{
|
||||
@ -534,16 +510,13 @@ CloneParseTree(ParseNode *opn, TreeContext *tc)
|
||||
{
|
||||
JS_CHECK_RECURSION(tc->parser->context, return NULL);
|
||||
|
||||
ParseNode *pn = NewOrRecycledNode(tc);
|
||||
ParseNode *pn = tc->parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
|
||||
opn->pn_pos);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
pn->setKind(opn->getKind());
|
||||
pn->setOp(opn->getOp());
|
||||
pn->setUsed(opn->isUsed());
|
||||
pn->setDefn(opn->isDefn());
|
||||
pn->setArity(opn->getArity());
|
||||
pn->setInParens(opn->isInParens());
|
||||
pn->pn_pos = opn->pn_pos;
|
||||
pn->setDefn(opn->isDefn());
|
||||
pn->setUsed(opn->isUsed());
|
||||
|
||||
switch (pn->getArity()) {
|
||||
#define NULLCHECK(e) JS_BEGIN_MACRO if (!(e)) return NULL; JS_END_MACRO
|
||||
@ -632,8 +605,6 @@ CloneParseTree(ParseNode *opn, TreeContext *tc)
|
||||
|
||||
#endif /* JS_HAS_DESTRUCTURING */
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Used by Parser::forStatement and comprehensionTail to clone the TARGET in
|
||||
* for (var/const/let TARGET in EXPR)
|
||||
@ -647,16 +618,13 @@ namespace js {
|
||||
ParseNode *
|
||||
CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
|
||||
{
|
||||
ParseNode *pn = NewOrRecycledNode(tc);
|
||||
ParseNode *pn = tc->parser->new_<ParseNode>(opn->getKind(), opn->getOp(), opn->getArity(),
|
||||
opn->pn_pos);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
pn->setKind(opn->getKind());
|
||||
pn->setOp(opn->getOp());
|
||||
pn->setUsed(opn->isUsed());
|
||||
pn->setDefn(opn->isDefn());
|
||||
pn->setArity(opn->getArity());
|
||||
pn->setInParens(opn->isInParens());
|
||||
pn->pn_pos = opn->pn_pos;
|
||||
pn->setDefn(opn->isDefn());
|
||||
pn->setUsed(opn->isUsed());
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
if (opn->isArity(PN_LIST)) {
|
||||
@ -674,7 +642,8 @@ CloneLeftHandSide(ParseNode *opn, TreeContext *tc)
|
||||
ParseNode *target = CloneLeftHandSide(opn2->pn_right, tc);
|
||||
if (!target)
|
||||
return NULL;
|
||||
pn2 = BinaryNode::create(TOK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target, tc);
|
||||
|
||||
pn2 = tc->parser->new_<BinaryNode>(TOK_COLON, JSOP_INITPROP, opn2->pn_pos, tag, target);
|
||||
} else if (opn2->isArity(PN_NULLARY)) {
|
||||
JS_ASSERT(opn2->isKind(TOK_COMMA));
|
||||
pn2 = CloneParseTree(opn2, tc);
|
||||
|
@ -346,10 +346,10 @@ struct ParseNode {
|
||||
/* Boolean attributes. */
|
||||
bool isInParens() const { return pn_parens; }
|
||||
void setInParens(bool enabled) { pn_parens = enabled; }
|
||||
bool isDefn() const { return pn_defn; }
|
||||
void setDefn(bool enabled) { pn_defn = enabled; }
|
||||
bool isUsed() const { return pn_used; }
|
||||
void setUsed(bool enabled) { pn_used = enabled; }
|
||||
bool isDefn() const { return pn_defn; }
|
||||
void setDefn(bool enabled) { pn_defn = enabled; }
|
||||
|
||||
TokenPos pn_pos; /* two 16-bit pairs here, for 64 bits */
|
||||
int32 pn_offset; /* first generated bytecode offset */
|
||||
@ -698,21 +698,30 @@ struct NullaryNode : public ParseNode {
|
||||
};
|
||||
|
||||
struct UnaryNode : public ParseNode {
|
||||
UnaryNode(TokenKind type, JSOp op, const TokenPos &pos, ParseNode *kid)
|
||||
: ParseNode(type, op, PN_UNARY, pos)
|
||||
{
|
||||
pn_kid = kid;
|
||||
}
|
||||
|
||||
static inline UnaryNode *create(TreeContext *tc) {
|
||||
return (UnaryNode *)ParseNode::create(PN_UNARY, tc);
|
||||
}
|
||||
};
|
||||
|
||||
struct BinaryNode : public ParseNode {
|
||||
static inline BinaryNode *create(TokenKind type, JSOp op, const TokenPos &pos,
|
||||
ParseNode *left, ParseNode *right,
|
||||
TreeContext *tc) {
|
||||
BinaryNode *pn = (BinaryNode *) ParseNode::create(PN_BINARY, type, op, pos, tc);
|
||||
if (pn) {
|
||||
pn->pn_left = left;
|
||||
pn->pn_right = right;
|
||||
}
|
||||
return pn;
|
||||
BinaryNode(TokenKind type, JSOp op, const TokenPos &pos, ParseNode *left, ParseNode *right)
|
||||
: ParseNode(type, op, PN_BINARY, pos)
|
||||
{
|
||||
pn_left = left;
|
||||
pn_right = right;
|
||||
}
|
||||
|
||||
BinaryNode(TokenKind type, JSOp op, ParseNode *left, ParseNode *right)
|
||||
: ParseNode(type, op, PN_BINARY, TokenPos::box(left->pn_pos, right->pn_pos))
|
||||
{
|
||||
pn_left = left;
|
||||
pn_right = right;
|
||||
}
|
||||
|
||||
static inline BinaryNode *create(TreeContext *tc) {
|
||||
@ -721,19 +730,14 @@ struct BinaryNode : public ParseNode {
|
||||
};
|
||||
|
||||
struct TernaryNode : public ParseNode {
|
||||
static inline TernaryNode *create(TokenKind type, JSOp op,
|
||||
ParseNode *kid1, ParseNode *kid2, ParseNode *kid3,
|
||||
TreeContext *tc) {
|
||||
TokenPos pos;
|
||||
pos.begin = (kid1 ? kid1 : kid2)->pn_pos.begin;
|
||||
pos.end = kid3->pn_pos.end;
|
||||
TernaryNode *pn = (TernaryNode *) ParseNode::create(PN_TERNARY, type, op, pos, tc);
|
||||
if (pn) {
|
||||
pn->pn_kid1 = kid1;
|
||||
pn->pn_kid2 = kid2;
|
||||
pn->pn_kid3 = kid3;
|
||||
}
|
||||
return pn;
|
||||
TernaryNode(TokenKind type, JSOp op, ParseNode *kid1, ParseNode *kid2, ParseNode *kid3)
|
||||
: ParseNode(type, op, PN_TERNARY,
|
||||
TokenPos((kid1 ? kid1 : kid2 ? kid2 : kid3)->pn_pos.begin,
|
||||
(kid3 ? kid3 : kid2 ? kid2 : kid1)->pn_pos.end))
|
||||
{
|
||||
pn_kid1 = kid1;
|
||||
pn_kid2 = kid2;
|
||||
pn_kid3 = kid3;
|
||||
}
|
||||
|
||||
static inline TernaryNode *create(TreeContext *tc) {
|
||||
@ -771,8 +775,8 @@ struct LexicalScopeNode : public ParseNode {
|
||||
}
|
||||
};
|
||||
|
||||
ParseNode *
|
||||
NewOrRecycledNode(TreeContext *tc);
|
||||
void *
|
||||
AllocNodeUninitialized(Parser *parser);
|
||||
|
||||
void
|
||||
AddNodeToFreeList(ParseNode *pn, Parser *parser);
|
||||
|
@ -788,10 +788,9 @@ ForgetUse(ParseNode *pn)
|
||||
static ParseNode *
|
||||
MakeAssignment(ParseNode *pn, ParseNode *rhs, TreeContext *tc)
|
||||
{
|
||||
ParseNode *lhs = NewOrRecycledNode(tc);
|
||||
ParseNode *lhs = tc->parser->new_<ParseNode>(*pn);
|
||||
if (!lhs)
|
||||
return NULL;
|
||||
*lhs = *pn;
|
||||
|
||||
if (pn->isUsed()) {
|
||||
Definition *dn = pn->pn_lexdef;
|
||||
@ -5977,7 +5976,7 @@ Parser::comprehensionTail(ParseNode *kid, uintN blockid, bool isGenexp,
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
|
||||
pn2->pn_left = TernaryNode::create(TOK_IN, JSOP_NOP, vars, pn3, pn4, tc);
|
||||
pn2->pn_left = new_<TernaryNode>(TOK_IN, JSOP_NOP, vars, pn3, pn4);
|
||||
if (!pn2->pn_left)
|
||||
return NULL;
|
||||
*pnp = pn2;
|
||||
@ -6218,16 +6217,9 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
||||
return NULL;
|
||||
|
||||
if (pn->isKind(TOK_ANYNAME) || pn->isKind(TOK_AT) || pn->isKind(TOK_DBLCOLON)) {
|
||||
pn2 = NewOrRecycledNode(tc);
|
||||
if (!pn2)
|
||||
pn = new_<UnaryNode>(TOK_UNARYOP, JSOP_XMLNAME, pn->pn_pos, pn);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
pn2->setKind(TOK_UNARYOP);
|
||||
pn2->pn_pos = pn->pn_pos;
|
||||
pn2->setOp(JSOP_XMLNAME);
|
||||
pn2->setArity(PN_UNARY);
|
||||
pn2->setInParens(false);
|
||||
pn2->pn_kid = pn;
|
||||
pn = pn2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,15 @@ struct Parser : private AutoGCRooter
|
||||
*/
|
||||
inline bool reportErrorNumber(ParseNode *pn, uintN flags, uintN errorNumber, ...);
|
||||
|
||||
private:
|
||||
void *allocParseNode(size_t size) {
|
||||
JS_ASSERT(size == sizeof(ParseNode));
|
||||
return AllocNodeUninitialized(this);
|
||||
}
|
||||
|
||||
public:
|
||||
JS_DECLARE_NEW_METHODS(allocParseNode,);
|
||||
|
||||
private:
|
||||
/*
|
||||
* JS parsers, from lowest to highest precedence.
|
||||
|
@ -179,29 +179,29 @@ struct TokenPtr {
|
||||
uint32 index; /* index of char in physical line */
|
||||
uint32 lineno; /* physical line number */
|
||||
|
||||
bool operator==(const TokenPtr& bptr) {
|
||||
bool operator==(const TokenPtr& bptr) const {
|
||||
return index == bptr.index && lineno == bptr.lineno;
|
||||
}
|
||||
|
||||
bool operator!=(const TokenPtr& bptr) {
|
||||
bool operator!=(const TokenPtr& bptr) const {
|
||||
return index != bptr.index || lineno != bptr.lineno;
|
||||
}
|
||||
|
||||
bool operator <(const TokenPtr& bptr) {
|
||||
bool operator <(const TokenPtr& bptr) const {
|
||||
return lineno < bptr.lineno ||
|
||||
(lineno == bptr.lineno && index < bptr.index);
|
||||
}
|
||||
|
||||
bool operator <=(const TokenPtr& bptr) {
|
||||
bool operator <=(const TokenPtr& bptr) const {
|
||||
return lineno < bptr.lineno ||
|
||||
(lineno == bptr.lineno && index <= bptr.index);
|
||||
}
|
||||
|
||||
bool operator >(const TokenPtr& bptr) {
|
||||
bool operator >(const TokenPtr& bptr) const {
|
||||
return !(*this <= bptr);
|
||||
}
|
||||
|
||||
bool operator >=(const TokenPtr& bptr) {
|
||||
bool operator >=(const TokenPtr& bptr) const {
|
||||
return !(*this < bptr);
|
||||
}
|
||||
};
|
||||
@ -210,27 +210,41 @@ struct TokenPos {
|
||||
TokenPtr begin; /* first character and line of token */
|
||||
TokenPtr end; /* index 1 past last char, last line */
|
||||
|
||||
bool operator==(const TokenPos& bpos) {
|
||||
TokenPos() {}
|
||||
|
||||
TokenPos(const TokenPtr &begin, const TokenPtr &end) : begin(begin), end(end) {
|
||||
JS_ASSERT(begin <= end);
|
||||
}
|
||||
|
||||
/* Return a TokenPos that covers left, right, and anything in between. */
|
||||
static TokenPos box(const TokenPos &left, const TokenPos &right) {
|
||||
JS_ASSERT(left.begin <= left.end);
|
||||
JS_ASSERT(left.end <= right.begin);
|
||||
JS_ASSERT(right.begin <= right.end);
|
||||
return TokenPos(left.begin, right.end);
|
||||
}
|
||||
|
||||
bool operator==(const TokenPos& bpos) const {
|
||||
return begin == bpos.begin && end == bpos.end;
|
||||
}
|
||||
|
||||
bool operator!=(const TokenPos& bpos) {
|
||||
bool operator!=(const TokenPos& bpos) const {
|
||||
return begin != bpos.begin || end != bpos.end;
|
||||
}
|
||||
|
||||
bool operator <(const TokenPos& bpos) {
|
||||
bool operator <(const TokenPos& bpos) const {
|
||||
return begin < bpos.begin;
|
||||
}
|
||||
|
||||
bool operator <=(const TokenPos& bpos) {
|
||||
bool operator <=(const TokenPos& bpos) const {
|
||||
return begin <= bpos.begin;
|
||||
}
|
||||
|
||||
bool operator >(const TokenPos& bpos) {
|
||||
bool operator >(const TokenPos& bpos) const {
|
||||
return !(*this <= bpos);
|
||||
}
|
||||
|
||||
bool operator >=(const TokenPos& bpos) {
|
||||
bool operator >=(const TokenPos& bpos) const {
|
||||
return !(*this < bpos);
|
||||
}
|
||||
};
|
||||
|
@ -2297,7 +2297,7 @@ ASTSerializer::leftAssociate(ParseNode *pn, Value *dst)
|
||||
if (!expression(next, &right))
|
||||
return false;
|
||||
|
||||
TokenPos subpos = { pn->pn_pos.begin, next->pn_pos.end };
|
||||
TokenPos subpos(pn->pn_pos.begin, next->pn_pos.end);
|
||||
|
||||
if (logop) {
|
||||
if (!builder.logicalExpression(lor, left, right, &subpos, &left))
|
||||
|
Loading…
Reference in New Issue
Block a user