aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4stringobject.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/qv4stringobject.cpp
parentacd206e317fd92f20aa4985f35288f793d05f3ac (diff)
Optimize String.match()
Change-Id: Idbf2b45a35c1bd1a843e8d01a3ea2f5157291033 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4stringobject.cpp')
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp71
1 files changed, 30 insertions, 41 deletions
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 66ad5e79d2..2fc05e4f56 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -402,67 +402,56 @@ ReturnedValue StringPrototype::method_localeCompare(const BuiltinFunction *b, Ca
ReturnedValue StringPrototype::method_match(const BuiltinFunction *b, CallData *callData)
{
ExecutionEngine *v4 = b->engine();
- if (callData->thisObject.isUndefined() || callData->thisObject.isNull())
+ if (callData->thisObject.isNullOrUndefined())
return v4->throwTypeError();
Scope scope(v4);
- ScopedString s(scope, callData->thisObject.toString(scope.engine));
-
- ScopedValue regexp(scope, callData->argument(0));
- Scoped<RegExpObject> rx(scope, regexp);
- if (!rx) {
- JSCall jsCall(scope, scope.engine->regExpCtor(), 1);
- jsCall->args[0] = regexp;
- rx = jsCall.callAsConstructor();
- }
+ callData->thisObject = callData->thisObject.toString(scope.engine);
+ if (v4->hasException)
+ return Encode::undefined();
- if (!rx)
- // ### CHECK
- return v4->throwTypeError();
+ if (!callData->argc)
+ callData->args[0] = Encode::undefined();
+ callData->argc = 1;
- bool global = rx->global();
+ if (!callData->args[0].as<RegExpObject>()) {
+ // convert args[0] to a regexp
+ callData->args[0] = RegExpCtor::construct(b, callData);
+ if (v4->hasException)
+ return Encode::undefined();
+ }
- // ### use the standard builtin function, not the one that might be redefined in the proto
- ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
- ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
+ bool global = static_cast<RegExpObject *>(&callData->args[0])->global();
- JSCall jsCall(scope, exec, 1);
- jsCall->thisObject = rx;
- jsCall->args[0] = s;
+ qSwap(callData->thisObject, callData->args[0]);
if (!global)
- return jsCall.call();
+ return RegExpPrototype::method_exec(b, callData);
- ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex")));
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
+ // rx is now in thisObject
+ RegExpObject *rx = static_cast<RegExpObject *>(&callData->thisObject);
+ rx->setLastIndex(0);
ScopedArrayObject a(scope, scope.engine->newArrayObject());
- double previousLastIndex = 0;
+ int previousLastIndex = 0;
uint n = 0;
- ScopedValue matchStr(scope);
- ScopedValue index(scope);
- ScopedValue result(scope);
while (1) {
- result = jsCall.call();
- if (result->isNull())
+ Value result = Primitive::fromReturnedValue(RegExpPrototype::execFirstMatch(b, callData));
+ if (result.isNull())
break;
- assert(result->isObject());
- index = rx->get(lastIndex, 0);
- double thisIndex = index->toInteger();
- if (previousLastIndex == thisIndex) {
- previousLastIndex = thisIndex + 1;
- rx->put(lastIndex, ScopedValue(scope, Primitive::fromDouble(previousLastIndex)));
+ int index = rx->lastIndex();
+ if (previousLastIndex == index) {
+ previousLastIndex = index + 1;
+ rx->setLastIndex(previousLastIndex);
} else {
- previousLastIndex = thisIndex;
+ previousLastIndex = index;
}
- matchStr = result->objectValue()->getIndexed(0);
- a->arraySet(n, matchStr);
+ a->arraySet(n, result);
++n;
}
if (!n)
- result = Encode::null();
+ return Encode::null();
else
- result = a.asReturnedValue();
- return result->asReturnedValue();
+ return a.asReturnedValue();
}
ReturnedValue StringPrototype::method_repeat(const BuiltinFunction *b, CallData *callData)