aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4regexpobject.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-09-01 16:26:51 +0200
committerLars Knoll <lars.knoll@qt.io>2017-09-15 10:45:19 +0000
commit4ca97d7289276816545ab01c9b49bfaaa29d8f5d (patch)
tree55e88ae9444732db290d1740fbf497e2e0db9f55 /src/qml/jsruntime/qv4regexpobject.cpp
parentacd206e317fd92f20aa4985f35288f793d05f3ac (diff)
Optimize String.match()
Change-Id: Idbf2b45a35c1bd1a843e8d01a3ea2f5157291033 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4regexpobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp48
1 files changed, 47 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index db5551f99c..c3a4275cac 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -314,6 +314,52 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
defineDefaultProperty(QStringLiteral("compile"), method_compile, 2);
}
+/* used by String.match */
+ReturnedValue RegExpPrototype::execFirstMatch(const BuiltinFunction *b, CallData *callData)
+{
+ Scope scope(b);
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
+ Q_ASSERT(r && r->global());
+
+ ScopedString str(scope, callData->args[0]);
+ Q_ASSERT(str);
+ QString s = str->toQString();
+
+ int offset = r->lastIndex();
+ if (offset < 0 || offset > s.length()) {
+ r->setLastIndex(0);
+ RETURN_RESULT(Encode::null());
+ }
+
+ Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint));
+ const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
+
+ RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
+ regExpCtor->d()->clearLastMatch();
+
+ if (result == -1) {
+ r->setLastIndex(0);
+ RETURN_RESULT(Encode::null());
+ }
+
+ ReturnedValue retVal = Encode::undefined();
+ // return first match
+ if (r->value()->captureCount()) {
+ int start = matchOffsets[0];
+ int end = matchOffsets[1];
+ retVal = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ }
+
+ RegExpCtor::Data *dd = regExpCtor->d();
+ dd->lastInput.set(scope.engine, str->d());
+ dd->lastMatchStart = matchOffsets[0];
+ dd->lastMatchEnd = matchOffsets[1];
+
+ r->setLastIndex(matchOffsets[1]);
+
+ return retVal;
+}
+
ReturnedValue RegExpPrototype::method_exec(const BuiltinFunction *b, CallData *callData)
{
Scope scope(b);
@@ -336,7 +382,7 @@ ReturnedValue RegExpPrototype::method_exec(const BuiltinFunction *b, CallData *c
Q_ALLOCA_VAR(uint, matchOffsets, r->value()->captureCount() * 2 * sizeof(uint));
const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
+ RegExpCtor *regExpCtor = static_cast<RegExpCtor *>(scope.engine->regExpCtor());
regExpCtor->d()->clearLastMatch();
if (result == -1) {