Backout rev 89551867dc2a for having the wrong bug number in the commit message (was bug 885762, should be bug 885761). Pointed out by Ms3ger. no_r=me.

--HG--
extra : rebase_source : 2171490306c5559161f34e537f035c2c69e1fdd2
This commit is contained in:
Jason Orendorff 2013-07-10 16:36:58 -05:00
parent 935768b349
commit 4ec3630342
6 changed files with 204 additions and 119 deletions

View File

@ -3429,6 +3429,7 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
} }
MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL); MUST_MATCH_TOKEN(TOK_ASSIGN, JSMSG_BAD_DESTRUCT_DECL);
JS_ASSERT(tokenStream.currentToken().t_op == JSOP_NOP);
Node init = assignExpr(); Node init = assignExpr();
if (!init) if (!init)
@ -3460,6 +3461,8 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
handler.addList(pn, pn2); handler.addList(pn, pn2);
if (tokenStream.matchToken(TOK_ASSIGN)) { if (tokenStream.matchToken(TOK_ASSIGN)) {
JS_ASSERT(tokenStream.currentToken().t_op == JSOP_NOP);
if (psimple) if (psimple)
*psimple = false; *psimple = false;
@ -3947,7 +3950,7 @@ Parser<FullParseHandler>::forStatement()
pn2 = pn1; pn2 = pn1;
pn1 = NULL; pn1 = NULL;
if (!setAssignmentLhsOps(pn2, true)) if (!setAssignmentLhsOps(pn2, JSOP_NOP))
return null(); return null();
} }
@ -4172,7 +4175,7 @@ Parser<SyntaxParseHandler>::forStatement()
return null(); return null();
} }
if (!isForDecl && !setAssignmentLhsOps(lhsNode, true)) if (!isForDecl && !setAssignmentLhsOps(lhsNode, JSOP_NOP))
return null(); return null();
if (!expr()) if (!expr())
@ -5104,7 +5107,7 @@ Parser<ParseHandler>::condExpr1()
template <> template <>
bool bool
Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, bool isPlainAssignment) Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, JSOp op)
{ {
switch (pn->getKind()) { switch (pn->getKind()) {
case PNK_NAME: case PNK_NAME:
@ -5122,7 +5125,7 @@ Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, bool isPlainAssignm
#if JS_HAS_DESTRUCTURING #if JS_HAS_DESTRUCTURING
case PNK_ARRAY: case PNK_ARRAY:
case PNK_OBJECT: case PNK_OBJECT:
if (!isPlainAssignment) { if (op != JSOP_NOP) {
report(ParseError, false, null(), JSMSG_BAD_DESTRUCT_ASS); report(ParseError, false, null(), JSMSG_BAD_DESTRUCT_ASS);
return false; return false;
} }
@ -5143,7 +5146,7 @@ Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, bool isPlainAssignm
template <> template <>
bool bool
Parser<SyntaxParseHandler>::setAssignmentLhsOps(Node pn, bool isPlainAssignment) Parser<SyntaxParseHandler>::setAssignmentLhsOps(Node pn, JSOp op)
{ {
/* Full syntax checking of valid assignment LHS terms requires a parse tree. */ /* Full syntax checking of valid assignment LHS terms requires a parse tree. */
if (pn != SyntaxParseHandler::NodeName && if (pn != SyntaxParseHandler::NodeName &&
@ -5198,20 +5201,19 @@ Parser<ParseHandler>::assignExpr()
return null(); return null();
ParseNodeKind kind; ParseNodeKind kind;
JSOp op;
switch (tokenStream.currentToken().type) { switch (tokenStream.currentToken().type) {
case TOK_ASSIGN: kind = PNK_ASSIGN; op = JSOP_NOP; break; case TOK_ASSIGN: kind = PNK_ASSIGN; break;
case TOK_ADDASSIGN: kind = PNK_ADDASSIGN; op = JSOP_ADD; break; case TOK_ADDASSIGN: kind = PNK_ADDASSIGN; break;
case TOK_SUBASSIGN: kind = PNK_SUBASSIGN; op = JSOP_SUB; break; case TOK_SUBASSIGN: kind = PNK_SUBASSIGN; break;
case TOK_BITORASSIGN: kind = PNK_BITORASSIGN; op = JSOP_BITOR; break; case TOK_BITORASSIGN: kind = PNK_BITORASSIGN; break;
case TOK_BITXORASSIGN: kind = PNK_BITXORASSIGN; op = JSOP_BITXOR; break; case TOK_BITXORASSIGN: kind = PNK_BITXORASSIGN; break;
case TOK_BITANDASSIGN: kind = PNK_BITANDASSIGN; op = JSOP_BITAND; break; case TOK_BITANDASSIGN: kind = PNK_BITANDASSIGN; break;
case TOK_LSHASSIGN: kind = PNK_LSHASSIGN; op = JSOP_LSH; break; case TOK_LSHASSIGN: kind = PNK_LSHASSIGN; break;
case TOK_RSHASSIGN: kind = PNK_RSHASSIGN; op = JSOP_RSH; break; case TOK_RSHASSIGN: kind = PNK_RSHASSIGN; break;
case TOK_URSHASSIGN: kind = PNK_URSHASSIGN; op = JSOP_URSH; break; case TOK_URSHASSIGN: kind = PNK_URSHASSIGN; break;
case TOK_MULASSIGN: kind = PNK_MULASSIGN; op = JSOP_MUL; break; case TOK_MULASSIGN: kind = PNK_MULASSIGN; break;
case TOK_DIVASSIGN: kind = PNK_DIVASSIGN; op = JSOP_DIV; break; case TOK_DIVASSIGN: kind = PNK_DIVASSIGN; break;
case TOK_MODASSIGN: kind = PNK_MODASSIGN; op = JSOP_MOD; break; case TOK_MODASSIGN: kind = PNK_MODASSIGN; break;
case TOK_ARROW: { case TOK_ARROW: {
tokenStream.seek(start); tokenStream.seek(start);
@ -5232,7 +5234,8 @@ Parser<ParseHandler>::assignExpr()
return lhs; return lhs;
} }
if (!setAssignmentLhsOps(lhs, kind == PNK_ASSIGN)) JSOp op = tokenStream.currentToken().t_op;
if (!setAssignmentLhsOps(lhs, op))
return null(); return null();
Node rhs = assignExpr(); Node rhs = assignExpr();
@ -5294,7 +5297,7 @@ template <>
bool bool
Parser<SyntaxParseHandler>::setIncOpKid(Node pn, Node kid, TokenKind tt, bool preorder) Parser<SyntaxParseHandler>::setIncOpKid(Node pn, Node kid, TokenKind tt, bool preorder)
{ {
return setAssignmentLhsOps(kid, false); return setAssignmentLhsOps(kid, JSOP_NOP);
} }
template <typename ParseHandler> template <typename ParseHandler>
@ -6647,7 +6650,7 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
if (!abortIfSyntaxParser()) if (!abortIfSyntaxParser())
return null(); return null();
tokenStream.ungetToken(); tokenStream.ungetToken();
if (!tokenStream.checkForKeyword(atom->charsZ(), atom->length(), NULL)) if (!tokenStream.checkForKeyword(atom->charsZ(), atom->length(), NULL, NULL))
return null(); return null();
handler.setListFlag(pn, PNX_DESTRUCT | PNX_NONCONST); handler.setListFlag(pn, PNX_DESTRUCT | PNX_NONCONST);
PropertyName *name = handler.isName(pn3); PropertyName *name = handler.isName(pn3);

View File

@ -515,7 +515,7 @@ class Parser : private AutoGCRooter, public StrictModeGetter
#endif #endif
} }
bool setAssignmentLhsOps(Node pn, bool isPlainAssignment); bool setAssignmentLhsOps(Node pn, JSOp op);
bool matchInOrOf(bool *isForOfp); bool matchInOrOf(bool *isForOfp);
bool checkFunctionArguments(); bool checkFunctionArguments();
@ -592,11 +592,11 @@ Parser<SyntaxParseHandler>::expr();
template <> template <>
bool bool
Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, bool isPlainAssignment); Parser<FullParseHandler>::setAssignmentLhsOps(ParseNode *pn, JSOp op);
template <> template <>
bool bool
Parser<SyntaxParseHandler>::setAssignmentLhsOps(Node pn, bool isPlainAssignment); Parser<SyntaxParseHandler>::setAssignmentLhsOps(Node pn, JSOp op);
} /* namespace frontend */ } /* namespace frontend */
} /* namespace js */ } /* namespace js */

View File

@ -40,12 +40,13 @@ using mozilla::PodZero;
struct KeywordInfo { struct KeywordInfo {
const char *chars; /* C string with keyword text */ const char *chars; /* C string with keyword text */
TokenKind tokentype; TokenKind tokentype;
JSOp op; /* JSOp */
JSVersion version; /* JSVersion */ JSVersion version; /* JSVersion */
}; };
static const KeywordInfo keywords[] = { static const KeywordInfo keywords[] = {
#define KEYWORD_INFO(keyword, name, type, version) \ #define KEYWORD_INFO(keyword, name, type, op, version) \
{js_##keyword##_str, type, version}, {js_##keyword##_str, type, op, version},
FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_INFO) FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_INFO)
#undef KEYWORD_INFO #undef KEYWORD_INFO
}; };
@ -311,6 +312,7 @@ TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options,
* - A single char long. * - A single char long.
* - Cannot be a prefix of any longer token (e.g. '+' is excluded because * - Cannot be a prefix of any longer token (e.g. '+' is excluded because
* '+=' is a valid token). * '+=' is a valid token).
* - Doesn't need tp->t_op set (e.g. this excludes '~').
* *
* The few token kinds satisfying these properties cover roughly 35--45% * The few token kinds satisfying these properties cover roughly 35--45%
* of the tokens seen in practice. * of the tokens seen in practice.
@ -329,7 +331,6 @@ TokenStream::TokenStream(ExclusiveContext *cx, const CompileOptions &options,
oneCharTokens[unsigned('}')] = TOK_RC; oneCharTokens[unsigned('}')] = TOK_RC;
oneCharTokens[unsigned('(')] = TOK_LP; oneCharTokens[unsigned('(')] = TOK_LP;
oneCharTokens[unsigned(')')] = TOK_RP; oneCharTokens[unsigned(')')] = TOK_RP;
oneCharTokens[unsigned('~')] = TOK_BITNOT;
/* See getChar() for an explanation of maybeEOL[]. */ /* See getChar() for an explanation of maybeEOL[]. */
memset(maybeEOL, 0, sizeof(maybeEOL)); memset(maybeEOL, 0, sizeof(maybeEOL));
@ -969,8 +970,10 @@ TokenStream::putIdentInTokenbuf(const jschar *identStart)
} }
bool bool
TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp) TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp, JSOp *topp)
{ {
JS_ASSERT(!ttp == !topp);
const KeywordInfo *kw = FindKeyword(s, length); const KeywordInfo *kw = FindKeyword(s, length);
if (!kw) if (!kw)
return true; return true;
@ -983,6 +986,7 @@ TokenStream::checkForKeyword(const jschar *s, size_t length, TokenKind *ttp)
/* Working keyword. */ /* Working keyword. */
if (ttp) { if (ttp) {
*ttp = kw->tokentype; *ttp = kw->tokentype;
*topp = (JSOp) kw->op;
return true; return true;
} }
return reportError(JSMSG_RESERVED_ID, kw->chars); return reportError(JSMSG_RESERVED_ID, kw->chars);
@ -1021,8 +1025,7 @@ enum FirstCharKind {
#define _______ Other #define _______ Other
/* /*
* OneChar: 40, 41, 44, 59, 63, 91, 93, 123, 125, 126: * OneChar: 40, 41, 44, 59, 63, 91, 93, 123, 125: '(', ')', ',', ';', '?', '[', ']', '{', '}'
* '(', ')', ',', ';', '?', '[', ']', '{', '}', '~'
* Ident: 36, 65..90, 95, 97..122: '$', 'A'..'Z', '_', 'a'..'z' * Ident: 36, 65..90, 95, 97..122: '$', 'A'..'Z', '_', 'a'..'z'
* Dot: 46: '.' * Dot: 46: '.'
* Equals: 61: '=' * Equals: 61: '='
@ -1048,7 +1051,7 @@ static const uint8_t firstCharKinds[] = {
/* 90+ */ Ident, OneChar, _______, OneChar, _______, Ident, _______, Ident, Ident, Ident, /* 90+ */ Ident, OneChar, _______, OneChar, _______, Ident, _______, Ident, Ident, Ident,
/* 100+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, /* 100+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 110+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, /* 110+ */ Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident, Ident,
/* 120+ */ Ident, Ident, Ident, OneChar, _______, OneChar, OneChar, _______ /* 120+ */ Ident, Ident, Ident, OneChar, _______, OneChar, _______, _______
}; };
#undef _______ #undef _______
@ -1176,7 +1179,7 @@ TokenStream::getTokenInternal()
length = userbuf.addressOfNextRawChar() - identStart; length = userbuf.addressOfNextRawChar() - identStart;
} }
tt = TOK_NAME; tt = TOK_NAME;
if (!checkForKeyword(chars, length, &tt)) if (!checkForKeyword(chars, length, &tt, &tp->t_op))
goto error; goto error;
if (tt != TOK_NAME) if (tt != TOK_NAME)
goto out; goto out;
@ -1194,7 +1197,7 @@ TokenStream::getTokenInternal()
atom = atomize(cx, tokenbuf); atom = atomize(cx, tokenbuf);
if (!atom) if (!atom)
goto error; goto error;
tp->setName(atom->asPropertyName()); tp->setName(JSOP_NAME, atom->asPropertyName());
tt = TOK_NAME; tt = TOK_NAME;
goto out; goto out;
} }
@ -1221,12 +1224,20 @@ TokenStream::getTokenInternal()
} }
if (c1kind == Equals) { if (c1kind == Equals) {
if (matchChar('=')) if (matchChar('=')) {
tt = matchChar('=') ? TOK_STRICTEQ : TOK_EQ; if (matchChar('=')) {
else if (matchChar('>')) tp->t_op = JSOP_STRICTEQ;
tt = TOK_STRICTEQ;
} else {
tp->t_op = JSOP_EQ;
tt = TOK_EQ;
}
} else if (matchChar('>')) {
tt = TOK_ARROW; tt = TOK_ARROW;
else } else {
tp->t_op = JSOP_NOP;
tt = TOK_ASSIGN; tt = TOK_ASSIGN;
}
goto out; goto out;
} }
@ -1328,7 +1339,7 @@ TokenStream::getTokenInternal()
JSAtom *atom = atomize(cx, tokenbuf); JSAtom *atom = atomize(cx, tokenbuf);
if (!atom) if (!atom)
goto error; goto error;
tp->setAtom(atom); tp->setAtom(JSOP_STRING, atom);
tt = TOK_STRING; tt = TOK_STRING;
goto out; goto out;
} }
@ -1393,15 +1404,21 @@ TokenStream::getTokenInternal()
} }
if (c1kind == Colon) { if (c1kind == Colon) {
tp->t_op = JSOP_NOP;
tt = TOK_COLON; tt = TOK_COLON;
goto out; goto out;
} }
if (c1kind == Plus) { if (c1kind == Plus) {
if (matchChar('+')) if (matchChar('=')) {
tp->t_op = JSOP_ADD;
tt = TOK_ADDASSIGN;
} else if (matchChar('+')) {
tt = TOK_INC; tt = TOK_INC;
else } else {
tt = matchChar('=') ? TOK_ADDASSIGN : TOK_PLUS; tp->t_op = JSOP_POS;
tt = TOK_PLUS;
}
goto out; goto out;
} }
@ -1479,28 +1496,49 @@ TokenStream::getTokenInternal()
goto badchar; goto badchar;
case '|': case '|':
if (matchChar('|')) if (matchChar(c)) {
tt = TOK_OR; tt = TOK_OR;
else } else if (matchChar('=')) {
tt = matchChar('=') ? TOK_BITORASSIGN : TOK_BITOR; tp->t_op = JSOP_BITOR;
tt = TOK_BITORASSIGN;
} else {
tt = TOK_BITOR;
}
break; break;
case '^': case '^':
tt = matchChar('=') ? TOK_BITXORASSIGN : TOK_BITXOR; if (matchChar('=')) {
tp->t_op = JSOP_BITXOR;
tt = TOK_BITXORASSIGN;
} else {
tt = TOK_BITXOR;
}
break; break;
case '&': case '&':
if (matchChar('&')) if (matchChar('&')) {
tt = TOK_AND; tt = TOK_AND;
else } else if (matchChar('=')) {
tt = matchChar('=') ? TOK_BITANDASSIGN : TOK_BITAND; tp->t_op = JSOP_BITAND;
tt = TOK_BITANDASSIGN;
} else {
tt = TOK_BITAND;
}
break; break;
case '!': case '!':
if (matchChar('=')) if (matchChar('=')) {
tt = matchChar('=') ? TOK_STRICTNE : TOK_NE; if (matchChar('=')) {
else tp->t_op = JSOP_STRICTNE;
tt = TOK_STRICTNE;
} else {
tp->t_op = JSOP_NE;
tt = TOK_NE;
}
} else {
tp->t_op = JSOP_NOT;
tt = TOK_NOT; tt = TOK_NOT;
}
break; break;
case '<': case '<':
@ -1516,24 +1554,41 @@ TokenStream::getTokenInternal()
ungetChar('!'); ungetChar('!');
} }
if (matchChar('<')) { if (matchChar('<')) {
tp->t_op = JSOP_LSH;
tt = matchChar('=') ? TOK_LSHASSIGN : TOK_LSH; tt = matchChar('=') ? TOK_LSHASSIGN : TOK_LSH;
} else { } else {
tt = matchChar('=') ? TOK_LE : TOK_LT; if (matchChar('=')) {
tp->t_op = JSOP_LE;
tt = TOK_LE;
} else {
tp->t_op = JSOP_LT;
tt = TOK_LT;
}
} }
break; break;
case '>': case '>':
if (matchChar('>')) { if (matchChar('>')) {
if (matchChar('>')) if (matchChar('>')) {
tp->t_op = JSOP_URSH;
tt = matchChar('=') ? TOK_URSHASSIGN : TOK_URSH; tt = matchChar('=') ? TOK_URSHASSIGN : TOK_URSH;
else } else {
tp->t_op = JSOP_RSH;
tt = matchChar('=') ? TOK_RSHASSIGN : TOK_RSH; tt = matchChar('=') ? TOK_RSHASSIGN : TOK_RSH;
}
} else { } else {
tt = matchChar('=') ? TOK_GE : TOK_GT; if (matchChar('=')) {
tp->t_op = JSOP_GE;
tt = TOK_GE;
} else {
tp->t_op = JSOP_GT;
tt = TOK_GT;
}
} }
break; break;
case '*': case '*':
tp->t_op = JSOP_MUL;
tt = matchChar('=') ? TOK_MULASSIGN : TOK_STAR; tt = matchChar('=') ? TOK_MULASSIGN : TOK_STAR;
break; break;
@ -1648,22 +1703,33 @@ TokenStream::getTokenInternal()
break; break;
} }
tp->t_op = JSOP_DIV;
tt = matchChar('=') ? TOK_DIVASSIGN : TOK_DIV; tt = matchChar('=') ? TOK_DIVASSIGN : TOK_DIV;
break; break;
case '%': case '%':
tp->t_op = JSOP_MOD;
tt = matchChar('=') ? TOK_MODASSIGN : TOK_MOD; tt = matchChar('=') ? TOK_MODASSIGN : TOK_MOD;
break; break;
case '~':
tp->t_op = JSOP_BITNOT;
tt = TOK_BITNOT;
break;
case '-': case '-':
if (matchChar('-')) { if (matchChar('=')) {
tp->t_op = JSOP_SUB;
tt = TOK_SUBASSIGN;
} else if (matchChar(c)) {
if (peekChar() == '>' && !(flags & TSF_DIRTYLINE)) { if (peekChar() == '>' && !(flags & TSF_DIRTYLINE)) {
flags &= ~TSF_IN_HTML_COMMENT; flags &= ~TSF_IN_HTML_COMMENT;
goto skipline; goto skipline;
} }
tt = TOK_DEC; tt = TOK_DEC;
} else { } else {
tt = matchChar('=') ? TOK_SUBASSIGN : TOK_MINUS; tp->t_op = JSOP_NEG;
tt = TOK_MINUS;
} }
break; break;

View File

@ -246,10 +246,18 @@ struct Token {
TokenKind type; /* char value or above enumerator */ TokenKind type; /* char value or above enumerator */
TokenPos pos; /* token position in file */ TokenPos pos; /* token position in file */
union { union {
struct { /* name or string literal */
JSOp op; /* operator, for minimal parser */
union {
private:
friend struct Token;
PropertyName *name; /* non-numeric atom */
JSAtom *atom; /* potentially-numeric atom */
} n;
} s;
private: private:
friend struct Token; friend struct Token;
PropertyName *name; /* non-numeric atom */
JSAtom *atom; /* potentially-numeric atom */
struct { struct {
double value; /* floating point number */ double value; /* floating point number */
DecimalPoint decimalPoint; /* literal contains . or exponent */ DecimalPoint decimalPoint; /* literal contains . or exponent */
@ -265,14 +273,18 @@ struct Token {
* type-safety. See bug 697000. * type-safety. See bug 697000.
*/ */
void setName(PropertyName *name) { void setName(JSOp op, PropertyName *name) {
JS_ASSERT(op == JSOP_NAME);
JS_ASSERT(!IsPoisonedPtr(name)); JS_ASSERT(!IsPoisonedPtr(name));
u.name = name; u.s.op = op;
u.s.n.name = name;
} }
void setAtom(JSAtom *atom) { void setAtom(JSOp op, JSAtom *atom) {
JS_ASSERT(op == JSOP_STRING);
JS_ASSERT(!IsPoisonedPtr(atom)); JS_ASSERT(!IsPoisonedPtr(atom));
u.atom = atom; u.s.op = op;
u.s.n.atom = atom;
} }
void setRegExpFlags(js::RegExpFlag flags) { void setRegExpFlags(js::RegExpFlag flags) {
@ -289,12 +301,12 @@ struct Token {
PropertyName *name() const { PropertyName *name() const {
JS_ASSERT(type == TOK_NAME); JS_ASSERT(type == TOK_NAME);
return u.name->asPropertyName(); /* poor-man's type verification */ return u.s.n.name->asPropertyName(); /* poor-man's type verification */
} }
JSAtom *atom() const { JSAtom *atom() const {
JS_ASSERT(type == TOK_STRING); JS_ASSERT(type == TOK_STRING);
return u.atom; return u.s.n.atom;
} }
js::RegExpFlag regExpFlags() const { js::RegExpFlag regExpFlags() const {
@ -314,6 +326,8 @@ struct Token {
} }
}; };
#define t_op u.s.op
enum TokenStreamFlags enum TokenStreamFlags
{ {
TSF_EOF = 0x02, /* hit end of file */ TSF_EOF = 0x02, /* hit end of file */
@ -673,17 +687,19 @@ class MOZ_STACK_CLASS TokenStream
/* /*
* If the name at s[0:length] is not a keyword in this version, return * If the name at s[0:length] is not a keyword in this version, return
* true with *ttp unchanged. * true with *ttp and *topp unchanged.
* *
* If it is a reserved word in this version and strictness mode, and thus * If it is a reserved word in this version and strictness mode, and thus
* can't be present in correct code, report a SyntaxError and return false. * can't be present in correct code, report a SyntaxError and return false.
* *
* If it is a keyword, like "if", the behavior depends on ttp. If ttp is * If it is a keyword, like "if", the behavior depends on ttp/topp. If ttp
* null, report a SyntaxError ("if is a reserved identifier") and return * and topp are null, report a SyntaxError ("if is a reserved identifier")
* false. If ttp is non-null, return true with the keyword's TokenKind in * and return false. If ttp and topp are non-null, return true with the
* *ttp. * keyword's TokenKind in *ttp and its JSOp in *topp.
*
* ttp and topp must be either both null or both non-null.
*/ */
bool checkForKeyword(const jschar *s, size_t length, TokenKind *ttp); bool checkForKeyword(const jschar *s, size_t length, TokenKind *ttp, JSOp *topp);
// This class maps a userbuf offset (which is 0-indexed) to a line number // This class maps a userbuf offset (which is 0-indexed) to a line number
// (which is 1-indexed) and a column index (which is 0-indexed). // (which is 1-indexed) and a column index (which is 0-indexed).

View File

@ -14,7 +14,7 @@
#include "vm/Keywords.h" #include "vm/Keywords.h"
const char * const keyword_list[] = { const char * const keyword_list[] = {
#define KEYWORD_STRING(keyword, name, type, version) #keyword, #define KEYWORD_STRING(keyword, name, type, op, version) #keyword,
FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_STRING) FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_STRING)
#undef KEYWORD_STRING #undef KEYWORD_STRING
}; };

View File

@ -13,67 +13,67 @@
#if JS_HAS_CONST #if JS_HAS_CONST
# define FOR_CONST_KEYWORD(macro) \ # define FOR_CONST_KEYWORD(macro) \
macro(const, const_, TOK_CONST, JSVERSION_DEFAULT) macro(const, const_, TOK_CONST, JSOP_DEFCONST, JSVERSION_DEFAULT)
#else #else
# define FOR_CONST_KEYWORD(macro) \ # define FOR_CONST_KEYWORD(macro) \
macro(const, const_, TOK_RESERVED, JSVERSION_DEFAULT) macro(const, const_, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT)
#endif #endif
#if JS_HAS_BLOCK_SCOPE #if JS_HAS_BLOCK_SCOPE
# define FOR_LET_KEYWORD(macro) \ # define FOR_LET_KEYWORD(macro) \
macro(let, let, TOK_LET, JSVERSION_1_7) macro(let, let, TOK_LET, JSOP_NOP, JSVERSION_1_7)
#else #else
# define FOR_LET_KEYWORD(macro) \ # define FOR_LET_KEYWORD(macro) \
macro(let, let, TOK_STRICT_RESERVED, JSVERSION_1_7) macro(let, let, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_1_7)
#endif #endif
#define FOR_EACH_JAVASCRIPT_KEYWORD(macro) \ #define FOR_EACH_JAVASCRIPT_KEYWORD(macro) \
macro(false, false_, TOK_FALSE, JSVERSION_DEFAULT) \ macro(false, false_, TOK_FALSE, JSOP_FALSE, JSVERSION_DEFAULT) \
macro(true, true_, TOK_TRUE, JSVERSION_DEFAULT) \ macro(true, true_, TOK_TRUE, JSOP_TRUE, JSVERSION_DEFAULT) \
macro(null, null, TOK_NULL, JSVERSION_DEFAULT) \ macro(null, null, TOK_NULL, JSOP_NULL, JSVERSION_DEFAULT) \
/* ES5 Keywords. */ \ /* ES5 Keywords. */ \
macro(break, break_, TOK_BREAK, JSVERSION_DEFAULT) \ macro(break, break_, TOK_BREAK, JSOP_NOP, JSVERSION_DEFAULT) \
macro(case, case_, TOK_CASE, JSVERSION_DEFAULT) \ macro(case, case_, TOK_CASE, JSOP_NOP, JSVERSION_DEFAULT) \
macro(catch, catch_, TOK_CATCH, JSVERSION_DEFAULT) \ macro(catch, catch_, TOK_CATCH, JSOP_NOP, JSVERSION_DEFAULT) \
macro(continue, continue_, TOK_CONTINUE, JSVERSION_DEFAULT) \ macro(continue, continue_, TOK_CONTINUE, JSOP_NOP, JSVERSION_DEFAULT) \
macro(debugger, debugger, TOK_DEBUGGER, JSVERSION_DEFAULT) \ macro(debugger, debugger, TOK_DEBUGGER, JSOP_NOP, JSVERSION_DEFAULT) \
macro(default, default_, TOK_DEFAULT, JSVERSION_DEFAULT) \ macro(default, default_, TOK_DEFAULT, JSOP_NOP, JSVERSION_DEFAULT) \
macro(delete, delete_, TOK_DELETE, JSVERSION_DEFAULT) \ macro(delete, delete_, TOK_DELETE, JSOP_NOP, JSVERSION_DEFAULT) \
macro(do, do_, TOK_DO, JSVERSION_DEFAULT) \ macro(do, do_, TOK_DO, JSOP_NOP, JSVERSION_DEFAULT) \
macro(else, else_, TOK_ELSE, JSVERSION_DEFAULT) \ macro(else, else_, TOK_ELSE, JSOP_NOP, JSVERSION_DEFAULT) \
macro(finally, finally_, TOK_FINALLY, JSVERSION_DEFAULT) \ macro(finally, finally_, TOK_FINALLY, JSOP_NOP, JSVERSION_DEFAULT) \
macro(for, for_, TOK_FOR, JSVERSION_DEFAULT) \ macro(for, for_, TOK_FOR, JSOP_NOP, JSVERSION_DEFAULT) \
macro(function, function, TOK_FUNCTION, JSVERSION_DEFAULT) \ macro(function, function, TOK_FUNCTION, JSOP_NOP, JSVERSION_DEFAULT) \
macro(if, if_, TOK_IF, JSVERSION_DEFAULT) \ macro(if, if_, TOK_IF, JSOP_NOP, JSVERSION_DEFAULT) \
macro(in, in, TOK_IN, JSVERSION_DEFAULT) \ macro(in, in, TOK_IN, JSOP_IN, JSVERSION_DEFAULT) \
macro(instanceof, instanceof, TOK_INSTANCEOF, JSVERSION_DEFAULT) \ macro(instanceof, instanceof, TOK_INSTANCEOF, JSOP_INSTANCEOF,JSVERSION_DEFAULT) \
macro(new, new_, TOK_NEW, JSVERSION_DEFAULT) \ macro(new, new_, TOK_NEW, JSOP_NEW, JSVERSION_DEFAULT) \
macro(return, return_, TOK_RETURN, JSVERSION_DEFAULT) \ macro(return, return_, TOK_RETURN, JSOP_NOP, JSVERSION_DEFAULT) \
macro(switch, switch_, TOK_SWITCH, JSVERSION_DEFAULT) \ macro(switch, switch_, TOK_SWITCH, JSOP_NOP, JSVERSION_DEFAULT) \
macro(this, this_, TOK_THIS, JSVERSION_DEFAULT) \ macro(this, this_, TOK_THIS, JSOP_THIS, JSVERSION_DEFAULT) \
macro(throw, throw_, TOK_THROW, JSVERSION_DEFAULT) \ macro(throw, throw_, TOK_THROW, JSOP_NOP, JSVERSION_DEFAULT) \
macro(try, try_, TOK_TRY, JSVERSION_DEFAULT) \ macro(try, try_, TOK_TRY, JSOP_NOP, JSVERSION_DEFAULT) \
macro(typeof, typeof, TOK_TYPEOF, JSVERSION_DEFAULT) \ macro(typeof, typeof, TOK_TYPEOF, JSOP_TYPEOF, JSVERSION_DEFAULT) \
macro(var, var, TOK_VAR, JSVERSION_DEFAULT) \ macro(var, var, TOK_VAR, JSOP_DEFVAR, JSVERSION_DEFAULT) \
macro(void, void_, TOK_VOID, JSVERSION_DEFAULT) \ macro(void, void_, TOK_VOID, JSOP_VOID, JSVERSION_DEFAULT) \
macro(while, while_, TOK_WHILE, JSVERSION_DEFAULT) \ macro(while, while_, TOK_WHILE, JSOP_NOP, JSVERSION_DEFAULT) \
macro(with, with, TOK_WITH, JSVERSION_DEFAULT) \ macro(with, with, TOK_WITH, JSOP_NOP, JSVERSION_DEFAULT) \
/* ES5 reserved keywords reserved in all code. */ \ /* ES5 reserved keywords reserved in all code. */ \
macro(class, class_, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(class, class_, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(enum, enum_, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(enum, enum_, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(export, export, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(export, export, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(extends, extends, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(extends, extends, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(import, import, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(import, import, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(super, super, TOK_RESERVED, JSVERSION_DEFAULT) \ macro(super, super, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
/* ES5 future reserved keywords in strict mode. */ \ /* ES5 future reserved keywords in strict mode. */ \
macro(implements, implements, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(implements, implements, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(interface, interface, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(interface, interface, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(package, package, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(package, package, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(private, private_, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(private, private_, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(protected, protected_, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(protected, protected_, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(public, public_, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(public, public_, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
macro(static, static_, TOK_STRICT_RESERVED, JSVERSION_DEFAULT) \ macro(static, static_, TOK_STRICT_RESERVED, JSOP_NOP, JSVERSION_DEFAULT) \
/* ES5 future reserved keyword in strict mode, keyword in JS1.7 even when not strict. */ \ /* ES5 future reserved keyword in strict mode, keyword in JS1.7 even when not strict. */ \
macro(yield, yield, TOK_YIELD, JSVERSION_1_7) \ macro(yield, yield, TOK_YIELD, JSOP_NOP, JSVERSION_1_7) \
/* Various conditional keywords. */ \ /* Various conditional keywords. */ \
FOR_CONST_KEYWORD(macro) \ FOR_CONST_KEYWORD(macro) \
FOR_LET_KEYWORD(macro) FOR_LET_KEYWORD(macro)