diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2012-03-19 12:29:32 +0100 |
---|---|---|
committer | Kent Hansen <kent.hansen@nokia.com> | 2012-03-19 12:37:03 +0100 |
commit | 4821058f10118be55a541ad39e25ec9165cca3b3 (patch) | |
tree | 167973e3c68fc442b0e37d6f628f3fdbe759f15a /src/qml/qml/qqmlvmemetaobject.cpp | |
parent | 83f11e33745180e9370d484cbcedd0bac020c9dd (diff) | |
parent | 26d5f2e833f0e3686aaa27e695bbfab5fbd808ad (diff) |
Merge master into api_changes
Conflicts:
src/qml/debugger/qqmlenginedebugservice.cpp
src/qml/qml/v8/qv8qobjectwrapper.cpp
src/quick/util/qquickimageprovider.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
Change-Id: Ie78ba2fabd32f4812bcae9dbdd66ed289dc11dcb
Diffstat (limited to 'src/qml/qml/qqmlvmemetaobject.cpp')
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index a7af2db837..c4e801f2db 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -56,6 +56,28 @@ Q_DECLARE_METATYPE(QJSValue); QT_BEGIN_NAMESPACE +QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr() + : QQmlGuard<QObject>(0), m_target(0), m_index(-1) +{ +} + +QQmlVMEVariantQObjectPtr::~QQmlVMEVariantQObjectPtr() +{ +} + +void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *) +{ + if (m_target && m_index >= 0) + m_target->activate(m_target->object, m_target->methodOffset + m_index, 0); +} + +void QQmlVMEVariantQObjectPtr::setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index) +{ + m_target = target; + m_index = index; + setObject(obj); +} + class QQmlVMEVariant { public: @@ -79,7 +101,7 @@ public: inline const QDateTime &asQDateTime(); inline const QJSValue &asQJSValue(); - inline void setValue(QObject *); + inline void setValue(QObject *v, QQmlVMEMetaObject *target, int index); inline void setValue(const QVariant &); inline void setValue(int); inline void setValue(bool); @@ -93,7 +115,7 @@ public: inline void setValue(const QJSValue &); private: int type; - void *data[4]; // Large enough to hold all types + void *data[6]; // Large enough to hold all types inline void cleanup(); }; @@ -127,7 +149,7 @@ void QQmlVMEVariant::cleanup() type == QMetaType::Double) { type = QVariant::Invalid; } else if (type == QMetaType::QObjectStar) { - ((QQmlGuard<QObject>*)dataPtr())->~QQmlGuard<QObject>(); + ((QQmlVMEVariantQObjectPtr*)dataPtr())->~QQmlVMEVariantQObjectPtr(); type = QVariant::Invalid; } else if (type == QMetaType::QString) { ((QString *)dataPtr())->~QString(); @@ -174,8 +196,8 @@ void *QQmlVMEVariant::dataPtr() QObject *QQmlVMEVariant::asQObject() { - if (type != QMetaType::QObjectStar) - setValue((QObject *)0); + if (type != QMetaType::QObjectStar) + setValue((QObject *)0, 0, -1); return *(QQmlGuard<QObject> *)(dataPtr()); } @@ -268,14 +290,14 @@ const QJSValue &QQmlVMEVariant::asQJSValue() return *(QJSValue *)(dataPtr()); } -void QQmlVMEVariant::setValue(QObject *v) +void QQmlVMEVariant::setValue(QObject *v, QQmlVMEMetaObject *target, int index) { if (type != QMetaType::QObjectStar) { cleanup(); type = QMetaType::QObjectStar; - new (dataPtr()) QQmlGuard<QObject>(); + new (dataPtr()) QQmlVMEVariantQObjectPtr; } - *(QQmlGuard<QObject>*)(dataPtr()) = v; + reinterpret_cast<QQmlVMEVariantQObjectPtr*>(dataPtr())->setGuardedValue(v, target, index); } void QQmlVMEVariant::setValue(const QVariant &v) @@ -629,7 +651,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) break; case QMetaType::QObjectStar: needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject(); - data[id].setValue(*reinterpret_cast<QObject **>(a[0])); + data[id].setValue(*reinterpret_cast<QObject **>(a[0]), this, id); break; case QMetaType::QVariant: writeProperty(id, *reinterpret_cast<QVariant *>(a[0])); @@ -810,15 +832,17 @@ v8::Handle<v8::Value> QQmlVMEMetaObject::readVarProperty(int id) { Q_ASSERT(id >= firstVarPropertyIndex); - ensureVarPropertiesAllocated(); - return varProperties->Get(id - firstVarPropertyIndex); + if (ensureVarPropertiesAllocated()) + return varProperties->Get(id - firstVarPropertyIndex); + return v8::Handle<v8::Value>(); } QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) { if (id >= firstVarPropertyIndex) { - ensureVarPropertiesAllocated(); - return QQmlEnginePrivate::get(ctxt->engine)->v8engine()->toVariant(varProperties->Get(id - firstVarPropertyIndex), -1); + if (ensureVarPropertiesAllocated()) + return QQmlEnginePrivate::get(ctxt->engine)->v8engine()->toVariant(varProperties->Get(id - firstVarPropertyIndex), -1); + return QVariant(); } else { if (data[id].dataType() == QMetaType::QObjectStar) { return QVariant::fromValue(data[id].asQObject()); @@ -831,7 +855,8 @@ QVariant QQmlVMEMetaObject::readPropertyAsVariant(int id) void QQmlVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value) { Q_ASSERT(id >= firstVarPropertyIndex); - ensureVarPropertiesAllocated(); + if (!ensureVarPropertiesAllocated()) + return; // Importantly, if the current value is a scarce resource, we need to ensure that it // gets automatically released by the engine if no other references to it exist. @@ -860,7 +885,8 @@ void QQmlVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value) void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) { if (id >= firstVarPropertyIndex) { - ensureVarPropertiesAllocated(); + if (!ensureVarPropertiesAllocated()) + return; // Importantly, if the current value is a scarce resource, we need to ensure that it // gets automatically released by the engine if no other references to it exist. @@ -892,7 +918,7 @@ void QQmlVMEMetaObject::writeProperty(int id, const QVariant &value) if (value.userType() == QMetaType::QObjectStar) { QObject *o = qvariant_cast<QObject *>(value); needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o); - data[id].setValue(qvariant_cast<QObject *>(value)); + data[id].setValue(qvariant_cast<QObject *>(value), this, id); } else { needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() || data[id].asQVariant().userType() != value.userType() || @@ -1007,10 +1033,17 @@ void QQmlVMEMetaObject::setVMEProperty(int index, v8::Handle<v8::Value> v) return writeVarProperty(index - propOffset, v); } -void QQmlVMEMetaObject::ensureVarPropertiesAllocated() +bool QQmlVMEMetaObject::ensureVarPropertiesAllocated() { if (!varPropertiesInitialized) allocateVarPropertiesArray(); + + // in some situations, the QObject's v8object (and associated v8 data, + // such as the varProperties array) will have been cleaned up, but the + // QObject ptr will not yet have been deleted (eg, waiting on deleteLater). + // In this situation, the varProperties handle will be (and should remain) + // empty. + return !varProperties.IsEmpty(); } // see also: QV8GCCallback::garbageCollectorPrologueCallback() |