diff options
Diffstat (limited to 'src')
55 files changed, 473 insertions, 553 deletions
diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index a7d95cc295..940c285b87 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -411,7 +411,7 @@ static void qmlsqldatabase_changeVersion(const QV4::BuiltinFunction *, QV4::Scop callData->args[0] = w; TransactionRollback rollbackOnException(&db, &w->d()->inTransaction); - callback->call(scope, callData); + callback->call(callData); rollbackOnException.clear(); if (!db.commit()) { db.rollback(); @@ -459,7 +459,7 @@ static void qmlsqldatabase_transaction_shared(const QV4::BuiltinFunction *, QV4: callData->thisObject = scope.engine->globalObject; callData->args[0] = w; TransactionRollback rollbackOnException(&db, &w->d()->inTransaction); - callback->call(scope, callData); + callback->call(callData); rollbackOnException.clear(); if (!db.commit()) @@ -757,7 +757,7 @@ void QQuickLocalStorage::openDatabaseSync(QQmlV4Function *args) ScopedCallData callData(scope, 1); callData->thisObject = scope.engine->globalObject; callData->args[0] = db; - dbcreationCallback->call(scope, callData); + dbcreationCallback->call(callData); } args->setReturnValue(db.asReturnedValue()); diff --git a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp index 13425b36c2..59d4687615 100644 --- a/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_nativedebugger/qqmlnativedebugservice.cpp @@ -207,7 +207,7 @@ private: void handleDebuggerDeleted(QObject *debugger); - void evaluateExpression(QV4::Scope &scope, const QString &expression); + QV4::ReturnedValue evaluateExpression(const QString &expression); bool checkCondition(const QString &expression); QStringList breakOnSignals; @@ -239,13 +239,12 @@ private: bool NativeDebugger::checkCondition(const QString &expression) { - QV4::Scope scope(m_engine); - evaluateExpression(scope, expression); - return scope.result.booleanValue(); + return evaluateExpression(expression).booleanValue(); } -void NativeDebugger::evaluateExpression(QV4::Scope &scope, const QString &expression) +QV4::ReturnedValue NativeDebugger::evaluateExpression(const QString &expression) { + QV4::Scope scope(m_engine); m_runningJob = true; QV4::ExecutionContextSaver saver(scope); @@ -260,9 +259,10 @@ void NativeDebugger::evaluateExpression(QV4::Scope &scope, const QString &expres script.inheritContext = true; script.parse(); if (!m_engine->hasException) - scope.result = script.run(); + return script.run(); m_runningJob = false; + return QV4::Encode::undefined(); } NativeDebugger::NativeDebugger(QQmlNativeDebugServiceImpl *service, QV4::ExecutionEngine *engine) @@ -542,8 +542,7 @@ void NativeDebugger::handleExpressions(QJsonObject *response, const QJsonObject TRACE_PROTOCOL("Evaluate expression: " << expression); m_runningJob = true; - evaluateExpression(scope, expression); - QV4::ScopedValue result(scope, scope.result); + QV4::ScopedValue result(scope, evaluateExpression(expression)); m_runningJob = false; if (result->isUndefined()) { diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index 3a3cf46ddb..b692b8e68d 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -667,11 +667,11 @@ QJSValue QJSValue::call(const QJSValueList &args) callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i)); } - f->call(scope, callData); + ScopedValue result(scope, f->call(callData)); if (engine->hasException) - scope.result = engine->catchException(); + result = engine->catchException(); - return QJSValue(engine, scope.result.asReturnedValue()); + return QJSValue(engine, result->asReturnedValue()); } /*! @@ -723,11 +723,11 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i)); } - f->call(scope, callData); + ScopedValue result(scope, f->call(callData)); if (engine->hasException) - scope.result = engine->catchException(); + result = engine->catchException(); - return QJSValue(engine, scope.result.asReturnedValue()); + return QJSValue(engine, result->asReturnedValue()); } /*! @@ -771,11 +771,11 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) callData->args[i] = QJSValuePrivate::convertedToValue(engine, args.at(i)); } - f->construct(scope, callData); + ScopedValue result(scope, f->construct(callData)); if (engine->hasException) - scope.result = engine->catchException(); + result = engine->catchException(); - return QJSValue(engine, scope.result.asReturnedValue()); + return QJSValue(engine, result->asReturnedValue()); } #ifdef QT_DEPRECATED diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index 0905c2828a..5d1d322f7b 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -138,7 +138,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionEngine *engine, uint index, con ScopedCallData callData(scope, 1); callData->thisObject = this->asReturnedValue(); callData->args[0] = desc->value; - setter->call(scope, callData); + setter->call(callData); if (attrs.isWritable()) { setArrayAttributes(index, mapAttrs); @@ -205,35 +205,33 @@ PropertyAttributes ArgumentsObject::queryIndexed(const Managed *m, uint index) DEFINE_OBJECT_VTABLE(ArgumentsGetterFunction); -void ArgumentsGetterFunction::call(const Managed *getter, Scope &scope, CallData *callData) +ReturnedValue ArgumentsGetterFunction::call(const Managed *getter, CallData *callData) { ExecutionEngine *v4 = static_cast<const ArgumentsGetterFunction *>(getter)->engine(); + Scope scope(v4); Scoped<ArgumentsGetterFunction> g(scope, static_cast<const ArgumentsGetterFunction *>(getter)); Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>()); - if (!o) { - scope.result = v4->throwTypeError(); - return; - } + if (!o) + return v4->throwTypeError(); Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->callData->argc)); - scope.result = o->context()->callData->args[g->index()]; + return o->context()->callData->args[g->index()].asReturnedValue(); } DEFINE_OBJECT_VTABLE(ArgumentsSetterFunction); -void ArgumentsSetterFunction::call(const Managed *setter, Scope &scope, CallData *callData) +ReturnedValue ArgumentsSetterFunction::call(const Managed *setter, CallData *callData) { ExecutionEngine *v4 = static_cast<const ArgumentsSetterFunction *>(setter)->engine(); + Scope scope(v4); Scoped<ArgumentsSetterFunction> s(scope, static_cast<const ArgumentsSetterFunction *>(setter)); Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>()); - if (!o) { - scope.result = v4->throwTypeError(); - return; - } + if (!o) + return v4->throwTypeError(); Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->callData->argc)); o->context()->callData->args[s->index()] = callData->argc ? callData->args[0].asReturnedValue() : Encode::undefined(); - scope.result = Encode::undefined(); + return Encode::undefined(); } uint ArgumentsObject::getLength(const Managed *m) diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 46e1f884e8..228e79c33b 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -97,7 +97,7 @@ struct ArgumentsGetterFunction: FunctionObject V4_OBJECT2(ArgumentsGetterFunction, FunctionObject) uint index() const { return d()->index; } - static void call(const Managed *that, Scope &scope, CallData *d); + static ReturnedValue call(const Managed *that, CallData *d); }; inline void @@ -112,7 +112,7 @@ struct ArgumentsSetterFunction: FunctionObject V4_OBJECT2(ArgumentsSetterFunction, FunctionObject) uint index() const { return d()->index; } - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; inline void diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp index ffe9aa846f..05a7176061 100644 --- a/src/qml/jsruntime/qv4arraybuffer.cpp +++ b/src/qml/jsruntime/qv4arraybuffer.cpp @@ -51,34 +51,30 @@ void Heap::ArrayBufferCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("ArrayBuffer")); } -void ArrayBufferCtor::construct(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferCtor::construct(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = static_cast<const Object *>(m)->engine(); + ExecutionEngine *v4 = m->engine(); + Scope scope(v4); ScopedValue l(scope, callData->argument(0)); double dl = l->toInteger(); - if (v4->hasException) { - scope.result = Encode::undefined(); - return; - } + if (v4->hasException) + return Encode::undefined(); uint len = (uint)qBound(0., dl, (double)UINT_MAX); - if (len != dl) { - scope.result = v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length")); - return; - } + if (len != dl) + return v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length")); Scoped<ArrayBuffer> a(scope, v4->newArrayBuffer(len)); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - } else { - scope.result = a->asReturnedValue(); - } + if (scope.engine->hasException) + return Encode::undefined(); + + return a->asReturnedValue(); } -void ArrayBufferCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ArrayBufferCtor::call(const Managed *that, CallData *callData) { - construct(that, scope, callData); + return construct(that, callData); } void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData) @@ -193,8 +189,7 @@ void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, C ScopedCallData cData(scope, 1); double newLen = qMax(final - first, 0.); cData->args[0] = QV4::Encode(newLen); - constructor->construct(scope, cData); - QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result); + QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->construct(cData)); if (!newBuffer || newBuffer->d()->data->size < (int)newLen) THROW_TYPE_ERROR(); diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h index 4f7926d3dc..1b3f09dea8 100644 --- a/src/qml/jsruntime/qv4arraybuffer_p.h +++ b/src/qml/jsruntime/qv4arraybuffer_p.h @@ -78,8 +78,8 @@ struct ArrayBufferCtor: FunctionObject { V4_OBJECT2(ArrayBufferCtor, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index a2c19e1f2d..4663faa640 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -55,19 +55,18 @@ void Heap::ArrayCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Array")); } -void ArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue ArrayCtor::construct(const Managed *m, CallData *callData) { ExecutionEngine *v4 = static_cast<const ArrayCtor *>(m)->engine(); + Scope scope(v4); ScopedArrayObject a(scope, v4->newArrayObject()); uint len; if (callData->argc == 1 && callData->args[0].isNumber()) { bool ok; len = callData->args[0].asArrayLength(&ok); - if (!ok) { - scope.result = v4->throwRangeError(callData->args[0]); - return; - } + if (!ok) + return v4->throwRangeError(callData->args[0]); if (len < 0x1000) a->arrayReserve(len); @@ -78,12 +77,12 @@ void ArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData) } a->setArrayLengthUnchecked(len); - scope.result = a.asReturnedValue(); + return a.asReturnedValue(); } -void ArrayCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ArrayCtor::call(const Managed *that, CallData *callData) { - construct(that, scope, callData); + return construct(that, callData); } void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor) @@ -134,7 +133,7 @@ void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scop if (!!f) { ScopedCallData d(scope, 0); d->thisObject = callData->thisObject; - f->call(scope, d); + scope.result = f->call(d); return; } ObjectPrototype::method_toString(builtin, scope, callData); @@ -207,7 +206,7 @@ void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); + scope.result = callback->call(cData); CHECK_EXCEPTION(); if (scope.result.toBoolean()) @@ -241,7 +240,7 @@ void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, Cal cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); + scope.result = callback->call(cData); CHECK_EXCEPTION(); if (scope.result.toBoolean()) @@ -770,6 +769,7 @@ void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallDat ScopedCallData cData(scope, 3); cData->args[2] = instance; cData->thisObject = callData->argument(1); + ScopedValue r(scope); ScopedValue v(scope); bool ok = true; @@ -781,8 +781,8 @@ void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallDat cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); - ok = scope.result.toBoolean(); + r = callback->call(cData); + ok = r->toBoolean(); } scope.result = Encode(ok); } @@ -812,7 +812,7 @@ void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); + scope.result = callback->call(cData); if (scope.result.toBoolean()) { scope.result = Encode(true); return; @@ -846,7 +846,7 @@ void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallD cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); + scope.result = callback->call(cData); } RETURN_UNDEFINED(); } @@ -867,6 +867,7 @@ void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData a->arrayReserve(len); a->setArrayLengthUnchecked(len); + ScopedValue mapped(scope); ScopedCallData cData(scope, 3); cData->thisObject = callData->argument(1); cData->args[2] = instance; @@ -880,8 +881,8 @@ void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); - a->arraySet(k, scope.result); + mapped = callback->call(cData); + a->arraySet(k, mapped); } scope.result = a.asReturnedValue(); } @@ -901,6 +902,7 @@ void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallDa ScopedArrayObject a(scope, scope.engine->newArrayObject()); a->arrayReserve(len); + ScopedValue selected(scope); ScopedCallData cData(scope, 3); cData->thisObject = callData->argument(1); cData->args[2] = instance; @@ -916,8 +918,8 @@ void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallDa cData->args[0] = v; cData->args[1] = Primitive::fromDouble(k); - callback->call(scope, cData); - if (scope.result.toBoolean()) { + selected = callback->call(cData); + if (selected->toBoolean()) { a->arraySet(to, v); ++to; } @@ -938,16 +940,17 @@ void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallDa THROW_TYPE_ERROR(); uint k = 0; + ScopedValue acc(scope); ScopedValue v(scope); if (callData->argc > 1) { - scope.result = callData->argument(1); + acc = callData->argument(1); } else { bool kPresent = false; while (k < len && !kPresent) { v = instance->getIndexed(k, &kPresent); if (kPresent) - scope.result = v; + acc = v; ++k; } if (!kPresent) @@ -956,20 +959,21 @@ void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallDa ScopedCallData cData(scope, 4); cData->thisObject = Primitive::undefinedValue(); - cData->args[0] = scope.result; + cData->args[0] = acc; cData->args[3] = instance; while (k < len) { bool kPresent; v = instance->getIndexed(k, &kPresent); if (kPresent) { - cData->args[0] = scope.result; + cData->args[0] = acc; cData->args[1] = v; cData->args[2] = Primitive::fromDouble(k); - callback->call(scope, cData); + acc = callback->call(cData); } ++k; } + scope.result = acc->asReturnedValue(); } void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, CallData *callData) @@ -992,15 +996,16 @@ void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, C } uint k = len; + ScopedValue acc(scope); ScopedValue v(scope); if (callData->argc > 1) { - scope.result = callData->argument(1); + acc = callData->argument(1); } else { bool kPresent = false; while (k > 0 && !kPresent) { v = instance->getIndexed(k - 1, &kPresent); if (kPresent) - scope.result = v; + acc = v; --k; } if (!kPresent) @@ -1015,13 +1020,13 @@ void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, C bool kPresent; v = instance->getIndexed(k - 1, &kPresent); if (kPresent) { - cData->args[0] = scope.result; + cData->args[0] = acc; cData->args[1] = v; cData->args[2] = Primitive::fromDouble(k - 1); - callback->call(scope, cData); + acc = callback->call(cData); } --k; } - scope.result = scope.result.asReturnedValue(); + scope.result = acc->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h index 689752433b..b6ee5c5dac 100644 --- a/src/qml/jsruntime/qv4arrayobject_p.h +++ b/src/qml/jsruntime/qv4arrayobject_p.h @@ -70,8 +70,8 @@ struct ArrayCtor: FunctionObject { V4_OBJECT2(ArrayCtor, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct ArrayPrototype: ArrayObject diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index c8e9ebb2dd..0ed8471753 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -50,16 +50,16 @@ void Heap::BooleanCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Boolean")); } -void BooleanCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue BooleanCtor::construct(const Managed *that, CallData *callData) { bool n = callData->argc ? callData->args[0].toBoolean() : false; - scope.result = Encode(scope.engine->newBooleanObject(n)); + return Encode(that->engine()->newBooleanObject(n)); } -void BooleanCtor::call(const Managed *, Scope &scope, CallData *callData) +ReturnedValue BooleanCtor::call(const Managed *, CallData *callData) { bool value = callData->argc ? callData->args[0].toBoolean() : 0; - scope.result = Encode(value); + return Encode(value); } void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h index ca2cf7d17a..9a004c7749 100644 --- a/src/qml/jsruntime/qv4booleanobject_p.h +++ b/src/qml/jsruntime/qv4booleanobject_p.h @@ -70,8 +70,8 @@ struct BooleanCtor: FunctionObject { V4_OBJECT2(BooleanCtor, FunctionObject) - static void construct(const Managed *, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct BooleanPrototype: BooleanObject diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp index f1405e08ee..b4e21b7ce5 100644 --- a/src/qml/jsruntime/qv4dataview.cpp +++ b/src/qml/jsruntime/qv4dataview.cpp @@ -54,34 +54,31 @@ void Heap::DataViewCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("DataView")); } -void DataViewCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue DataViewCtor::construct(const Managed *m, CallData *callData) { + Scope scope(m->engine()); Scoped<ArrayBuffer> buffer(scope, callData->argument(0)); - if (!buffer) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (!buffer) + return scope.engine->throwTypeError(); double bo = callData->argc > 1 ? callData->args[1].toNumber() : 0; uint byteOffset = (uint)bo; uint bufferLength = buffer->d()->data->size; double bl = callData->argc < 3 || callData->args[2].isUndefined() ? (bufferLength - bo) : callData->args[2].toNumber(); uint byteLength = (uint)bl; - if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength) { - scope.result = scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range")); - return; - } + if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength) + return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range")); Scoped<DataView> a(scope, scope.engine->memoryManager->allocObject<DataView>()); a->d()->buffer.set(scope.engine, buffer->d()); a->d()->byteLength = byteLength; a->d()->byteOffset = byteOffset; - scope.result = a.asReturnedValue(); + return a.asReturnedValue(); } -void DataViewCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue DataViewCtor::call(const Managed *that, CallData *callData) { - construct(that, scope, callData); + return construct(that, callData); } void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h index 5c50df4655..123a290e28 100644 --- a/src/qml/jsruntime/qv4dataview_p.h +++ b/src/qml/jsruntime/qv4dataview_p.h @@ -79,8 +79,8 @@ struct DataViewCtor: FunctionObject { V4_OBJECT2(DataViewCtor, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct DataView : Object diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index c56d007028..0e681f9946 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -677,7 +677,7 @@ void Heap::DateCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Date")); } -void DateCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue DateCtor::construct(const Managed *that, CallData *callData) { double t = 0; @@ -685,6 +685,7 @@ void DateCtor::construct(const Managed *, Scope &scope, CallData *callData) t = currentTime(); else if (callData->argc == 1) { + Scope scope(that->engine()); ScopedValue arg(scope, callData->args[0]); if (DateObject *d = arg->as<DateObject>()) { t = d->date(); @@ -712,13 +713,13 @@ void DateCtor::construct(const Managed *, Scope &scope, CallData *callData) t = TimeClip(UTC(t)); } - scope.result = Encode(scope.engine->newDateObject(Primitive::fromDouble(t))); + return Encode(that->engine()->newDateObject(Primitive::fromDouble(t))); } -void DateCtor::call(const Managed *m, Scope &scope, CallData *) +ReturnedValue DateCtor::call(const Managed *m, CallData *) { double t = currentTime(); - scope.result = static_cast<const DateCtor *>(m)->engine()->newString(ToString(t)); + return m->engine()->newString(ToString(t))->asReturnedValue(); } void DatePrototype::init(ExecutionEngine *engine, Object *ctor) @@ -1378,7 +1379,7 @@ void DatePrototype::method_toJSON(const BuiltinFunction *, Scope &scope, CallDat ScopedCallData cData(scope); cData->thisObject = callData->thisObject; - toIso->call(scope, cData); + scope.result = toIso->call(cData); } void DatePrototype::timezoneUpdated() diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h index b0373884dd..2455861319 100644 --- a/src/qml/jsruntime/qv4dateobject_p.h +++ b/src/qml/jsruntime/qv4dateobject_p.h @@ -108,8 +108,8 @@ struct DateCtor: FunctionObject { V4_OBJECT2(DateCtor, FunctionObject) - static void construct(const Managed *, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *); }; struct DatePrototype: Object diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index d9678636c7..922c65fbe8 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -535,7 +535,7 @@ inline void Managed::mark(MarkStack *markStack) m()->mark(markStack); } -#define CHECK_STACK_LIMITS(v4, scope) if ((v4)->checkStackLimits(scope)) return; \ +#define CHECK_STACK_LIMITS(v4, scope) if ((v4)->checkStackLimits(scope)) return Encode::undefined(); \ ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); struct ExecutionEngineCallDepthRecorder diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index f7c34e7550..1eb2cd866d 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -231,15 +231,14 @@ void Heap::ErrorCtor::init(QV4::ExecutionContext *scope, const QString &name) Heap::FunctionObject::init(scope, name); } -void ErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue ErrorCtor::construct(const Managed *that, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<ErrorObject>(scope.engine, v); + return ErrorObject::create<ErrorObject>(that->engine(), callData->args[0])->asReturnedValue(); } -void ErrorCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ErrorCtor::call(const Managed *that, CallData *callData) { - static_cast<const Object *>(that)->construct(scope, callData); + return static_cast<const Object *>(that)->construct(callData); } void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope) @@ -247,10 +246,9 @@ void Heap::EvalErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("EvalError")); } -void EvalErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue EvalErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<EvalErrorObject>(scope.engine, v); + return ErrorObject::create<EvalErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope) @@ -258,10 +256,9 @@ void Heap::RangeErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("RangeError")); } -void RangeErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue RangeErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<RangeErrorObject>(scope.engine, v); + return ErrorObject::create<RangeErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope) @@ -269,10 +266,9 @@ void Heap::ReferenceErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("ReferenceError")); } -void ReferenceErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue ReferenceErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<ReferenceErrorObject>(scope.engine, v); + return ErrorObject::create<ReferenceErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope) @@ -280,10 +276,9 @@ void Heap::SyntaxErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("SyntaxError")); } -void SyntaxErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue SyntaxErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<SyntaxErrorObject>(scope.engine, v); + return ErrorObject::create<SyntaxErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope) @@ -291,10 +286,9 @@ void Heap::TypeErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("TypeError")); } -void TypeErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue TypeErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<TypeErrorObject>(scope.engine, v); + return ErrorObject::create<TypeErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope) @@ -302,10 +296,9 @@ void Heap::URIErrorCtor::init(QV4::ExecutionContext *scope) Heap::ErrorCtor::init(scope, QStringLiteral("URIError")); } -void URIErrorCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue URIErrorCtor::construct(const Managed *m, CallData *callData) { - ScopedValue v(scope, callData->argument(0)); - scope.result = ErrorObject::create<URIErrorObject>(scope.engine, v); + return ErrorObject::create<URIErrorObject>(m->engine(), callData->args[0])->asReturnedValue(); } void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t) diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index d556617b48..2a0d15a63c 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -229,50 +229,50 @@ struct ErrorCtor: FunctionObject { V4_OBJECT2(ErrorCtor, FunctionObject) - static void construct(const Managed *, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct EvalErrorCtor: ErrorCtor { V4_OBJECT2(EvalErrorCtor, ErrorCtor) - static void construct(const Managed *m, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); }; struct RangeErrorCtor: ErrorCtor { V4_OBJECT2(RangeErrorCtor, ErrorCtor) - static void construct(const Managed *, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); }; struct ReferenceErrorCtor: ErrorCtor { V4_OBJECT2(ReferenceErrorCtor, ErrorCtor) - static void construct(const Managed *m, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); }; struct SyntaxErrorCtor: ErrorCtor { V4_OBJECT2(SyntaxErrorCtor, ErrorCtor) - static void construct(const Managed *m, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); }; struct TypeErrorCtor: ErrorCtor { V4_OBJECT2(TypeErrorCtor, ErrorCtor) - static void construct(const Managed *m, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); }; struct URIErrorCtor: ErrorCtor { V4_OBJECT2(URIErrorCtor, ErrorCtor) - static void construct(const Managed *m, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 960919b1ff..9a88ee326a 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -139,14 +139,14 @@ ReturnedValue FunctionObject::name() const return get(scope()->internalClass->engine->id_name()); } -void FunctionObject::construct(const Managed *that, Scope &scope, CallData *) +ReturnedValue FunctionObject::construct(const Managed *that, CallData *) { - scope.result = static_cast<const FunctionObject *>(that)->engine()->throwTypeError(); + return that->engine()->throwTypeError(); } -void FunctionObject::call(const Managed *, Scope &scope, CallData *) +ReturnedValue FunctionObject::call(const Managed *, CallData *) { - scope.result = Encode::undefined(); + return Encode::undefined(); } Heap::FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function) @@ -177,8 +177,9 @@ void Heap::FunctionCtor::init(QV4::ExecutionContext *scope) } // 15.3.2 -void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue FunctionCtor::construct(const Managed *that, CallData *callData) { + Scope scope(that->engine()); Scoped<FunctionCtor> f(scope, static_cast<const FunctionCtor *>(that)); QString arguments; @@ -191,10 +192,8 @@ void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callDa } body = callData->args[callData->argc - 1].toQString(); } - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1Char('}'); @@ -205,16 +204,12 @@ void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callDa const bool parsed = parser.parseExpression(); - if (!parsed) { - scope.result = scope.engine->throwSyntaxError(QLatin1String("Parse error")); - return; - } + if (!parsed) + return scope.engine->throwSyntaxError(QLatin1String("Parse error")); QQmlJS::AST::FunctionExpression *fe = QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(parser.rootNode()); - if (!fe) { - scope.result = scope.engine->throwSyntaxError(QLatin1String("Parse error")); - return; - } + if (!fe) + return scope.engine->throwSyntaxError(QLatin1String("Parse error")); Compiler::Module module(scope.engine->debugger() != 0); @@ -226,13 +221,13 @@ void FunctionCtor::construct(const Managed *that, Scope &scope, CallData *callDa Function *vmf = compilationUnit->linkToEngine(scope.engine); ExecutionContext *global = scope.engine->rootContext(); - scope.result = FunctionObject::createScriptFunction(global, vmf); + return Encode(FunctionObject::createScriptFunction(global, vmf)); } // 15.3.1: This is equivalent to new Function(...) -void FunctionCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue FunctionCtor::call(const Managed *that, CallData *callData) { - construct(that, scope, callData); + return construct(that, callData); } DEFINE_OBJECT_VTABLE(FunctionPrototype); @@ -312,7 +307,7 @@ void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, Call } cData->thisObject = callData->argument(0); - o->call(scope, cData); + scope.result = o->call(cData); } void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData) @@ -328,7 +323,7 @@ void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallD } cData->thisObject = callData->argument(0); - o->call(scope, cData); + scope.result = o->call(cData); } void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData) @@ -352,13 +347,13 @@ void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallD DEFINE_OBJECT_VTABLE(ScriptFunction); -void ScriptFunction::construct(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ScriptFunction::construct(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = scope.engine; - if (Q_UNLIKELY(v4->hasException)) { - scope.result = Encode::undefined(); - return; - } + ExecutionEngine *v4 = that->engine(); + if (Q_UNLIKELY(v4->hasException)) + return Encode::undefined(); + + Scope scope(v4); CHECK_STACK_LIMITS(v4, scope); ExecutionContextSaver ctxSaver(scope); @@ -379,20 +374,20 @@ void ScriptFunction::construct(const Managed *that, Scope &scope, CallData *call else c->call(scope, callData, v4Function, f); - if (Q_UNLIKELY(v4->hasException)) { - scope.result = Encode::undefined(); - } else if (!scope.result.isObject()) { - scope.result = obj.asReturnedValue(); - } + if (Q_UNLIKELY(v4->hasException)) + return Encode::undefined(); + else if (!scope.result.isObject()) + return obj.asReturnedValue(); + return Encode(scope.result); } -void ScriptFunction::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ScriptFunction::call(const Managed *that, CallData *callData) { - ExecutionEngine *v4 = scope.engine; - if (Q_UNLIKELY(v4->hasException)) { - scope.result = Encode::undefined(); - return; - } + ExecutionEngine *v4 = that->engine(); + if (Q_UNLIKELY(v4->hasException)) + return Encode::undefined(); + + Scope scope(v4); CHECK_STACK_LIMITS(v4, scope); Scoped<ScriptFunction> f(scope, static_cast<const ScriptFunction *>(that)); @@ -405,6 +400,7 @@ void ScriptFunction::call(const Managed *that, Scope &scope, CallData *callData) c->simpleCall(scope, callData, v4Function); else c->call(scope, callData, v4Function, f); + return Encode(scope.result); } void Heap::ScriptFunction::init(QV4::ExecutionContext *scope, Function *function) @@ -457,31 +453,32 @@ void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name this->code = code; } -void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *) +ReturnedValue BuiltinFunction::construct(const Managed *f, CallData *) { - scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError(); + return f->engine()->throwTypeError(); } -void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue BuiltinFunction::call(const Managed *that, CallData *callData) { const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that); - ExecutionEngine *v4 = scope.engine; - if (v4->hasException) { - scope.result = Encode::undefined(); - return; - } + ExecutionEngine *v4 = f->engine(); + if (v4->hasException) + return Encode::undefined(); + + Scope scope(v4); f->d()->code(f, scope, callData); + return Encode(scope.result); } -void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue IndexedBuiltinFunction::call(const Managed *that, CallData *callData) { const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that); - ExecutionEngine *v4 = scope.engine; - if (v4->hasException) { - scope.result = Encode::undefined(); - return; - } + ExecutionEngine *v4 = f->engine(); + if (v4->hasException) + return Encode::undefined(); + + Scope scope(v4); CHECK_STACK_LIMITS(v4, scope); ExecutionContextSaver ctxSaver(scope); @@ -494,6 +491,7 @@ void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *c scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index); v4->memoryManager->freeSimpleCallContext(); + return Encode(scope.result); } DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction); @@ -526,13 +524,13 @@ void Heap::BoundFunction::init(QV4::ExecutionContext *scope, QV4::FunctionObject f->insertMember(s.engine->id_caller(), pd, Attr_Accessor|Attr_NotConfigurable|Attr_NotEnumerable); } -void BoundFunction::call(const Managed *that, Scope &scope, CallData *dd) +ReturnedValue BoundFunction::call(const Managed *that, CallData *dd) { const BoundFunction *f = static_cast<const BoundFunction *>(that); - if (scope.hasException()) { - scope.result = Encode::undefined(); - return; - } + Scope scope(f->engine()); + + if (scope.hasException()) + return Encode::undefined(); Scoped<MemberData> boundArgs(scope, f->boundArgs()); ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc); @@ -544,16 +542,16 @@ void BoundFunction::call(const Managed *that, Scope &scope, CallData *dd) } memcpy(argp, dd->args, dd->argc*sizeof(Value)); ScopedFunctionObject t(scope, f->target()); - t->call(scope, callData); + return t->call(callData); } -void BoundFunction::construct(const Managed *that, Scope &scope, CallData *dd) +ReturnedValue BoundFunction::construct(const Managed *that, CallData *dd) { const BoundFunction *f = static_cast<const BoundFunction *>(that); - if (scope.hasException()) { - scope.result = Encode::undefined(); - return; - } + Scope scope(f->engine()); + + if (scope.hasException()) + return Encode::undefined(); Scoped<MemberData> boundArgs(scope, f->boundArgs()); ScopedCallData callData(scope, (boundArgs ? boundArgs->size() : 0) + dd->argc); @@ -564,5 +562,5 @@ void BoundFunction::construct(const Managed *that, Scope &scope, CallData *dd) } memcpy(argp, dd->args, dd->argc*sizeof(Value)); ScopedFunctionObject t(scope, f->target()); - t->construct(scope, callData); + return t->construct(callData); } diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index 6ce5734b6d..e62ffae20b 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -156,8 +156,8 @@ struct Q_QML_EXPORT FunctionObject: Object { using Object::construct; using Object::call; - static void construct(const Managed *that, Scope &scope, CallData *); - static void call(const Managed *that, Scope &scope, CallData *d); + static ReturnedValue construct(const Managed *that, CallData *); + static ReturnedValue call(const Managed *that, CallData *d); static Heap::FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function); @@ -178,8 +178,8 @@ struct FunctionCtor: FunctionObject { V4_OBJECT2(FunctionCtor, FunctionObject) - static void construct(const Managed *that, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct FunctionPrototype: FunctionObject @@ -203,20 +203,20 @@ struct Q_QML_EXPORT BuiltinFunction : FunctionObject { return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code); } - static void construct(const Managed *, Scope &scope, CallData *); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct IndexedBuiltinFunction: FunctionObject { V4_OBJECT2(IndexedBuiltinFunction, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *) + static ReturnedValue construct(const Managed *m, CallData *) { - scope.result = static_cast<const IndexedBuiltinFunction *>(m)->engine()->throwTypeError(); + return m->engine()->throwTypeError(); } - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; void Heap::IndexedBuiltinFunction::init(QV4::ExecutionContext *scope, uint index, @@ -232,8 +232,8 @@ struct ScriptFunction : FunctionObject { V4_OBJECT2(ScriptFunction, FunctionObject) V4_INTERNALCLASS(ScriptFunction) - static void construct(const Managed *, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); InternalClass *classForConstructor() const; }; @@ -251,8 +251,8 @@ struct BoundFunction: FunctionObject { Value boundThis() const { return d()->boundThis; } Heap::MemberData *boundArgs() const { return d()->boundArgs; } - static void construct(const Managed *, Scope &scope, CallData *d); - static void call(const Managed *that, Scope &scope, CallData *dd); + static ReturnedValue construct(const Managed *, CallData *d); + static ReturnedValue call(const Managed *that, CallData *dd); }; } diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index ff395adb27..35961e6f75 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -337,14 +337,13 @@ void Heap::EvalFunction::init(QV4::ExecutionContext *scope) f->defineReadonlyProperty(s.engine->id_length(), Primitive::fromInt32(1)); } -void EvalFunction::evalCall(Scope &scope, CallData *callData, bool directCall) const +ReturnedValue EvalFunction::evalCall(CallData *callData, bool directCall) const { - if (callData->argc < 1) { - scope.result = Encode::undefined(); - return; - } + if (callData->argc < 1) + return Encode::undefined(); ExecutionEngine *v4 = engine(); + Scope scope(v4); ExecutionContextSaver ctxSaver(scope); ExecutionContext *currentContext = v4->currentContext; @@ -357,10 +356,8 @@ void EvalFunction::evalCall(Scope &scope, CallData *callData, bool directCall) c } String *scode = callData->args[0].stringValue(); - if (!scode) { - scope.result = callData->args[0].asReturnedValue(); - return; - } + if (!scode) + return callData->args[0].asReturnedValue(); const QString code = scode->toQString(); bool inheritContext = !ctx->d()->strictMode; @@ -369,23 +366,18 @@ void EvalFunction::evalCall(Scope &scope, CallData *callData, bool directCall) c script.strictMode = (directCall && currentContext->d()->strictMode); script.inheritContext = inheritContext; script.parse(); - if (v4->hasException) { - scope.result = Encode::undefined(); - return; - } + if (v4->hasException) + return Encode::undefined(); Function *function = script.function(); - if (!function) { - scope.result = Encode::undefined(); - return; - } + if (!function) + return Encode::undefined(); if (function->isStrict() || (ctx->d()->strictMode)) { ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function)); ScopedCallData callData(scope, 0); callData->thisObject = ctx->thisObject(); - e->call(scope, callData); - return; + return e->call(callData); } ContextStateSaver stateSaver(scope, ctx); @@ -394,14 +386,14 @@ void EvalFunction::evalCall(Scope &scope, CallData *callData, bool directCall) c ctx->d()->strictMode = false; ctx->d()->v4Function = function; - scope.result = Q_V4_PROFILE(ctx->engine(), function); + return Q_V4_PROFILE(ctx->engine(), function); } -void EvalFunction::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue EvalFunction::call(const Managed *that, CallData *callData) { // indirect call - static_cast<const EvalFunction *>(that)->evalCall(scope, callData, false); + return static_cast<const EvalFunction *>(that)->evalCall(callData, false); } diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h index 273f1ba7ea..152b69001b 100644 --- a/src/qml/jsruntime/qv4globalobject_p.h +++ b/src/qml/jsruntime/qv4globalobject_p.h @@ -69,9 +69,9 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject { V4_OBJECT2(EvalFunction, FunctionObject) - void evalCall(Scope &scope, CallData *callData, bool directCall) const; + ReturnedValue evalCall(CallData *callData, bool directCall) const; - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct GlobalFunctions diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index 1edb7d3914..2f00022659 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -121,7 +121,7 @@ void QV4Include::callback(const QV4::Value &callback, const QV4::Value &status) QV4::ScopedCallData callData(scope, 1); callData->thisObject = v4->globalObject->asReturnedValue(); callData->args[0] = status; - f->call(scope, callData); + f->call(callData); if (scope.hasException()) scope.engine->catchException(); } diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 0f021c8bd0..60d1f13358 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -689,57 +689,57 @@ static QString quote(const QString &str) QString Stringify::Str(const QString &key, const Value &v) { Scope scope(v4); - scope.result = v; - ScopedObject o(scope, scope.result); + ScopedValue value(scope, v); + ScopedObject o(scope, value); if (o) { ScopedString s(scope, v4->newString(QStringLiteral("toJSON"))); ScopedFunctionObject toJSON(scope, o->get(s)); if (!!toJSON) { ScopedCallData callData(scope, 1); - callData->thisObject = scope.result; + callData->thisObject = value; callData->args[0] = v4->newString(key); - toJSON->call(scope, callData); + value = toJSON->call(callData); } } if (replacerFunction) { ScopedObject holder(scope, v4->newObject()); - holder->put(scope.engine->id_empty(), scope.result); + holder->put(scope.engine->id_empty(), value); ScopedCallData callData(scope, 2); callData->args[0] = v4->newString(key); - callData->args[1] = scope.result; + callData->args[1] = value; callData->thisObject = holder; - replacerFunction->call(scope, callData); + value = replacerFunction->call(callData); } - o = scope.result.asReturnedValue(); + o = value->asReturnedValue(); if (o) { if (NumberObject *n = o->as<NumberObject>()) - scope.result = Encode(n->value()); + value = Encode(n->value()); else if (StringObject *so = o->as<StringObject>()) - scope.result = so->d()->string; + value = so->d()->string; else if (BooleanObject *b = o->as<BooleanObject>()) - scope.result = Encode(b->value()); + value = Encode(b->value()); } - if (scope.result.isNull()) + if (value->isNull()) return QStringLiteral("null"); - if (scope.result.isBoolean()) - return scope.result.booleanValue() ? QStringLiteral("true") : QStringLiteral("false"); - if (String *s = scope.result.stringValue()) - return quote(s->toQString()); - - if (scope.result.isNumber()) { - double d = scope.result.toNumber(); - return std::isfinite(d) ? scope.result.toQString() : QStringLiteral("null"); + if (value->isBoolean()) + return value->booleanValue() ? QStringLiteral("true") : QStringLiteral("false"); + if (value->isString()) + return quote(value->stringValue()->toQString()); + + if (value->isNumber()) { + double d = value->toNumber(); + return std::isfinite(d) ? value->toQString() : QStringLiteral("null"); } - if (const QV4::VariantObject *v = scope.result.as<QV4::VariantObject>()) { + if (const QV4::VariantObject *v = value->as<QV4::VariantObject>()) { return v->d()->data().toString(); } - o = scope.result.asReturnedValue(); + o = value->asReturnedValue(); if (o) { if (!o->as<FunctionObject>()) { if (o->as<ArrayObject>()) { diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index a576da0ea7..1d32d453ac 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -535,8 +535,7 @@ ReturnedValue Lookup::getterAccessor0(Lookup *l, ExecutionEngine *engine, const ScopedCallData callData(scope, 0); callData->thisObject = object; - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } l->getter = getterFallback; @@ -558,8 +557,7 @@ ReturnedValue Lookup::getterAccessor1(Lookup *l, ExecutionEngine *engine, const ScopedCallData callData(scope, 0); callData->thisObject = object; - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } l->getter = getterFallback; @@ -584,8 +582,7 @@ ReturnedValue Lookup::getterAccessor2(Lookup *l, ExecutionEngine *engine, const ScopedCallData callData(scope, 0); callData->thisObject = object; - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } } @@ -640,8 +637,7 @@ ReturnedValue Lookup::primitiveGetterAccessor0(Lookup *l, ExecutionEngine *engin ScopedCallData callData(scope, 0); callData->thisObject = object; - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } l->getter = getterGeneric; @@ -661,8 +657,7 @@ ReturnedValue Lookup::primitiveGetterAccessor1(Lookup *l, ExecutionEngine *engin ScopedCallData callData(scope, 0); callData->thisObject = object; - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } l->getter = getterGeneric; @@ -781,8 +776,7 @@ ReturnedValue Lookup::globalGetterAccessor0(Lookup *l, ExecutionEngine *engine) ScopedCallData callData(scope, 0); callData->thisObject = Primitive::undefinedValue(); - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } l->globalGetter = globalGetterGeneric; return globalGetterGeneric(l, engine); @@ -800,8 +794,7 @@ ReturnedValue Lookup::globalGetterAccessor1(Lookup *l, ExecutionEngine *engine) ScopedCallData callData(scope, 0); callData->thisObject = Primitive::undefinedValue(); - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } l->globalGetter = globalGetterGeneric; return globalGetterGeneric(l, engine); @@ -822,8 +815,7 @@ ReturnedValue Lookup::globalGetterAccessor2(Lookup *l, ExecutionEngine *engine) ScopedCallData callData(scope, 0); callData->thisObject = Primitive::undefinedValue(); - getter->call(scope, callData); - return scope.result.asReturnedValue(); + return getter->call(callData); } } } diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 8cfa930888..40586b558b 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -78,16 +78,16 @@ void Heap::NumberCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Number")); } -void NumberCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue NumberCtor::construct(const Managed *m, CallData *callData) { double dbl = callData->argc ? callData->args[0].toNumber() : 0.; - scope.result = Encode(scope.engine->newNumberObject(dbl)); + return Encode(m->engine()->newNumberObject(dbl)); } -void NumberCtor::call(const Managed *, Scope &scope, CallData *callData) +ReturnedValue NumberCtor::call(const Managed *, CallData *callData) { double dbl = callData->argc ? callData->args[0].toNumber() : 0.; - scope.result = Encode(dbl); + return Encode(dbl); } void NumberPrototype::init(ExecutionEngine *engine, Object *ctor) diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h index 0bc2cd8c65..5622bf4728 100644 --- a/src/qml/jsruntime/qv4numberobject_p.h +++ b/src/qml/jsruntime/qv4numberobject_p.h @@ -79,8 +79,8 @@ struct NumberCtor: FunctionObject { V4_OBJECT2(NumberCtor, FunctionObject) - static void construct(const Managed *that, Scope &scope, CallData *callData); - static void call(const Managed *, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *, CallData *callData); }; struct NumberPrototype: NumberObject diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 8032c11add..9c1cbf2357 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -108,8 +108,7 @@ ReturnedValue Object::getValue(const Value &thisObject, const Value &v, Property Scope scope(f->engine()); ScopedCallData callData(scope); callData->thisObject = thisObject; - f->call(scope, callData); - return scope.result.asReturnedValue(); + return f->call(callData); } bool Object::putValue(uint memberIndex, const Value &value) @@ -128,7 +127,7 @@ bool Object::putValue(uint memberIndex, const Value &value) ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = this; - setter->call(scope, callData); + setter->call(callData); return !ic->engine->hasException; } goto reject; @@ -400,14 +399,14 @@ bool Object::hasOwnProperty(uint index) const return false; } -void Object::construct(const Managed *m, Scope &scope, CallData *) +ReturnedValue Object::construct(const Managed *m, CallData *) { - scope.result = static_cast<const Object *>(m)->engine()->throwTypeError(); + return m->engine()->throwTypeError(); } -void Object::call(const Managed *m, Scope &scope, CallData *) +ReturnedValue Object::call(const Managed *m, CallData *) { - scope.result = static_cast<const Object *>(m)->engine()->throwTypeError(); + return m->engine()->throwTypeError(); } ReturnedValue Object::get(const Managed *m, String *name, bool *hasProperty) @@ -770,7 +769,7 @@ bool Object::internalPut(String *name, const Value &value) ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = this; - setter->call(scope, callData); + setter->call(callData); return !internalClass()->engine->hasException; } @@ -844,7 +843,7 @@ bool Object::internalPutIndexed(uint index, const Value &value) ScopedCallData callData(scope, 1); callData->args[0] = value; callData->thisObject = this; - setter->call(scope, callData); + setter->call(callData); return !internalClass()->engine->hasException; } diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index f05b84d598..5c642bef0a 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -175,8 +175,8 @@ Q_STATIC_ASSERT(Object::markTable == ((2 << 2) | (2 << 4))); struct ObjectVTable { VTable vTable; - void (*call)(const Managed *, Scope &scope, CallData *data); - void (*construct)(const Managed *, Scope &scope, CallData *data); + ReturnedValue (*call)(const Managed *, CallData *data); + ReturnedValue (*construct)(const Managed *, CallData *data); ReturnedValue (*get)(const Managed *, String *name, bool *hasProperty); ReturnedValue (*getIndexed)(const Managed *, uint index, bool *hasProperty); bool (*put)(Managed *, String *name, const Value &value); @@ -440,13 +440,13 @@ public: ReturnedValue instanceOf(const Value &var) const { return vtable()->instanceOf(this, var); } - inline void construct(Scope &scope, CallData *d) const - { return vtable()->construct(this, scope, d); } - inline void call(Scope &scope, CallData *d) const - { vtable()->call(this, scope, d); } + inline ReturnedValue construct(CallData *d) const + { return vtable()->construct(this, d); } + inline ReturnedValue call(CallData *d) const + { return vtable()->call(this, d); } protected: - static void construct(const Managed *m, Scope &scope, CallData *); - static void call(const Managed *m, Scope &scope, CallData *); + static ReturnedValue construct(const Managed *m, CallData *); + static ReturnedValue call(const Managed *m, CallData *); static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); static ReturnedValue getIndexed(const Managed *m, uint index, bool *hasProperty); static bool put(Managed *m, String *name, const Value &value); diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 2e72c0f13f..27bab52064 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -60,27 +60,29 @@ void Heap::ObjectCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("Object")); } -void ObjectCtor::construct(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue ObjectCtor::construct(const Managed *m, CallData *callData) { - const ObjectCtor *ctor = static_cast<const ObjectCtor *>(that); + ExecutionEngine *v4 = m->engine(); + const ObjectCtor *ctor = static_cast<const ObjectCtor *>(m); if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) { + Scope scope(v4); ScopedObject obj(scope, scope.engine->newObject()); ScopedObject proto(scope, ctor->get(scope.engine->id_prototype())); if (!!proto) obj->setPrototype(proto); - scope.result = obj.asReturnedValue(); + return obj.asReturnedValue(); } else { - scope.result = callData->args[0].toObject(scope.engine); + return callData->args[0].toObject(v4)->asReturnedValue(); } } -void ObjectCtor::call(const Managed *, Scope &scope, CallData *callData) +ReturnedValue ObjectCtor::call(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = scope.engine; + ExecutionEngine *v4 = m->engine(); if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull()) { - scope.result = v4->newObject()->asReturnedValue(); + return v4->newObject()->asReturnedValue(); } else { - scope.result = callData->args[0].toObject(v4); + return callData->args[0].toObject(v4)->asReturnedValue(); } } @@ -476,7 +478,7 @@ void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scop THROW_TYPE_ERROR(); ScopedCallData cData(scope); cData->thisObject = o; - f->call(scope, callData); + scope.result = f->call(callData); } void ObjectPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData) diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h index 44b54267f3..d1383df192 100644 --- a/src/qml/jsruntime/qv4objectproto_p.h +++ b/src/qml/jsruntime/qv4objectproto_p.h @@ -70,8 +70,8 @@ struct ObjectCtor: FunctionObject { V4_OBJECT2(ObjectCtor, FunctionObject) - static void construct(const Managed *that, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *that, CallData *callData); + static ReturnedValue call(const Managed *m, CallData *callData); }; struct ObjectPrototype: Object diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index fbb7f9729b..b710fd8444 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -826,7 +826,7 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase } } - f->call(scope, callData); + f->call(callData); if (scope.hasException()) { QQmlError error = v4->catchExceptionAsQmlError(); if (error.description().isEmpty()) { @@ -1885,32 +1885,25 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con return Encode::undefined(); } -void QObjectMethod::call(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue QObjectMethod::call(const Managed *m, CallData *callData) { const QObjectMethod *This = static_cast<const QObjectMethod*>(m); - This->callInternal(callData, scope); + return This->callInternal(callData); } -void QObjectMethod::callInternal(CallData *callData, Scope &scope) const +ReturnedValue QObjectMethod::callInternal(CallData *callData) const { ExecutionEngine *v4 = engine(); ExecutionContext *context = v4->currentContext; - if (d()->index == DestroyMethod) { - scope.result = method_destroy(context, callData->args, callData->argc); - return; - } - - else if (d()->index == ToStringMethod) { - scope.result = method_toString(context); - return; - } + if (d()->index == DestroyMethod) + return method_destroy(context, callData->args, callData->argc); + else if (d()->index == ToStringMethod) + return method_toString(context); QQmlObjectOrGadget object(d()->object()); if (!d()->object()) { - if (!d()->valueTypeWrapper) { - scope.result = Encode::undefined(); - return; - } + if (!d()->valueTypeWrapper) + return Encode::undefined(); object = QQmlObjectOrGadget(d()->propertyCache(), d()->valueTypeWrapper->gadgetPtr); } @@ -1919,20 +1912,16 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const if (d()->propertyCache()) { QQmlPropertyData *data = d()->propertyCache()->method(d()->index); - if (!data) { - scope.result = QV4::Encode::undefined(); - return; - } + if (!data) + return QV4::Encode::undefined(); method = *data; } else { const QMetaObject *mo = d()->object()->metaObject(); const QMetaMethod moMethod = mo->method(d()->index); method.load(moMethod); - if (method.coreIndex() == -1) { - scope.result = QV4::Encode::undefined(); - return; - } + if (method.coreIndex() == -1) + return QV4::Encode::undefined(); // Look for overloaded methods QByteArray methodName = moMethod.name(); @@ -1948,20 +1937,21 @@ void QObjectMethod::callInternal(CallData *callData, Scope &scope) const } if (method.isV4Function()) { - scope.result = QV4::Encode::undefined(); - QQmlV4Function func(callData, &scope.result, v4); + Scope scope(v4); + QV4::ScopedValue rv(scope, QV4::Primitive::undefinedValue()); + QQmlV4Function func(callData, rv, v4); QQmlV4Function *funcptr = &func; void *args[] = { 0, &funcptr }; object.metacall(QMetaObject::InvokeMetaMethod, method.coreIndex(), args); - return; + return rv->asReturnedValue(); } if (!method.isOverload()) { - scope.result = CallPrecise(object, method, v4, callData); + return CallPrecise(object, method, v4, callData); } else { - scope.result = CallOverloaded(object, method, v4, callData, d()->propertyCache()); + return CallOverloaded(object, method, v4, callData, d()->propertyCache()); } } @@ -2024,10 +2014,10 @@ void QMetaObjectWrapper::init(ExecutionEngine *) { } } -void QMetaObjectWrapper::construct(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue QMetaObjectWrapper::construct(const Managed *m, CallData *callData) { const QMetaObjectWrapper *This = static_cast<const QMetaObjectWrapper*>(m); - scope.result = This->constructInternal(callData); + return This->constructInternal(callData); } ReturnedValue QMetaObjectWrapper::constructInternal(CallData * callData) const { diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 018e444f7c..9188bba990 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -237,9 +237,9 @@ struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject QV4::ReturnedValue method_toString(QV4::ExecutionContext *ctx) const; QV4::ReturnedValue method_destroy(QV4::ExecutionContext *ctx, const Value *args, int argc) const; - static void call(const Managed *, Scope &scope, CallData *callData); + static ReturnedValue call(const Managed *, CallData *callData); - void callInternal(CallData *callData, Scope &scope) const; + ReturnedValue callInternal(CallData *callData) const; static QPair<QObject *, int> extractQtMethod(const QV4::FunctionObject *function); }; @@ -251,7 +251,7 @@ struct Q_QML_EXPORT QMetaObjectWrapper : public QV4::FunctionObject V4_NEEDS_DESTROY static ReturnedValue create(ExecutionEngine *engine, const QMetaObject* metaObject); - static void construct(const Managed *, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *, CallData *callData); static bool isEqualTo(Managed *a, Managed *b); const QMetaObject *metaObject() const { return d()->metaObject; } diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index d9869920d9..4df9d47e7d 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -216,39 +216,33 @@ void Heap::RegExpCtor::clearLastMatch() lastMatchEnd = 0; } -void RegExpCtor::construct(const Managed *, Scope &scope, CallData *callData) +ReturnedValue RegExpCtor::construct(const Managed *m, CallData *callData) { + Scope scope(m->engine()); ScopedValue r(scope, callData->argument(0)); ScopedValue f(scope, callData->argument(1)); Scoped<RegExpObject> re(scope, r); if (re) { - if (!f->isUndefined()) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (!f->isUndefined()) + return scope.engine->throwTypeError(); Scoped<RegExp> regexp(scope, re->value()); - scope.result = Encode(scope.engine->newRegExpObject(regexp, re->global())); - return; + return Encode(scope.engine->newRegExpObject(regexp, re->global())); } QString pattern; if (!r->isUndefined()) pattern = r->toQString(); - if (scope.hasException()) { - scope.result = Encode::undefined(); - return; - } + if (scope.hasException()) + return Encode::undefined(); bool global = false; bool ignoreCase = false; bool multiLine = false; if (!f->isUndefined()) { ScopedString s(scope, f->toString(scope.engine)); - if (scope.hasException()) { - scope.result = Encode::undefined(); - return; - } + if (scope.hasException()) + return Encode::undefined(); QString str = s->toQString(); for (int i = 0; i < str.length(); ++i) { if (str.at(i) == QLatin1Char('g') && !global) { @@ -258,31 +252,28 @@ void RegExpCtor::construct(const Managed *, Scope &scope, CallData *callData) } else if (str.at(i) == QLatin1Char('m') && !multiLine) { multiLine = true; } else { - scope.result = scope.engine->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor")); - return; + return scope.engine->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor")); } } } Scoped<RegExp> regexp(scope, RegExp::create(scope.engine, pattern, ignoreCase, multiLine)); if (!regexp->isValid()) { - scope.result = scope.engine->throwSyntaxError(QStringLiteral("Invalid regular expression")); - return; + return scope.engine->throwSyntaxError(QStringLiteral("Invalid regular expression")); } - scope.result = Encode(scope.engine->newRegExpObject(regexp, global)); + return Encode(scope.engine->newRegExpObject(regexp, global)); } -void RegExpCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue RegExpCtor::call(const Managed *that, CallData *callData) { if (callData->argc > 0 && callData->args[0].as<RegExpObject>()) { if (callData->argc == 1 || callData->args[1].isUndefined()) { - scope.result = callData->args[0]; - return; + return Encode(callData->args[0]); } } - construct(that, scope, callData); + return construct(that, callData); } void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor) @@ -402,7 +393,7 @@ void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, Call ScopedCallData cData(scope, callData->argc); memcpy(cData->args, callData->args, callData->argc*sizeof(Value)); - scope.engine->regExpCtor()->as<FunctionObject>()->construct(scope, cData); + scope.result = scope.engine->regExpCtor()->as<FunctionObject>()->construct(cData); Scoped<RegExpObject> re(scope, scope.result.asReturnedValue()); r->d()->value.set(scope.engine, re->value()); diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index f6e7df978b..ea16591445 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -150,8 +150,8 @@ struct RegExpCtor: FunctionObject int lastMatchStart() { return d()->lastMatchStart; } int lastMatchEnd() { return d()->lastMatchEnd; } - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; struct RegExpPrototype: RegExpObject diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index cbe55fe080..f5a6914182 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -428,9 +428,9 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH ScopedValue conv(scope, object->get(meth1)); if (FunctionObject *o = conv->as<FunctionObject>()) { - o->call(scope, callData); - if (scope.result.isPrimitive()) - return scope.result.asReturnedValue(); + ScopedValue r(scope, o->call(callData)); + if (r->isPrimitive()) + return r->asReturnedValue(); } if (engine->hasException) @@ -438,9 +438,9 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(const Object *object, int typeH conv = object->get(meth2); if (FunctionObject *o = conv->as<FunctionObject>()) { - o->call(scope, callData); - if (scope.result.isPrimitive()) - return scope.result.asReturnedValue(); + ScopedValue r(scope, o->call(callData)); + if (r->isPrimitive()) + return r->asReturnedValue(); } return engine->throwTypeError(); @@ -1011,13 +1011,10 @@ ReturnedValue Runtime::method_callGlobalLookup(ExecutionEngine *engine, uint ind return engine->throwTypeError(); ScopedString name(scope, engine->current->v4Function->compilationUnit->runtimeStrings[l->nameIndex]); - if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) { - static_cast<EvalFunction *>(o.getPointer())->evalCall(scope, callData, true); - } else { - o->call(scope, callData); - } + if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) + return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true); - return scope.result.asReturnedValue(); + return o->call(callData); } @@ -1044,13 +1041,10 @@ ReturnedValue Runtime::method_callActivationProperty(ExecutionEngine *engine, in return engine->throwTypeError(msg); } - if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) { - static_cast<EvalFunction *>(o)->evalCall(scope, callData, true); - } else { - o->call(scope, callData); - } + if (o->d() == scope.engine->evalFunction()->d() && name->equals(scope.engine->id_eval())) + return static_cast<EvalFunction *>(o)->evalCall(callData, true); - return scope.result.asReturnedValue(); + return o->call(callData); } ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) @@ -1073,8 +1067,7 @@ ReturnedValue Runtime::method_callProperty(ExecutionEngine *engine, int nameInde ScopedFunctionObject o(scope, baseObject->get(name)); if (o) { - o->call(scope, callData); - return scope.result.asReturnedValue(); + return o->call(callData); } else { QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow()); return engine->throwTypeError(error); @@ -1088,11 +1081,9 @@ ReturnedValue Runtime::method_callPropertyLookup(ExecutionEngine *engine, uint i Value v; v = l->getter(l, engine, callData->thisObject); Object *o = v.objectValue(); - if (Q_LIKELY(o)) { - Scope scope(engine); - o->call(scope, callData); - return scope.result.asReturnedValue(); - } + if (Q_LIKELY(o)) + return o->call(callData); + return engine->throwTypeError(); } @@ -1110,17 +1101,14 @@ ReturnedValue Runtime::method_callElement(ExecutionEngine *engine, const Value & if (!o) return engine->throwTypeError(); - o->call(scope, callData); - return scope.result.asReturnedValue(); + return o->call(callData); } ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &func, CallData *callData) { - if (Object *o = func.objectValue()) { - Scope scope(engine); - o->call(scope, callData); - return scope.result.asReturnedValue(); - } + if (Object *o = func.objectValue()) + return o->call(callData); + return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow())); } @@ -1132,12 +1120,10 @@ ReturnedValue Runtime::method_constructGlobalLookup(ExecutionEngine *engine, uin Lookup *l = engine->current->v4Function->compilationUnit->runtimeLookups + index; ScopedObject f(scope, l->globalGetter(l, engine)); - if (f) { - f->construct(scope, callData); - return scope.result.asReturnedValue(); - } else { - return engine->throwTypeError(); - } + if (f) + return f->construct(callData); + + return engine->throwTypeError(); } @@ -1153,8 +1139,7 @@ ReturnedValue Runtime::method_constructActivationProperty(ExecutionEngine *engin if (!f) return engine->throwTypeError(); - f->construct(scope, callData); - return scope.result.asReturnedValue(); + return f->construct(callData); } ReturnedValue Runtime::method_constructValue(ExecutionEngine *engine, const Value &func, CallData *callData) @@ -1163,9 +1148,7 @@ ReturnedValue Runtime::method_constructValue(ExecutionEngine *engine, const Valu if (!f) return engine->throwTypeError(); - Scope scope(engine); - f->construct(scope, callData); - return scope.result.asReturnedValue(); + return f->construct(callData); } ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData) @@ -1177,13 +1160,10 @@ ReturnedValue Runtime::method_constructProperty(ExecutionEngine *engine, int nam return Encode::undefined(); ScopedObject f(scope, thisObject->get(name)); - if (f) { - Scope scope(engine); - f->construct(scope, callData); - return scope.result.asReturnedValue(); - } else { - return engine->throwTypeError(); - } + if (f) + return f->construct(callData); + + return engine->throwTypeError(); } ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData) @@ -1192,11 +1172,9 @@ ReturnedValue Runtime::method_constructPropertyLookup(ExecutionEngine *engine, u Value v; v = l->getter(l, engine, callData->thisObject); Object *o = v.objectValue(); - if (Q_LIKELY(o)) { - Scope scope(engine); - o->construct(scope, callData); - return scope.result.asReturnedValue(); - } + if (Q_LIKELY(o)) + return o->construct(callData); + return engine->throwTypeError(); } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 4d208ad574..0abe6ddd98 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -421,8 +421,8 @@ public: callData->args[0] = convertElementToValue(m_v4, lhs); callData->args[1] = convertElementToValue(m_v4, rhs); callData->thisObject = m_v4->globalObject; - compare->call(scope, callData); - return scope.result.toNumber() < 0; + QV4::ScopedValue result(scope, compare->call(callData)); + return result->toNumber() < 0; } private: diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index ab74fd22d3..16998c4728 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -150,24 +150,25 @@ void Heap::StringCtor::init(QV4::ExecutionContext *scope) Heap::FunctionObject::init(scope, QStringLiteral("String")); } -void StringCtor::construct(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue StringCtor::construct(const Managed *m, 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(); - scope.result = Encode(v4->newStringObject(value)); + return Encode(v4->newStringObject(value)); } -void StringCtor::call(const Managed *, Scope &scope, CallData *callData) +ReturnedValue StringCtor::call(const Managed *m, CallData *callData) { - ExecutionEngine *v4 = scope.engine; + ExecutionEngine *v4 = m->engine(); if (callData->argc) - scope.result = callData->args[0].toString(v4); + return callData->args[0].toString(v4)->asReturnedValue(); else - scope.result = v4->newString(); + return v4->newString()->asReturnedValue(); } void StringPrototype::init(ExecutionEngine *engine, Object *ctor) @@ -397,8 +398,7 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa if (!rx) { ScopedCallData callData(scope, 1); callData->args[0] = regexp; - scope.engine->regExpCtor()->construct(scope, callData); - rx = scope.result.asReturnedValue(); + rx = scope.engine->regExpCtor()->construct(callData); } if (!rx) @@ -415,7 +415,7 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa cData->thisObject = rx; cData->args[0] = s; if (!global) { - exec->call(scope, cData); + scope.result = exec->call(cData); return; } @@ -428,7 +428,7 @@ void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallDa ScopedValue matchStr(scope); ScopedValue index(scope); while (1) { - exec->call(scope, cData); + scope.result = exec->call(cData); if (scope.result.isNull()) break; assert(scope.result.isObject()); @@ -569,6 +569,7 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call } QString result; + ScopedValue replacement(scope); ScopedValue replaceValue(scope, callData->argument(1)); ScopedFunctionObject searchCallback(scope, replaceValue); if (!!searchCallback) { @@ -593,9 +594,9 @@ void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, Call callData->args[numCaptures] = Primitive::fromUInt32(matchStart); callData->args[numCaptures + 1] = scope.engine->newString(string); - searchCallback->call(scope, callData); + replacement = searchCallback->call(callData); result += string.midRef(lastEnd, matchStart - lastEnd); - result += scope.result.toQString(); + result += replacement->toQString(); lastEnd = matchEnd; } result += string.midRef(lastEnd); @@ -634,7 +635,7 @@ void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallD if (!regExp) { ScopedCallData callData(scope, 1); callData->args[0] = scope.result; - scope.engine->regExpCtor()->construct(scope, callData); + scope.result = scope.engine->regExpCtor()->construct(callData); CHECK_EXCEPTION(); regExp = scope.result.as<RegExpObject>(); diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h index ce046f4844..f1c0c2904e 100644 --- a/src/qml/jsruntime/qv4stringobject_p.h +++ b/src/qml/jsruntime/qv4stringobject_p.h @@ -106,8 +106,8 @@ struct StringCtor: FunctionObject { V4_OBJECT2(StringCtor, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *, CallData *callData); }; struct StringPrototype: StringObject diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp index fe27d7c2d2..1944e0b87e 100644 --- a/src/qml/jsruntime/qv4typedarray.cpp +++ b/src/qml/jsruntime/qv4typedarray.cpp @@ -208,34 +208,30 @@ void Heap::TypedArrayCtor::init(QV4::ExecutionContext *scope, TypedArray::Type t type = t; } -void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callData) +ReturnedValue TypedArrayCtor::construct(const Managed *m, CallData *callData) { + Scope scope(m->engine()); Scoped<TypedArrayCtor> that(scope, static_cast<const TypedArrayCtor *>(m)); if (!callData->argc || !callData->args[0].isObject()) { // ECMA 6 22.2.1.1 double l = callData->argc ? callData->args[0].toNumber() : 0; - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); uint len = (uint)l; if (l != len) scope.engine->throwRangeError(QStringLiteral("Non integer length for typed array.")); uint byteLength = len * operations[that->d()->type].bytesPerElement; Scoped<ArrayBuffer> buffer(scope, scope.engine->newArrayBuffer(byteLength)); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); array->d()->buffer.set(scope.engine, buffer->d()); array->d()->byteLength = byteLength; array->d()->byteOffset = 0; - scope.result = array.asReturnedValue(); - return; + return array.asReturnedValue(); } Scoped<TypedArray> typedArray(scope, callData->argument(0)); if (!!typedArray) { @@ -247,10 +243,8 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat uint destByteLength = byteLength*destElementSize/srcElementSize; Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(destByteLength)); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); array->d()->buffer.set(scope.engine, newBuffer->d()); @@ -275,8 +269,7 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat } } - scope.result = array.asReturnedValue(); - return; + return array.asReturnedValue(); } Scoped<ArrayBuffer> buffer(scope, callData->argument(0)); if (!!buffer) { @@ -285,29 +278,21 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat double dbyteOffset = callData->argc > 1 ? callData->args[1].toInteger() : 0; uint byteOffset = (uint)dbyteOffset; uint elementSize = operations[that->d()->type].bytesPerElement; - if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength()) { - scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset")); - return; - } + if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength()) + return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset")); uint byteLength; if (callData->argc < 3 || callData->args[2].isUndefined()) { byteLength = buffer->byteLength() - byteOffset; - if (buffer->byteLength() < byteOffset || byteLength % elementSize) { - scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); - return; - } + if (buffer->byteLength() < byteOffset || byteLength % elementSize) + return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); } else { double l = qBound(0., callData->args[2].toInteger(), (double)UINT_MAX); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); l *= elementSize; - if (buffer->byteLength() - byteOffset < l) { - scope.result = scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); - return; - } + if (buffer->byteLength() - byteOffset < l) + return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); byteLength = (uint)l; } @@ -315,25 +300,20 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat array->d()->buffer.set(scope.engine, buffer->d()); array->d()->byteLength = byteLength; array->d()->byteOffset = byteOffset; - scope.result = array.asReturnedValue(); - return; + return array.asReturnedValue(); } // ECMA 6 22.2.1.3 ScopedObject o(scope, callData->argument(0)); uint l = (uint) qBound(0., ScopedValue(scope, o->get(scope.engine->id_length()))->toInteger(), (double)UINT_MAX); - if (scope.engine->hasException) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (scope.engine->hasException) + return scope.engine->throwTypeError(); uint elementSize = operations[that->d()->type].bytesPerElement; Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(l * elementSize)); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); array->d()->buffer.set(scope.engine, newBuffer->d()); @@ -346,21 +326,19 @@ void TypedArrayCtor::construct(const Managed *m, Scope &scope, CallData *callDat while (idx < l) { val = o->getIndexed(idx); array->d()->type->write(scope.engine, b, 0, val); - if (scope.engine->hasException) { - scope.result = Encode::undefined(); - return; - } + if (scope.engine->hasException) + return Encode::undefined(); ++idx; b += elementSize; } - scope.result = array.asReturnedValue(); + return array.asReturnedValue(); } -void TypedArrayCtor::call(const Managed *that, Scope &scope, CallData *callData) +ReturnedValue TypedArrayCtor::call(const Managed *that, CallData *callData) { - construct(that, scope, callData); + return construct(that, callData); } void Heap::TypedArray::init(Type t) @@ -596,5 +574,5 @@ void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, cData->args[0] = buffer; cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement); cData->args[2] = Encode(newLen); - constructor->construct(scope, cData); + scope.result = constructor->construct(cData); } diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h index a472dfa607..fad7901428 100644 --- a/src/qml/jsruntime/qv4typedarray_p.h +++ b/src/qml/jsruntime/qv4typedarray_p.h @@ -141,8 +141,8 @@ struct TypedArrayCtor: FunctionObject { V4_OBJECT2(TypedArrayCtor, FunctionObject) - static void construct(const Managed *m, Scope &scope, CallData *callData); - static void call(const Managed *that, Scope &scope, CallData *callData); + static ReturnedValue construct(const Managed *m, CallData *callData); + static ReturnedValue call(const Managed *that, CallData *callData); }; diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 7629e764cf..e34ee0ccbe 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -682,6 +682,9 @@ struct Encode { Encode(ReturnedValue v) { val = v; } + Encode(Value v) { + val = v.rawValue(); + } Encode(Heap::Base *o) { Q_ASSERT(o); diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 62288a5845..911df78595 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -202,12 +202,11 @@ protected: bool isUndefined = false; - QV4::ScopedCallData callData(scope); - QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); + QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined)); bool error = false; if (!watcher.wasDeleted() && isAddedToObject() && !hasError()) - error = !write(scope.result, isUndefined, flags); + error = !write(result, isUndefined, flags); if (!watcher.wasDeleted()) { @@ -412,12 +411,11 @@ QVariant QQmlBinding::evaluate() bool isUndefined = false; QV4::Scope scope(ep->v4engine()); - QV4::ScopedCallData callData(scope); - QQmlJavaScriptExpression::evaluate(callData, &isUndefined, scope); + QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined)); ep->dereferenceScarceResources(); - return scope.engine->toVariant(scope.result, qMetaTypeId<QList<QObject*> >()); + return scope.engine->toVariant(result, qMetaTypeId<QList<QObject*> >()); } QString QQmlBinding::expressionIdentifier() const diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index 19ece44beb..2c0f0091ea 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -220,7 +220,7 @@ void QQmlBoundSignalExpression::evaluate(void **a) } } - QQmlJavaScriptExpression::evaluate(callData, 0, scope); + QQmlJavaScriptExpression::evaluate(callData, 0); ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. } @@ -242,7 +242,7 @@ void QQmlBoundSignalExpression::evaluate(const QList<QVariant> &args) callData->args[ii] = scope.engine->fromVariant(args[ii]); } - QQmlJavaScriptExpression::evaluate(callData, 0, scope); + QQmlJavaScriptExpression::evaluate(callData, 0); ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. } diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index e7a45482e6..b22fa31d13 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1545,7 +1545,7 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) QV4::ScopedCallData callData(scope, 1); callData->thisObject = this; callData->args[0] = QV4::Primitive::fromUInt32(s); - f->call(scope, callData); + f->call(callData); if (scope.hasException()) { QQmlError error = scope.engine->catchExceptionAsQmlError(); QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error); diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 0c82eadc97..5f274b8da5 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -73,7 +73,7 @@ void QQmlDelayedCallQueue::DelayedFunctionCall::execute(QV4::ExecutionEngine *en const QV4::FunctionObject *callback = m_function.as<QV4::FunctionObject>(); Q_ASSERT(callback); - callback->call(scope, callData); + callback->call(callData); if (scope.engine->hasException) { QQmlError error = scope.engine->catchExceptionAsQmlError(); diff --git a/src/qml/qml/qqmlexpression.cpp b/src/qml/qml/qqmlexpression.cpp index b70db5ed86..c4b705230a 100644 --- a/src/qml/qml/qqmlexpression.cpp +++ b/src/qml/qml/qqmlexpression.cpp @@ -248,15 +248,14 @@ void QQmlExpression::setExpression(const QString &expression) } // Must be called with a valid handle scope -void QQmlExpressionPrivate::v4value(bool *isUndefined, QV4::Scope &scope) +QV4::ReturnedValue QQmlExpressionPrivate::v4value(bool *isUndefined) { if (!expressionFunctionValid) { createQmlBinding(context(), scopeObject(), expression, url, line); expressionFunctionValid = true; } - QV4::ScopedCallData callData(scope); - evaluate(callData, isUndefined, scope); + return evaluate(isUndefined); } QVariant QQmlExpressionPrivate::value(bool *isUndefined) @@ -275,9 +274,9 @@ QVariant QQmlExpressionPrivate::value(bool *isUndefined) { QV4::Scope scope(QV8Engine::getV4(ep->v8engine())); - v4value(isUndefined, scope); + QV4::ScopedValue result(scope, v4value(isUndefined)); if (!hasError()) - rv = scope.engine->toVariant(scope.result, -1); + rv = scope.engine->toVariant(result, -1); } ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. diff --git a/src/qml/qml/qqmlexpression_p.h b/src/qml/qml/qqmlexpression_p.h index 44342a957b..a94ca0fc2d 100644 --- a/src/qml/qml/qqmlexpression_p.h +++ b/src/qml/qml/qqmlexpression_p.h @@ -75,7 +75,7 @@ public: QVariant value(bool *isUndefined = 0); - void v4value(bool *isUndefined, QV4::Scope &scope); + QV4::ReturnedValue v4value(bool *isUndefined = 0); static inline QQmlExpressionPrivate *get(QQmlExpression *expr); static inline QQmlExpression *get(QQmlExpressionPrivate *expr); diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 17cccc0bbd..6c5c00e8ae 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -179,9 +179,16 @@ void QQmlJavaScriptExpression::refresh() { } +QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(bool *isUndefined) +{ + QV4::ExecutionEngine *v4 = QV8Engine::getV4(m_context->engine); + QV4::Scope scope(v4); + QV4::ScopedCallData callData(scope); + return evaluate(callData, isUndefined); +} -void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined, QV4::Scope &scope) +QV4::ReturnedValue QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefined) { Q_ASSERT(m_context && m_context->engine); @@ -189,7 +196,7 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin if (!v4Function) { if (isUndefined) *isUndefined = true; - return; + return QV4::Encode::undefined(); } QQmlEnginePrivate *ep = QQmlEnginePrivate::get(m_context->engine); @@ -209,7 +216,8 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin capture.guards.copyAndClearPrepend(activeGuards); QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine()); - scope.result = QV4::Primitive::undefinedValue(); + QV4::Scope scope(v4); + QV4::ScopedValue result(scope, QV4::Primitive::undefinedValue()); callData->thisObject = v4->globalObject; if (scopeObject()) { QV4::ScopedValue value(scope, QV4::QObjectWrapper::wrap(v4, scopeObject())); @@ -223,6 +231,7 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin } else { outer->call(scope, callData, v4Function); } + result = scope.result; if (scope.hasException()) { if (watcher.wasDeleted()) @@ -233,7 +242,7 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin *isUndefined = true; } else { if (isUndefined) - *isUndefined = scope.result.isUndefined(); + *isUndefined = result->isUndefined(); if (!watcher.wasDeleted() && hasDelayedError()) delayedError()->clearError(); @@ -250,6 +259,8 @@ void QQmlJavaScriptExpression::evaluate(QV4::CallData *callData, bool *isUndefin g->Delete(); ep->propertyCapture = lastPropertyCapture; + + return result->asReturnedValue(); } void QQmlPropertyCapture::captureProperty(QQmlNotifier *n, Duration duration) diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h index 646cc5ab3d..6941aebe64 100644 --- a/src/qml/qml/qqmljavascriptexpression_p.h +++ b/src/qml/qml/qqmljavascriptexpression_p.h @@ -103,7 +103,8 @@ public: virtual QString expressionIdentifier() const = 0; virtual void expressionChanged() = 0; - void evaluate(QV4::CallData *callData, bool *isUndefined, QV4::Scope &scope); + QV4::ReturnedValue evaluate(bool *isUndefined); + QV4::ReturnedValue evaluate(QV4::CallData *callData, bool *isUndefined); inline bool notifyOnValueChanged() const; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index a2ab9bdfed..7e6fa2ee67 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -955,14 +955,15 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * for (uint ii = 0; ii < parameterCount; ++ii) callData->args[ii] = scope.engine->fromVariant(*(QVariant *)a[ii + 1]); - function->call(scope, callData); + QV4::ScopedValue result(scope); + result = function->call(callData); if (scope.hasException()) { QQmlError error = scope.engine->catchExceptionAsQmlError(); if (error.isValid()) ep->warning(error); if (a[0]) *(QVariant *)a[0] = QVariant(); } else { - if (a[0]) *(QVariant *)a[0] = scope.engine->toVariant(scope.result, 0); + if (a[0]) *(QVariant *)a[0] = scope.engine->toVariant(result, 0); } ep->dereferenceScarceResources(); // "release" scarce resources if top-level expression evaluation is complete. diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 9e8735cbc6..59db5bd9ac 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1559,7 +1559,7 @@ void QQmlXMLHttpRequest::dispatchCallback(Object *thisObj, QQmlContextData *cont QV4::ScopedCallData callData(scope); callData->thisObject = Encode::undefined(); - callback->call(scope, callData); + callback->call(callData); if (scope.engine->hasException) { QQmlError error = scope.engine->catchExceptionAsQmlError(); @@ -1617,23 +1617,22 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject { V4_OBJECT2(QQmlXMLHttpRequestCtor, FunctionObject) - static void construct(const Managed *that, Scope &scope, QV4::CallData *) + static ReturnedValue construct(const Managed *that, QV4::CallData *) { + Scope scope(that->engine()); Scoped<QQmlXMLHttpRequestCtor> ctor(scope, that->as<QQmlXMLHttpRequestCtor>()); - if (!ctor) { - scope.result = scope.engine->throwTypeError(); - return; - } + if (!ctor) + return scope.engine->throwTypeError(); QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(scope.engine->v8Engine->networkAccessManager()); Scoped<QQmlXMLHttpRequestWrapper> w(scope, scope.engine->memoryManager->allocObject<QQmlXMLHttpRequestWrapper>(r)); ScopedObject proto(scope, ctor->d()->proto); w->setPrototype(proto); - scope.result = w.asReturnedValue(); + return w.asReturnedValue(); } - static void call(const Managed *, Scope &scope, QV4::CallData *) { - scope.result = Primitive::undefinedValue(); + static ReturnedValue call(const Managed *, QV4::CallData *) { + return Encode::undefined(); } void setupProto(); diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index 9620df6af9..a1e3fde1b6 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -96,17 +96,16 @@ struct DelegateModelGroupFunction : QV4::FunctionObject return scope->engine()->memoryManager->allocObject<DelegateModelGroupFunction>(scope, flag, code); } - static void call(const QV4::Managed *that, QV4::Scope &scope, QV4::CallData *callData) + static ReturnedValue call(const QV4::Managed *that, QV4::CallData *callData) { + QV4::Scope scope(that->engine()); QV4::Scoped<DelegateModelGroupFunction> f(scope, static_cast<const DelegateModelGroupFunction *>(that)); QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject); - if (!o) { - scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); - return; - } + if (!o) + return scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object")); QV4::ScopedValue v(scope, callData->argument(0)); - scope.result = f->d()->code(o->d()->item, f->d()->flag, v); + return f->d()->code(o->d()->item, f->d()->flag, v); } }; diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index 6b7e3dee9f..743bcbc5a3 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -250,8 +250,7 @@ void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() QV4::ScopedCallData callData(scope, 1); callData->args[0] = function; callData->thisObject = global(); - createsendconstructor->call(scope, callData); - createsend.set(scope.engine, scope.result.asReturnedValue()); + createsend.set(scope.engine, createsendconstructor->call(callData)); } // Requires handle and context scope @@ -264,13 +263,14 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(i QV4::Scope scope(v4); QV4::ScopedFunctionObject f(scope, createsend.value()); + QV4::ScopedValue v(scope); QV4::ScopedCallData callData(scope, 1); callData->args[0] = QV4::Primitive::fromInt32(id); callData->thisObject = global(); - f->call(scope, callData); + v = f->call(callData); if (scope.hasException()) - scope.result = scope.engine->catchException(); - return scope.result.asReturnedValue(); + v = scope.engine->catchException(); + return v->asReturnedValue(); } #if QT_CONFIG(qml_network) @@ -367,7 +367,7 @@ void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &d callData->thisObject = workerEngine->global(); callData->args[0] = qmlContext->d()->qml(); // ### callData->args[1] = value; - f->call(scope, callData); + f->call(callData); if (scope.hasException()) { QQmlError error = scope.engine->catchExceptionAsQmlError(); reportScriptException(script, error); diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 670dc6d032..027b4b3595 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -734,7 +734,7 @@ void QQuickCanvasItem::updatePolish() for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) { QV4::ScopedFunctionObject f(scope, it.value().value()); callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000); - f->call(scope, callData); + f->call(callData); } } else { |