Navigation Menu

Skip to content

Commit

Permalink
Don't leak function objects created by VisualDataModel.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Mar 15, 2012
1 parent d7f2a77 commit 1c7b036
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 22 deletions.
24 changes: 12 additions & 12 deletions src/quick/items/qquickvisualadaptormodel.cpp
Expand Up @@ -173,7 +173,7 @@ class QQuickVisualAdaptorModelPrivate : public QObjectPrivate
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;
Expand Down Expand Up @@ -716,19 +716,19 @@ 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
&& m_listAccessor->type() != QQuickListAccessor::ListProperty
&& 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;
}

Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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) {
Expand All @@ -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);
}
}

Expand Down
18 changes: 9 additions & 9 deletions src/quick/items/qquickvisualdatamodel.cpp
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion src/quick/items/qquickvisualdatamodel_p_p.h
Expand Up @@ -92,7 +92,7 @@ class QQuickVisualDataModelItemMetaType : public QQmlRefCount
QV8Engine * const v8Engine;
QMetaObject *metaObject;
const QStringList groupNames;
v8::Persistent<v8::Function> constructor;
v8::Persistent<v8::ObjectTemplate> constructor;
};

class QQuickVisualAdaptorModel;
Expand Down

0 comments on commit 1c7b036

Please sign in to comment.