diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/3rdparty/masm/yarr/YarrJIT.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexp.cpp | 60 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 8 |
3 files changed, 52 insertions, 24 deletions
diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp index 0655bb0a70..dee2ade407 100644 --- a/src/3rdparty/masm/yarr/YarrJIT.cpp +++ b/src/3rdparty/masm/yarr/YarrJIT.cpp @@ -3531,14 +3531,14 @@ public: if (compileMode == MatchOnly) { if (m_charSize == Char8) - codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 8-bit regular expression")); + codeBlock.set8BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarrJIT", "Match-only 8-bit regular expression")); else - codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarJIT", "Match-only 16-bit regular expression")); + codeBlock.set16BitCodeMatchOnly(FINALIZE_CODE(linkBuffer, "YarrJIT", "Match-only 16-bit regular expression")); } else { if (m_charSize == Char8) - codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "8-bit regular expression")); + codeBlock.set8BitCode(FINALIZE_CODE(linkBuffer, "YarrJIT", "8-bit regular expression")); else - codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarJIT", "16-bit regular expression")); + codeBlock.set16BitCode(FINALIZE_CODE(linkBuffer, "YarrJIT", "16-bit regular expression")); } if (m_failureReason) codeBlock.setFallBackWithFailureReason(*m_failureReason); diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp index 05c3b4c4ca..4ed1dbd5aa 100644 --- a/src/qml/jsruntime/qv4regexp.cpp +++ b/src/qml/jsruntime/qv4regexp.cpp @@ -45,6 +45,22 @@ using namespace QV4; +static JSC::RegExpFlags jscFlags(uint flags) +{ + JSC::RegExpFlags jscFlags = JSC::NoFlags; + if (flags & CompiledData::RegExp::RegExp_Global) + jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagGlobal); + if (flags & CompiledData::RegExp::RegExp_IgnoreCase) + jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagIgnoreCase); + if (flags & CompiledData::RegExp::RegExp_Multiline) + jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagMultiline); + if (flags & CompiledData::RegExp::RegExp_Unicode) + jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagUnicode); + if (flags & CompiledData::RegExp::RegExp_Sticky) + jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagSticky); + return jscFlags; +} + RegExpCache::~RegExpCache() { for (RegExpCache::Iterator it = begin(), e = end(); it != e; ++it) { @@ -57,21 +73,43 @@ DEFINE_MANAGED_VTABLE(RegExp); uint RegExp::match(const QString &string, int start, uint *matchOffsets) { + static const uint offsetJITFail = std::numeric_limits<unsigned>::max() - 1; + if (!isValid()) return JSC::Yarr::offsetNoMatch; WTF::String s(string); #if ENABLE(YARR_JIT) - if (d()->hasValidJITCode()) { + auto *priv = d(); + if (priv->hasValidJITCode()) { + uint ret = JSC::Yarr::offsetNoMatch; #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) char buffer[8192]; - return uint(jitCode()->execute(s.characters16(), start, s.length(), (int*)matchOffsets, buffer, 8192).start); + ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(), + (int*)matchOffsets, buffer, 8192).start); #else - return uint(jitCode()->execute(s.characters16(), start, s.length(), (int*)matchOffsets).start); + ret = uint(priv->jitCode->execute(s.characters16(), start, s.length(), + (int*)matchOffsets).start); #endif + if (ret != offsetJITFail) + return ret; + + // JIT failed. We need byteCode to run the interpreter. + if (!priv->byteCode) { + JSC::Yarr::ErrorCode error = JSC::Yarr::ErrorCode::NoError; + JSC::Yarr::YarrPattern yarrPattern(WTF::String(*priv->pattern), jscFlags(priv->flags), + error); + + // As we successfully parsed the pattern before, we should still be able to. + Q_ASSERT(error == JSC::Yarr::ErrorCode::NoError); + + priv->byteCode = JSC::Yarr::byteCompile( + yarrPattern, + priv->internalClass->engine->bumperPointerAllocator).release(); + } } -#endif +#endif // ENABLE(YARR_JIT) return JSC::Yarr::interpret(byteCode(), s.characters16(), string.length(), start, matchOffsets); } @@ -176,19 +214,7 @@ void Heap::RegExp::init(ExecutionEngine *engine, const QString &pattern, uint fl valid = false; JSC::Yarr::ErrorCode error = JSC::Yarr::ErrorCode::NoError; - JSC::RegExpFlags jscFlags = JSC::NoFlags; - if (flags & CompiledData::RegExp::RegExp_Global) - jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagGlobal); - if (flags & CompiledData::RegExp::RegExp_IgnoreCase) - jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagIgnoreCase); - if (flags & CompiledData::RegExp::RegExp_Multiline) - jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagMultiline); - if (flags & CompiledData::RegExp::RegExp_Unicode) - jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagUnicode); - if (flags & CompiledData::RegExp::RegExp_Sticky) - jscFlags = static_cast<JSC::RegExpFlags>(flags | JSC::FlagSticky); - - JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), jscFlags, error); + JSC::Yarr::YarrPattern yarrPattern(WTF::String(pattern), jscFlags(flags), error); if (error != JSC::Yarr::ErrorCode::NoError) return; subPatternCount = yarrPattern.m_numSubpatterns; diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 9df286065d..39a2e96b45 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -181,17 +181,19 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s } Q_ALLOCA_VAR(uint, matchOffsets, value()->captureCount() * 2 * sizeof(uint)); - const int result = Scoped<RegExp>(scope, value())->match(s, offset, matchOffsets); + const uint result = Scoped<RegExp>(scope, value())->match(s, offset, matchOffsets); RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor()); regExpCtor->d()->clearLastMatch(); - if (result == -1) { + if (result == JSC::Yarr::offsetNoMatch) { if (global() || sticky()) setLastIndex(0); RETURN_RESULT(Encode::null()); } + Q_ASSERT(result <= uint(std::numeric_limits<int>::max())); + // fill in result data ScopedArrayObject array(scope, scope.engine->newArrayObject(scope.engine->internalClasses(EngineBase::Class_RegExpExecArray))); int len = value()->captureCount(); @@ -207,7 +209,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s array->arrayPut(i, v); } array->setArrayLengthUnchecked(len); - array->setProperty(Index_ArrayIndex, Value::fromInt32(result)); + array->setProperty(Index_ArrayIndex, Value::fromInt32(int(result))); array->setProperty(Index_ArrayInput, *str); RegExpCtor::Data *dd = regExpCtor->d(); |