aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Adams <christopher.adams@nokia.com>2011-10-06 16:29:52 +1000
committerQt by Nokia <qt-info@nokia.com>2011-10-07 01:43:09 +0200
commite29f198b2a91b30678ebeea0d4908634e7c2b5be (patch)
tree28ff64878c827e4ae8483bafc033521795d60ec0
parent71611d0f56ff37165d31b74c55d4b35907f69543 (diff)
Fix v8 handle management in QSGLoader
Previously, setting the source to a remote url and specified some initial property values while active was false, and then setting active to true, would cause undefined behaviour. This commit ensures that the handles are managed correctly, and that an appropriate v8 context exists during object creation with initial property values specified. Task-number: QTBUG-21868 Change-Id: I101c6546537aa05aaeb420195aca670bc71f31e1 Reviewed-on: http://codereview.qt-project.org/6109 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
-rw-r--r--src/declarative/items/qsgloader.cpp5
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp3
-rw-r--r--tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml20
-rw-r--r--tests/auto/declarative/qsgloader/tst_qsgloader.cpp11
4 files changed, 38 insertions, 1 deletions
diff --git a/src/declarative/items/qsgloader.cpp b/src/declarative/items/qsgloader.cpp
index 91dce3b364..93f32b81a1 100644
--- a/src/declarative/items/qsgloader.cpp
+++ b/src/declarative/items/qsgloader.cpp
@@ -266,7 +266,6 @@ void QSGLoader::setActive(bool newVal)
} else {
loadFromSourceComponent();
}
- d->disposeInitialPropertyValues(); // release persistent handles
} else {
if (d->item) {
QSGItemPrivate *p = QSGItemPrivate::get(d->item);
@@ -487,6 +486,7 @@ void QSGLoader::setSource(QDeclarativeV8Function *args)
d->clear();
QUrl sourceUrl = d->resolveSourceUrl(args);
if (!ipv.IsEmpty()) {
+ d->disposeInitialPropertyValues();
d->initialPropertyValues = qPersistentNew(ipv);
d->qmlGlobalForIpv = qPersistentNew(args->qmlGlobal());
}
@@ -539,6 +539,7 @@ void QSGLoaderPrivate::_q_sourceLoaded()
emit q->sourceComponentChanged();
emit q->statusChanged();
emit q->progressChanged();
+ disposeInitialPropertyValues(); // cleanup
return;
}
@@ -557,6 +558,7 @@ void QSGLoaderPrivate::_q_sourceLoaded()
completeCreateWithInitialPropertyValues(c, obj, initialPropertyValues, qmlGlobalForIpv);
delete obj;
delete ctxt;
+ disposeInitialPropertyValues(); // cleanup
return;
}
if (obj) {
@@ -589,6 +591,7 @@ void QSGLoaderPrivate::_q_sourceLoaded()
emit q->itemChanged();
emit q->loaded();
}
+ disposeInitialPropertyValues(); // cleanup
}
/*!
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 0bcfd5a28e..e4c3003047 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -1134,6 +1134,9 @@ QObject *QDeclarativeComponentPrivate::completeCreateObjectWithInitialProperties
{
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
QV8Engine *v8engine = ep->v8engine();
+
+ v8::HandleScope handle_scope;
+ v8::Context::Scope scope(v8engine->context());
v8::Handle<v8::Value> ov = v8engine->newQObject(toCreate);
Q_ASSERT(ov->IsObject());
v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(ov);
diff --git a/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml b/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml
new file mode 100644
index 0000000000..79e9264d4a
--- /dev/null
+++ b/tests/auto/declarative/qsgloader/data/initialPropertyValues.8.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int initialValue: 0
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ active: false
+ onLoaded: {
+ root.initialValue = loader.item.canary; // should be six
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("http://127.0.0.1:14450/InitialPropertyValuesComponent.qml", {"canary": 6});
+ loader.active = true;
+ }
+}
diff --git a/tests/auto/declarative/qsgloader/tst_qsgloader.cpp b/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
index ba8d5e01d7..a073e1f9fd 100644
--- a/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
+++ b/tests/auto/declarative/qsgloader/tst_qsgloader.cpp
@@ -651,6 +651,11 @@ void tst_QSGLoader::initialPropertyValues_data()
<< QStringList()
<< (QStringList() << "loaderValue" << "createObjectValue")
<< (QVariantList() << 1 << 1);
+
+ QTest::newRow("ensure initial property values aren't disposed prior to component completion") << TEST_FILE("initialPropertyValues.8.qml")
+ << QStringList()
+ << (QStringList() << "initialValue")
+ << (QVariantList() << 6);
}
void tst_QSGLoader::initialPropertyValues()
@@ -660,12 +665,18 @@ void tst_QSGLoader::initialPropertyValues()
QFETCH(QStringList, propertyNames);
QFETCH(QVariantList, propertyValues);
+ TestHTTPServer server(SERVER_PORT);
+ QVERIFY(server.isValid());
+ server.serveDirectory(SRCDIR "/data");
+
foreach (const QString &warning, expectedWarnings)
QTest::ignoreMessage(QtWarningMsg, warning.toAscii().constData());
QDeclarativeComponent component(&engine, qmlFile);
QObject *object = component.create();
QVERIFY(object != 0);
+ qApp->processEvents();
+ QTest::qWait(50);
for (int i = 0; i < propertyNames.size(); ++i)
QCOMPARE(object->property(propertyNames.at(i).toAscii().constData()), propertyValues.at(i));