[JSC] Lexer flags should be an OptionSet
authorross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Oct 2019 23:42:05 +0000 (23:42 +0000)
committerross.kirsling@sony.com <ross.kirsling@sony.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Oct 2019 23:42:05 +0000 (23:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203032

Reviewed by Yusuke Suzuki.

LexerFlags has an annoyingly misspelled value LexexFlagsDontBuildKeywords;
let's use this as an opportunity to modernize this enum.

* parser/ASTBuilder.h:
* parser/Lexer.cpp:
(JSC::Lexer<LChar>::parseIdentifier):
(JSC::Lexer<UChar>::parseIdentifier):
(JSC::Lexer<CharacterType>::parseIdentifierSlowCase):
(JSC::Lexer<T>::lexWithoutClearingLineTerminator):
* parser/Lexer.h:
(JSC::Lexer<T>::lexExpectIdentifier):
(JSC::Lexer<T>::lex):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parseMemberExpression):
* parser/Parser.h:
(JSC::Parser::next):
(JSC::Parser::nextWithoutClearingLineTerminator):
(JSC::Parser::nextExpectIdentifier):
(JSC::Parser::consume):
* parser/SyntaxChecker.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@251684 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Lexer.cpp
Source/JavaScriptCore/parser/Lexer.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/parser/SyntaxChecker.h

index 95110f6..d363736 100644 (file)
@@ -1,3 +1,32 @@
+2019-10-28  Ross Kirsling  <ross.kirsling@sony.com>
+
+        [JSC] Lexer flags should be an OptionSet
+        https://bugs.webkit.org/show_bug.cgi?id=203032
+
+        Reviewed by Yusuke Suzuki.
+
+        LexerFlags has an annoyingly misspelled value LexexFlagsDontBuildKeywords;
+        let's use this as an opportunity to modernize this enum.
+
+        * parser/ASTBuilder.h:
+        * parser/Lexer.cpp:
+        (JSC::Lexer<LChar>::parseIdentifier):
+        (JSC::Lexer<UChar>::parseIdentifier):
+        (JSC::Lexer<CharacterType>::parseIdentifierSlowCase):
+        (JSC::Lexer<T>::lexWithoutClearingLineTerminator):
+        * parser/Lexer.h:
+        (JSC::Lexer<T>::lexExpectIdentifier):
+        (JSC::Lexer<T>::lex):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parseProperty):
+        (JSC::Parser<LexerType>::parseMemberExpression):
+        * parser/Parser.h:
+        (JSC::Parser::next):
+        (JSC::Parser::nextWithoutClearingLineTerminator):
+        (JSC::Parser::nextExpectIdentifier):
+        (JSC::Parser::consume):
+        * parser/SyntaxChecker.h:
+
 2019-10-28  Yusuke Suzuki  <ysuzuki@apple.com>
 
         [JSC] Optimize Promise runtime functions
index 9b46027..caf0308 100644 (file)
@@ -125,8 +125,8 @@ public:
     static constexpr bool CreatesAST = true;
     static constexpr bool NeedsFreeVariableInfo = true;
     static constexpr bool CanUseFunctionCache = true;
-    static constexpr int  DontBuildKeywords = 0;
-    static constexpr int  DontBuildStrings = 0;
+    static constexpr OptionSet<LexerFlags> DontBuildKeywords = { };
+    static constexpr OptionSet<LexerFlags> DontBuildStrings = { };
 
     ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
     ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, bool previousBaseWasSuper, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd, size_t callOrApplyChildDepth, bool isOptionalCall);
index 7d70319..ad0a5e3 100644 (file)
@@ -927,11 +927,11 @@ bool isSafeBuiltinIdentifier(VM& vm, const Identifier* ident)
 #endif
     
 template <>
-template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::parseIdentifier(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
+template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::parseIdentifier(JSTokenData* tokenData, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     tokenData->escaped = false;
     const ptrdiff_t remaining = m_codeEnd - m_code;
-    if ((remaining >= maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) {
+    if ((remaining >= maxTokenLength) && !lexerFlags.contains(LexerFlags::IgnoreReservedWords)) {
         JSTokenType keyword = parseKeyword<shouldCreateIdentifier>(tokenData);
         if (keyword != IDENT) {
             ASSERT((!shouldCreateIdentifier) || tokenData->ident);
@@ -975,7 +975,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
     } else
         tokenData->ident = nullptr;
 
-    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) {
+    if (UNLIKELY((remaining < maxTokenLength) && !lexerFlags.contains(LexerFlags::IgnoreReservedWords)) && !isPrivateName) {
         ASSERT(shouldCreateIdentifier);
         if (remaining < maxTokenLength) {
             const HashTableValue* entry = JSC::mainTable.entry(*ident);
@@ -992,11 +992,11 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<LChar>::p
 }
 
 template <>
-template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::parseIdentifier(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
+template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::parseIdentifier(JSTokenData* tokenData, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     tokenData->escaped = false;
     const ptrdiff_t remaining = m_codeEnd - m_code;
-    if ((remaining >= maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) {
+    if ((remaining >= maxTokenLength) && !lexerFlags.contains(LexerFlags::IgnoreReservedWords)) {
         JSTokenType keyword = parseKeyword<shouldCreateIdentifier>(tokenData);
         if (keyword != IDENT) {
             ASSERT((!shouldCreateIdentifier) || tokenData->ident);
@@ -1053,7 +1053,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
     } else
         tokenData->ident = nullptr;
     
-    if (UNLIKELY((remaining < maxTokenLength) && !(lexerFlags & LexerFlagsIgnoreReservedWords)) && !isPrivateName) {
+    if (UNLIKELY((remaining < maxTokenLength) && !lexerFlags.contains(LexerFlags::IgnoreReservedWords)) && !isPrivateName) {
         ASSERT(shouldCreateIdentifier);
         if (remaining < maxTokenLength) {
             const HashTableValue* entry = JSC::mainTable.entry(*ident);
@@ -1069,7 +1069,7 @@ template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType Lexer<UChar>::p
     return IDENT;
 }
 
-template<typename CharacterType> template<bool shouldCreateIdentifier> JSTokenType Lexer<CharacterType>::parseIdentifierSlowCase(JSTokenData* tokenData, unsigned lexerFlags, bool strictMode)
+template<typename CharacterType> template<bool shouldCreateIdentifier> JSTokenType Lexer<CharacterType>::parseIdentifierSlowCase(JSTokenData* tokenData, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     tokenData->escaped = true;
     auto identifierStart = currentSourcePtr();
@@ -1119,7 +1119,7 @@ template<typename CharacterType> template<bool shouldCreateIdentifier> JSTokenTy
 
     m_buffer16.shrink(0);
 
-    if (LIKELY(!(lexerFlags & LexerFlagsIgnoreReservedWords))) {
+    if (LIKELY(!lexerFlags.contains(LexerFlags::IgnoreReservedWords))) {
         ASSERT(shouldCreateIdentifier);
         const HashTableValue* entry = JSC::mainTable.entry(*ident);
         if (!entry)
@@ -1859,7 +1859,7 @@ void Lexer<T>::fillTokenInfo(JSToken* tokenRecord, JSTokenType token, int lineNu
 }
 
 template <typename T>
-JSTokenType Lexer<T>::lexWithoutClearingLineTerminator(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
+JSTokenType Lexer<T>::lexWithoutClearingLineTerminator(JSToken* tokenRecord, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     JSTokenData* tokenData = &tokenRecord->m_data;
     JSTokenLocation* tokenLocation = &tokenRecord->m_location;
@@ -2379,7 +2379,7 @@ start:
         break;
     case CharacterQuote: {
         StringParseResult result = StringCannotBeParsed;
-        if (lexerFlags & LexerFlagsDontBuildStrings)
+        if (lexerFlags.contains(LexerFlags::DontBuildStrings))
             result = parseString<false>(tokenData, strictMode);
         else
             result = parseString<true>(tokenData, strictMode);
@@ -2397,7 +2397,7 @@ start:
         FALLTHROUGH;
     case CharacterBackSlash:
         parseIdent:
-        if (lexerFlags & LexexFlagsDontBuildKeywords)
+        if (lexerFlags.contains(LexerFlags::DontBuildKeywords))
             token = parseIdentifier<false>(tokenData, lexerFlags, strictMode);
         else
             token = parseIdentifier<true>(tokenData, lexerFlags, strictMode);
index a58f76b..c7a14db 100644 (file)
 
 namespace JSC {
 
-enum LexerFlags {
-    LexerFlagsIgnoreReservedWords = 1
-    LexerFlagsDontBuildStrings = 2,
-    LexexFlagsDontBuildKeywords = 4
+enum class LexerFlags : uint8_t {
+    IgnoreReservedWords = 1 << 0
+    DontBuildStrings = 1 << 1,
+    DontBuildKeywords = 1 << 2
 };
 
 enum class LexerEscapeParseMode { Template, String };
@@ -64,8 +64,8 @@ public:
     void setIsReparsingFunction() { m_isReparsingFunction = true; }
     bool isReparsingFunction() const { return m_isReparsingFunction; }
 
-    JSTokenType lex(JSToken*, unsigned, bool strictMode);
-    JSTokenType lexWithoutClearingLineTerminator(JSToken*, unsigned, bool strictMode);
+    JSTokenType lex(JSToken*, OptionSet<LexerFlags>, bool strictMode);
+    JSTokenType lexWithoutClearingLineTerminator(JSToken*, OptionSet<LexerFlags>, bool strictMode);
     bool nextTokenIsColon();
     int lineNumber() const { return m_lineNumber; }
     ALWAYS_INLINE int currentOffset() const { return offsetFromSourcePtr(m_code); }
@@ -116,7 +116,7 @@ public:
         m_hasLineTerminatorBeforeToken = terminator;
     }
 
-    JSTokenType lexExpectIdentifier(JSToken*, unsigned, bool strictMode);
+    JSTokenType lexExpectIdentifier(JSToken*, OptionSet<LexerFlags>, bool strictMode);
 
     ALWAYS_INLINE StringView getToken(const JSToken& token)
     {
@@ -164,8 +164,8 @@ private:
 
     template <int shiftAmount> void internalShift();
     template <bool shouldCreateIdentifier> ALWAYS_INLINE JSTokenType parseKeyword(JSTokenData*);
-    template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, unsigned lexerFlags, bool strictMode);
-    template <bool shouldBuildIdentifiers> NEVER_INLINE JSTokenType parseIdentifierSlowCase(JSTokenData*, unsigned lexerFlags, bool strictMode);
+    template <bool shouldBuildIdentifiers> ALWAYS_INLINE JSTokenType parseIdentifier(JSTokenData*, OptionSet<LexerFlags>, bool strictMode);
+    template <bool shouldBuildIdentifiers> NEVER_INLINE JSTokenType parseIdentifierSlowCase(JSTokenData*, OptionSet<LexerFlags>, bool strictMode);
     enum StringParseResult {
         StringParsedSuccessfully,
         StringUnterminated,
@@ -340,11 +340,11 @@ bool isSafeBuiltinIdentifier(VM&, const Identifier*);
 #endif
 
 template <typename T>
-ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
+ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     JSTokenData* tokenData = &tokenRecord->m_data;
     JSTokenLocation* tokenLocation = &tokenRecord->m_location;
-    ASSERT((lexerFlags & LexerFlagsIgnoreReservedWords));
+    ASSERT(lexerFlags.contains(LexerFlags::IgnoreReservedWords));
     const T* start = m_code;
     const T* ptr = start;
     const T* end = m_codeEnd;
@@ -374,7 +374,7 @@ ALWAYS_INLINE JSTokenType Lexer<T>::lexExpectIdentifier(JSToken* tokenRecord, un
     ASSERT(currentOffset() >= currentLineStartOffset());
 
     // Create the identifier if needed
-    if (lexerFlags & LexexFlagsDontBuildKeywords
+    if (lexerFlags.contains(LexerFlags::DontBuildKeywords)
 #if !ASSERT_DISABLED
         && !m_parsingBuiltinFunction
 #endif
@@ -405,7 +405,7 @@ slowCase:
 }
 
 template <typename T>
-ALWAYS_INLINE JSTokenType Lexer<T>::lex(JSToken* tokenRecord, unsigned lexerFlags, bool strictMode)
+ALWAYS_INLINE JSTokenType Lexer<T>::lex(JSToken* tokenRecord, OptionSet<LexerFlags> lexerFlags, bool strictMode)
 {
     m_hasLineTerminatorBeforeToken = false;
     return lexWithoutClearingLineTerminator(tokenRecord, lexerFlags, strictMode);
index b67d939..83f3d72 100644 (file)
@@ -4003,9 +4003,9 @@ namedProperty:
         JSToken identToken = m_token;
 
         if (complete || (wasIdent && !isGeneratorMethodParseMode(parseMode)  && (*ident == m_vm.propertyNames->get || *ident == m_vm.propertyNames->set)))
-            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
+            nextExpectIdentifier(LexerFlags::IgnoreReservedWords);
         else
-            nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
+            nextExpectIdentifier(TreeBuilder::DontBuildKeywords | LexerFlags::IgnoreReservedWords);
 
         if (!isGeneratorMethodParseMode(parseMode) && !isAsyncMethodParseMode(parseMode) && match(COLON)) {
             next();
@@ -4849,7 +4849,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
             case DOT: {
                 m_parserState.nonTrivialExpressionCount++;
                 JSTextPosition expressionEnd = lastTokenEndPosition();
-                nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
+                nextExpectIdentifier(TreeBuilder::DontBuildKeywords | LexerFlags::IgnoreReservedWords);
                 matchOrFail(IDENT, "Expected a property name after ", optionalChainBase ? "'?.'" : "'.'");
                 base = context.createDotAccess(startLocation, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEndPosition());
                 if (UNLIKELY(baseIsSuper && currentScope()->isArrowFunction()))
index c89b00d..cfd943e 100644 (file)
@@ -1355,7 +1355,7 @@ private:
     bool isFunctionMetadataNode(ScopeNode*) { return false; }
     bool isFunctionMetadataNode(FunctionMetadataNode*) { return true; }
 
-    ALWAYS_INLINE void next(unsigned lexerFlags = 0)
+    ALWAYS_INLINE void next(OptionSet<LexerFlags> lexerFlags = { })
     {
         int lastLine = m_token.m_location.line;
         int lastTokenEnd = m_token.m_location.endOffset;
@@ -1365,7 +1365,7 @@ private:
         m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
     }
 
-    ALWAYS_INLINE void nextWithoutClearingLineTerminator(unsigned lexerFlags = 0)
+    ALWAYS_INLINE void nextWithoutClearingLineTerminator(OptionSet<LexerFlags> lexerFlags = { })
     {
         int lastLine = m_token.m_location.line;
         int lastTokenEnd = m_token.m_location.endOffset;
@@ -1375,7 +1375,7 @@ private:
         m_token.m_type = m_lexer->lexWithoutClearingLineTerminator(&m_token, lexerFlags, strictMode());
     }
 
-    ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
+    ALWAYS_INLINE void nextExpectIdentifier(OptionSet<LexerFlags> lexerFlags = { })
     {
         int lastLine = m_token.m_location.line;
         int lastTokenEnd = m_token.m_location.endOffset;
@@ -1396,7 +1396,7 @@ private:
         return m_lexer->nextTokenIsColon();
     }
 
-    ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
+    ALWAYS_INLINE bool consume(JSTokenType expected, OptionSet<LexerFlags> flags = { })
     {
         bool result = m_token.m_type == expected;
         if (result)
index bd34384..fb82b70 100644 (file)
@@ -143,8 +143,8 @@ public:
     static constexpr bool CreatesAST = false;
     static constexpr bool NeedsFreeVariableInfo = false;
     static constexpr bool CanUseFunctionCache = true;
-    static constexpr unsigned DontBuildKeywords = LexexFlagsDontBuildKeywords;
-    static constexpr unsigned DontBuildStrings = LexerFlagsDontBuildStrings;
+    static constexpr OptionSet<LexerFlags> DontBuildKeywords = LexerFlags::DontBuildKeywords;
+    static constexpr OptionSet<LexerFlags> DontBuildStrings = LexerFlags::DontBuildStrings;
 
     int createSourceElements() { return SourceElementsResult; }
     ExpressionType makeFunctionCallNode(const JSTokenLocation&, ExpressionType, bool, int, int, int, int, size_t, bool) { return CallExpr; }