diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-10-21 09:57:58 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-29 10:38:59 +0100 |
commit | af22149dd8daf593182fec978f15dc1667c9cf8d (patch) | |
tree | 17334ae83a3015fd6ca535fb9d2e97b40e1da825 /src/qml/jsruntime/qv4qobjectwrapper.cpp | |
parent | 2b996ca17fbc36029af3900933b6fcc1418afb6a (diff) |
Avoid side effects when en exception has been thrown.
We don't want to check for exceptions after every single
line on our runtime methods. A better way to handle this
is to add the check in all methods that have direct side
effects (as e.g. writing to a property of the JS stack).
We also need to return whereever we throw an exception.
To simplify the code, ExecutionContext::throwXxx methods now
return a ReturnedValue (always undefined) for convenience.
Change-Id: Ide6c804f819c731a3f14c6c43121d08029c9fb90
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/jsruntime/qv4qobjectwrapper.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 05d5532f8f..a581e6bc69 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -436,7 +436,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC if (!result->isWritable() && !result->isQList()) { QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"'); - ctx->throwTypeError(error); + return ctx->throwTypeError(error); } QQmlBinding *newBinding = 0; @@ -451,6 +451,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC else error += QLatin1String(QMetaType::typeName(result->propType)); ctx->throwError(error); + return false; } } else { // binding assignment. @@ -504,6 +505,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC else error += QLatin1String(QMetaType::typeName(result->propType)); ctx->throwError(error); + return false; } else if (value->asFunctionObject()) { // this is handled by the binding creation above } else if (result->propType == QMetaType::Int && value->isNumber()) { @@ -542,6 +544,7 @@ bool QObjectWrapper::setQmlProperty(ExecutionContext *ctx, QQmlContextData *qmlC QLatin1String(" to ") + QLatin1String(targetTypeName); ctx->throwError(error); + return false; } } @@ -1281,7 +1284,7 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d if (returnType == QMetaType::UnknownType) { QString typeName = QString::fromLatin1(unknownTypeError); QString error = QString::fromLatin1("Unknown method return type: %1").arg(typeName); - QV8Engine::getV4(engine)->current->throwError(error); + return QV8Engine::getV4(engine)->current->throwError(error); } if (data.hasArguments()) { @@ -1295,12 +1298,12 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d if (!args) { QString typeName = QString::fromLatin1(unknownTypeError); QString error = QString::fromLatin1("Unknown method parameter type: %1").arg(typeName); - QV8Engine::getV4(engine)->current->throwError(error); + return QV8Engine::getV4(engine)->current->throwError(error); } if (args[0] > callArgs->argc) { QString error = QLatin1String("Insufficient arguments"); - QV8Engine::getV4(engine)->current->throwError(error); + return QV8Engine::getV4(engine)->current->throwError(error); } return CallMethod(object, data.coreIndex, returnType, args[0], args + 1, engine, callArgs); @@ -1399,7 +1402,7 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData candidate = RelatedMethod(object, candidate, dummy); } - QV8Engine::getV4(engine)->current->throwError(error); + return QV8Engine::getV4(engine)->current->throwError(error); } } @@ -1697,7 +1700,7 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con if (!m_object) return Encode::undefined(); if (QQmlData::keepAliveDuringGarbageCollection(m_object)) - ctx->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object")); + return ctx->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object")); int delay = 0; if (argc > 0) |