From f6193fd0f4689643f47c6ac9aa5aac3b8cc10213 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:37:06 -0400 Subject: 1326454 - Introduce TokenStream::error that reports an error at the current offset. --- js/src/frontend/TokenStream.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 6ba9fba5a..f08d317ba 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -366,6 +366,9 @@ class MOZ_STACK_CLASS TokenStream bool reportErrorNoOffset(unsigned errorNumber, ...); bool reportWarning(unsigned errorNumber, ...); + // Report the given error at the current offset. + void error(unsigned errorNumber, ...); + static const uint32_t NoOffset = UINT32_MAX; // General-purpose error reporters. You should avoid calling these -- cgit v1.2.3 From 068916b59a847bede7c6c788e803442c1833fe67 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:40:56 -0400 Subject: 1326454 - Introduce TokenStream::warning that warns at the current offset. --- js/src/frontend/TokenStream.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index f08d317ba..18e9cb3ca 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -364,16 +364,18 @@ class MOZ_STACK_CLASS TokenStream // TokenStream-specific error reporters. bool reportError(unsigned errorNumber, ...); bool reportErrorNoOffset(unsigned errorNumber, ...); - bool reportWarning(unsigned errorNumber, ...); // Report the given error at the current offset. void error(unsigned errorNumber, ...); + // Warn at the current offset. + MOZ_MUST_USE bool warning(unsigned errorNumber, ...); + static const uint32_t NoOffset = UINT32_MAX; // General-purpose error reporters. You should avoid calling these - // directly, and instead use the more succinct alternatives (e.g. - // reportError()) in TokenStream, Parser, and BytecodeEmitter. + // directly, and instead use the more succinct alternatives (error(), + // warning(), &c.) in TokenStream, Parser, and BytecodeEmitter. bool reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigned errorNumber, va_list args); bool reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber, -- cgit v1.2.3 From b41de8683d8d28d08a6e2b79511610a268342a0e Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:48:25 -0400 Subject: 1326454 - Rename TokenStream::getBracedUnicode to TokenStream::matchBracedUnicode and make its signature fallible. --- js/src/frontend/TokenStream.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 18e9cb3ca..19385b499 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -368,6 +368,9 @@ class MOZ_STACK_CLASS TokenStream // Report the given error at the current offset. void error(unsigned errorNumber, ...); + // Report the given error at the given offset. + void errorAt(uint32_t offset, unsigned errorNumber, ...); + // Warn at the current offset. MOZ_MUST_USE bool warning(unsigned errorNumber, ...); @@ -952,7 +955,7 @@ class MOZ_STACK_CLASS TokenStream MOZ_MUST_USE bool getTokenInternal(TokenKind* ttp, Modifier modifier); - MOZ_MUST_USE bool getBracedUnicode(uint32_t* code); + MOZ_MUST_USE bool matchBracedUnicode(bool* matched, uint32_t* code); MOZ_MUST_USE bool getStringOrTemplateToken(int untilChar, Token** tp); int32_t getChar(); -- cgit v1.2.3 From d400e9491c0be93f34f368227d6a3e4d056d9061 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:52:17 -0400 Subject: 1326454 - Make TokenStream::peekChar's signature fallible. --- js/src/frontend/TokenStream.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 19385b499..e0e4b959e 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -990,10 +990,10 @@ class MOZ_STACK_CLASS TokenStream MOZ_ASSERT(c == expect); } - int32_t peekChar() { - int32_t c = getChar(); - ungetChar(c); - return c; + MOZ_MUST_USE bool peekChar(int32_t* c) { + *c = getChar(); + ungetChar(*c); + return true; } void skipChars(int n) { -- cgit v1.2.3 From 0ed4cf321f276d88f80d13daf2644f9bc51b0957 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:54:42 -0400 Subject: 1326454 - Make TokenStream::skipChars{,IgnoreEOL} accept an unsigned integral number of chars to skip. --- js/src/frontend/TokenStream.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index e0e4b959e..a058759c6 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -972,7 +972,7 @@ class MOZ_STACK_CLASS TokenStream MOZ_MUST_USE bool getDirectives(bool isMultiline, bool shouldWarnDeprecated); MOZ_MUST_USE bool getDirective(bool isMultiline, bool shouldWarnDeprecated, - const char* directive, int directiveLength, + const char* directive, uint8_t directiveLength, const char* errorMsgPragma, UniquePtr* destination); MOZ_MUST_USE bool getDisplayURL(bool isMultiline, bool shouldWarnDeprecated); @@ -996,13 +996,13 @@ class MOZ_STACK_CLASS TokenStream return true; } - void skipChars(int n) { - while (--n >= 0) + void skipChars(uint8_t n) { + while (n-- > 0) getChar(); } - void skipCharsIgnoreEOL(int n) { - while (--n >= 0) + void skipCharsIgnoreEOL(uint8_t n) { + while (n-- > 0) getCharIgnoreEOL(); } -- cgit v1.2.3 From aa2decd154dbbd17e0eac9c570841eb445c63a3f Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 15:55:51 -0400 Subject: 1326454 - Add assertions to TokenStream::skipChars{,IgnoreEOL} verifying EOF isn't yet hit and that newlines aren't skipped, if appropriate. --- js/src/frontend/TokenStream.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index a058759c6..4efc31446 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -997,13 +997,18 @@ class MOZ_STACK_CLASS TokenStream } void skipChars(uint8_t n) { - while (n-- > 0) - getChar(); + while (n-- > 0) { + MOZ_ASSERT(userbuf.hasRawChars()); + mozilla::DebugOnly c = getCharIgnoreEOL(); + MOZ_ASSERT(c != '\n'); + } } void skipCharsIgnoreEOL(uint8_t n) { - while (n-- > 0) + while (n-- > 0) { + MOZ_ASSERT(userbuf.hasRawChars()); getCharIgnoreEOL(); + } } void updateLineInfoForEOL(); -- cgit v1.2.3 From afb28a43d481075a244b0e18faa8447dfadacf8f Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sat, 8 Jun 2019 16:51:29 -0400 Subject: 1317375 - Implement "Template Literals Revision / Lifting Template Literal Restriction" ECMAScript proposal --- js/src/frontend/TokenStream.h | 62 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 4efc31446..fbfefbfe1 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -80,6 +80,20 @@ struct TokenPos { enum DecimalPoint { NoDecimal = false, HasDecimal = true }; +enum class InvalidEscapeType { + // No invalid character escapes. + None, + // A malformed \x escape. + Hexadecimal, + // A malformed \u escape. + Unicode, + // An otherwise well-formed \u escape which represents a + // codepoint > 10FFFF. + UnicodeOverflow, + // An octal escape in a template token. + Octal +}; + class TokenStream; struct Token @@ -361,6 +375,23 @@ class MOZ_STACK_CLASS TokenStream bool hadError() const { return flags.hadError; } void clearSawOctalEscape() { flags.sawOctalEscape = false; } + bool hasInvalidTemplateEscape() const { + return invalidTemplateEscapeType != InvalidEscapeType::None; + } + void clearInvalidTemplateEscape() { + invalidTemplateEscapeType = InvalidEscapeType::None; + } + + // If there is an invalid escape in a template, report it and return false, + // otherwise return true. + bool checkForInvalidTemplateEscapeError() { + if (invalidTemplateEscapeType == InvalidEscapeType::None) + return true; + + reportInvalidEscapeError(invalidTemplateEscapeOffset, invalidTemplateEscapeType); + return false; + } + // TokenStream-specific error reporters. bool reportError(unsigned errorNumber, ...); bool reportErrorNoOffset(unsigned errorNumber, ...); @@ -422,6 +453,33 @@ class MOZ_STACK_CLASS TokenStream bool reportStrictModeError(unsigned errorNumber, ...); bool strictMode() const { return strictModeGetter && strictModeGetter->strictMode(); } + void setInvalidTemplateEscape(uint32_t offset, InvalidEscapeType type) { + MOZ_ASSERT(type != InvalidEscapeType::None); + if (invalidTemplateEscapeType != InvalidEscapeType::None) + return; + invalidTemplateEscapeOffset = offset; + invalidTemplateEscapeType = type; + } + void reportInvalidEscapeError(uint32_t offset, InvalidEscapeType type) { + switch (type) { + case InvalidEscapeType::None: + MOZ_ASSERT_UNREACHABLE("unexpected InvalidEscapeType"); + return; + case InvalidEscapeType::Hexadecimal: + errorAt(offset, JSMSG_MALFORMED_ESCAPE, "hexadecimal"); + return; + case InvalidEscapeType::Unicode: + errorAt(offset, JSMSG_MALFORMED_ESCAPE, "Unicode"); + return; + case InvalidEscapeType::UnicodeOverflow: + errorAt(offset, JSMSG_UNICODE_OVERFLOW, "escape sequence"); + return; + case InvalidEscapeType::Octal: + errorAt(offset, JSMSG_DEPRECATED_OCTAL); + return; + } + } + static JSAtom* atomize(ExclusiveContext* cx, CharBuffer& cb); MOZ_MUST_USE bool putIdentInTokenbuf(const char16_t* identStart); @@ -442,6 +500,9 @@ class MOZ_STACK_CLASS TokenStream bool awaitIsKeyword = false; friend class AutoAwaitIsKeyword; + uint32_t invalidTemplateEscapeOffset = 0; + InvalidEscapeType invalidTemplateEscapeType = InvalidEscapeType::None; + public: typedef Token::Modifier Modifier; static constexpr Modifier None = Token::None; @@ -955,7 +1016,6 @@ class MOZ_STACK_CLASS TokenStream MOZ_MUST_USE bool getTokenInternal(TokenKind* ttp, Modifier modifier); - MOZ_MUST_USE bool matchBracedUnicode(bool* matched, uint32_t* code); MOZ_MUST_USE bool getStringOrTemplateToken(int untilChar, Token** tp); int32_t getChar(); -- cgit v1.2.3 From 412f15de44cee51e2443bc4846fe9679dca7e1b4 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 9 Jun 2019 14:23:16 -0400 Subject: 1283712 - Part 3: Add Parser::errorWithNotes and Parser::errorWithNotesAt. --- js/src/frontend/TokenStream.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index fbfefbfe1..e0119c83d 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -410,11 +410,12 @@ class MOZ_STACK_CLASS TokenStream // General-purpose error reporters. You should avoid calling these // directly, and instead use the more succinct alternatives (error(), // warning(), &c.) in TokenStream, Parser, and BytecodeEmitter. - bool reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigned errorNumber, - va_list args); - bool reportStrictModeErrorNumberVA(uint32_t offset, bool strictMode, unsigned errorNumber, - va_list args); - bool reportExtraWarningErrorNumberVA(uint32_t offset, unsigned errorNumber, va_list args); + bool reportCompileErrorNumberVA(UniquePtr notes, uint32_t offset, unsigned flags, + unsigned errorNumber, va_list args); + bool reportStrictModeErrorNumberVA(UniquePtr notes, uint32_t offset, + bool strictMode, unsigned errorNumber, va_list args); + bool reportExtraWarningErrorNumberVA(UniquePtr notes, uint32_t offset, + unsigned errorNumber, va_list args); // asm.js reporter void reportAsmJSError(uint32_t offset, unsigned errorNumber, ...); -- cgit v1.2.3 From 05c9c752a34ce4c9d246b63e2fbb46eaa946f8b6 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 9 Jun 2019 16:14:01 -0400 Subject: 1336783 - Part 1: Rework on reserved word and remove TokenStream::KeywordIsName. --- js/src/frontend/TokenStream.h | 135 +++++++++--------------------------------- 1 file changed, 29 insertions(+), 106 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index e0119c83d..e92de4b03 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -26,14 +26,13 @@ #include "js/UniquePtr.h" #include "js/Vector.h" #include "vm/RegExpObject.h" +#include "vm/String.h" struct KeywordInfo; namespace js { namespace frontend { -class AutoAwaitIsKeyword; - struct TokenPos { uint32_t begin; // Offset of the token's first char. uint32_t end; // Offset of 1 past the token's last char. @@ -120,9 +119,6 @@ struct Token // TOK_DIV. Operand, - // Treat keywords as names by returning TOK_NAME. - KeywordIsName, - // Treat subsequent characters as the tail of a template literal, after // a template substitution, beginning with a "}", continuing with zero // or more template literal characters, and ending with either "${" or @@ -164,10 +160,6 @@ struct Token // If a semicolon is inserted automatically, the next token is already // gotten with None, but we expect Operand. OperandIsNone, - - // If name of method definition is `get` or `set`, the next token is - // already gotten with KeywordIsName, but we expect None. - NoneIsKeywordIsName, }; friend class TokenStream; @@ -224,11 +216,6 @@ struct Token return u.name->JSAtom::asPropertyName(); // poor-man's type verification } - bool nameContainsEscape() const { - PropertyName* n = name(); - return pos.begin + n->length() != pos.end; - } - JSAtom* atom() const { MOZ_ASSERT(type == TOK_STRING || type == TOK_TEMPLATE_HEAD || @@ -254,10 +241,22 @@ struct Token }; class CompileError : public JSErrorReport { -public: + public: void throwError(JSContext* cx); }; +extern const char* +ReservedWordToCharZ(PropertyName* str); + +extern MOZ_MUST_USE bool +IsFutureReservedWord(JSLinearString* str); + +extern MOZ_MUST_USE bool +IsReservedWordLiteral(JSLinearString* str); + +extern MOZ_MUST_USE bool +IsStrictReservedWord(JSLinearString* str); + // Ideally, tokenizing would be entirely independent of context. But the // strict mode flag, which is in SharedContext, affects tokenizing, and // TokenStream needs to see it. @@ -344,25 +343,26 @@ class MOZ_STACK_CLASS TokenStream JSVersion versionNumber() const { return VersionNumber(options().version); } JSVersion versionWithFlags() const { return options().version; } + private: + PropertyName* reservedWordToPropertyName(TokenKind tt) const; + + public: PropertyName* currentName() const { - if (isCurrentTokenType(TOK_YIELD)) - return cx->names().yield; - MOZ_ASSERT(isCurrentTokenType(TOK_NAME)); - return currentToken().name(); + if (isCurrentTokenType(TOK_NAME)) { + return currentToken().name(); + } + + MOZ_ASSERT(TokenKindIsPossibleIdentifierName(currentToken().type)); + return reservedWordToPropertyName(currentToken().type); } PropertyName* nextName() const { - if (nextToken().type == TOK_YIELD) - return cx->names().yield; - MOZ_ASSERT(nextToken().type == TOK_NAME); - return nextToken().name(); - } + if (nextToken().type != TOK_NAME) { + return nextToken().name(); + } - bool nextNameContainsEscape() const { - if (nextToken().type == TOK_YIELD) - return false; - MOZ_ASSERT(nextToken().type == TOK_NAME); - return nextToken().nameContainsEscape(); + MOZ_ASSERT(TokenKindIsPossibleIdentifierName(nextToken().type)); + return reservedWordToPropertyName(nextToken().type); } bool isCurrentTokenAssignment() const { @@ -498,9 +498,6 @@ class MOZ_STACK_CLASS TokenStream {} }; - bool awaitIsKeyword = false; - friend class AutoAwaitIsKeyword; - uint32_t invalidTemplateEscapeOffset = 0; InvalidEscapeType invalidTemplateEscapeType = InvalidEscapeType::None; @@ -508,14 +505,12 @@ class MOZ_STACK_CLASS TokenStream typedef Token::Modifier Modifier; static constexpr Modifier None = Token::None; static constexpr Modifier Operand = Token::Operand; - static constexpr Modifier KeywordIsName = Token::KeywordIsName; static constexpr Modifier TemplateTail = Token::TemplateTail; typedef Token::ModifierException ModifierException; static constexpr ModifierException NoException = Token::NoException; static constexpr ModifierException NoneIsOperand = Token::NoneIsOperand; static constexpr ModifierException OperandIsNone = Token::OperandIsNone; - static constexpr ModifierException NoneIsKeywordIsName = Token::NoneIsKeywordIsName; void addModifierException(ModifierException modifierException) { #ifdef DEBUG @@ -544,10 +539,6 @@ class MOZ_STACK_CLASS TokenStream MOZ_ASSERT(next.type != TOK_DIV && next.type != TOK_REGEXP, "next token requires contextual specifier to be parsed unambiguously"); break; - case NoneIsKeywordIsName: - MOZ_ASSERT(next.modifier == KeywordIsName); - MOZ_ASSERT(next.type != TOK_NAME); - break; default: MOZ_CRASH("unexpected modifier exception"); } @@ -574,12 +565,6 @@ class MOZ_STACK_CLASS TokenStream return; } - if (lookaheadToken.modifierException == NoneIsKeywordIsName) { - // getToken() permissibly following getToken(KeywordIsName). - if (modifier == None && lookaheadToken.modifier == KeywordIsName) - return; - } - MOZ_ASSERT_UNREACHABLE("this token was previously looked up with a " "different modifier, potentially making " "tokenization non-deterministic"); @@ -714,36 +699,6 @@ class MOZ_STACK_CLASS TokenStream MOZ_ALWAYS_TRUE(matched); } - // Like matchToken(..., TOK_NAME) but further matching the name token only - // if it has the given characters, without containing escape sequences. - // If the name token has the given characters yet *does* contain an escape, - // a syntax error will be reported. - // - // This latter behavior makes this method unsuitable for use in any context - // where ASI might occur. In such places, an escaped "contextual keyword" - // on a new line is the start of an ExpressionStatement, not a continuation - // of a StatementListItem (or ImportDeclaration or ExportDeclaration, in - // modules). - MOZ_MUST_USE bool matchContextualKeyword(bool* matchedp, Handle keyword, - Modifier modifier = None) - { - TokenKind token; - if (!getToken(&token, modifier)) - return false; - if (token == TOK_NAME && currentToken().name() == keyword) { - if (currentToken().nameContainsEscape()) { - reportError(JSMSG_ESCAPED_KEYWORD); - return false; - } - - *matchedp = true; - } else { - *matchedp = false; - ungetToken(); - } - return true; - } - MOZ_MUST_USE bool nextTokenEndsExpr(bool* endsExpr) { TokenKind tt; if (!peekToken(&tt)) @@ -809,19 +764,6 @@ class MOZ_STACK_CLASS TokenStream return sourceMapURL_.get(); } - // If |atom| is not a keyword in this version, return true with *ttp - // unchanged. - // - // 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. - // - // If it is a keyword, like "if", return true with the keyword's TokenKind - // in *ttp. - MOZ_MUST_USE bool checkForKeyword(JSAtom* atom, TokenKind* ttp); - - // Same semantics as above, but for the provided keyword. - MOZ_MUST_USE bool checkForKeyword(const KeywordInfo* kw, TokenKind* ttp); - // 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). class SourceCoords @@ -1103,25 +1045,6 @@ class MOZ_STACK_CLASS TokenStream StrictModeGetter* strictModeGetter; // used to test for strict mode }; -class MOZ_STACK_CLASS AutoAwaitIsKeyword -{ -private: - TokenStream* ts_; - bool oldAwaitIsKeyword_; - -public: - AutoAwaitIsKeyword(TokenStream* ts, bool awaitIsKeyword) { - ts_ = ts; - oldAwaitIsKeyword_ = ts_->awaitIsKeyword; - ts_->awaitIsKeyword = awaitIsKeyword; - } - - ~AutoAwaitIsKeyword() { - ts_->awaitIsKeyword = oldAwaitIsKeyword_; - ts_ = nullptr; - } -}; - extern const char* TokenKindToDesc(TokenKind tt); -- cgit v1.2.3 From 638a904d0dbe4bcc5a625ea472c7e65ac75dbc06 Mon Sep 17 00:00:00 2001 From: Gaming4JC Date: Sun, 14 Jul 2019 16:28:47 -0400 Subject: Refactor Token& nextToken --- js/src/frontend/TokenStream.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'js/src/frontend/TokenStream.h') diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index e92de4b03..2744fd144 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -571,6 +571,11 @@ class MOZ_STACK_CLASS TokenStream #endif } + const Token& nextToken() const { + MOZ_ASSERT(hasLookahead()); + return tokens[(cursor + 1) & ntokensMask]; + } + // Advance to the next token. If the token stream encountered an error, // return false. Otherwise return true and store the token kind in |*ttp|. MOZ_MUST_USE bool getToken(TokenKind* ttp, Modifier modifier = None) { @@ -1017,10 +1022,6 @@ class MOZ_STACK_CLASS TokenStream void updateLineInfoForEOL(); void updateFlagsForEOL(); - const Token& nextToken() const { - MOZ_ASSERT(hasLookahead()); - return tokens[(cursor + 1) & ntokensMask]; - } bool hasLookahead() const { return lookahead > 0; } -- cgit v1.2.3