diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-06-22 10:12:13 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2016-06-22 11:07:05 +0000 |
commit | 702c4247d74ffb7e4fb1aaca96d70f4591203ba2 (patch) | |
tree | 6c0a41332cf4a8ab0051600efdd27b0746574795 /src/qml/jsruntime/qv4stringobject.cpp | |
parent | fd0e3c6d569a7410fff33974ce9f908dc2de0e22 (diff) |
V4: Pass scope around as parameters inside the runtime.
The implementation of many (or all) runtime functions consist of first
creating a QV4::Scope, which saves and restores the JS stack pointer.
It also prevents tail-calls because of that restoring behavior. In many
cases it suffices to do that at the entry-point of the runtime.
The return value of a JS function call is now also stored in the scope.
Previously, all return values were stored in a ScopedValue, got loaded
on return, and immediately stored in another ScopedValue in the caller.
This resulted in a lot of stores, where now there is only one store
needed, and no extra ScopedValue for every function.
Change-Id: I13d80fc0ce72c5702ef1536d41d12f710c5914fa
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4stringobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index b4f04bbc76..1989f747e9 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -157,28 +157,24 @@ Heap::StringCtor::StringCtor(QV4::ExecutionContext *scope) { } -ReturnedValue StringCtor::construct(const Managed *m, CallData *callData) +void StringCtor::construct(const Managed *m, Scope &scope, CallData *callData) { ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); - Scope scope(v4); ScopedString value(scope); if (callData->argc) value = callData->args[0].toString(v4); else value = v4->newString(); - return Encode(v4->newStringObject(value)); + scope.result = Encode(v4->newStringObject(value)); } -ReturnedValue StringCtor::call(const Managed *m, CallData *callData) +void StringCtor::call(const Managed *, Scope &scope, CallData *callData) { - ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); - Scope scope(v4); - ScopedValue value(scope); + ExecutionEngine *v4 = scope.engine; if (callData->argc) - value = callData->args[0].toString(v4); + scope.result = callData->args[0].toString(v4); else - value = v4->newString(); - return value->asReturnedValue(); + scope.result = v4->newString(); } void StringPrototype::init(ExecutionEngine *engine, Object *ctor) @@ -423,7 +419,8 @@ ReturnedValue StringPrototype::method_match(CallContext *context) if (!rx) { ScopedCallData callData(scope, 1); callData->args[0] = regexp; - rx = context->d()->engine->regExpCtor()->construct(callData); + context->d()->engine->regExpCtor()->construct(scope, callData); + rx = scope.result.asReturnedValue(); } if (!rx) @@ -439,8 +436,10 @@ ReturnedValue StringPrototype::method_match(CallContext *context) ScopedCallData callData(scope, 1); callData->thisObject = rx; callData->args[0] = s; - if (!global) - return exec->call(callData); + if (!global) { + exec->call(scope, callData); + return scope.result.asReturnedValue(); + } ScopedString lastIndex(scope, context->d()->engine->newString(QStringLiteral("lastIndex"))); rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0))); @@ -448,14 +447,13 @@ ReturnedValue StringPrototype::method_match(CallContext *context) double previousLastIndex = 0; uint n = 0; - ScopedValue result(scope); ScopedValue matchStr(scope); ScopedValue index(scope); while (1) { - result = exec->call(callData); - if (result->isNull()) + exec->call(scope, callData); + if (scope.result.isNull()) break; - assert(result->isObject()); + assert(scope.result.isObject()); index = rx->get(lastIndex, 0); double thisIndex = index->toInteger(); if (previousLastIndex == thisIndex) { @@ -464,7 +462,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context) } else { previousLastIndex = thisIndex; } - matchStr = result->objectValue()->getIndexed(0); + matchStr = scope.result.objectValue()->getIndexed(0); a->arraySet(n, matchStr); ++n; } @@ -580,7 +578,6 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx) } QString result; - ScopedValue replacement(scope); ScopedValue replaceValue(scope, ctx->argument(1)); ScopedFunctionObject searchCallback(scope, replaceValue); if (!!searchCallback) { @@ -605,9 +602,9 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx) callData->args[numCaptures] = Primitive::fromUInt32(matchStart); callData->args[numCaptures + 1] = ctx->d()->engine->newString(string); - replacement = searchCallback->call(callData); + searchCallback->call(scope, callData); result += string.midRef(lastEnd, matchStart - lastEnd); - result += replacement->toQString(); + result += scope.result.toQString(); lastEnd = matchEnd; } result += string.midRef(lastEnd); @@ -640,17 +637,17 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx) { Scope scope(ctx); QString string = getThisString(ctx); - ScopedValue regExpValue(scope, ctx->argument(0)); + scope.result = ctx->argument(0); if (scope.engine->hasException) return Encode::undefined(); - Scoped<RegExpObject> regExp(scope, regExpValue->as<RegExpObject>()); + Scoped<RegExpObject> regExp(scope, scope.result.as<RegExpObject>()); if (!regExp) { ScopedCallData callData(scope, 1); - callData->args[0] = regExpValue; - regExpValue = ctx->d()->engine->regExpCtor()->construct(callData); + callData->args[0] = scope.result; + ctx->d()->engine->regExpCtor()->construct(scope, callData); if (scope.engine->hasException) return Encode::undefined(); - regExp = regExpValue->as<RegExpObject>(); + regExp = scope.result.as<RegExpObject>(); Q_ASSERT(regExp); } Scoped<RegExp> re(scope, regExp->value()); |