Timo Jyrinki has proposed merging 
lp:~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8 into 
lp:~kubuntu-packagers/kubuntu-packaging/qtdeclarative-opensource-src.

Requested reviews:
  Kubuntu Packagers (kubuntu-packagers)
Related bugs:
  Bug #1349297 in qtdeclarative-opensource-src (Ubuntu): "Better fix for crash 
due to wrong objects being garbage collected"
  
https://bugs.launchpad.net/ubuntu/+source/qtdeclarative-opensource-src/+bug/1349297

For more details, see:
https://code.launchpad.net/~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8/+merge/229651
-- 
https://code.launchpad.net/~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8/+merge/229651
Your team Kubuntu Packagers is requested to review the proposed merge of 
lp:~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8 into 
lp:~kubuntu-packagers/kubuntu-packaging/qtdeclarative-opensource-src.
=== modified file 'debian/changelog'
--- debian/changelog	2014-07-07 08:43:27 +0000
+++ debian/changelog	2014-08-05 16:02:47 +0000
@@ -1,3 +1,21 @@
+qtdeclarative-opensource-src (5.3.0-3ubuntu8) utopic; urgency=medium
+
+  [ MichaƂ Sawicz ]
+  * debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch
+    - Fix flickable interaction (LP: #1349705)
+  * debian/control
+  * debian/rules
+    - Force gcc-4.8 to avoid symbols changes
+
+  [ Timo Jyrinki ]
+  * debian/patches/parenttosubcreator_qqmlobjectcreator.patch:
+    - Drop, rejected by upstream
+  * debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch
+    debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch:
+    - Replace the old patch with accepted upstream approach (LP: #1349297)
+
+ -- Timo Jyrinki <timo-jyri...@ubuntu.com>  Mon, 04 Aug 2014 10:58:28 +0000
+
 qtdeclarative-opensource-src (5.3.0-3ubuntu7) utopic; urgency=medium
 
   * debian/patches/Support-RFC2822Date-date-format-similar-to-V8.patch

=== modified file 'debian/control'
--- debian/control	2014-06-19 19:14:47 +0000
+++ debian/control	2014-08-05 16:02:47 +0000
@@ -11,6 +11,8 @@
            Timo Jyrinki <t...@debian.org>
 Build-Depends: debhelper (>= 9),
                dpkg-dev (>= 1.16.1),
+# Avoiding symbols updates due to switch to gcc 4.9 by default.
+               g++-4.8,
                libqt5xmlpatterns5-private-dev (>= 5.3.0-0~),
                pkg-kde-tools (>= 0.15.12~),
                python,

=== added file 'debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch'
--- debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch	1970-01-01 00:00:00 +0000
+++ debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch	2014-08-05 16:02:47 +0000
@@ -0,0 +1,152 @@
+From 8454a21b837ccf3968f6dbc56ed4f06d60d63c8f Mon Sep 17 00:00:00 2001
+From: Albert Astals Cid <albert.ast...@canonical.com>
+Date: Wed, 23 Jul 2014 15:40:42 +0200
+Subject: [PATCH] Flickable: Cancel interaction on interactive changes
+
+Otherwise if you have a listview with a flickable inside with a mouseare inside
+the pressed is never set to false if you make the interactive property of the
+outer list depend on the moving of the inner flickable. This makes that when
+later you change currentIndex of the list and you have
+StrictlyEnforceRange set, the list won't move because it still thinks it is pressed
+
+Change-Id: I2c2021f486fc0a31840c3f2199bc7cb76dc01e3e
+Reviewed-by: Martin Jones <martin.jo...@jollamobile.com>
+---
+ src/quick/items/qquickflickable.cpp          | 41 ++++++++++++++--------------
+ src/quick/items/qquickflickable_p_p.h        |  2 ++
+ tests/auto/qmltest/listview/tst_listview.qml | 41 ++++++++++++++++++++++++++++
+ 3 files changed, 63 insertions(+), 21 deletions(-)
+
+diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
+index ee71ea8..63dde66 100644
+--- a/src/quick/items/qquickflickable.cpp
++++ b/src/quick/items/qquickflickable.cpp
+@@ -763,15 +763,8 @@ void QQuickFlickable::setInteractive(bool interactive)
+     Q_D(QQuickFlickable);
+     if (interactive != d->interactive) {
+         d->interactive = interactive;
+-        if (!interactive && (d->hData.flicking || d->vData.flicking)) {
+-            d->clearTimeline();
+-            d->hData.vTime = d->vData.vTime = d->timeline.time();
+-            d->hData.flicking = false;
+-            d->vData.flicking = false;
+-            emit flickingChanged();
+-            emit flickingHorizontallyChanged();
+-            emit flickingVerticallyChanged();
+-            emit flickEnded();
++        if (!interactive) {
++            d->cancelInteraction();
+         }
+         emit interactiveChanged();
+     }
+@@ -2015,18 +2008,24 @@ bool QQuickFlickable::yflick() const
+ void QQuickFlickable::mouseUngrabEvent()
+ {
+     Q_D(QQuickFlickable);
+-    if (d->pressed) {
+-        // if our mouse grab has been removed (probably by another Flickable),
+-        // fix our state
+-        d->clearDelayedPress();
+-        d->pressed = false;
+-        d->draggingEnding();
+-        d->stealMouse = false;
+-        setKeepMouseGrab(false);
+-        d->fixupX();
+-        d->fixupY();
+-        if (!d->isViewMoving())
+-            movementEnding();
++    // if our mouse grab has been removed (probably by another Flickable),
++    // fix our state
++    d->cancelInteraction();
++}
++
++void QQuickFlickablePrivate::cancelInteraction()
++{
++    Q_Q(QQuickFlickable);
++    if (pressed) {
++        clearDelayedPress();
++        pressed = false;
++        draggingEnding();
++        stealMouse = false;
++        q->setKeepMouseGrab(false);
++        fixupX();
++        fixupY();
++        if (!isViewMoving())
++            q->movementEnding();
+     }
+ }
+ 
+diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
+index 33a642e..13af2e0 100644
+--- a/src/quick/items/qquickflickable_p_p.h
++++ b/src/quick/items/qquickflickable_p_p.h
+@@ -200,6 +200,8 @@ public:
+ 
+     bool isViewMoving() const;
+ 
++    void cancelInteraction();
++
+ public:
+     QQuickItem *contentItem;
+ 
+diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
+index 03be579..069b62a 100644
+--- a/tests/auto/qmltest/listview/tst_listview.qml
++++ b/tests/auto/qmltest/listview/tst_listview.qml
+@@ -108,6 +108,33 @@ Item {
+         property int createdDelegates: 0
+     }
+ 
++    ListView
++    {
++        id: listInteractiveCurrentIndexEnforce
++        width: 600
++        height: 600
++
++        snapMode: ListView.SnapOneItem
++        orientation: ListView.Horizontal
++        interactive: !currentItem.moving
++        highlightRangeMode: ListView.StrictlyEnforceRange
++
++        model: 4
++
++        focus: true
++        Keys.onPressed: if (event.key == Qt.Key_K) currentIndex = currentIndex + 1;
++
++        delegate: Flickable {
++            width: 600
++            height: 600
++            contentWidth: 600
++            contentHeight: 1200
++
++            MouseArea { anchors.fill: parent }
++            Rectangle { anchors.fill: parent; color: index == 0 ? "red" : index == 1 ? "green" : index == 2 ? "blue" : "white" }
++        }
++    }
++
+     Component {
+         id: delegateModelAfterCreateComponent
+         Rectangle {
+@@ -272,5 +299,19 @@ Item {
+             listViewDelegateModelAfterCreate.model = 40;
+             verify(listViewDelegateModelAfterCreate.createdDelegates > 0);
+         }
++
++        function test_listInteractiveCurrentIndexEnforce() {
++            mousePress(listInteractiveCurrentIndexEnforce, 10, 50);
++            mouseMove(listInteractiveCurrentIndexEnforce, 10, 40);
++            mouseMove(listInteractiveCurrentIndexEnforce, 10, 30);
++            mouseMove(listInteractiveCurrentIndexEnforce, 10, 20);
++            mouseMove(listInteractiveCurrentIndexEnforce, 10, 10);
++            compare(listInteractiveCurrentIndexEnforce.interactive, false);
++            mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10);
++            tryCompare(listInteractiveCurrentIndexEnforce, "interactive", true);
++            keyClick("k");
++            compare(listInteractiveCurrentIndexEnforce.currentIndex, 1);
++            tryCompare(listInteractiveCurrentIndexEnforce, "contentX", listInteractiveCurrentIndexEnforce.width);
++        }
+     }
+ }
+-- 
+2.0.1
+

=== added file 'debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch'
--- debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch	1970-01-01 00:00:00 +0000
+++ debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch	2014-08-05 16:02:47 +0000
@@ -0,0 +1,129 @@
+From 195b998175b629e6e915588e66991f74cffa4e48 Mon Sep 17 00:00:00 2001
+From: Simon Hausmann <simon.hausm...@digia.com>
+Date: Fri, 20 Jun 2014 17:26:57 +0200
+Subject: [PATCH] Fix crash when deleting component in Component.onComplete
+ through loader
+
+This is a regression introduced with Qt 5.3.0. The recursion watcher code that
+is supposed to handle the test case of QTBUG-39775 can detect the recursion
+into the object creator. However the boolean that indicates the recursion is a
+member of a structure that's deleted afterwards. To avoid access to deleted
+memory, this patch simply reference counts data structure shared between the
+creators and also wraps the recursion watcher into a convenience class that
+also increases/decreases the reference count accordingly.
+
+Change-Id: I8d2e3e200ab1295e89d951e09f187d382a056d5a
+Task-number: QTBUG-39775
+Reviewed-by: Lars Knoll <lars.kn...@digia.com>
+---
+ src/qml/qml/qqmlobjectcreator.cpp | 17 ++++++++++++-----
+ src/qml/qml/qqmlobjectcreator_p.h | 18 ++++++++++++++++--
+ 2 files changed, 28 insertions(+), 7 deletions(-)
+
+diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
+index 16c9dd7..36c7dfb 100644
+--- a/src/qml/qml/qqmlobjectcreator.cpp
++++ b/src/qml/qml/qqmlobjectcreator.cpp
+@@ -91,7 +91,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
+     init(parentContext);
+ 
+     sharedState = new QQmlObjectCreatorSharedState;
+-    sharedState.setFlag(); // We own it, so we must delete it
++    topLevelCreator = true;
+     sharedState->componentAttached = 0;
+     sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
+     sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
+@@ -115,6 +115,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
+     init(parentContext);
+ 
+     sharedState = inheritedSharedState;
++    topLevelCreator = false;
+ }
+ 
+ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
+@@ -139,9 +140,9 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
+ 
+ QQmlObjectCreator::~QQmlObjectCreator()
+ {
+-    if (sharedState.flag()) {
++    if (topLevelCreator) {
+         {
+-            QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
++            QQmlObjectCreatorRecursionWatcher watcher(this);
+         }
+         for (int i = 0; i < sharedState->allCreatedBindings.count(); ++i) {
+             QQmlAbstractBinding *b = sharedState->allCreatedBindings.at(i);
+@@ -157,7 +158,6 @@ QQmlObjectCreator::~QQmlObjectCreator()
+             QQmlComponentAttached *a = sharedState->componentAttached;
+             a->rem();
+         }
+-        delete sharedState.data();
+     }
+ }
+ 
+@@ -1172,7 +1172,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
+     Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
+     phase = Finalizing;
+ 
+-    QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
++    QQmlObjectCreatorRecursionWatcher watcher(this);
+     ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
+ 
+     {
+@@ -1334,3 +1334,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
+ }
+ 
+ 
++
++
++QQmlObjectCreatorRecursionWatcher::QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)
++    : sharedState(creator->sharedState)
++    , watcher(creator->sharedState.data())
++{
++}
+diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
+index 379a3b2..ad2d676 100644
+--- a/src/qml/qml/qqmlobjectcreator_p.h
++++ b/src/qml/qml/qqmlobjectcreator_p.h
+@@ -57,7 +57,7 @@ struct QQmlTypeCompiler;
+ class QQmlInstantiationInterrupt;
+ struct QQmlVmeProfiler;
+ 
+-struct QQmlObjectCreatorSharedState
++struct QQmlObjectCreatorSharedState : public QSharedData
+ {
+     QQmlContextData *rootContext;
+     QQmlContextData *creationContext;
+@@ -128,7 +128,8 @@ private:
+     const QVector<QQmlPropertyCache *> &propertyCaches;
+     const QVector<QByteArray> &vmeMetaObjectData;
+     QHash<int, int> objectIndexToId;
+-    QFlagPointer<QQmlObjectCreatorSharedState> sharedState;
++    QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
++    bool topLevelCreator;
+     void *activeVMEDataForRootContext;
+ 
+     QObject *_qobject;
+@@ -142,6 +143,19 @@ private:
+     QQmlVMEMetaObject *_vmeMetaObject;
+     QQmlListProperty<void> _currentList;
+     QV4::ExecutionContext *_qmlContext;
++
++    friend struct QQmlObjectCreatorRecursionWatcher;
++};
++
++struct QQmlObjectCreatorRecursionWatcher
++{
++    QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator);
++
++    bool hasRecursed() const { return watcher.hasRecursed(); }
++
++private:
++    QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
++    QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher;
+ };
+ 
+ QT_END_NAMESPACE
+-- 
+2.0.1
+

=== added file 'debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch'
--- debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch	1970-01-01 00:00:00 +0000
+++ debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch	2014-08-05 16:02:47 +0000
@@ -0,0 +1,335 @@
+From 14bc8dc3f3016889cfcbdbe7309b09be7687ebe0 Mon Sep 17 00:00:00 2001
+From: Simon Hausmann <simon.hausm...@digia.com>
+Date: Wed, 14 May 2014 16:04:33 +0200
+Subject: [PATCH] Fix interaction of garbage collector with JS objects during
+ QML type instantiation
+
+It may happen that during the lengthy process of instantiating a tree of
+objects for QML, the garbage collector runs.
+
+For objects created by QML we support different ownership models, for example
+in QtQuick visual parents keep their visual children alive, despite perhaps a
+lack of QObject parentship. That ownership becomes active once the QML
+autoparent function has assigned the correct visual parent, which happens after
+object instantiation (after QQmlObjectCreator).
+
+Similarly when a composite type is created, its QObject parent is only set
+after all properties have been set. The root QObject is kept alive through a
+special boolean, but if the sub-objects aren't children yet, their JS wrapper
+might get deleted. For composite types with var properties, that also means
+their var properties get deleted, such as the model property of TableView.qml
+in the bug report.
+
+In the future we want to support creating QWidget hierarchies with QML, which
+also for layouts may rely on a delayed parent assignment for layouts.
+
+To accommodate all this, this patch introduces an array on the JS stack that
+keeps track of all JS wrappers for all QObjects created. This array is alive
+during object tree creation. Afterwards, the different ownership models take
+over, for example the auto parent function assigning a visual parent.
+
+This patch also fixes an off-by-one in the total object count calculation
+for composite types, where when instantiating a composite type as a sub-object
+we counted the sub composite's object count but forgot the object itself.
+
+Task-number: QTBUG-38835
+Task-number: QTBUG-39966
+Change-Id: I6104b2434510642081e0c54793ed296adeca7481
+Reviewed-by: Lars Knoll <lars.kn...@digia.com>
+---
+ src/qml/compiler/qqmltypecompiler.cpp              |  4 +-
+ src/qml/qml/qqmlobjectcreator.cpp                  | 27 +++++++---
+ src/qml/qml/qqmlobjectcreator_p.h                  |  1 +
+ tests/auto/qml/qqmlecmascript/testtypes.cpp        | 60 ++++++++++++++++++++++
+ tests/auto/qml/qqmlecmascript/testtypes.h          | 45 ++++++++++++++++
+ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 28 ++++++++++
+ 6 files changed, 157 insertions(+), 8 deletions(-)
+
+diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
+index 60a0829..dacaa14 100644
+--- a/src/qml/compiler/qqmltypecompiler.cpp
++++ b/src/qml/compiler/qqmltypecompiler.cpp
+@@ -277,12 +277,12 @@ bool QQmlTypeCompiler::compile()
+                 if (qmlType->parserStatusCast() != -1)
+                     ++parserStatusCount;
+             }
++            ++objectCount;
+             if (typeRef->component) {
+                 bindingCount += typeRef->component->totalBindingsCount;
+                 parserStatusCount += typeRef->component->totalParserStatusCount;
+                 objectCount += typeRef->component->totalObjectCount;
+-            } else
+-                ++objectCount;
++            }
+         }
+     }
+ 
+diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
+index 36c7dfb..1de467b 100644
+--- a/src/qml/qml/qqmlobjectcreator.cpp
++++ b/src/qml/qml/qqmlobjectcreator.cpp
+@@ -96,6 +96,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
+     sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
+     sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
+     sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount);
++    sharedState->allJavaScriptObjects = 0;
+     sharedState->creationContext = creationContext;
+     sharedState->rootContext = 0;
+ 
+@@ -195,6 +196,13 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
+         sharedState->rootContext->isRootObjectInCreation = true;
+     }
+ 
++    QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
++    QV4::Scope scope(v4);
++
++    Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
++    if (topLevelCreator)
++        sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount);
++
+     QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
+     for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd();
+          it != end; ++it) {
+@@ -208,8 +216,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
+     context->setIdPropertyData(mapping);
+ 
+     if (subComponentIndex == -1) {
+-        QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+-        QV4::Scope scope(v4);
+         QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
+         context->importedScripts = scripts;
+         for (int i = 0; i < compiledData->scripts.count(); ++i) {
+@@ -230,6 +236,9 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
+         ddata->compiledData->addref();
+     }
+ 
++    if (topLevelCreator)
++        sharedState->allJavaScriptObjects = 0;
++
+     phase = CreatingObjectsPhase2;
+ 
+     if (interrupt && interrupt->shouldInterrupt())
+@@ -258,8 +267,11 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
+ 
+     QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
+     QV4::Scope valueScope(v4);
+-    QV4::ScopedValue scopeObjectProtector(valueScope, declarativeData->jsWrapper.value());
+-    Q_UNUSED(scopeObjectProtector);
++
++    Q_ASSERT(topLevelCreator);
++    Q_ASSERT(!sharedState->allJavaScriptObjects);
++    sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount);
++
+     QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
+     QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
+     QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
+@@ -1150,9 +1162,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
+     qSwap(_scopeObject, scopeObject);
+ 
+     QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
++
++    Q_ASSERT(sharedState->allJavaScriptObjects);
++    QV4::ValueRef ref = QV4::ValueRef::fromRawValue(sharedState->allJavaScriptObjects++);
++    ref = QV4::QObjectWrapper::wrap(v4, instance);
++
+     QV4::Scope valueScope(v4);
+-    QV4::ScopedValue scopeObjectProtector(valueScope, ddata ? ddata->jsWrapper.value() : 0);
+-    Q_UNUSED(scopeObjectProtector);
+     QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
+     QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
+     QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
+diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
+index ad2d676..fb4d71d 100644
+--- a/src/qml/qml/qqmlobjectcreator_p.h
++++ b/src/qml/qml/qqmlobjectcreator_p.h
+@@ -64,6 +64,7 @@ struct QQmlObjectCreatorSharedState : public QSharedData
+     QFiniteStack<QQmlAbstractBinding*> allCreatedBindings;
+     QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
+     QFiniteStack<QObject*> allCreatedObjects;
++    QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
+     QQmlComponentAttached *componentAttached;
+     QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
+     QQmlVmeProfiler profiler;
+diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
+index eb06b9e..560d860 100644
+--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
++++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
+@@ -300,6 +300,62 @@ static QObject *create_singletonWithEnum(QQmlEngine *, QJSEngine *)
+     return new SingletonWithEnum;
+ }
+ 
++QObjectContainer::QObjectContainer()
++    : widgetParent(0)
++    , gcOnAppend(false)
++{}
++
++QQmlListProperty<QObject> QObjectContainer::data()
++{
++    return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear);
++}
++
++void QObjectContainer::children_append(QQmlListProperty<QObject> *prop, QObject *o)
++{
++    QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
++    that->dataChildren.append(o);
++    QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*)));
++
++    if (that->gcOnAppend) {
++        QQmlEngine *engine = qmlEngine(that);
++        engine->collectGarbage();
++        QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
++        QCoreApplication::processEvents();
++    }
++}
++
++int QObjectContainer::children_count(QQmlListProperty<QObject> *prop)
++{
++    return static_cast<QObjectContainer*>(prop->object)->dataChildren.count();
++}
++
++QObject *QObjectContainer::children_at(QQmlListProperty<QObject> *prop, int index)
++{
++    return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index);
++}
++
++void QObjectContainer::children_clear(QQmlListProperty<QObject> *prop)
++{
++    QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
++    foreach (QObject *c, that->dataChildren)
++        QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*)));
++    that->dataChildren.clear();
++}
++
++void QObjectContainer::childDestroyed(QObject *child) {
++    dataChildren.removeAll(child);
++}
++
++void FloatingQObject::classBegin()
++{
++    setParent(0);
++}
++
++void FloatingQObject::componentComplete()
++{
++    Q_ASSERT(!parent());
++}
++
+ void registerTypes()
+ {
+     qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias");
+@@ -381,6 +437,10 @@ void registerTypes()
+     qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi2",1,0,"Data",testImportOrder_api2);
+ 
+     qmlRegisterSingletonType<SingletonWithEnum>("Qt.test.singletonWithEnum", 1, 0, "SingletonWithEnum", create_singletonWithEnum);
++
++    qmlRegisterType<QObjectContainer>("Qt.test", 1, 0, "QObjectContainer");
++    qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.test", 1, 0, "QObjectContainerWithGCOnAppend");
++    qmlRegisterType<FloatingQObject>("Qt.test", 1, 0, "FloatingQObject");
+ }
+ 
+ #include "testtypes.moc"
+diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
+index 928d594..d5a1220 100644
+--- a/tests/auto/qml/qqmlecmascript/testtypes.h
++++ b/tests/auto/qml/qqmlecmascript/testtypes.h
+@@ -1661,6 +1661,51 @@ public:
+     };
+ };
+ 
++// Like QtObject, but with default property
++class QObjectContainer : public QObject
++{
++    Q_OBJECT
++    Q_CLASSINFO("DefaultProperty", "data")
++    Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
++public:
++    QObjectContainer();
++
++    QQmlListProperty<QObject> data();
++
++    static void children_append(QQmlListProperty<QObject> *prop, QObject *o);
++    static int children_count(QQmlListProperty<QObject> *prop);
++    static QObject *children_at(QQmlListProperty<QObject> *prop, int index);
++    static void children_clear(QQmlListProperty<QObject> *prop);
++
++    QList<QObject*> dataChildren;
++    QWidget *widgetParent;
++    bool gcOnAppend;
++
++protected slots:
++    void childDestroyed(QObject *child);
++};
++
++class QObjectContainerWithGCOnAppend : public QObjectContainer
++{
++    Q_OBJECT
++public:
++    QObjectContainerWithGCOnAppend()
++    {
++        gcOnAppend = true;
++    }
++};
++
++class FloatingQObject : public QObject, public QQmlParserStatus
++{
++    Q_OBJECT
++    Q_INTERFACES(QQmlParserStatus)
++public:
++    FloatingQObject() {}
++
++    virtual void classBegin();
++    virtual void componentComplete();
++};
++
+ void registerTypes();
+ 
+ #endif // TESTTYPES_H
+diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+index a1e36b4..a9486a8 100644
+--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
++++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+@@ -322,6 +322,7 @@ private slots:
+     void varPropertyAccessOnObjectWithInvalidContext();
+     void importedScriptsAccessOnObjectWithInvalidContext();
+     void contextObjectOnLazyBindings();
++    void garbageCollectionDuringCreation();
+ 
+ private:
+ //    static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
+@@ -7603,6 +7604,33 @@ void tst_qqmlecmascript::contextObjectOnLazyBindings()
+     QCOMPARE(subObject->property("testValue").toInt(), int(42));
+ }
+ 
++void tst_qqmlecmascript::garbageCollectionDuringCreation()
++{
++    QQmlComponent component(&engine);
++    component.setData("import Qt.test 1.0\n"
++                      "QObjectContainerWithGCOnAppend {\n"
++                      "    objectName: \"root\"\n"
++                      "    FloatingQObject {\n"
++                      "        objectName: \"parentLessChild\"\n"
++                      "        property var blah;\n" // Ensure we have JS wrapper
++                      "    }\n"
++                      "}\n",
++                      QUrl());
++
++    QScopedPointer<QObject> object(component.create());
++    QVERIFY(!object.isNull());
++
++    QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
++    QCOMPARE(container->dataChildren.count(), 1);
++
++    QObject *child = container->dataChildren.first();
++    QQmlData *ddata = QQmlData::get(child);
++    QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
++
++    gc(engine);
++    QCOMPARE(container->dataChildren.count(), 0);
++}
++
+ QTEST_MAIN(tst_qqmlecmascript)
+ 
+ #include "tst_qqmlecmascript.moc"
+-- 
+2.0.1
+

=== removed file 'debian/patches/parenttosubcreator_qqmlobjectcreator.patch'
--- debian/patches/parenttosubcreator_qqmlobjectcreator.patch	2014-07-01 08:22:15 +0000
+++ debian/patches/parenttosubcreator_qqmlobjectcreator.patch	1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
-commit 249b1a73fdb01fc27e036fc4334925674c281793
-Author: Albert Astals Cid <albert.ast...@canonical.com>
-Date:   Mon Jun 30 17:22:55 2014 +0200
-
-    Pass down parent to subCreator
-    
-    Otherwise the object might get garbage collected while it's being created
-    
-    Change-Id: I553c3432d5242bcd89723b72d8f8ae82577abaf9
-    Task-number: QTBUG-39966
-
-diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
-index 36c7dfb..cceb9b2 100644
---- a/src/qml/qml/qqmlobjectcreator.cpp
-+++ b/src/qml/qml/qqmlobjectcreator.cpp
-@@ -1076,7 +1076,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
-             }
- 
-             QQmlObjectCreator subCreator(context, typeRef->component, sharedState.data());
--            instance = subCreator.create();
-+            instance = subCreator.create(-1, parent);
-             if (!instance) {
-                 errors += subCreator.errors;
-                 return 0;

=== modified file 'debian/patches/series'
--- debian/patches/series	2014-07-07 08:45:33 +0000
+++ debian/patches/series	2014-08-05 16:02:47 +0000
@@ -6,5 +6,7 @@
 v4_yarr_jit_push_pop_addressTempRegister.patch
 fix_qqmlobjectcreator.patch
 Implement-proper-support-for-layoutChange-in-QQmlDel.patch
-parenttosubcreator_qqmlobjectcreator.patch
+Fix-crash-when-deleting-component-in-Component.onCom.patch
+Fix-interaction-of-garbage-collector-with-JS-objects.patch
 Support-RFC2822Date-date-format-similar-to-V8.patch
+8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch

=== modified file 'debian/rules'
--- debian/rules	2014-05-28 05:57:55 +0000
+++ debian/rules	2014-08-05 16:02:47 +0000
@@ -1,10 +1,17 @@
 #!/usr/bin/make -f
 
+include /usr/share/dpkg/default.mk
+
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 
 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
 
+# Explicitly selecting a G{CC,++}-version here to avoid symbol changes
+# because of the default gcc switch.
+export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.8
+export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.8
+
 export CFLAGS := $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS)
 export CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) $(shell dpkg-buildflags --get CPPFLAGS)
 export LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS) -Wl,--as-needed
@@ -14,7 +21,7 @@
 	dh $@ --parallel --with pkgkde_symbolshelper --dbg-package=qtdeclarative5-dbg
 
 override_dh_auto_configure:
-	qmake QT_BUILD_PARTS+=tests
+	qmake QT_BUILD_PARTS+=tests QMAKE_CC=$(CC) QMAKE_CXX=$(CXX)
 
 override_dh_auto_build-indep:
 	dh_auto_build -Smakefile -- html_docs

-- 
kubuntu-devel mailing list
kubuntu-devel@lists.ubuntu.com
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/kubuntu-devel

Reply via email to