Bug 1066827 - Part2: Check error in TokenStream.getToken. r=jwalden

This commit is contained in:
Tooru Fujisawa 2014-10-24 20:59:00 +02:00
parent 1f2ef81022
commit 88d758d4bd
4 changed files with 193 additions and 137 deletions

View File

@ -6864,15 +6864,16 @@ ParseFunction(ModuleCompiler &m, ParseNode **fnOut)
{
TokenStream &tokenStream = m.tokenStream();
DebugOnly<TokenKind> tk = tokenStream.getToken();
MOZ_ASSERT(tk == TOK_FUNCTION);
tokenStream.consumeKnownToken(TOK_FUNCTION);
RootedPropertyName name(m.cx());
TokenKind tt = tokenStream.getToken();
if (tt == TOK_NAME) {
TokenKind tk;
if (!tokenStream.getToken(&tk))
return false;
if (tk == TOK_NAME) {
name = tokenStream.currentName();
} else if (tt == TOK_YIELD) {
} else if (tk == TOK_YIELD) {
if (!m.parser().checkYieldNameValidity())
return false;
name = m.cx()->names().yield;

View File

@ -59,10 +59,11 @@ typedef Handle<NestedScopeObject*> HandleNestedScopeObject;
/* Read a token. Report an error and return null() if that token isn't of type tt. */
#define MUST_MATCH_TOKEN(tt, errno) \
JS_BEGIN_MACRO \
TokenKind token = tokenStream.getToken(); \
TokenKind token; \
if (!tokenStream.getToken(&token)) \
return null(); \
if (token != tt) { \
if (token != TOK_ERROR) \
report(ParseError, false, null(), errno); \
report(ParseError, false, null(), errno); \
return null(); \
} \
JS_END_MACRO
@ -1226,7 +1227,7 @@ MatchOrInsertSemicolon(TokenStream &ts)
return false;
if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
/* Advance the scanner for proper error location reporting. */
ts.getToken(TokenStream::Operand);
ts.consumeKnownToken(tt);
ts.reportError(JSMSG_SEMI_BEFORE_STMNT);
return false;
}
@ -1537,7 +1538,10 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
parenFreeArrow = true;
}
if (!parenFreeArrow) {
if (tokenStream.getToken() != TOK_LP) {
TokenKind tt;
if (!tokenStream.getToken(&tt))
return false;
if (tt != TOK_LP) {
report(ParseError, false, null(),
kind == Arrow ? JSMSG_BAD_ARROW_ARGS : JSMSG_PAREN_BEFORE_FORMAL);
return false;
@ -1564,7 +1568,9 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
return false;
}
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return false;
MOZ_ASSERT_IF(parenFreeArrow, tt == TOK_NAME);
switch (tt) {
case TOK_LB:
@ -1632,10 +1638,10 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
case TOK_TRIPLEDOT:
{
*hasRest = true;
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return false;
if (tt != TOK_NAME) {
if (tt != TOK_ERROR)
report(ParseError, false, null(), JSMSG_NO_REST_NAME);
report(ParseError, false, null(), JSMSG_NO_REST_NAME);
return false;
}
goto TOK_NAME;
@ -1685,15 +1691,18 @@ Parser<ParseHandler>::functionArguments(FunctionSyntaxKind kind, Node *listp, No
default:
report(ParseError, false, null(), JSMSG_MISSING_FORMAL);
/* FALL THROUGH */
case TOK_ERROR:
return false;
}
} while (!parenFreeArrow && tokenStream.matchToken(TOK_COMMA));
if (!parenFreeArrow && tokenStream.getToken() != TOK_RP) {
report(ParseError, false, null(), JSMSG_PAREN_AFTER_FORMAL);
return false;
if (!parenFreeArrow) {
TokenKind tt;
if (!tokenStream.getToken(&tt))
return false;
if (tt != TOK_RP) {
report(ParseError, false, null(), JSMSG_PAREN_AFTER_FORMAL);
return false;
}
}
if (!hasDefaults)
@ -1995,17 +2004,14 @@ Parser<ParseHandler>::addExprAndGetNextTemplStrToken(Node nodeList, TokenKind &t
return false;
handler.addList(nodeList, pn);
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return false;
if (tt != TOK_RC) {
if (tt != TOK_ERROR)
report(ParseError, false, null(), JSMSG_TEMPLSTR_UNTERM_EXPR);
report(ParseError, false, null(), JSMSG_TEMPLSTR_UNTERM_EXPR);
return false;
}
tt = tokenStream.getToken(TokenStream::TemplateTail);
if (tt == TOK_ERROR)
return false;
return true;
return tokenStream.getToken(&tt, TokenStream::TemplateTail);
}
template <typename ParseHandler>
@ -2439,7 +2445,10 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun, Fu
// Parse the function body.
FunctionBodyType bodyType = StatementListBody;
if (tokenStream.getToken(TokenStream::Operand) != TOK_LC) {
TokenKind tt;
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return false;
if (tt != TOK_LC) {
if (funbox->isStarGenerator()) {
report(ParseError, false, null(), JSMSG_CURLY_BEFORE_BODY);
return false;
@ -2502,11 +2511,14 @@ Parser<ParseHandler>::functionStmt()
RootedPropertyName name(context);
GeneratorKind generatorKind = NotGenerator;
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_MUL) {
generatorKind = StarGenerator;
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return null();
}
if (tt == TOK_NAME) {
@ -2515,8 +2527,6 @@ Parser<ParseHandler>::functionStmt()
if (!checkYieldNameValidity())
return null();
name = tokenStream.currentName();
} else if (tt == TOK_ERROR) {
return null();
} else {
/* Unnamed function expressions are forbidden in statement context. */
report(ParseError, false, null(), JSMSG_UNNAMED_FUNCTION_STMT);
@ -2538,11 +2548,14 @@ Parser<ParseHandler>::functionExpr()
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
GeneratorKind generatorKind = NotGenerator;
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_MUL) {
generatorKind = StarGenerator;
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return null();
}
RootedPropertyName name(context);
@ -2552,8 +2565,6 @@ Parser<ParseHandler>::functionExpr()
if (!checkYieldNameValidity())
return null();
name = tokenStream.currentName();
} else if (tt == TOK_ERROR) {
return null();
} else {
tokenStream.ungetToken();
}
@ -3665,7 +3676,9 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
*psimple = false;
first = false;
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_LB || tt == TOK_LC) {
if (psimple)
*psimple = false;
@ -3712,8 +3725,7 @@ Parser<ParseHandler>::variables(ParseNodeKind kind, bool *psimple,
if (!checkYieldNameValidity())
return null();
} else {
if (tt != TOK_ERROR)
report(ParseError, false, null(), JSMSG_NO_VARIABLE_NAME);
report(ParseError, false, null(), JSMSG_NO_VARIABLE_NAME);
return null();
}
}
@ -3942,7 +3954,9 @@ Parser<ParseHandler>::importDeclaration()
}
uint32_t begin = pos().begin;
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
Node importSpecSet = handler.newList(PNK_IMPORT_SPEC_LIST);
if (!importSpecSet)
@ -3985,10 +3999,12 @@ Parser<ParseHandler>::importDeclaration()
if (!importName)
return null();
if (tokenStream.getToken() == TOK_NAME &&
tokenStream.currentName() == context->names().as)
{
if (tokenStream.getToken() != TOK_NAME) {
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_NAME && tokenStream.currentName() == context->names().as) {
if (!tokenStream.getToken(&tt))
return null();
if (tt != TOK_NAME) {
report(ParseError, false, null(), JSMSG_NO_BINDING_NAME);
return null();
}
@ -4019,9 +4035,9 @@ Parser<ParseHandler>::importDeclaration()
MUST_MATCH_TOKEN(TOK_RC, JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
}
if (tokenStream.getToken() != TOK_NAME ||
tokenStream.currentName() != context->names().from)
{
if (!tokenStream.getToken(&tt))
return null();
if (tt != TOK_NAME || tokenStream.currentName() != context->names().from) {
report(ParseError, false, null(), JSMSG_FROM_AFTER_IMPORT_SPEC_SET);
return null();
}
@ -4071,7 +4087,10 @@ Parser<ParseHandler>::exportDeclaration()
uint32_t begin = pos().begin;
Node kid;
switch (TokenKind tt = tokenStream.getToken()) {
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
switch (tt) {
case TOK_LC:
case TOK_MUL:
kid = handler.newList(PNK_EXPORT_SPEC_LIST);
@ -4093,10 +4112,12 @@ Parser<ParseHandler>::exportDeclaration()
if (!bindingName)
return null();
if (tokenStream.getToken() == TOK_NAME &&
tokenStream.currentName() == context->names().as)
{
if (tokenStream.getToken(TokenStream::KeywordIsName) != TOK_NAME) {
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_NAME && tokenStream.currentName() == context->names().as) {
if (!tokenStream.getToken(&tt, TokenStream::KeywordIsName))
return null();
if (tt != TOK_NAME) {
report(ParseError, false, null(), JSMSG_NO_EXPORT_NAME);
return null();
}
@ -4124,9 +4145,9 @@ Parser<ParseHandler>::exportDeclaration()
handler.addList(kid, exportSpec);
}
if (tokenStream.getToken() == TOK_NAME &&
tokenStream.currentName() == context->names().from)
{
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_NAME && tokenStream.currentName() == context->names().from) {
MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
Node moduleSpec = stringLiteral();
@ -4408,7 +4429,7 @@ Parser<FullParseHandler>::forStatement()
pn1 = variables(tt == TOK_VAR ? PNK_VAR : PNK_CONST);
} else if (tt == TOK_LET) {
handler.disableSyntaxParser();
(void) tokenStream.getToken();
tokenStream.consumeKnownToken(tt);
if (!tokenStream.peekToken(&tt))
return null();
if (tt == TOK_LP) {
@ -4840,7 +4861,11 @@ Parser<ParseHandler>::switchStatement()
bool seenDefault = false;
TokenKind tt;
while ((tt = tokenStream.getToken()) != TOK_RC) {
while (true) {
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_RC)
break;
uint32_t caseBegin = pos().begin;
Node caseExpr;
@ -4860,9 +4885,6 @@ Parser<ParseHandler>::switchStatement()
return null();
break;
case TOK_ERROR:
return null();
default:
report(ParseError, false, null(), JSMSG_BAD_SWITCH);
return null();
@ -5352,7 +5374,9 @@ Parser<ParseHandler>::tryStatement()
bool hasUnconditionalCatch = false;
Node catchList = null();
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_CATCH) {
catchList = handler.newList(PNK_CATCH);
if (!catchList)
@ -5395,7 +5419,8 @@ Parser<ParseHandler>::tryStatement()
JSMSG_TOO_MANY_CATCH_VARS);
MOZ_ASSERT(data.let.blockObj);
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return null();
Node catchName;
switch (tt) {
case TOK_LB:
@ -5456,7 +5481,8 @@ Parser<ParseHandler>::tryStatement()
handler.setEndPosition(catchList, pos().end);
handler.setEndPosition(pnblock, pos().end);
tt = tokenStream.getToken(TokenStream::Operand);
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
} while (tt == TOK_CATCH);
}
@ -5504,7 +5530,10 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
{
JS_CHECK_RECURSION(context, return null());
switch (TokenKind tt = tokenStream.getToken(TokenStream::Operand)) {
TokenKind tt;
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
switch (tt) {
case TOK_LC:
return blockStatement();
@ -5569,9 +5598,6 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
report(ParseError, false, null(), JSMSG_FINALLY_WITHOUT_TRY);
return null();
case TOK_ERROR:
return null();
case TOK_STRING:
if (!canHaveDirectives && tokenStream.currentToken().atom() == context->names().useAsm) {
if (!abortIfSyntaxParser())
@ -5744,8 +5770,8 @@ Parser<ParseHandler>::orExpr1()
// If a binary operator follows, consume it and compute the
// corresponding operator.
TokenKind tok = tokenStream.getToken();
if (tok == TOK_ERROR)
TokenKind tok;
if (!tokenStream.getToken(&tok))
return null();
ParseNodeKind pnk;
if (IsBinaryOpToken(tok, oldParsingForInit)) {
@ -5812,7 +5838,10 @@ Parser<ParseHandler>::condExpr1()
if (!elseExpr)
return null();
tokenStream.getToken(); /* read one token past the end */
// Advance to the next token; the caller is responsible for interpreting it.
TokenKind ignored;
if (!tokenStream.getToken(&ignored))
return null();
return handler.newConditional(condition, thenExpr, elseExpr);
}
@ -5901,7 +5930,9 @@ Parser<ParseHandler>::assignExpr()
// assignExpr(), condExpr1(), orExpr1(), unaryExpr(), memberExpr(), and
// primaryExpr().
TokenKind tt = tokenStream.getToken(TokenStream::Operand);
TokenKind tt;
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
if (tt == TOK_NAME && tokenStream.nextTokenEndsExpr())
return identifierName();
@ -5947,9 +5978,9 @@ Parser<ParseHandler>::assignExpr()
if (!abortIfSyntaxParser())
return null();
if (tokenStream.getToken() == TOK_ERROR)
TokenKind ignored;
if (!tokenStream.peekToken(&ignored))
return null();
tokenStream.ungetToken();
return functionDef(NullPtr(), Normal, Arrow, NotGenerator);
}
@ -6033,7 +6064,9 @@ Parser<ParseHandler>::unaryExpr()
JS_CHECK_RECURSION(context, return null());
TokenKind tt = tokenStream.getToken(TokenStream::Operand);
TokenKind tt;
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
uint32_t begin = pos().begin;
switch (tt) {
case TOK_TYPEOF:
@ -6052,7 +6085,9 @@ Parser<ParseHandler>::unaryExpr()
case TOK_INC:
case TOK_DEC:
{
TokenKind tt2 = tokenStream.getToken(TokenStream::Operand);
TokenKind tt2;
if (!tokenStream.getToken(&tt2, TokenStream::Operand))
return null();
pn2 = memberExpr(tt2, true);
if (!pn2)
return null();
@ -6080,9 +6115,6 @@ Parser<ParseHandler>::unaryExpr()
return handler.newDelete(begin, expr);
}
case TOK_ERROR:
return null();
default:
pn = memberExpr(tt, true);
if (!pn)
@ -6482,7 +6514,8 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyExpr, unsigned
uint32_t startYieldOffset = pc->lastYieldOffset;
RootedPropertyName name(context);
tt = tokenStream.getToken();
if (!tokenStream.getToken(&tt))
return null();
switch (tt) {
case TOK_LB:
case TOK_LC:
@ -6510,8 +6543,6 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyExpr, unsigned
default:
report(ParseError, false, null(), JSMSG_NO_VARIABLE_NAME);
case TOK_ERROR:
return null();
}
@ -7129,7 +7160,10 @@ Parser<ParseHandler>::argumentList(Node listNode, bool *isSpread)
handler.addList(listNode, argNode);
} while (tokenStream.matchToken(TOK_COMMA));
if (tokenStream.getToken() != TOK_RP) {
TokenKind tt;
if (!tokenStream.getToken(&tt))
return false;
if (tt != TOK_RP) {
report(ParseError, false, null(), JSMSG_PAREN_AFTER_ARGS);
return false;
}
@ -7153,7 +7187,8 @@ Parser<ParseHandler>::memberExpr(TokenKind tt, bool allowCallSyntax)
if (!lhs)
return null();
tt = tokenStream.getToken(TokenStream::Operand);
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
Node ctorExpr = memberExpr(tt, false);
if (!ctorExpr)
return null();
@ -7173,11 +7208,15 @@ Parser<ParseHandler>::memberExpr(TokenKind tt, bool allowCallSyntax)
return null();
}
while ((tt = tokenStream.getToken()) > TOK_EOF) {
while (true) {
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_EOF)
break;
Node nextMember;
if (tt == TOK_DOT) {
tt = tokenStream.getToken(TokenStream::KeywordIsName);
if (tt == TOK_ERROR)
if (!tokenStream.getToken(&tt, TokenStream::KeywordIsName))
return null();
if (tt == TOK_NAME) {
PropertyName *field = tokenStream.currentName();
@ -7256,8 +7295,6 @@ Parser<ParseHandler>::memberExpr(TokenKind tt, bool allowCallSyntax)
lhs = nextMember;
}
if (tt == TOK_ERROR)
return null();
return lhs;
}
@ -7499,14 +7536,17 @@ Parser<ParseHandler>::objectLiteral()
bool seenPrototypeMutation = false;
RootedAtom atom(context);
for (;;) {
TokenKind ltok = tokenStream.getToken(TokenStream::KeywordIsName);
TokenKind ltok;
if (!tokenStream.getToken(&ltok, TokenStream::KeywordIsName))
return null();
if (ltok == TOK_RC)
break;
bool isGenerator = false;
if (ltok == TOK_MUL) {
isGenerator = true;
ltok = tokenStream.getToken(TokenStream::KeywordIsName);
if (!tokenStream.getToken(&ltok, TokenStream::KeywordIsName))
return null();
}
atom = nullptr;
@ -7514,8 +7554,6 @@ Parser<ParseHandler>::objectLiteral()
JSOp op = JSOP_INITPROP;
Node propname;
switch (ltok) {
case TOK_ERROR:
return null();
case TOK_NUMBER:
atom = DoubleToAtom(context, tokenStream.currentToken().number());
if (!atom)
@ -7553,7 +7591,9 @@ Parser<ParseHandler>::objectLiteral()
// We have parsed |get| or |set|. Look for an accessor property
// name next.
TokenKind tt = tokenStream.getToken(TokenStream::KeywordIsName);
TokenKind tt;
if (!tokenStream.getToken(&tt, TokenStream::KeywordIsName))
return null();
if (tt == TOK_NAME) {
atom = tokenStream.currentName();
propname = newName(atom->asPropertyName());
@ -7621,8 +7661,8 @@ Parser<ParseHandler>::objectLiteral()
}
if (op == JSOP_INITPROP) {
TokenKind tt = tokenStream.getToken();
if (tt == TOK_ERROR)
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_COLON) {
@ -7699,7 +7739,9 @@ Parser<ParseHandler>::objectLiteral()
}
}
TokenKind tt = tokenStream.getToken();
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt == TOK_RC)
break;
if (tt != TOK_COMMA) {
@ -7811,8 +7853,7 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
// function as a trailing rest param: `(a, b, ...rest) => body`. Check
// for a name, closing parenthesis, and arrow, and allow it only if all
// are present.
next = tokenStream.getToken();
if (next == TOK_ERROR)
if (!tokenStream.getToken(&next))
return null();
if (next != TOK_NAME) {
report(ParseError, false, null(), JSMSG_UNEXPECTED_TOKEN,
@ -7820,8 +7861,7 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
return null();
}
next = tokenStream.getToken();
if (next == TOK_ERROR)
if (!tokenStream.getToken(&next))
return null();
if (next != TOK_RP) {
report(ParseError, false, null(), JSMSG_UNEXPECTED_TOKEN,
@ -7843,10 +7883,6 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt)
return handler.newNullLiteral(pos());
}
case TOK_ERROR:
/* The scanner or one of its subroutines reported the error. */
return null();
default:
unexpected_token:
report(ParseError, false, null(), JSMSG_UNEXPECTED_TOKEN,
@ -7895,7 +7931,10 @@ Parser<ParseHandler>::parenExprOrGeneratorComprehension()
if (!pn)
return null();
handler.setBeginPosition(pn, begin);
if (tokenStream.getToken() != TOK_RP) {
TokenKind tt;
if (!tokenStream.getToken(&tt))
return null();
if (tt != TOK_RP) {
report(ParseError, false, null(),
JSMSG_BAD_GENERATOR_SYNTAX, js_generator_str);
return null();

View File

@ -368,19 +368,22 @@ class MOZ_STACK_CLASS TokenStream
TemplateTail, // Treat next characters as part of a template string
};
// Get the next token from the stream, make it the current token, and
// return its kind.
TokenKind getToken(Modifier modifier = None) {
// Advance to the next token. If the token stream encountered an error,
// return false. Otherwise return true and store the token kind in |*ttp|.
bool getToken(TokenKind *ttp, Modifier modifier = None) {
// Check for a pushed-back token resulting from mismatching lookahead.
if (lookahead != 0) {
lookahead--;
cursor = (cursor + 1) & ntokensMask;
TokenKind tt = currentToken().type;
MOZ_ASSERT(tt != TOK_EOL);
return tt;
*ttp = tt;
return tt != TOK_ERROR;
}
return getTokenInternal(modifier);
TokenKind tt = getTokenInternal(modifier);
*ttp = tt;
return tt != TOK_ERROR;
}
// Push the last scanned token back into the stream.
@ -432,7 +435,9 @@ class MOZ_STACK_CLASS TokenStream
// is a newline between the next token and the one after that.
// The following test is somewhat expensive but gets these cases (and
// all others) right.
(void)getToken(modifier);
TokenKind tmp;
if (!getToken(&tmp, modifier))
return TOK_ERROR;
const Token &next = currentToken();
ungetToken();
return srcCoords.lineNum(curr.pos.end) == srcCoords.lineNum(next.pos.begin)
@ -442,18 +447,29 @@ class MOZ_STACK_CLASS TokenStream
// Get the next token from the stream if its kind is |tt|.
bool matchToken(TokenKind tt, Modifier modifier = None) {
if (getToken(modifier) == tt)
TokenKind token;
if (!getToken(&token, modifier)) {
ungetToken();
return false;
}
if (token == tt)
return true;
ungetToken();
return false;
}
void consumeKnownToken(TokenKind tt) {
MOZ_ASSERT(lookahead != 0);
JS_ALWAYS_TRUE(matchToken(tt));
}
bool matchContextualKeyword(Handle<PropertyName*> keyword) {
if (getToken() == TOK_NAME && currentToken().name() == keyword)
TokenKind token;
if (!getToken(&token)) {
ungetToken();
return false;
}
if (token == TOK_NAME && currentToken().name() == keyword)
return true;
ungetToken();
return false;

View File

@ -936,7 +936,10 @@ js::FindBody(JSContext *cx, HandleFunction fun, HandleLinearString src, size_t *
bool onward = true;
// Skip arguments list.
do {
switch (ts.getToken()) {
TokenKind tt;
if (!ts.getToken(&tt))
return false;
switch (tt) {
case TOK_NAME:
case TOK_YIELD:
if (nest == 0)
@ -949,18 +952,17 @@ js::FindBody(JSContext *cx, HandleFunction fun, HandleLinearString src, size_t *
if (--nest == 0)
onward = false;
break;
case TOK_ERROR:
// Must be memory.
return false;
default:
break;
}
} while (onward);
TokenKind tt = ts.getToken();
if (tt == TOK_ARROW)
tt = ts.getToken();
if (tt == TOK_ERROR)
TokenKind tt;
if (!ts.getToken(&tt))
return false;
if (tt == TOK_ARROW) {
if (!ts.getToken(&tt))
return false;
}
bool braced = tt == TOK_LC;
MOZ_ASSERT_IF(fun->isExprClosure(), !braced);
*bodyStart = ts.currentToken().pos.begin;
@ -1660,12 +1662,9 @@ js_fun_bind(JSContext *cx, HandleObject target, HandleValue thisArg,
* error was already reported.
*/
static bool
OnBadFormal(JSContext *cx, TokenKind tt)
OnBadFormal(JSContext *cx)
{
if (tt != TOK_ERROR)
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_FORMAL);
else
MOZ_ASSERT(cx->isExceptionPending());
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BAD_FORMAL);
return false;
}
@ -1806,13 +1805,12 @@ FunctionConstructor(JSContext *cx, unsigned argc, Value *vp, GeneratorKind gener
bool yieldIsValidName = ts.versionNumber() < JSVERSION_1_7 && !isStarGenerator;
/* The argument string may be empty or contain no tokens. */
TokenKind tt = ts.getToken();
TokenKind tt;
if (!ts.getToken(&tt))
return false;
if (tt != TOK_EOF) {
for (;;) {
/*
* Check that it's a name. This also implicitly guards against
* TOK_ERROR, which was already reported.
*/
/* Check that it's a name. */
if (hasRest) {
ts.reportError(JSMSG_PARAMETER_AFTER_REST);
return false;
@ -1824,16 +1822,16 @@ FunctionConstructor(JSContext *cx, unsigned argc, Value *vp, GeneratorKind gener
if (tt != TOK_NAME) {
if (tt == TOK_TRIPLEDOT) {
hasRest = true;
tt = ts.getToken();
if (!ts.getToken(&tt))
return false;
if (tt == TOK_YIELD && yieldIsValidName)
tt = TOK_NAME;
if (tt != TOK_NAME) {
if (tt != TOK_ERROR)
ts.reportError(JSMSG_NO_REST_NAME);
ts.reportError(JSMSG_NO_REST_NAME);
return false;
}
} else {
return OnBadFormal(cx, tt);
return OnBadFormal(cx);
}
}
@ -1844,12 +1842,14 @@ FunctionConstructor(JSContext *cx, unsigned argc, Value *vp, GeneratorKind gener
* Get the next token. Stop on end of stream. Otherwise
* insist on a comma, get another name, and iterate.
*/
tt = ts.getToken();
if (!ts.getToken(&tt))
return false;
if (tt == TOK_EOF)
break;
if (tt != TOK_COMMA)
return OnBadFormal(cx, tt);
tt = ts.getToken();
return OnBadFormal(cx);
if (!ts.getToken(&tt))
return false;
}
}
}