diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-09-01 16:26:51 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-09-15 10:45:19 +0000 |
commit | 4ca97d7289276816545ab01c9b49bfaaa29d8f5d (patch) | |
tree | 55e88ae9444732db290d1740fbf497e2e0db9f55 /src/qml/jsruntime/qv4regexpobject.cpp | |
parent | acd206e317fd92f20aa4985f35288f793d05f3ac (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.cpp | 48 |
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) { |