mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 713755 - Convert all |a.<stuff>| parsing to use constructors that don't examine the token stream. r=jorendorff
--HG-- extra : rebase_source : c64a37e810c201df6fa2e5124f115ecc9c2e9b43
This commit is contained in:
parent
be9a24ff19
commit
35a64c3f7e
@ -1215,6 +1215,85 @@ class BooleanLiteral : public ParseNode {
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PropertyAccess : public ParseNode {
|
||||||
|
public:
|
||||||
|
PropertyAccess(ParseNode *lhs, PropertyName *name,
|
||||||
|
const TokenPtr &begin, const TokenPtr &end)
|
||||||
|
: ParseNode(PNK_DOT, JSOP_GETPROP, PN_NAME, TokenPos::make(begin, end))
|
||||||
|
{
|
||||||
|
JS_ASSERT(lhs != NULL);
|
||||||
|
JS_ASSERT(name != NULL);
|
||||||
|
pn_u.name.expr = lhs;
|
||||||
|
pn_u.name.atom = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &expression() const {
|
||||||
|
return *pn_u.name.expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyName &name() const {
|
||||||
|
return *pn_u.name.atom->asPropertyName();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XMLDoubleColonProperty : public ParseNode {
|
||||||
|
public:
|
||||||
|
XMLDoubleColonProperty(ParseNode *lhs, ParseNode *rhs,
|
||||||
|
const TokenPtr &begin, const TokenPtr &end)
|
||||||
|
: ParseNode(PNK_LB, JSOP_GETELEM, PN_BINARY, TokenPos::make(begin, end))
|
||||||
|
{
|
||||||
|
JS_ASSERT(rhs->isKind(PNK_DBLCOLON));
|
||||||
|
pn_u.binary.left = lhs;
|
||||||
|
pn_u.binary.right = rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &left() const {
|
||||||
|
return *pn_u.binary.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &right() const {
|
||||||
|
return *pn_u.binary.right;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XMLFilterExpression : public ParseNode {
|
||||||
|
public:
|
||||||
|
XMLFilterExpression(ParseNode *lhs, ParseNode *filterExpr,
|
||||||
|
const TokenPtr &begin, const TokenPtr &end)
|
||||||
|
: ParseNode(PNK_FILTER, JSOP_FILTER, PN_BINARY, TokenPos::make(begin, end))
|
||||||
|
{
|
||||||
|
pn_u.binary.left = lhs;
|
||||||
|
pn_u.binary.right = filterExpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &left() const {
|
||||||
|
return *pn_u.binary.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &filter() const {
|
||||||
|
return *pn_u.binary.right;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class XMLProperty : public ParseNode {
|
||||||
|
public:
|
||||||
|
XMLProperty(ParseNode *lhs, ParseNode *propertyId,
|
||||||
|
const TokenPtr &begin, const TokenPtr &end)
|
||||||
|
: ParseNode(PNK_LB, JSOP_GETELEM, PN_BINARY, TokenPos::make(begin, end))
|
||||||
|
{
|
||||||
|
pn_u.binary.left = lhs;
|
||||||
|
pn_u.binary.right = propertyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &left() const {
|
||||||
|
return *pn_u.binary.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode &right() const {
|
||||||
|
return *pn_u.binary.right;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ParseNode *
|
ParseNode *
|
||||||
CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
|
CloneLeftHandSide(ParseNode *opn, TreeContext *tc);
|
||||||
|
|
||||||
|
@ -5732,39 +5732,36 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((tt = tokenStream.getToken()) > TOK_EOF) {
|
while ((tt = tokenStream.getToken()) > TOK_EOF) {
|
||||||
ParseNode *pn2;
|
ParseNode *nextMember;
|
||||||
if (tt == TOK_DOT) {
|
if (tt == TOK_DOT) {
|
||||||
pn2 = NameNode::create(PNK_DOT, NULL, tc);
|
|
||||||
if (!pn2)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
tt = tokenStream.getToken(TSF_KEYWORD_IS_NAME);
|
tt = tokenStream.getToken(TSF_KEYWORD_IS_NAME);
|
||||||
if (tt == TOK_ERROR)
|
if (tt == TOK_ERROR)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (tt == TOK_NAME) {
|
if (tt == TOK_NAME) {
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
if (!tc->inStrictMode() && tokenStream.peekToken() == TOK_DBLCOLON) {
|
if (!tc->inStrictMode() && tokenStream.peekToken() == TOK_DBLCOLON) {
|
||||||
ParseNode *pn3 = propertyQualifiedIdentifier();
|
ParseNode *propertyId = propertyQualifiedIdentifier();
|
||||||
if (!pn3)
|
if (!propertyId)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
JS_ASSERT(pn3->isKind(PNK_DBLCOLON));
|
nextMember = new_<XMLDoubleColonProperty>(lhs, propertyId,
|
||||||
pn2->setKind(PNK_LB);
|
lhs->pn_pos.begin,
|
||||||
pn2->setOp(JSOP_GETELEM);
|
tokenStream.currentToken().pos.end);
|
||||||
pn2->setArity(PN_BINARY);
|
if (!nextMember)
|
||||||
pn2->pn_left = lhs;
|
return NULL;
|
||||||
pn2->pn_right = pn3;
|
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
pn2->setOp(JSOP_GETPROP);
|
nextMember = new_<PropertyAccess>(lhs, tokenStream.currentToken().name(),
|
||||||
pn2->pn_expr = lhs;
|
lhs->pn_pos.begin,
|
||||||
pn2->pn_atom = tokenStream.currentToken().name();
|
tokenStream.currentToken().pos.end);
|
||||||
|
if (!nextMember)
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
else if (!tc->inStrictMode()) {
|
else if (!tc->inStrictMode()) {
|
||||||
ParseNode *pn3;
|
TokenPtr begin = lhs->pn_pos.begin;
|
||||||
if (tt == TOK_LP) {
|
if (tt == TOK_LP) {
|
||||||
/* Filters are effectively 'with', so deoptimize names. */
|
/* Filters are effectively 'with', so deoptimize names. */
|
||||||
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
||||||
@ -5774,40 +5771,38 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||||||
tc->innermostWith = lhs;
|
tc->innermostWith = lhs;
|
||||||
PushStatement(tc, &stmtInfo, STMT_WITH, -1);
|
PushStatement(tc, &stmtInfo, STMT_WITH, -1);
|
||||||
|
|
||||||
pn3 = bracketedExpr();
|
ParseNode *filter = bracketedExpr();
|
||||||
if (!pn3)
|
if (!filter)
|
||||||
return NULL;
|
return NULL;
|
||||||
pn3->setInParens(true);
|
filter->setInParens(true);
|
||||||
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
|
MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN);
|
||||||
|
|
||||||
tc->innermostWith = oldWith;
|
tc->innermostWith = oldWith;
|
||||||
PopStatement(tc);
|
PopStatement(tc);
|
||||||
|
|
||||||
pn2->setKind(PNK_FILTER);
|
nextMember =
|
||||||
pn2->setOp(JSOP_FILTER);
|
new_<XMLFilterExpression>(lhs, filter,
|
||||||
} else if (tt == TOK_AT || tt == TOK_STAR) {
|
begin, tokenStream.currentToken().pos.end);
|
||||||
pn3 = starOrAtPropertyIdentifier(tt);
|
if (!nextMember)
|
||||||
if (!pn3)
|
return NULL;
|
||||||
|
} else if (tt == TOK_AT || tt == TOK_STAR) {
|
||||||
|
ParseNode *propertyId = starOrAtPropertyIdentifier(tt);
|
||||||
|
if (!propertyId)
|
||||||
|
return NULL;
|
||||||
|
nextMember = new_<XMLProperty>(lhs, propertyId,
|
||||||
|
begin, tokenStream.currentToken().pos.end);
|
||||||
|
if (!nextMember)
|
||||||
return NULL;
|
return NULL;
|
||||||
pn2->setKind(PNK_LB);
|
|
||||||
pn2->setOp(JSOP_GETELEM);
|
|
||||||
} else {
|
} else {
|
||||||
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn2->setArity(PN_BINARY);
|
|
||||||
pn2->pn_left = lhs;
|
|
||||||
pn2->pn_right = pn3;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn2->pn_pos.begin = lhs->pn_pos.begin;
|
|
||||||
pn2->pn_pos.end = tokenStream.currentToken().pos.end;
|
|
||||||
#if JS_HAS_XML_SUPPORT
|
#if JS_HAS_XML_SUPPORT
|
||||||
} else if (tt == TOK_DBLDOT) {
|
} else if (tt == TOK_DBLDOT) {
|
||||||
if (tc->inStrictMode()) {
|
if (tc->inStrictMode()) {
|
||||||
@ -5815,8 +5810,8 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pn2 = BinaryNode::create(PNK_DBLDOT, tc);
|
nextMember = BinaryNode::create(PNK_DBLDOT, tc);
|
||||||
if (!pn2)
|
if (!nextMember)
|
||||||
return NULL;
|
return NULL;
|
||||||
tt = tokenStream.getToken(TSF_OPERAND | TSF_KEYWORD_IS_NAME);
|
tt = tokenStream.getToken(TSF_OPERAND | TSF_KEYWORD_IS_NAME);
|
||||||
ParseNode *pn3 = primaryExpr(tt, JS_TRUE);
|
ParseNode *pn3 = primaryExpr(tt, JS_TRUE);
|
||||||
@ -5830,62 +5825,62 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||||||
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
reportErrorNumber(NULL, JSREPORT_ERROR, JSMSG_NAME_AFTER_DOT);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pn2->setOp(JSOP_DESCENDANTS);
|
nextMember->setOp(JSOP_DESCENDANTS);
|
||||||
pn2->pn_left = lhs;
|
nextMember->pn_left = lhs;
|
||||||
pn2->pn_right = pn3;
|
nextMember->pn_right = pn3;
|
||||||
pn2->pn_pos.begin = lhs->pn_pos.begin;
|
nextMember->pn_pos.begin = lhs->pn_pos.begin;
|
||||||
pn2->pn_pos.end = tokenStream.currentToken().pos.end;
|
nextMember->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||||
#endif
|
#endif
|
||||||
} else if (tt == TOK_LB) {
|
} else if (tt == TOK_LB) {
|
||||||
pn2 = BinaryNode::create(PNK_LB, tc);
|
nextMember = BinaryNode::create(PNK_LB, tc);
|
||||||
if (!pn2)
|
if (!nextMember)
|
||||||
return NULL;
|
return NULL;
|
||||||
ParseNode *pn3 = expr();
|
ParseNode *pn3 = expr();
|
||||||
if (!pn3)
|
if (!pn3)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
|
MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX);
|
||||||
pn2->pn_pos.begin = lhs->pn_pos.begin;
|
nextMember->pn_pos.begin = lhs->pn_pos.begin;
|
||||||
pn2->pn_pos.end = tokenStream.currentToken().pos.end;
|
nextMember->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optimize o['p'] to o.p by rewriting pn2, but avoid rewriting
|
* Optimize o['p'] to o.p by rewriting nextMember, but don't
|
||||||
* o['0'] to use JSOP_GETPROP, to keep fast indexing disjoint in
|
* rewrite o['0'] to use JSOP_GETPROP, to keep fast indexing
|
||||||
* the interpreter from fast property access. However, if the
|
* disjoint in the interpreter from fast property access. However,
|
||||||
* bracketed string is a uint32, we rewrite pn3 to be a number
|
* if the bracketed string is a uint32_t, we rewrite pn3 to be a
|
||||||
* instead of a string.
|
* number instead of a string.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
if (pn3->isKind(PNK_STRING)) {
|
if (pn3->isKind(PNK_STRING)) {
|
||||||
jsuint index;
|
jsuint index;
|
||||||
|
|
||||||
if (!js_IdIsIndex(ATOM_TO_JSID(pn3->pn_atom), &index)) {
|
if (!js_IdIsIndex(ATOM_TO_JSID(pn3->pn_atom), &index)) {
|
||||||
pn2->setKind(PNK_DOT);
|
nextMember->setKind(PNK_DOT);
|
||||||
pn2->setOp(JSOP_GETPROP);
|
nextMember->setOp(JSOP_GETPROP);
|
||||||
pn2->setArity(PN_NAME);
|
nextMember->setArity(PN_NAME);
|
||||||
pn2->pn_expr = lhs;
|
nextMember->pn_expr = lhs;
|
||||||
pn2->pn_atom = pn3->pn_atom;
|
nextMember->pn_atom = pn3->pn_atom;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pn3->setKind(PNK_NUMBER);
|
pn3->setKind(PNK_NUMBER);
|
||||||
pn3->setOp(JSOP_DOUBLE);
|
pn3->setOp(JSOP_DOUBLE);
|
||||||
pn3->pn_dval = index;
|
pn3->pn_dval = index;
|
||||||
}
|
}
|
||||||
pn2->setOp(JSOP_GETELEM);
|
nextMember->setOp(JSOP_GETELEM);
|
||||||
pn2->pn_left = lhs;
|
nextMember->pn_left = lhs;
|
||||||
pn2->pn_right = pn3;
|
nextMember->pn_right = pn3;
|
||||||
} while (0);
|
} while (0);
|
||||||
} else if (allowCallSyntax && tt == TOK_LP) {
|
} else if (allowCallSyntax && tt == TOK_LP) {
|
||||||
pn2 = ListNode::create(PNK_LP, tc);
|
nextMember = ListNode::create(PNK_LP, tc);
|
||||||
if (!pn2)
|
if (!nextMember)
|
||||||
return NULL;
|
return NULL;
|
||||||
pn2->setOp(JSOP_CALL);
|
nextMember->setOp(JSOP_CALL);
|
||||||
|
|
||||||
lhs = CheckForImmediatelyAppliedLambda(lhs);
|
lhs = CheckForImmediatelyAppliedLambda(lhs);
|
||||||
if (lhs->isOp(JSOP_NAME)) {
|
if (lhs->isOp(JSOP_NAME)) {
|
||||||
if (lhs->pn_atom == context->runtime->atomState.evalAtom) {
|
if (lhs->pn_atom == context->runtime->atomState.evalAtom) {
|
||||||
/* Select JSOP_EVAL and flag tc as heavyweight. */
|
/* Select JSOP_EVAL and flag tc as heavyweight. */
|
||||||
pn2->setOp(JSOP_EVAL);
|
nextMember->setOp(JSOP_EVAL);
|
||||||
tc->noteCallsEval();
|
tc->noteCallsEval();
|
||||||
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
tc->flags |= TCF_FUN_HEAVYWEIGHT;
|
||||||
/*
|
/*
|
||||||
@ -5898,28 +5893,28 @@ Parser::memberExpr(JSBool allowCallSyntax)
|
|||||||
} else if (lhs->isOp(JSOP_GETPROP)) {
|
} else if (lhs->isOp(JSOP_GETPROP)) {
|
||||||
/* Select JSOP_FUNAPPLY given foo.apply(...). */
|
/* Select JSOP_FUNAPPLY given foo.apply(...). */
|
||||||
if (lhs->pn_atom == context->runtime->atomState.applyAtom)
|
if (lhs->pn_atom == context->runtime->atomState.applyAtom)
|
||||||
pn2->setOp(JSOP_FUNAPPLY);
|
nextMember->setOp(JSOP_FUNAPPLY);
|
||||||
else if (lhs->pn_atom == context->runtime->atomState.callAtom)
|
else if (lhs->pn_atom == context->runtime->atomState.callAtom)
|
||||||
pn2->setOp(JSOP_FUNCALL);
|
nextMember->setOp(JSOP_FUNCALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
pn2->initList(lhs);
|
nextMember->initList(lhs);
|
||||||
pn2->pn_pos.begin = lhs->pn_pos.begin;
|
nextMember->pn_pos.begin = lhs->pn_pos.begin;
|
||||||
|
|
||||||
if (!argumentList(pn2))
|
if (!argumentList(nextMember))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (pn2->pn_count > ARGC_LIMIT) {
|
if (nextMember->pn_count > ARGC_LIMIT) {
|
||||||
JS_ReportErrorNumber(context, js_GetErrorMessage, NULL,
|
JS_ReportErrorNumber(context, js_GetErrorMessage, NULL,
|
||||||
JSMSG_TOO_MANY_FUN_ARGS);
|
JSMSG_TOO_MANY_FUN_ARGS);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pn2->pn_pos.end = tokenStream.currentToken().pos.end;
|
nextMember->pn_pos.end = tokenStream.currentToken().pos.end;
|
||||||
} else {
|
} else {
|
||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = pn2;
|
lhs = nextMember;
|
||||||
}
|
}
|
||||||
if (tt == TOK_ERROR)
|
if (tt == TOK_ERROR)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user