diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-10-15 12:43:57 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-15 14:00:57 +0200 |
commit | 5302fea533f68abbe91ffc32ec732c11c8eef7ee (patch) | |
tree | ef083453747ddc8acf757bb1ff0a1d836eedeb51 /src/qml/qml | |
parent | dfa234a60a112903995944573a7d2cf400af7f24 (diff) |
Make sure the incubated object survives the statusChanged call
QQmlComponent::statusChanged() marked the incubated object
as destructable when it was done loading. This implied
that any gc call afterwards could clean it up. To fix, push
the object on the GC stack so it lives until the method returns.
Also renamed the WrapperIncubator to QQmlComponentIncubator.
Change-Id: I5a8f478a1fd65ea73ddff310392219709a935a70
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 1e9dbdfaf1..e0360b67cb 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1105,7 +1105,7 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, enginePriv->incubate(incubator, forContextData); } -class WrapperIncubator; +class QQmlComponentIncubator; class QmlIncubatorObject : public QV4::Object { @@ -1122,7 +1122,7 @@ public: static void destroy(Managed *that); static void markObjects(Managed *that); - QScopedPointer<WrapperIncubator> incubator; + QScopedPointer<QQmlComponentIncubator> incubator; QV8Engine *v8; QPointer<QObject> parent; QV4::SafeValue valuemap; @@ -1135,13 +1135,14 @@ public: DEFINE_MANAGED_VTABLE(QmlIncubatorObject); -class WrapperIncubator : public QQmlIncubator +class QQmlComponentIncubator : public QQmlIncubator { public: - WrapperIncubator(QmlIncubatorObject *inc, IncubationMode mode) + QQmlComponentIncubator(QmlIncubatorObject *inc, IncubationMode mode) : QQmlIncubator(mode) , incubatorObject(inc) {} + virtual void statusChanged(Status s) { incubatorObject->statusChanged(s); } @@ -1506,7 +1507,7 @@ QQmlComponentExtension::~QQmlComponentExtension() QmlIncubatorObject::QmlIncubatorObject(QV8Engine *engine, QQmlIncubator::IncubationMode m) : Object(QV8Engine::getV4(engine)) { - incubator.reset(new WrapperIncubator(this, m)); + incubator.reset(new QQmlComponentIncubator(this, m)); v8 = engine; vtbl = &static_vtbl; @@ -1553,13 +1554,16 @@ void QmlIncubatorObject::markObjects(QV4::Managed *that) void QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) { + QV4::Scope scope(QV8Engine::getV4(v8)); + // hold the incubated object in a scoped value to prevent it's destruction before this method returns + QV4::ScopedObject incubatedObject(scope, QV4::QObjectWrapper::wrap(scope.engine, incubator->object())); + if (s == QQmlIncubator::Ready) { Q_ASSERT(QQmlData::get(incubator->object())); QQmlData::get(incubator->object())->explicitIndestructibleSet = false; QQmlData::get(incubator->object())->indestructible = false; } - QV4::Scope scope(QV8Engine::getV4(v8)); QV4::ScopedFunctionObject f(scope, m_statusChanged); if (f) { QV4::ExecutionContext *ctx = scope.engine->current; |