aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-21 10:24:20 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-21 10:24:20 +0100
commit5030a9d8c6a3422d5803d21937cbe9753975e019 (patch)
tree8044b34c0d8161671f404a09c50e8fb2490146d4 /src/qml/jsruntime
parent8fd3cfe7d0f39a731c585334299f5160ad952df9 (diff)
parent4ed072432172398d753d1664244d74548704c107 (diff)
Merge remote-tracking branch 'origin/5.12.1' into 5.12
Diffstat (limited to 'src/qml/jsruntime')
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp60
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp8
2 files changed, 48 insertions, 20 deletions
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();