Don't leak function objects created by VisualDataModel.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Thu, 15 Mar 2012 05:55:24 +0000 (15:55 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 15 Mar 2012 08:01:23 +0000 (09:01 +0100)
Function objects created from a FunctionTemplate are not short lived,
and the objects created by a VisualDataModel can change between
instances meaning a template is needed per instance.  So use an object
template as a constructor instead of a function.

Change-Id: I364c6e4f714a623b7adb7475a3ee9862eeeeb119
Reviewed-by: Martin Jones <martin.jones@nokia.com>
src/quick/items/qquickvisualadaptormodel.cpp
src/quick/items/qquickvisualdatamodel.cpp
src/quick/items/qquickvisualdatamodel_p_p.h

index fb85810..622adf4 100644 (file)
@@ -173,7 +173,7 @@ public:
     VDMDelegateDataType *m_delegateDataType;
     CreateModelData createItem;
     StringValue stringValue;
-    v8::Persistent<v8::Function> m_constructor;
+    v8::Persistent<v8::ObjectTemplate> m_constructor;
 
     int m_ref;
     int m_count;
@@ -716,9 +716,9 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
 
     v8::HandleScope handleScope;
     v8::Context::Scope contextScope(v8Engine->context());
-    v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
-    ft->InstanceTemplate()->SetHasExternalResource(true);
-    ft->PrototypeTemplate()->SetAccessor(
+    v8::Local<v8::ObjectTemplate> constructor = v8::ObjectTemplate::New();
+    constructor->SetHasExternalResource(true);
+    constructor->SetAccessor(
             v8::String::New("index"), QQuickVisualDataModelItemMetaObject::get_index);
 
     if (m_listAccessor
@@ -726,9 +726,9 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
             && m_listAccessor->type() != QQuickListAccessor::Instance) {
         createItem = &QQuickVDMListAccessorData::create;
         stringValue = &QQuickVDMListAccessorData::stringValue;
-        ft->PrototypeTemplate()->SetAccessor(
+        constructor->SetAccessor(
                 v8::String::New("modelData"), QQuickVDMListAccessorData::get_modelData);
-        m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
+        m_constructor = qPersistentNew(constructor);
         return;
     }
 
@@ -741,7 +741,7 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
             const QString roleName = m_listModelInterface->toString(role);
             const QByteArray propertyName = roleName.toUtf8();
             addProperty(role, propertyId, propertyName, "QVariant");
-            ft->PrototypeTemplate()->SetAccessor(
+            constructor->SetAccessor(
                     v8Engine->toString(roleName),
                     QQuickVDMListModelInterfaceData::get_property,
                     QQuickVDMListModelInterfaceData::set_property,
@@ -751,7 +751,7 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
         m_roleCount = m_propertyData.count();
         if (m_propertyData.count() == 1) {
             addProperty(roles.first(), 1, "modelData", "QVariant", true);
-            ft->PrototypeTemplate()->SetAccessor(
+            constructor->SetAccessor(
                     v8::String::New("modelData"),
                     QQuickVDMListModelInterfaceData::get_property,
                     QQuickVDMListModelInterfaceData::set_property,
@@ -764,7 +764,7 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
         for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) {
             const int propertyId = m_propertyData.count();
             addProperty(it.key(), propertyId, it.value(), "QVariant");
-            ft->PrototypeTemplate()->SetAccessor(
+            constructor->SetAccessor(
                     v8::String::New(it.value().constData(), it.value().length()),
                     QQuickVDMAbstractItemModelData::get_property,
                     QQuickVDMAbstractItemModelData::set_property,
@@ -774,14 +774,14 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
         m_roleCount = m_propertyData.count();
         if (m_propertyData.count() == 1) {
             addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true);
-            ft->PrototypeTemplate()->SetAccessor(
+            constructor->SetAccessor(
                     v8::String::New("modelData"),
                     QQuickVDMAbstractItemModelData::get_property,
                     QQuickVDMAbstractItemModelData::set_property,
                     v8::Int32::New(0));
             m_roleNames.insert("modelData", roleNames.begin().key());
         }
-        ft->PrototypeTemplate()->SetAccessor(
+        constructor->SetAccessor(
                 v8::String::New("hasModelChildren"),
                 QQuickVDMAbstractItemModelData::get_hasModelChildren);
     } else if (m_listAccessor) {
@@ -796,7 +796,7 @@ void QQuickVisualAdaptorModelPrivate::createMetaObject()
     if (!m_objectList) {
         m_delegateDataType->propertyCache = new QQmlPropertyCache(
                 m_engine, m_delegateDataType->metaObject);
-        m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
+        m_constructor = qPersistentNew(constructor);
     }
 }
 
index 97d1372..88d46c6 100644 (file)
@@ -1306,11 +1306,13 @@ QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType(
 
     v8::HandleScope handleScope;
     v8::Context::Scope contextScope(engine->context());
-    v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
-    ft->InstanceTemplate()->SetHasExternalResource(true);
-    ft->PrototypeTemplate()->SetAccessor(v8::String::New("model"), get_model);
-    ft->PrototypeTemplate()->SetAccessor(v8::String::New("groups"), get_groups, set_groups);
-    ft->PrototypeTemplate()->SetAccessor(v8::String::New("isUnresolved"), get_member, 0, v8::Int32::New(30));
+
+    constructor = qPersistentNew(v8::ObjectTemplate::New());
+
+    constructor->SetHasExternalResource(true);
+    constructor->SetAccessor(v8::String::New("model"), get_model);
+    constructor->SetAccessor(v8::String::New("groups"), get_groups, set_groups);
+    constructor->SetAccessor(v8::String::New("isUnresolved"), get_member, 0, v8::Int32::New(30));
 
     int notifierId = 0;
     for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
@@ -1321,7 +1323,7 @@ QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType(
                 propertyName.toUtf8(), "bool", notifierId);
         propertyBuilder.setWritable(true);
 
-        ft->PrototypeTemplate()->SetAccessor(
+        constructor->SetAccessor(
                 engine->toString(propertyName), get_member, set_member, v8::Int32::New(i + 1));
     }
     for (int i = 0; i < groupNames.count(); ++i, ++notifierId) {
@@ -1331,13 +1333,11 @@ QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType(
                 propertyName.toUtf8(), "int", notifierId);
         propertyBuilder.setWritable(true);
 
-        ft->PrototypeTemplate()->SetAccessor(
+        constructor->SetAccessor(
                 engine->toString(propertyName), get_index, 0, v8::Int32::New(i + 1));
     }
 
     metaObject = builder.toMetaObject();
-
-    constructor = qPersistentNew<v8::Function>(ft->GetFunction());
 }
 
 QQuickVisualDataModelItemMetaType::~QQuickVisualDataModelItemMetaType()
index c53ed5b..c2db045 100644 (file)
@@ -92,7 +92,7 @@ public:
     QV8Engine * const v8Engine;
     QMetaObject *metaObject;
     const QStringList groupNames;
-    v8::Persistent<v8::Function> constructor;
+    v8::Persistent<v8::ObjectTemplate> constructor;
 };
 
 class QQuickVisualAdaptorModel;