aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
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
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')
-rw-r--r--src/declarative/qml/qdeclarativevmemetaobject.cpp48
-rw-r--r--src/declarative/qml/v8/qv8variantresource_p.h81
-rw-r--r--src/declarative/qml/v8/qv8variantwrapper.cpp30
-rw-r--r--src/declarative/qml/v8/v8.pri1
4 files changed, 150 insertions, 10 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 {
diff --git a/src/declarative/qml/v8/qv8variantresource_p.h b/src/declarative/qml/v8/qv8variantresource_p.h
new file mode 100644
index 0000000000..d1a5f92696
--- /dev/null
+++ b/src/declarative/qml/v8/qv8variantresource_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QV8VARIANTRESOURCE_P_H
+#define QV8VARIANTRESOURCE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+#include <private/qv8_p.h>
+#include <private/qv8engine_p.h>
+#include <private/qdeclarativeengine_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QV8VariantResource : public QV8ObjectResource,
+ public QDeclarativeEnginePrivate::ScarceResourceData
+{
+ V8_RESOURCE_TYPE(VariantType)
+
+public:
+ QV8VariantResource(QV8Engine *engine, const QVariant &data);
+
+ void addVmePropertyReference();
+ void removeVmePropertyReference();
+
+ bool m_isScarceResource;
+ int m_vmePropertyReferenceCount;
+};
+
+QT_END_NAMESPACE
+
+#endif // QV8VARIANTRESOURCE_P_H
+
diff --git a/src/declarative/qml/v8/qv8variantwrapper.cpp b/src/declarative/qml/v8/qv8variantwrapper.cpp
index 671e4d33c3..28bcccbaab 100644
--- a/src/declarative/qml/v8/qv8variantwrapper.cpp
+++ b/src/declarative/qml/v8/qv8variantwrapper.cpp
@@ -40,22 +40,35 @@
****************************************************************************/
#include "qv8variantwrapper_p.h"
+#include "qv8variantresource_p.h"
#include "qv8engine_p.h"
#include <private/qdeclarativeengine_p.h>
QT_BEGIN_NAMESPACE
-class QV8VariantResource : public QV8ObjectResource,
- public QDeclarativeEnginePrivate::ScarceResourceData
+QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
+: QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data), m_isScarceResource(false), m_vmePropertyReferenceCount(0)
{
- V8_RESOURCE_TYPE(VariantType);
-public:
- QV8VariantResource(QV8Engine *engine, const QVariant &data);
-};
+}
-QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
-: QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data)
+void QV8VariantResource::addVmePropertyReference()
+{
+ if (m_isScarceResource && ++m_vmePropertyReferenceCount == 1) {
+ // remove from the ep->scarceResources list
+ // since it is now no longer eligible to be
+ // released automatically by the engine.
+ node.remove();
+ }
+}
+
+void QV8VariantResource::removeVmePropertyReference()
{
+ if (m_isScarceResource && --m_vmePropertyReferenceCount == 0) {
+ // and add to the ep->scarceResources list
+ // since it is now eligible to be released
+ // automatically by the engine.
+ QDeclarativeEnginePrivate::get(engine->engine())->scarceResources.insert(this);
+ }
}
QV8VariantWrapper::QV8VariantWrapper()
@@ -133,6 +146,7 @@ v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value)
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine->engine());
Q_ASSERT(ep->scarceResourcesRefCount);
rv = m_scarceConstructor->NewInstance();
+ r->m_isScarceResource = true;
ep->scarceResources.insert(r);
} else {
rv = m_constructor->NewInstance();
diff --git a/src/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri
index 924602ec39..e3488cd1e5 100644
--- a/src/declarative/qml/v8/v8.pri
+++ b/src/declarative/qml/v8/v8.pri
@@ -16,6 +16,7 @@ HEADERS += \
$$PWD/qv8typewrapper_p.h \
$$PWD/qv8listwrapper_p.h \
$$PWD/qv8variantwrapper_p.h \
+ $$PWD/qv8variantresource_p.h \
$$PWD/qv8valuetypewrapper_p.h \
$$PWD/qv8include_p.h \
$$PWD/qv8worker_p.h \