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, ®exAllocator);
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;