Title: [226128] trunk/Source
Revision
226128
Author
[email protected]
Date
2017-12-19 11:16:21 -0800 (Tue, 19 Dec 2017)

Log Message

[YARR] Yarr should return ErrorCode instead of error messages (const char*)
https://bugs.webkit.org/show_bug.cgi?id=180966

Reviewed by Mark Lam.

Source/_javascript_Core:

Currently, Yarr returns const char*` for an error message when needed.
But it is easier to handle error status if Yarr returns an error code
instead of `const char*`.

In this patch, we introduce Yarr::ErrorCode. Yarr returns it instead of
`const char*`. `std::expected<void, Yarr::ErrorCode>` would be appropriate
for the Yarr API interface. But it requires substantial changes removing
ErrorCode::NoError, so this patch just uses the current Yarr::ErrorCode as
a first step.

* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* inspector/ContentSearchUtilities.cpp:
(Inspector::ContentSearchUtilities::findMagicComment):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createRegExp):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parsePrimaryExpression):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createRegExp):
* runtime/RegExp.cpp:
(JSC::RegExp::RegExp):
(JSC::RegExp::byteCodeCompileIfNecessary):
(JSC::RegExp::compile):
(JSC::RegExp::compileMatchOnly):
* runtime/RegExp.h:
* yarr/RegularExpression.cpp:
(JSC::Yarr::RegularExpression::Private::Private):
(JSC::Yarr::RegularExpression::Private::compile):
* yarr/YarrErrorCode.cpp: Added.
(JSC::Yarr::errorMessage):
* yarr/YarrErrorCode.h: Copied from Source/_javascript_Core/yarr/YarrSyntaxChecker.h.
(JSC::Yarr::hasError):
* yarr/YarrParser.h:
(JSC::Yarr::Parser::CharacterClassParserDelegate::CharacterClassParserDelegate):
(JSC::Yarr::Parser::CharacterClassParserDelegate::atomPatternCharacter):
(JSC::Yarr::Parser::Parser):
(JSC::Yarr::Parser::isIdentityEscapeAnError):
(JSC::Yarr::Parser::parseEscape):
(JSC::Yarr::Parser::parseCharacterClass):
(JSC::Yarr::Parser::parseParenthesesBegin):
(JSC::Yarr::Parser::parseParenthesesEnd):
(JSC::Yarr::Parser::parseQuantifier):
(JSC::Yarr::Parser::parseTokens):
(JSC::Yarr::Parser::parse):
(JSC::Yarr::Parser::tryConsumeUnicodeEscape):
(JSC::Yarr::Parser::tryConsumeUnicodePropertyExpression):
(JSC::Yarr::parse):
* yarr/YarrPattern.cpp:
(JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
(JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
(JSC::Yarr::YarrPatternConstructor::setupOffsets):
(JSC::Yarr::YarrPattern::compile):
(JSC::Yarr::YarrPattern::YarrPattern):
(JSC::Yarr::YarrPattern::errorMessage): Deleted.
* yarr/YarrPattern.h:
(JSC::Yarr::YarrPattern::reset):
* yarr/YarrSyntaxChecker.cpp:
(JSC::Yarr::checkSyntax):
* yarr/YarrSyntaxChecker.h:

Source/WebCore:

Remove unnecessary String creation.

No behavior change.

* contentextensions/URLFilterParser.cpp:
(WebCore::ContentExtensions::URLFilterParser::addPattern):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (226127 => 226128)


--- trunk/Source/_javascript_Core/ChangeLog	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-12-19 19:16:21 UTC (rev 226128)
@@ -1,3 +1,71 @@
+2017-12-19  Yusuke Suzuki  <[email protected]>
+
+        [YARR] Yarr should return ErrorCode instead of error messages (const char*)
+        https://bugs.webkit.org/show_bug.cgi?id=180966
+
+        Reviewed by Mark Lam.
+
+        Currently, Yarr returns const char*` for an error message when needed.
+        But it is easier to handle error status if Yarr returns an error code
+        instead of `const char*`.
+
+        In this patch, we introduce Yarr::ErrorCode. Yarr returns it instead of
+        `const char*`. `std::expected<void, Yarr::ErrorCode>` would be appropriate
+        for the Yarr API interface. But it requires substantial changes removing
+        ErrorCode::NoError, so this patch just uses the current Yarr::ErrorCode as
+        a first step.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * inspector/ContentSearchUtilities.cpp:
+        (Inspector::ContentSearchUtilities::findMagicComment):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createRegExp):
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createRegExp):
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::RegExp):
+        (JSC::RegExp::byteCodeCompileIfNecessary):
+        (JSC::RegExp::compile):
+        (JSC::RegExp::compileMatchOnly):
+        * runtime/RegExp.h:
+        * yarr/RegularExpression.cpp:
+        (JSC::Yarr::RegularExpression::Private::Private):
+        (JSC::Yarr::RegularExpression::Private::compile):
+        * yarr/YarrErrorCode.cpp: Added.
+        (JSC::Yarr::errorMessage):
+        * yarr/YarrErrorCode.h: Copied from Source/_javascript_Core/yarr/YarrSyntaxChecker.h.
+        (JSC::Yarr::hasError):
+        * yarr/YarrParser.h:
+        (JSC::Yarr::Parser::CharacterClassParserDelegate::CharacterClassParserDelegate):
+        (JSC::Yarr::Parser::CharacterClassParserDelegate::atomPatternCharacter):
+        (JSC::Yarr::Parser::Parser):
+        (JSC::Yarr::Parser::isIdentityEscapeAnError):
+        (JSC::Yarr::Parser::parseEscape):
+        (JSC::Yarr::Parser::parseCharacterClass):
+        (JSC::Yarr::Parser::parseParenthesesBegin):
+        (JSC::Yarr::Parser::parseParenthesesEnd):
+        (JSC::Yarr::Parser::parseQuantifier):
+        (JSC::Yarr::Parser::parseTokens):
+        (JSC::Yarr::Parser::parse):
+        (JSC::Yarr::Parser::tryConsumeUnicodeEscape):
+        (JSC::Yarr::Parser::tryConsumeUnicodePropertyExpression):
+        (JSC::Yarr::parse):
+        * yarr/YarrPattern.cpp:
+        (JSC::Yarr::YarrPatternConstructor::YarrPatternConstructor):
+        (JSC::Yarr::YarrPatternConstructor::setupDisjunctionOffsets):
+        (JSC::Yarr::YarrPatternConstructor::setupOffsets):
+        (JSC::Yarr::YarrPattern::compile):
+        (JSC::Yarr::YarrPattern::YarrPattern):
+        (JSC::Yarr::YarrPattern::errorMessage): Deleted.
+        * yarr/YarrPattern.h:
+        (JSC::Yarr::YarrPattern::reset):
+        * yarr/YarrSyntaxChecker.cpp:
+        (JSC::Yarr::checkSyntax):
+        * yarr/YarrSyntaxChecker.h:
+
 2017-12-18  Saam Barati  <[email protected]>
 
         Follow up to bug#179762. Fix PreciseLocalClobberize to handle Spread/PhantomSpread(PhantomNewArrayBuffer)

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (226127 => 226128)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-12-19 19:16:21 UTC (rev 226128)
@@ -1673,6 +1673,7 @@
 		E3201C1E1F8E824C0076A032 /* ScriptFetchParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = E38D060C1F8E814100649CF2 /* ScriptFetchParameters.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E322E5A31DA64439006E7709 /* DFGSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E322E5A11DA64435006E7709 /* DFGSnippetParams.h */; };
 		E322E5A71DA644A8006E7709 /* FTLSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E322E5A51DA644A4006E7709 /* FTLSnippetParams.h */; };
+		E3282BBB1FE930AF00EDAF71 /* YarrErrorCode.h in Headers */ = {isa = PBXBuildFile; fileRef = E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328C6C71DA4304500D255FD /* MaxFrameExtentForSlowPathCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328C6C81DA4306100D255FD /* RegisterAtOffsetList.h in Headers */ = {isa = PBXBuildFile; fileRef = 6540C79D1B82D99D000F6B79 /* RegisterAtOffsetList.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328C6C91DA432F900D255FD /* RegisterAtOffset.h in Headers */ = {isa = PBXBuildFile; fileRef = 6540C79F1B82D9CE000F6B79 /* RegisterAtOffset.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4498,6 +4499,8 @@
 		E322E5A41DA644A4006E7709 /* FTLSnippetParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSnippetParams.cpp; path = ftl/FTLSnippetParams.cpp; sourceTree = "<group>"; };
 		E322E5A51DA644A4006E7709 /* FTLSnippetParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSnippetParams.h; path = ftl/FTLSnippetParams.h; sourceTree = "<group>"; };
 		E326C4961ECBEF5700A9A905 /* ClassInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassInfo.cpp; sourceTree = "<group>"; };
+		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
+		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
 		E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; };
 		E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; };
 		E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; };
@@ -7002,6 +7005,8 @@
 				863C6D991521111200585E4E /* YarrCanonicalize.h */,
 				863C6D981521111200585E4E /* YarrCanonicalizeUCS2.cpp */,
 				863C6D9A1521111200585E4E /* YarrCanonicalizeUCS2.js */,
+				E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */,
+				E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */,
 				86704B7D12DBA33700A9FE7B /* YarrInterpreter.cpp */,
 				86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */,
 				86704B7F12DBA33700A9FE7B /* YarrJIT.cpp */,
@@ -9466,6 +9471,7 @@
 				9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
 				9959E92E1BD17FA4001AA413 /* xxd.pl in Headers */,
 				451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
+				E3282BBB1FE930AF00EDAF71 /* YarrErrorCode.h in Headers */,
 				86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
 				86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
 				86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
@@ -9999,6 +10005,7 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				FE05FAFD1FE4CEDA00093230 /* DeprecatedInspectorValues.cpp in Sources */,
 				536B319E1F735F160037FC33 /* LowLevelInterpreter.cpp in Sources */,
 				0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
 				0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
@@ -10107,7 +10114,6 @@
 				536B31411F71C5990037FC33 /* UnifiedSource94.cpp in Sources */,
 				536B31381F71C5990037FC33 /* UnifiedSource95.cpp in Sources */,
 				536B312F1F71C5990037FC33 /* UnifiedSource96.cpp in Sources */,
-				FE05FAFD1FE4CEDA00093230 /* DeprecatedInspectorValues.cpp in Sources */,
 				536B31361F71C5990037FC33 /* UnifiedSource97.cpp in Sources */,
 				536B316A1F71C5990037FC33 /* UnifiedSource98.cpp in Sources */,
 				536B31631F71C5990037FC33 /* UnifiedSource99.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/Sources.txt (226127 => 226128)


--- trunk/Source/_javascript_Core/Sources.txt	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/Sources.txt	2017-12-19 19:16:21 UTC (rev 226128)
@@ -1015,6 +1015,7 @@
 
 yarr/RegularExpression.cpp
 yarr/YarrCanonicalizeUCS2.cpp
+yarr/YarrErrorCode.cpp
 yarr/YarrInterpreter.cpp
 yarr/YarrJIT.cpp
 yarr/YarrPattern.cpp

Modified: trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -177,9 +177,9 @@
     if (content.isEmpty())
         return String();
 
-    const char* error = nullptr;
-    YarrPattern pattern(patternString, JSC::RegExpFlags::FlagMultiline, &error);
-    ASSERT(!error);
+    JSC::Yarr::ErrorCode error { JSC::Yarr::ErrorCode::NoError };
+    YarrPattern pattern(patternString, JSC::RegExpFlags::FlagMultiline, error);
+    ASSERT(!hasError(error));
     BumpPointerAllocator regexAllocator;
     auto bytecodePattern = byteCompile(pattern, &regexAllocator);
     ASSERT(bytecodePattern);

Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (226127 => 226128)


--- trunk/Source/_javascript_Core/parser/ASTBuilder.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -335,7 +335,7 @@
 
     ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start)
     {
-        if (Yarr::checkSyntax(pattern.string(), flags.string()))
+        if (Yarr::hasError(Yarr::checkSyntax(pattern.string(), flags.string())))
             return 0;
         RegExpNode* node = new (m_parserArena) RegExpNode(location, pattern, flags);
         int size = pattern.length() + 2; // + 2 for the two /'s

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -4547,8 +4547,8 @@
         next();
         TreeExpression re = context.createRegExp(location, *pattern, *flags, start);
         if (!re) {
-            const char* yarrErrorMsg = Yarr::checkSyntax(pattern->string(), flags->string());
-            regexFail(yarrErrorMsg);
+            Yarr::ErrorCode errorCode = Yarr::checkSyntax(pattern->string(), flags->string());
+            regexFail(Yarr::errorMessage(errorCode));
         }
         return re;
     }

Modified: trunk/Source/_javascript_Core/parser/SyntaxChecker.h (226127 => 226128)


--- trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/parser/SyntaxChecker.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -181,7 +181,7 @@
     ExpressionType createNull(const JSTokenLocation&) { return NullExpr; }
     ExpressionType createBracketAccess(const JSTokenLocation&, ExpressionType, ExpressionType, bool, int, int, int) { return BracketExpr; }
     ExpressionType createDotAccess(const JSTokenLocation&, ExpressionType, const Identifier*, int, int, int) { return DotExpr; }
-    ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags, int) { return Yarr::checkSyntax(pattern.string(), flags.string()) ? 0 : RegExpExpr; }
+    ExpressionType createRegExp(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags, int) { return Yarr::hasError(Yarr::checkSyntax(pattern.string(), flags.string())) ? 0 : RegExpExpr; }
     ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int, int, int) { return NewExpr; }
     ExpressionType createNewExpr(const JSTokenLocation&, ExpressionType, int, int) { return NewExpr; }
     ExpressionType createConditionalExpr(const JSTokenLocation&, ExpressionType, ExpressionType, ExpressionType) { return ConditionalExpr; }

Modified: trunk/Source/_javascript_Core/runtime/RegExp.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/runtime/RegExp.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/runtime/RegExp.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -214,16 +214,6 @@
     , m_state(NotCompiled)
     , m_patternString(patternString)
     , m_flags(flags)
-    , m_constructionError(0)
-    , m_numSubpatterns(0)
-#if ENABLE(REGEXP_TRACING)
-    , m_rtMatchOnlyTotalSubjectStringLen(0.0)
-    , m_rtMatchTotalSubjectStringLen(0.0)
-    , m_rtMatchOnlyCallCount(0)
-    , m_rtMatchOnlyFoundCount(0)
-    , m_rtMatchCallCount(0)
-    , m_rtMatchFoundCount(0)
-#endif
 {
 }
 
@@ -230,7 +220,7 @@
 void RegExp::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    Yarr::YarrPattern pattern(m_patternString, m_flags, &m_constructionError, vm.stackLimit());
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm.stackLimit());
     if (!isValid())
         m_state = ParseError;
     else {
@@ -282,8 +272,8 @@
     if (m_regExpBytecode)
         return;
 
-    Yarr::YarrPattern pattern(m_patternString, m_flags, &m_constructionError, vm->stackLimit());
-    if (m_constructionError) {
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    if (hasError(m_constructionErrorCode)) {
         RELEASE_ASSERT_NOT_REACHED();
 #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;
@@ -299,8 +289,8 @@
 {
     ConcurrentJSLocker locker(m_lock);
     
-    Yarr::YarrPattern pattern(m_patternString, m_flags, &m_constructionError, vm->stackLimit());
-    if (m_constructionError) {
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    if (hasError(m_constructionErrorCode)) {
         RELEASE_ASSERT_NOT_REACHED();
 #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;
@@ -355,8 +345,8 @@
 {
     ConcurrentJSLocker locker(m_lock);
     
-    Yarr::YarrPattern pattern(m_patternString, m_flags, &m_constructionError, vm->stackLimit());
-    if (m_constructionError) {
+    Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
+    if (hasError(m_constructionErrorCode)) {
         RELEASE_ASSERT_NOT_REACHED();
 #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
         m_state = ParseError;

Modified: trunk/Source/_javascript_Core/runtime/RegExp.h (226127 => 226128)


--- trunk/Source/_javascript_Core/runtime/RegExp.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/runtime/RegExp.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -60,8 +60,8 @@
 
     const String& pattern() const { return m_patternString; }
 
-    bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
-    const char* errorMessage() const { return m_constructionError; }
+    bool isValid() const { return !Yarr::hasError(m_constructionErrorCode) && m_flags != InvalidFlags; }
+    const char* errorMessage() const { return Yarr::errorMessage(m_constructionErrorCode); }
 
     JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int>& ovector);
 
@@ -138,8 +138,6 @@
         NotCompiled
     };
 
-    RegExpState m_state;
-
     void byteCodeCompileIfNecessary(VM*);
 
     void compile(VM*, Yarr::YarrCharSize);
@@ -152,19 +150,20 @@
     void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
 #endif
 
+    RegExpState m_state { NotCompiled };
     String m_patternString;
     RegExpFlags m_flags;
-    const char* m_constructionError;
-    unsigned m_numSubpatterns;
+    Yarr::ErrorCode m_constructionErrorCode { Yarr::ErrorCode::NoError };
+    unsigned m_numSubpatterns { 0 };
     Vector<String> m_captureGroupNames;
     HashMap<String, unsigned> m_namedGroupToParenIndex;
 #if ENABLE(REGEXP_TRACING)
-    double m_rtMatchOnlyTotalSubjectStringLen;
-    double m_rtMatchTotalSubjectStringLen;
-    unsigned m_rtMatchOnlyCallCount;
-    unsigned m_rtMatchOnlyFoundCount;
-    unsigned m_rtMatchCallCount;
-    unsigned m_rtMatchFoundCount;
+    double m_rtMatchOnlyTotalSubjectStringLen { 0.0 };
+    double m_rtMatchTotalSubjectStringLen { 0.0 };
+    unsigned m_rtMatchOnlyCallCount { 0 };
+    unsigned m_rtMatchOnlyFoundCount { 0 };
+    unsigned m_rtMatchCallCount { 0 };
+    unsigned m_rtMatchFoundCount { 0 };
 #endif
     ConcurrentJSLock m_lock;
 

Modified: trunk/Source/_javascript_Core/yarr/RegularExpression.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/RegularExpression.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/RegularExpression.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -42,7 +42,7 @@
         return adoptRef(*new Private(pattern, caseSensitivity, multilineMode));
     }
 
-    int lastMatchLength;
+    int lastMatchLength { -1 };
 
     unsigned m_numSubpatterns;
     std::unique_ptr<JSC::Yarr::BytecodePattern> m_regExpByteCode;
@@ -49,9 +49,7 @@
 
 private:
     Private(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)
-        : lastMatchLength(-1)
-        , m_regExpByteCode(compile(pattern, caseSensitivity, multilineMode))
-        , m_constructionError(nullptr)
+        : m_regExpByteCode(compile(pattern, caseSensitivity, multilineMode))
     {
     }
 
@@ -65,9 +63,9 @@
         if (multilineMode == MultilineEnabled)
             flags = static_cast<RegExpFlags>(flags | FlagMultiline);
 
-        JSC::Yarr::YarrPattern pattern(patternString, flags, &m_constructionError);
-        if (m_constructionError) {
-            LOG_ERROR("RegularExpression: YARR compile failed with '%s'", m_constructionError);
+        JSC::Yarr::YarrPattern pattern(patternString, flags, m_constructionErrorCode);
+        if (JSC::Yarr::hasError(m_constructionErrorCode)) {
+            LOG_ERROR("RegularExpression: YARR compile failed with '%s'", JSC::Yarr::errorMessage(m_constructionErrorCode));
             return nullptr;
         }
 
@@ -77,7 +75,7 @@
     }
 
     BumpPointerAllocator m_regexAllocator;
-    const char* m_constructionError;
+    JSC::Yarr::ErrorCode m_constructionErrorCode { Yarr::ErrorCode::NoError };
 };
 
 RegularExpression::RegularExpression(const String& pattern, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode)

Added: trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp (0 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2017 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "YarrErrorCode.h"
+
+namespace JSC { namespace Yarr {
+
+const char* errorMessage(ErrorCode error)
+{
+#define REGEXP_ERROR_PREFIX "Invalid regular _expression_: "
+    // The order of this array must match the ErrorCode enum.
+    static const char* errorMessages[] = {
+        nullptr,                                                              // NoError
+        REGEXP_ERROR_PREFIX "regular _expression_ too large",                   // PatternTooLarge
+        REGEXP_ERROR_PREFIX "numbers out of order in {} quantifier",          // QuantifierOutOfOrder
+        REGEXP_ERROR_PREFIX "nothing to repeat",                              // QuantifierWithoutAtom
+        REGEXP_ERROR_PREFIX "number too large in {} quantifier",              // QuantifierTooLarge
+        REGEXP_ERROR_PREFIX "missing )",                                      // MissingParentheses
+        REGEXP_ERROR_PREFIX "unmatched parentheses",                          // ParenthesesUnmatched
+        REGEXP_ERROR_PREFIX "unrecognized character after (?",                // ParenthesesTypeInvalid
+        REGEXP_ERROR_PREFIX "invalid group specifier name",                   // InvalidGroupName
+        REGEXP_ERROR_PREFIX "duplicate group specifier name",                 // DuplicateGroupName
+        REGEXP_ERROR_PREFIX "missing terminating ] for character class",      // CharacterClassUnmatched
+        REGEXP_ERROR_PREFIX "range out of order in character class",          // CharacterClassOutOfOrder
+        REGEXP_ERROR_PREFIX "\\ at end of pattern",                           // EscapeUnterminated
+        REGEXP_ERROR_PREFIX "invalid unicode {} escape",                      // InvalidUnicodeEscape
+        REGEXP_ERROR_PREFIX "invalid backreference for unicode pattern",      // InvalidBackreference
+        REGEXP_ERROR_PREFIX "invalid escaped character for unicode pattern",  // InvalidIdentityEscape
+        REGEXP_ERROR_PREFIX "invalid property _expression_",                    // InvalidUnicodePropertyExpression
+        REGEXP_ERROR_PREFIX "too many nested disjunctions",                   // TooManyDisjunctions
+        REGEXP_ERROR_PREFIX "pattern exceeds string length limits",           // OffsetTooLarge
+        REGEXP_ERROR_PREFIX "invalid flags"                                   // InvalidRegularExpressionFlags
+    };
+
+    return errorMessages[static_cast<unsigned>(error)];
+}
+
+} } // namespace JSC::Yarr

Copied: trunk/Source/_javascript_Core/yarr/YarrErrorCode.h (from rev 226127, trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.h) (0 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrErrorCode.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/yarr/YarrErrorCode.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 Yusuke Suzuki <[email protected]>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+namespace JSC { namespace Yarr {
+
+enum class ErrorCode : unsigned {
+    NoError = 0,
+    PatternTooLarge,
+    QuantifierOutOfOrder,
+    QuantifierWithoutAtom,
+    QuantifierTooLarge,
+    MissingParentheses,
+    ParenthesesUnmatched,
+    ParenthesesTypeInvalid,
+    InvalidGroupName,
+    DuplicateGroupName,
+    CharacterClassUnmatched,
+    CharacterClassOutOfOrder,
+    EscapeUnterminated,
+    InvalidUnicodeEscape,
+    InvalidBackreference,
+    InvalidIdentityEscape,
+    InvalidUnicodePropertyExpression,
+    TooManyDisjunctions,
+    OffsetTooLarge,
+    InvalidRegularExpressionFlags,
+};
+
+JS_EXPORT_PRIVATE const char* errorMessage(ErrorCode);
+inline bool hasError(ErrorCode errorCode)
+{
+    return errorCode != ErrorCode::NoError;
+}
+
+} } // namespace JSC::Yarr

Modified: trunk/Source/_javascript_Core/yarr/YarrParser.h (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrParser.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/YarrParser.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -41,7 +41,7 @@
 class Parser {
 private:
     template<class FriendDelegate>
-    friend const char* parse(FriendDelegate&, const String& pattern, bool isUnicode, unsigned backReferenceLimit);
+    friend ErrorCode parse(FriendDelegate&, const String& pattern, bool isUnicode, unsigned backReferenceLimit);
 
     /*
      * CharacterClassParserDelegate:
@@ -54,9 +54,9 @@
      */
     class CharacterClassParserDelegate {
     public:
-        CharacterClassParserDelegate(Delegate& delegate, YarrPattern::ErrorCode& err)
+        CharacterClassParserDelegate(Delegate& delegate, ErrorCode& err)
             : m_delegate(delegate)
-            , m_err(err)
+            , m_errorCode(err)
             , m_state(Empty)
             , m_character(0)
         {
@@ -116,7 +116,7 @@
 
             case CachedCharacterHyphen:
                 if (ch < m_character) {
-                    m_err = YarrPattern::CharacterClassOutOfOrder;
+                    m_errorCode = ErrorCode::CharacterClassOutOfOrder;
                     return;
                 }
                 m_delegate.atomCharacterClassRange(m_character, ch);
@@ -198,7 +198,7 @@
 
     private:
         Delegate& m_delegate;
-        YarrPattern::ErrorCode& m_err;
+        ErrorCode& m_errorCode;
         enum CharacterClassConstructionState {
             Empty,
             CachedCharacter,
@@ -212,12 +212,9 @@
     Parser(Delegate& delegate, const String& pattern, bool isUnicode, unsigned backReferenceLimit)
         : m_delegate(delegate)
         , m_backReferenceLimit(backReferenceLimit)
-        , m_err(YarrPattern::NoError)
         , m_data(pattern.characters<CharType>())
         , m_size(pattern.length())
-        , m_index(0)
         , m_isUnicode(isUnicode)
-        , m_parenthesesNestingDepth(0)
     {
     }
 
@@ -227,7 +224,7 @@
     bool isIdentityEscapeAnError(int ch)
     {
         if (m_isUnicode && !strchr("^$\\.*+?()[]{}|/", ch)) {
-            m_err = YarrPattern::InvalidIdentityEscape;
+            m_errorCode = ErrorCode::InvalidIdentityEscape;
             return true;
         }
 
@@ -257,12 +254,12 @@
     template<bool inCharacterClass, class EscapeDelegate>
     bool parseEscape(EscapeDelegate& delegate)
     {
-        ASSERT(!m_err);
+        ASSERT(!hasError(m_errorCode));
         ASSERT(peek() == '\\');
         consume();
 
         if (atEndOfPattern()) {
-            m_err = YarrPattern::EscapeUnterminated;
+            m_errorCode = ErrorCode::EscapeUnterminated;
             return false;
         }
 
@@ -343,7 +340,7 @@
                 restoreState(state);
 
                 if (m_isUnicode) {
-                    m_err = YarrPattern::InvalidBackreference;
+                    m_errorCode = ErrorCode::InvalidBackreference;
                     return false;
                 }
             }
@@ -429,7 +426,7 @@
                         break;
                     }
                     if (m_isUnicode) {
-                        m_err = YarrPattern::InvalidBackreference;
+                        m_errorCode = ErrorCode::InvalidBackreference;
                         break;
                     }
                 }
@@ -455,12 +452,12 @@
                 consume();
                 auto optClassID = tryConsumeUnicodePropertyExpression();
                 if (!optClassID) {
-                    // tryConsumeUnicodePropertyExpression() will set m_err for a malformed property _expression_
+                    // tryConsumeUnicodePropertyExpression() will set m_errorCode for a malformed property _expression_
                     break;
                 }
                 delegate.atomBuiltInCharacterClass(optClassID.value(), escapeChar == 'P');
             } else
-                m_err = YarrPattern::InvalidUnicodePropertyExpression;
+                m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
             break;
         }
 
@@ -480,7 +477,7 @@
                 UChar32 codePoint = 0;
                 do {
                     if (atEndOfPattern() || !isASCIIHexDigit(peek())) {
-                        m_err = YarrPattern::InvalidUnicodeEscape;
+                        m_errorCode = ErrorCode::InvalidUnicodeEscape;
                         break;
                     }
 
@@ -487,13 +484,13 @@
                     codePoint = (codePoint << 4) | toASCIIHexValue(consume());
 
                     if (codePoint > UCHAR_MAX_VALUE)
-                        m_err = YarrPattern::InvalidUnicodeEscape;
+                        m_errorCode = ErrorCode::InvalidUnicodeEscape;
                 } while (!atEndOfPattern() && peek() != '}');
                 if (!atEndOfPattern() && peek() == '}')
                     consume();
-                else if (!m_err)
-                    m_err = YarrPattern::InvalidUnicodeEscape;
-                if (m_err)
+                else if (!hasError(m_errorCode))
+                    m_errorCode = ErrorCode::InvalidUnicodeEscape;
+                if (hasError(m_errorCode))
                     return false;
 
                 delegate.atomPatternCharacter(codePoint);
@@ -585,11 +582,11 @@
      */
     void parseCharacterClass()
     {
-        ASSERT(!m_err);
+        ASSERT(!hasError(m_errorCode));
         ASSERT(peek() == '[');
         consume();
 
-        CharacterClassParserDelegate characterClassConstructor(m_delegate, m_err);
+        CharacterClassParserDelegate characterClassConstructor(m_delegate, m_errorCode);
 
         characterClassConstructor.begin(tryConsume('^'));
 
@@ -608,11 +605,11 @@
                 characterClassConstructor.atomPatternCharacter(consumePossibleSurrogatePair(), true);
             }
 
-            if (m_err)
+            if (hasError(m_errorCode))
                 return;
         }
 
-        m_err = YarrPattern::CharacterClassUnmatched;
+        m_errorCode = ErrorCode::CharacterClassUnmatched;
     }
 
     /*
@@ -622,13 +619,13 @@
      */
     void parseParenthesesBegin()
     {
-        ASSERT(!m_err);
+        ASSERT(!hasError(m_errorCode));
         ASSERT(peek() == '(');
         consume();
 
         if (tryConsume('?')) {
             if (atEndOfPattern()) {
-                m_err = YarrPattern::ParenthesesTypeInvalid;
+                m_errorCode = ErrorCode::ParenthesesTypeInvalid;
                 return;
             }
 
@@ -652,15 +649,15 @@
                     if (setAddResult.isNewEntry)
                         m_delegate.atomParenthesesSubpatternBegin(true, groupName);
                     else
-                        m_err = YarrPattern::DuplicateGroupName;
+                        m_errorCode = ErrorCode::DuplicateGroupName;
                 } else
-                    m_err = YarrPattern::InvalidGroupName;
+                    m_errorCode = ErrorCode::InvalidGroupName;
 
                 break;
             }
 
             default:
-                m_err = YarrPattern::ParenthesesTypeInvalid;
+                m_errorCode = ErrorCode::ParenthesesTypeInvalid;
             }
         } else
             m_delegate.atomParenthesesSubpatternBegin();
@@ -675,7 +672,7 @@
      */
     void parseParenthesesEnd()
     {
-        ASSERT(!m_err);
+        ASSERT(!hasError(m_errorCode));
         ASSERT(peek() == ')');
         consume();
 
@@ -682,7 +679,7 @@
         if (m_parenthesesNestingDepth > 0)
             m_delegate.atomParenthesesEnd();
         else
-            m_err = YarrPattern::ParenthesesUnmatched;
+            m_errorCode = ErrorCode::ParenthesesUnmatched;
 
         --m_parenthesesNestingDepth;
     }
@@ -694,11 +691,11 @@
      */
     void parseQuantifier(bool lastTokenWasAnAtom, unsigned min, unsigned max)
     {
-        ASSERT(!m_err);
+        ASSERT(!hasError(m_errorCode));
         ASSERT(min <= max);
 
         if (min == UINT_MAX) {
-            m_err = YarrPattern::QuantifierTooLarge;
+            m_errorCode = ErrorCode::QuantifierTooLarge;
             return;
         }
 
@@ -705,7 +702,7 @@
         if (lastTokenWasAnAtom)
             m_delegate.quantifyAtom(min, max, !tryConsume('?'));
         else
-            m_err = YarrPattern::QuantifierWithoutAtom;
+            m_errorCode = ErrorCode::QuantifierWithoutAtom;
     }
 
     /*
@@ -799,7 +796,7 @@
                         if (min <= max)
                             parseQuantifier(lastTokenWasAnAtom, min, max);
                         else
-                            m_err = YarrPattern::QuantifierOutOfOrder;
+                            m_errorCode = ErrorCode::QuantifierOutOfOrder;
                         lastTokenWasAnAtom = false;
                         break;
                     }
@@ -815,29 +812,28 @@
                 lastTokenWasAnAtom = true;
             }
 
-            if (m_err)
+            if (hasError(m_errorCode))
                 return;
         }
 
         if (m_parenthesesNestingDepth > 0)
-            m_err = YarrPattern::MissingParentheses;
+            m_errorCode = ErrorCode::MissingParentheses;
     }
 
     /*
      * parse():
      *
-     * This method calls parseTokens() to parse over the input and converts any
-     * error code to a const char* for a result.
+     * This method calls parseTokens() to parse over the input and returns error code for a result.
      */
-    const char* parse()
+    ErrorCode parse()
     {
         if (m_size > MAX_PATTERN_SIZE)
-            m_err = YarrPattern::PatternTooLarge;
+            m_errorCode = ErrorCode::PatternTooLarge;
         else
             parseTokens();
-        ASSERT(atEndOfPattern() || m_err);
+        ASSERT(atEndOfPattern() || hasError(m_errorCode));
         
-        return YarrPattern::errorMessage(m_err);
+        return m_errorCode;
     }
 
     // Misc helper functions:
@@ -892,7 +888,7 @@
             int codePoint = 0;
             do {
                 if (atEndOfPattern() || !isASCIIHexDigit(peek())) {
-                    m_err = YarrPattern::InvalidUnicodeEscape;
+                    m_errorCode = ErrorCode::InvalidUnicodeEscape;
                     return -1;
                 }
 
@@ -899,15 +895,15 @@
                 codePoint = (codePoint << 4) | toASCIIHexValue(consume());
 
                 if (codePoint > UCHAR_MAX_VALUE) {
-                    m_err = YarrPattern::InvalidUnicodeEscape;
+                    m_errorCode = ErrorCode::InvalidUnicodeEscape;
                     return -1;
                 }
             } while (!atEndOfPattern() && peek() != '}');
             if (!atEndOfPattern() && peek() == '}')
                 consume();
-            else if (!m_err)
-                m_err = YarrPattern::InvalidUnicodeEscape;
-            if (m_err)
+            else if (!hasError(m_errorCode))
+                m_errorCode = ErrorCode::InvalidUnicodeEscape;
+            if (hasError(m_errorCode))
                 return -1;
 
             return codePoint;
@@ -1053,7 +1049,7 @@
     std::optional<BuiltInCharacterClassID> tryConsumeUnicodePropertyExpression()
     {
         if (atEndOfPattern() || !isUnicodePropertyValueExpressionChar(peek())) {
-            m_err = YarrPattern::InvalidUnicodePropertyExpression;
+            m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
             return std::nullopt;
         }
 
@@ -1069,7 +1065,7 @@
             if (ch == '}') {
                 consume();
                 if (errors) {
-                    m_err = YarrPattern::InvalidUnicodePropertyExpression;
+                    m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
                     return std::nullopt;
                 }
 
@@ -1076,13 +1072,13 @@
                 if (foundEquals) {
                     auto result = unicodeMatchPropertyValue(unicodePropertyName, expressionBuilder.toString());
                     if (!result)
-                        m_err = YarrPattern::InvalidUnicodePropertyExpression;
+                        m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
                     return result;
                 }
 
                 auto result = unicodeMatchProperty(expressionBuilder.toString());
                 if (!result)
-                    m_err = YarrPattern::InvalidUnicodePropertyExpression;
+                    m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
                 return result;
             }
 
@@ -1100,18 +1096,18 @@
                 expressionBuilder.append(ch);
         }
 
-        m_err = YarrPattern::InvalidUnicodePropertyExpression;
+        m_errorCode = ErrorCode::InvalidUnicodePropertyExpression;
         return std::nullopt;
     }
 
     Delegate& m_delegate;
     unsigned m_backReferenceLimit;
-    YarrPattern::ErrorCode m_err;
+    ErrorCode m_errorCode { ErrorCode::NoError };
     const CharType* m_data;
     unsigned m_size;
-    unsigned m_index;
+    unsigned m_index { 0 };
     bool m_isUnicode;
-    unsigned m_parenthesesNestingDepth;
+    unsigned m_parenthesesNestingDepth { 0 };
     HashSet<String> m_captureGroupNames;
 
     // Derived by empirical testing of compile time in PCRE and WREC.
@@ -1179,7 +1175,7 @@
  */
 
 template<class Delegate>
-const char* parse(Delegate& delegate, const String& pattern, bool isUnicode, unsigned backReferenceLimit = quantifyInfinite)
+ErrorCode parse(Delegate& delegate, const String& pattern, bool isUnicode, unsigned backReferenceLimit = quantifyInfinite)
 {
     if (pattern.is8Bit())
         return Parser<Delegate, LChar>(delegate, pattern, isUnicode, backReferenceLimit).parse();

Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrPattern.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -435,7 +435,6 @@
         : m_pattern(pattern)
         , m_characterClassConstructor(pattern.ignoreCase(), pattern.unicode() ? CanonicalMode::Unicode : CanonicalMode::UCS2)
         , m_stackLimit(stackLimit)
-        , m_invertParentheticalAssertion(false)
     {
         auto body = std::make_unique<PatternDisjunction>();
         m_pattern.m_body = body.get();
@@ -764,12 +763,12 @@
         m_alternative = m_alternative->m_parent->addNewAlternative();
     }
 
-    YarrPattern::ErrorCode setupAlternativeOffsets(PatternAlternative* alternative, unsigned currentCallFrameSize, unsigned initialInputPosition, unsigned& newCallFrameSize) WARN_UNUSED_RETURN
+    ErrorCode setupAlternativeOffsets(PatternAlternative* alternative, unsigned currentCallFrameSize, unsigned initialInputPosition, unsigned& newCallFrameSize) WARN_UNUSED_RETURN
     {
         if (UNLIKELY(!isSafeToRecurse()))
-            return YarrPattern::TooManyDisjunctions;
+            return ErrorCode::TooManyDisjunctions;
 
-        YarrPattern::ErrorCode error = YarrPattern::NoError;
+        ErrorCode error = ErrorCode::NoError;
         alternative->m_hasFixedSize = true;
         Checked<unsigned, RecordOverflow> currentInputPosition = initialInputPosition;
 
@@ -803,7 +802,7 @@
                     Checked<unsigned, RecordOverflow> tempCount = term.quantityMaxCount;
                     tempCount *= U16_LENGTH(term.patternCharacter);
                     if (tempCount.hasOverflowed())
-                        return YarrPattern::OffsetTooLarge;
+                        return ErrorCode::OffsetTooLarge;
                     currentInputPosition += tempCount;
                 } else
                     currentInputPosition += term.quantityMaxCount;
@@ -830,7 +829,7 @@
                 if (term.quantityMaxCount == 1 && !term.parentheses.isCopy) {
                     currentCallFrameSize += YarrStackSpaceForBackTrackInfoParenthesesOnce;
                     error = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, currentInputPosition.unsafeGet(), currentCallFrameSize);
-                    if (error)
+                    if (hasError(error))
                         return error;
                     // If quantity is fixed, then pre-check its minimum size.
                     if (term.quantityType == QuantifierFixedCount)
@@ -839,7 +838,7 @@
                 } else if (term.parentheses.isTerminal) {
                     currentCallFrameSize += YarrStackSpaceForBackTrackInfoParenthesesTerminal;
                     error = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, currentInputPosition.unsafeGet(), currentCallFrameSize);
-                    if (error)
+                    if (hasError(error))
                         return error;
                     term.inputPosition = currentInputPosition.unsafeGet();
                 } else {
@@ -846,7 +845,7 @@
                     term.inputPosition = currentInputPosition.unsafeGet();
                     currentCallFrameSize += YarrStackSpaceForBackTrackInfoParentheses;
                     error = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, currentInputPosition.unsafeGet(), currentCallFrameSize);
-                    if (error)
+                    if (hasError(error))
                         return error;
                 }
                 // Fixed count of 1 could be accepted, if they have a fixed size *AND* if all alternatives are of the same length.
@@ -857,7 +856,7 @@
                 term.inputPosition = currentInputPosition.unsafeGet();
                 term.frameLocation = currentCallFrameSize;
                 error = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize + YarrStackSpaceForBackTrackInfoParentheticalAssertion, currentInputPosition.unsafeGet(), currentCallFrameSize);
-                if (error)
+                if (hasError(error))
                     return error;
                 break;
 
@@ -871,7 +870,7 @@
                 break;
             }
             if (currentInputPosition.hasOverflowed())
-                return YarrPattern::OffsetTooLarge;
+                return ErrorCode::OffsetTooLarge;
         }
 
         alternative->m_minimumSize = (currentInputPosition - initialInputPosition).unsafeGet();
@@ -879,10 +878,10 @@
         return error;
     }
 
-    YarrPattern::ErrorCode setupDisjunctionOffsets(PatternDisjunction* disjunction, unsigned initialCallFrameSize, unsigned initialInputPosition, unsigned& callFrameSize)
+    ErrorCode setupDisjunctionOffsets(PatternDisjunction* disjunction, unsigned initialCallFrameSize, unsigned initialInputPosition, unsigned& callFrameSize)
     {
         if (UNLIKELY(!isSafeToRecurse()))
-            return YarrPattern::TooManyDisjunctions;
+            return ErrorCode::TooManyDisjunctions;
 
         if ((disjunction != m_pattern.m_body) && (disjunction->m_alternatives.size() > 1))
             initialCallFrameSize += YarrStackSpaceForBackTrackInfoAlternative;
@@ -890,13 +889,13 @@
         unsigned minimumInputSize = UINT_MAX;
         unsigned maximumCallFrameSize = 0;
         bool hasFixedSize = true;
-        YarrPattern::ErrorCode error = YarrPattern::NoError;
+        ErrorCode error = ErrorCode::NoError;
 
         for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
             PatternAlternative* alternative = disjunction->m_alternatives[alt].get();
             unsigned currentAlternativeCallFrameSize;
             error = setupAlternativeOffsets(alternative, initialCallFrameSize, initialInputPosition, currentAlternativeCallFrameSize);
-            if (error)
+            if (hasError(error))
                 return error;
             minimumInputSize = std::min(minimumInputSize, alternative->m_minimumSize);
             maximumCallFrameSize = std::max(maximumCallFrameSize, currentAlternativeCallFrameSize);
@@ -915,14 +914,11 @@
         return error;
     }
 
-    const char* setupOffsets()
+    ErrorCode setupOffsets()
     {
         // FIXME: Yarr should not use the stack to handle subpatterns (rdar://problem/26436314).
         unsigned ignoredCallFrameSize;
-        YarrPattern::ErrorCode error = setupDisjunctionOffsets(m_pattern.m_body, 0, 0, ignoredCallFrameSize);
-        if (error)
-            return YarrPattern::errorMessage(error);
-        return nullptr;
+        return setupDisjunctionOffsets(m_pattern.m_body, 0, 0, ignoredCallFrameSize);
     }
 
     // This optimization identifies sets of parentheses that we will never need to backtrack.
@@ -1084,48 +1080,21 @@
     CharacterClassConstructor m_characterClassConstructor;
     void* m_stackLimit;
     bool m_invertCharacterClass;
-    bool m_invertParentheticalAssertion;
+    bool m_invertParentheticalAssertion { false };
 };
 
-const char* YarrPattern::errorMessage(YarrPattern::ErrorCode error)
+ErrorCode YarrPattern::compile(const String& patternString, void* stackLimit)
 {
-#define REGEXP_ERROR_PREFIX "Invalid regular _expression_: "
-    // The order of this array must match the ErrorCode enum.
-    static const char* errorMessages[NumberOfErrorCodes] = {
-        nullptr,                                                              // NoError
-        REGEXP_ERROR_PREFIX "regular _expression_ too large",                   // PatternTooLarge     
-        REGEXP_ERROR_PREFIX "numbers out of order in {} quantifier",          // QuantifierOutOfOrder
-        REGEXP_ERROR_PREFIX "nothing to repeat",                              // QuantifierWithoutAtom
-        REGEXP_ERROR_PREFIX "number too large in {} quantifier",              // QuantifierTooLarge
-        REGEXP_ERROR_PREFIX "missing )",                                      // MissingParentheses
-        REGEXP_ERROR_PREFIX "unmatched parentheses",                          // ParenthesesUnmatched
-        REGEXP_ERROR_PREFIX "unrecognized character after (?",                // ParenthesesTypeInvalid
-        REGEXP_ERROR_PREFIX "invalid group specifier name",                   // InvalidGroupName
-        REGEXP_ERROR_PREFIX "duplicate group specifier name",                 // DuplicateGroupName
-        REGEXP_ERROR_PREFIX "missing terminating ] for character class",      // CharacterClassUnmatched
-        REGEXP_ERROR_PREFIX "range out of order in character class",          // CharacterClassOutOfOrder
-        REGEXP_ERROR_PREFIX "\\ at end of pattern",                           // EscapeUnterminated
-        REGEXP_ERROR_PREFIX "invalid unicode {} escape",                      // InvalidUnicodeEscape
-        REGEXP_ERROR_PREFIX "invalid backreference for unicode pattern",      // InvalidBackreference
-        REGEXP_ERROR_PREFIX "invalid escaped character for unicode pattern",  // InvalidIdentityEscape
-        REGEXP_ERROR_PREFIX "invalid property _expression_",                    // InvalidUnicodePropertyExpression
-        REGEXP_ERROR_PREFIX "too many nested disjunctions",                   // TooManyDisjunctions
-        REGEXP_ERROR_PREFIX "pattern exceeds string length limits",           // OffsetTooLarge
-        REGEXP_ERROR_PREFIX "invalid flags"                                   // InvalidRegularExpressionFlags
-    };
-
-    return errorMessages[error];
-}
-
-const char* YarrPattern::compile(const String& patternString, void* stackLimit)
-{
     YarrPatternConstructor constructor(*this, stackLimit);
 
     if (m_flags == InvalidFlags)
-        return errorMessage(InvalidRegularExpressionFlags);
+        return ErrorCode::InvalidRegularExpressionFlags;
 
-    if (const char* error = parse(constructor, patternString, unicode()))
-        return error;
+    {
+        ErrorCode error = parse(constructor, patternString, unicode());
+        if (hasError(error))
+            return error;
+    }
     
     // If the pattern contains illegal backreferences reset & reparse.
     // Quoting Netscape's "What's new in _javascript_ 1.2",
@@ -1133,17 +1102,13 @@
     //       in \#, the \# is taken as an octal escape as described in the next row."
     if (containsIllegalBackReference()) {
         if (unicode())
-            return errorMessage(InvalidBackreference);
+            return ErrorCode::InvalidBackreference;
 
         unsigned numSubpatterns = m_numSubpatterns;
 
         constructor.reset();
-#if !ASSERT_DISABLED
-        const char* error =
-#endif
-            parse(constructor, patternString, unicode(), numSubpatterns);
-
-        ASSERT(!error);
+        ErrorCode error = parse(constructor, patternString, unicode(), numSubpatterns);
+        ASSERT_UNUSED(error, !hasError(error));
         ASSERT(numSubpatterns == m_numSubpatterns);
     }
 
@@ -1150,17 +1115,20 @@
     constructor.checkForTerminalParentheses();
     constructor.optimizeDotStarWrappedExpressions();
     constructor.optimizeBOL();
-        
-    if (const char* error = constructor.setupOffsets())
-        return error;
 
+    {
+        ErrorCode error = constructor.setupOffsets();
+        if (hasError(error))
+            return error;
+    }
+
     if (Options::dumpCompiledRegExpPatterns())
         dumpPattern(patternString);
 
-    return nullptr;
+    return ErrorCode::NoError;
 }
 
-YarrPattern::YarrPattern(const String& pattern, RegExpFlags flags, const char** error, void* stackLimit)
+YarrPattern::YarrPattern(const String& pattern, RegExpFlags flags, ErrorCode& error, void* stackLimit)
     : m_containsBackreferences(false)
     , m_containsBOL(false)
     , m_containsUnsignedLengthPattern(false)
@@ -1167,20 +1135,8 @@
     , m_hasCopiedParenSubexpressions(false)
     , m_saveInitialStartValue(false)
     , m_flags(flags)
-    , m_numSubpatterns(0)
-    , m_maxBackReference(0)
-    , anycharCached(0)
-    , newlineCached(0)
-    , digitsCached(0)
-    , spacesCached(0)
-    , wordcharCached(0)
-    , wordUnicodeIgnoreCaseCharCached(0)
-    , nondigitsCached(0)
-    , nonspacesCached(0)
-    , nonwordcharCached(0)
-    , nonwordUnicodeIgnoreCasecharCached(0)
 {
-    *error = compile(pattern, stackLimit);
+    error = compile(pattern, stackLimit);
 }
 
 void indentForNestingLevel(PrintStream& out, unsigned nestingDepth)

Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.h (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrPattern.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -27,6 +27,7 @@
 #pragma once
 
 #include "RegExpKey.h"
+#include "YarrErrorCode.h"
 #include "YarrUnicodeProperties.h"
 #include <wtf/CheckedArithmetic.h>
 #include <wtf/HashMap.h>
@@ -351,34 +352,8 @@
 
 
 struct YarrPattern {
-    JS_EXPORT_PRIVATE YarrPattern(const String& pattern, RegExpFlags, const char** error, void* stackLimit = nullptr);
+    JS_EXPORT_PRIVATE YarrPattern(const String& pattern, RegExpFlags, ErrorCode&, void* stackLimit = nullptr);
 
-    enum ErrorCode {
-        NoError,
-        PatternTooLarge,
-        QuantifierOutOfOrder,
-        QuantifierWithoutAtom,
-        QuantifierTooLarge,
-        MissingParentheses,
-        ParenthesesUnmatched,
-        ParenthesesTypeInvalid,
-        InvalidGroupName,
-        DuplicateGroupName,
-        CharacterClassUnmatched,
-        CharacterClassOutOfOrder,
-        EscapeUnterminated,
-        InvalidUnicodeEscape,
-        InvalidBackreference,
-        InvalidIdentityEscape,
-        InvalidUnicodePropertyExpression,
-        TooManyDisjunctions,
-        OffsetTooLarge,
-        InvalidRegularExpressionFlags,
-        NumberOfErrorCodes
-    };
-    
-    JS_EXPORT_PRIVATE static const char* errorMessage(ErrorCode);
-
     void reset()
     {
         m_numSubpatterns = 0;
@@ -391,16 +366,16 @@
         m_hasCopiedParenSubexpressions = false;
         m_saveInitialStartValue = false;
 
-        anycharCached = 0;
-        newlineCached = 0;
-        digitsCached = 0;
-        spacesCached = 0;
-        wordcharCached = 0;
-        wordUnicodeIgnoreCaseCharCached = 0;
-        nondigitsCached = 0;
-        nonspacesCached = 0;
-        nonwordcharCached = 0;
-        nonwordUnicodeIgnoreCasecharCached = 0;
+        anycharCached = nullptr;
+        newlineCached = nullptr;
+        digitsCached = nullptr;
+        spacesCached = nullptr;
+        wordcharCached = nullptr;
+        wordUnicodeIgnoreCaseCharCached = nullptr;
+        nondigitsCached = nullptr;
+        nonspacesCached = nullptr;
+        nonwordcharCached = nullptr;
+        nonwordUnicodeIgnoreCasecharCached = nullptr;
         unicodePropertiesCached.clear();
 
         m_disjunctions.clear();
@@ -530,9 +505,9 @@
     bool m_hasCopiedParenSubexpressions : 1;
     bool m_saveInitialStartValue : 1;
     RegExpFlags m_flags;
-    unsigned m_numSubpatterns;
-    unsigned m_maxBackReference;
-    unsigned m_initialStartValueFrameLocation;
+    unsigned m_numSubpatterns { 0 };
+    unsigned m_maxBackReference { 0 };
+    unsigned m_initialStartValueFrameLocation { 0 };
     PatternDisjunction* m_body;
     Vector<std::unique_ptr<PatternDisjunction>, 4> m_disjunctions;
     Vector<std::unique_ptr<CharacterClass>> m_userCharacterClasses;
@@ -540,18 +515,18 @@
     HashMap<String, unsigned> m_namedGroupToParenIndex;
 
 private:
-    const char* compile(const String& patternString, void* stackLimit);
+    ErrorCode compile(const String& patternString, void* stackLimit);
 
-    CharacterClass* anycharCached;
-    CharacterClass* newlineCached;
-    CharacterClass* digitsCached;
-    CharacterClass* spacesCached;
-    CharacterClass* wordcharCached;
-    CharacterClass* wordUnicodeIgnoreCaseCharCached;
-    CharacterClass* nondigitsCached;
-    CharacterClass* nonspacesCached;
-    CharacterClass* nonwordcharCached;
-    CharacterClass* nonwordUnicodeIgnoreCasecharCached;
+    CharacterClass* anycharCached { nullptr };
+    CharacterClass* newlineCached { nullptr };
+    CharacterClass* digitsCached { nullptr };
+    CharacterClass* spacesCached { nullptr };
+    CharacterClass* wordcharCached { nullptr };
+    CharacterClass* wordUnicodeIgnoreCaseCharCached { nullptr };
+    CharacterClass* nondigitsCached { nullptr };
+    CharacterClass* nonspacesCached { nullptr };
+    CharacterClass* nonwordcharCached { nullptr };
+    CharacterClass* nonwordUnicodeIgnoreCasecharCached { nullptr };
     HashMap<unsigned, CharacterClass*> unicodePropertiesCached;
 };
 

Modified: trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -53,7 +53,7 @@
     void disjunction() {}
 };
 
-const char* checkSyntax(const String& pattern, const String& flags)
+ErrorCode checkSyntax(const String& pattern, const String& flags)
 {
     SyntaxChecker syntaxChecker;
     return parse(syntaxChecker, pattern, flags.contains('u'));

Modified: trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.h (226127 => 226128)


--- trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.h	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.h	2017-12-19 19:16:21 UTC (rev 226128)
@@ -25,10 +25,11 @@
 
 #pragma once
 
+#include "YarrErrorCode.h"
 #include <wtf/text/WTFString.h>
 
 namespace JSC { namespace Yarr {
 
-const char* checkSyntax(const String& pattern, const String& flags);
+ErrorCode checkSyntax(const String& pattern, const String& flags);
 
 }} // JSC::Yarr

Modified: trunk/Source/WebCore/ChangeLog (226127 => 226128)


--- trunk/Source/WebCore/ChangeLog	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/WebCore/ChangeLog	2017-12-19 19:16:21 UTC (rev 226128)
@@ -1,3 +1,17 @@
+2017-12-19  Yusuke Suzuki  <[email protected]>
+
+        [YARR] Yarr should return ErrorCode instead of error messages (const char*)
+        https://bugs.webkit.org/show_bug.cgi?id=180966
+
+        Reviewed by Mark Lam.
+
+        Remove unnecessary String creation.
+
+        No behavior change.
+
+        * contentextensions/URLFilterParser.cpp:
+        (WebCore::ContentExtensions::URLFilterParser::addPattern):
+
 2017-12-19  Zalan Bujtas  <[email protected]>
 
         [RenderTreeBuilder] Move finding-the-parent/creating-wrapper logic from RenderTableRow::addChild to RenderTreeBuilder

Modified: trunk/Source/WebCore/contentextensions/URLFilterParser.cpp (226127 => 226128)


--- trunk/Source/WebCore/contentextensions/URLFilterParser.cpp	2017-12-19 18:56:47 UTC (rev 226127)
+++ trunk/Source/WebCore/contentextensions/URLFilterParser.cpp	2017-12-19 19:16:21 UTC (rev 226128)
@@ -348,8 +348,7 @@
 
     ParseStatus status = Ok;
     PatternParser patternParser(patternIsCaseSensitive);
-    String error = String(JSC::Yarr::parse(patternParser, pattern, false, 0));
-    if (error.isNull())
+    if (!JSC::Yarr::hasError(JSC::Yarr::parse(patternParser, pattern, false, 0)))
         patternParser.finalize(patternId, m_combinedURLFilters);
     else
         status = YarrError;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to