aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-10-15 12:43:57 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-15 14:00:57 +0200
commit5302fea533f68abbe91ffc32ec732c11c8eef7ee (patch)
treeef083453747ddc8acf757bb1ff0a1d836eedeb51 /src
parentdfa234a60a112903995944573a7d2cf400af7f24 (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')
-rw-r--r--src/qml/qml/qqmlcomponent.cpp16
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;