aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/qdeclarativevmemetaobject.cpp
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-10-10 12:11:21 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-06 02:46:28 +0100
commit564d58025e46c825ec763193767defd78f5e13a0 (patch)
tree31d046ac0c016df416afd4923fb749d8bf73d6bc /src/declarative/qml/qdeclarativevmemetaobject.cpp
parent8601f3444f7926a7b47ae217d8bf51044ff61809 (diff)
Ensure that scarce resources work with var properties
Now that we have a new property type which stores JavaScript handles, we need to ensure that scarce resources can be used with them. Task-number: QMLNG-18 Task-number: QTBUG-21843 Change-Id: I4a920ae39e7d33cf5e33362e5e0ee21c74cb35e3 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/declarative/qml/qdeclarativevmemetaobject.cpp')
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp48
1 files changed, 46 insertions, 2 deletions
diff --git a/src/declarative/qml/qdeclarativevmemetaobject.cpp b/src/declarative/qml/qdeclarativevmemetaobject.cpp
index 229a93b961..0ff6ad581c 100644
--- a/src/declarative/qml/qdeclarativevmemetaobject.cpp
+++ b/src/declarative/qml/qdeclarativevmemetaobject.cpp
@@ -50,6 +50,8 @@
#include "qdeclarativebinding_p.h"
#include "qdeclarativepropertyvalueinterceptor_p.h"
+#include <private/qv8variantresource_p.h>
+
Q_DECLARE_METATYPE(QJSValue);
QT_BEGIN_NAMESPACE
@@ -819,8 +821,28 @@ QVariant QDeclarativeVMEMetaObject::readPropertyAsVariant(int id)
void QDeclarativeVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value)
{
Q_ASSERT(id >= firstVarPropertyIndex);
-
ensureVarPropertiesAllocated();
+
+ // 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.
+ v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
+ if (oldv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
+ if (r) {
+ r->removeVmePropertyReference();
+ }
+ }
+
+ // And, if the new value is a scarce resource, we need to ensure that it does not get
+ // automatically released by the engine until no other references to it exist.
+ if (value->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(value));
+ if (r) {
+ r->addVmePropertyReference();
+ }
+ }
+
+ // Write the value and emit change signal as appropriate.
varProperties->Set(id - firstVarPropertyIndex, value);
activate(object, methodOffset + id, 0);
}
@@ -829,8 +851,30 @@ void QDeclarativeVMEMetaObject::writeProperty(int id, const QVariant &value)
{
if (id >= firstVarPropertyIndex) {
ensureVarPropertiesAllocated();
+
+ // 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.
+ v8::Local<v8::Value> oldv = varProperties->Get(id - firstVarPropertyIndex);
+ if (oldv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(oldv));
+ if (r) {
+ r->removeVmePropertyReference();
+ }
+ }
+
+ // And, if the new value is a scarce resource, we need to ensure that it does not get
+ // automatically released by the engine until no other references to it exist.
+ v8::Handle<v8::Value> newv = QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value);
+ if (newv->IsObject()) {
+ QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(newv));
+ if (r) {
+ r->addVmePropertyReference();
+ }
+ }
+
+ // Write the value and emit change signal as appropriate.
QVariant currentValue = readPropertyAsVariant(id);
- varProperties->Set(id - firstVarPropertyIndex, QDeclarativeEnginePrivate::get(ctxt->engine)->v8engine()->fromVariant(value));
+ varProperties->Set(id - firstVarPropertyIndex, newv);
if ((currentValue.userType() != value.userType() || currentValue != value))
activate(object, methodOffset + id, 0);
} else {