Merge lp:~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8 into lp:~kubuntu-packagers/kubuntu-packaging/qtdeclarative-opensource-src

Proposed by Timo Jyrinki
Status: Merged
Approved by: Timo Jyrinki
Approved revision: 164
Merged at revision: 162
Proposed branch: lp:~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8
Merge into: lp:~kubuntu-packagers/kubuntu-packaging/qtdeclarative-opensource-src
Diff against target: 742 lines (+647/-26)
8 files modified
debian/changelog (+18/-0)
debian/control (+2/-0)
debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch (+152/-0)
debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch (+129/-0)
debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch (+335/-0)
debian/patches/parenttosubcreator_qqmlobjectcreator.patch (+0/-24)
debian/patches/series (+3/-1)
debian/rules (+8/-1)
To merge this branch: bzr merge lp:~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Kubuntu Packagers Pending
Review via email: mp+229651@code.launchpad.net

Commit message

[ 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)

To post a comment you must log in.
Revision history for this message
Timo Jyrinki (timo-jyrinki) wrote :

Released, this is to trigger code coverage collection only.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Autolanding.
No commit message was specified in the merge proposal. Hit 'Add commit message' on the merge proposal web page or follow the link below. You can approve the merge proposal yourself to rerun.
https://code.launchpad.net/~timo-jyrinki/kubuntu-packaging/qtdeclarative-opensource-src_530ubuntu8/+merge/229651/+edit-commit-message

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-07-07 08:43:27 +0000
3+++ debian/changelog 2014-08-05 16:09:22 +0000
4@@ -1,3 +1,21 @@
5+qtdeclarative-opensource-src (5.3.0-3ubuntu8) utopic; urgency=medium
6+
7+ [ Michał Sawicz ]
8+ * debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch
9+ - Fix flickable interaction (LP: #1349705)
10+ * debian/control
11+ * debian/rules
12+ - Force gcc-4.8 to avoid symbols changes
13+
14+ [ Timo Jyrinki ]
15+ * debian/patches/parenttosubcreator_qqmlobjectcreator.patch:
16+ - Drop, rejected by upstream
17+ * debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch
18+ debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch:
19+ - Replace the old patch with accepted upstream approach (LP: #1349297)
20+
21+ -- Timo Jyrinki <timo-jyrinki@ubuntu.com> Mon, 04 Aug 2014 10:58:28 +0000
22+
23 qtdeclarative-opensource-src (5.3.0-3ubuntu7) utopic; urgency=medium
24
25 * debian/patches/Support-RFC2822Date-date-format-similar-to-V8.patch
26
27=== modified file 'debian/control'
28--- debian/control 2014-06-19 19:14:47 +0000
29+++ debian/control 2014-08-05 16:09:22 +0000
30@@ -11,6 +11,8 @@
31 Timo Jyrinki <timo@debian.org>
32 Build-Depends: debhelper (>= 9),
33 dpkg-dev (>= 1.16.1),
34+# Avoiding symbols updates due to switch to gcc 4.9 by default.
35+ g++-4.8,
36 libqt5xmlpatterns5-private-dev (>= 5.3.0-0~),
37 pkg-kde-tools (>= 0.15.12~),
38 python,
39
40=== added file 'debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch'
41--- debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch 1970-01-01 00:00:00 +0000
42+++ debian/patches/8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch 2014-08-05 16:09:22 +0000
43@@ -0,0 +1,152 @@
44+From 8454a21b837ccf3968f6dbc56ed4f06d60d63c8f Mon Sep 17 00:00:00 2001
45+From: Albert Astals Cid <albert.astals@canonical.com>
46+Date: Wed, 23 Jul 2014 15:40:42 +0200
47+Subject: [PATCH] Flickable: Cancel interaction on interactive changes
48+
49+Otherwise if you have a listview with a flickable inside with a mouseare inside
50+the pressed is never set to false if you make the interactive property of the
51+outer list depend on the moving of the inner flickable. This makes that when
52+later you change currentIndex of the list and you have
53+StrictlyEnforceRange set, the list won't move because it still thinks it is pressed
54+
55+Change-Id: I2c2021f486fc0a31840c3f2199bc7cb76dc01e3e
56+Reviewed-by: Martin Jones <martin.jones@jollamobile.com>
57+---
58+ src/quick/items/qquickflickable.cpp | 41 ++++++++++++++--------------
59+ src/quick/items/qquickflickable_p_p.h | 2 ++
60+ tests/auto/qmltest/listview/tst_listview.qml | 41 ++++++++++++++++++++++++++++
61+ 3 files changed, 63 insertions(+), 21 deletions(-)
62+
63+diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp
64+index ee71ea8..63dde66 100644
65+--- a/src/quick/items/qquickflickable.cpp
66++++ b/src/quick/items/qquickflickable.cpp
67+@@ -763,15 +763,8 @@ void QQuickFlickable::setInteractive(bool interactive)
68+ Q_D(QQuickFlickable);
69+ if (interactive != d->interactive) {
70+ d->interactive = interactive;
71+- if (!interactive && (d->hData.flicking || d->vData.flicking)) {
72+- d->clearTimeline();
73+- d->hData.vTime = d->vData.vTime = d->timeline.time();
74+- d->hData.flicking = false;
75+- d->vData.flicking = false;
76+- emit flickingChanged();
77+- emit flickingHorizontallyChanged();
78+- emit flickingVerticallyChanged();
79+- emit flickEnded();
80++ if (!interactive) {
81++ d->cancelInteraction();
82+ }
83+ emit interactiveChanged();
84+ }
85+@@ -2015,18 +2008,24 @@ bool QQuickFlickable::yflick() const
86+ void QQuickFlickable::mouseUngrabEvent()
87+ {
88+ Q_D(QQuickFlickable);
89+- if (d->pressed) {
90+- // if our mouse grab has been removed (probably by another Flickable),
91+- // fix our state
92+- d->clearDelayedPress();
93+- d->pressed = false;
94+- d->draggingEnding();
95+- d->stealMouse = false;
96+- setKeepMouseGrab(false);
97+- d->fixupX();
98+- d->fixupY();
99+- if (!d->isViewMoving())
100+- movementEnding();
101++ // if our mouse grab has been removed (probably by another Flickable),
102++ // fix our state
103++ d->cancelInteraction();
104++}
105++
106++void QQuickFlickablePrivate::cancelInteraction()
107++{
108++ Q_Q(QQuickFlickable);
109++ if (pressed) {
110++ clearDelayedPress();
111++ pressed = false;
112++ draggingEnding();
113++ stealMouse = false;
114++ q->setKeepMouseGrab(false);
115++ fixupX();
116++ fixupY();
117++ if (!isViewMoving())
118++ q->movementEnding();
119+ }
120+ }
121+
122+diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h
123+index 33a642e..13af2e0 100644
124+--- a/src/quick/items/qquickflickable_p_p.h
125++++ b/src/quick/items/qquickflickable_p_p.h
126+@@ -200,6 +200,8 @@ public:
127+
128+ bool isViewMoving() const;
129+
130++ void cancelInteraction();
131++
132+ public:
133+ QQuickItem *contentItem;
134+
135+diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
136+index 03be579..069b62a 100644
137+--- a/tests/auto/qmltest/listview/tst_listview.qml
138++++ b/tests/auto/qmltest/listview/tst_listview.qml
139+@@ -108,6 +108,33 @@ Item {
140+ property int createdDelegates: 0
141+ }
142+
143++ ListView
144++ {
145++ id: listInteractiveCurrentIndexEnforce
146++ width: 600
147++ height: 600
148++
149++ snapMode: ListView.SnapOneItem
150++ orientation: ListView.Horizontal
151++ interactive: !currentItem.moving
152++ highlightRangeMode: ListView.StrictlyEnforceRange
153++
154++ model: 4
155++
156++ focus: true
157++ Keys.onPressed: if (event.key == Qt.Key_K) currentIndex = currentIndex + 1;
158++
159++ delegate: Flickable {
160++ width: 600
161++ height: 600
162++ contentWidth: 600
163++ contentHeight: 1200
164++
165++ MouseArea { anchors.fill: parent }
166++ Rectangle { anchors.fill: parent; color: index == 0 ? "red" : index == 1 ? "green" : index == 2 ? "blue" : "white" }
167++ }
168++ }
169++
170+ Component {
171+ id: delegateModelAfterCreateComponent
172+ Rectangle {
173+@@ -272,5 +299,19 @@ Item {
174+ listViewDelegateModelAfterCreate.model = 40;
175+ verify(listViewDelegateModelAfterCreate.createdDelegates > 0);
176+ }
177++
178++ function test_listInteractiveCurrentIndexEnforce() {
179++ mousePress(listInteractiveCurrentIndexEnforce, 10, 50);
180++ mouseMove(listInteractiveCurrentIndexEnforce, 10, 40);
181++ mouseMove(listInteractiveCurrentIndexEnforce, 10, 30);
182++ mouseMove(listInteractiveCurrentIndexEnforce, 10, 20);
183++ mouseMove(listInteractiveCurrentIndexEnforce, 10, 10);
184++ compare(listInteractiveCurrentIndexEnforce.interactive, false);
185++ mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10);
186++ tryCompare(listInteractiveCurrentIndexEnforce, "interactive", true);
187++ keyClick("k");
188++ compare(listInteractiveCurrentIndexEnforce.currentIndex, 1);
189++ tryCompare(listInteractiveCurrentIndexEnforce, "contentX", listInteractiveCurrentIndexEnforce.width);
190++ }
191+ }
192+ }
193+--
194+2.0.1
195+
196
197=== added file 'debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch'
198--- debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch 1970-01-01 00:00:00 +0000
199+++ debian/patches/Fix-crash-when-deleting-component-in-Component.onCom.patch 2014-08-05 16:09:22 +0000
200@@ -0,0 +1,129 @@
201+From 195b998175b629e6e915588e66991f74cffa4e48 Mon Sep 17 00:00:00 2001
202+From: Simon Hausmann <simon.hausmann@digia.com>
203+Date: Fri, 20 Jun 2014 17:26:57 +0200
204+Subject: [PATCH] Fix crash when deleting component in Component.onComplete
205+ through loader
206+
207+This is a regression introduced with Qt 5.3.0. The recursion watcher code that
208+is supposed to handle the test case of QTBUG-39775 can detect the recursion
209+into the object creator. However the boolean that indicates the recursion is a
210+member of a structure that's deleted afterwards. To avoid access to deleted
211+memory, this patch simply reference counts data structure shared between the
212+creators and also wraps the recursion watcher into a convenience class that
213+also increases/decreases the reference count accordingly.
214+
215+Change-Id: I8d2e3e200ab1295e89d951e09f187d382a056d5a
216+Task-number: QTBUG-39775
217+Reviewed-by: Lars Knoll <lars.knoll@digia.com>
218+---
219+ src/qml/qml/qqmlobjectcreator.cpp | 17 ++++++++++++-----
220+ src/qml/qml/qqmlobjectcreator_p.h | 18 ++++++++++++++++--
221+ 2 files changed, 28 insertions(+), 7 deletions(-)
222+
223+diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
224+index 16c9dd7..36c7dfb 100644
225+--- a/src/qml/qml/qqmlobjectcreator.cpp
226++++ b/src/qml/qml/qqmlobjectcreator.cpp
227+@@ -91,7 +91,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
228+ init(parentContext);
229+
230+ sharedState = new QQmlObjectCreatorSharedState;
231+- sharedState.setFlag(); // We own it, so we must delete it
232++ topLevelCreator = true;
233+ sharedState->componentAttached = 0;
234+ sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
235+ sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
236+@@ -115,6 +115,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
237+ init(parentContext);
238+
239+ sharedState = inheritedSharedState;
240++ topLevelCreator = false;
241+ }
242+
243+ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
244+@@ -139,9 +140,9 @@ void QQmlObjectCreator::init(QQmlContextData *providedParentContext)
245+
246+ QQmlObjectCreator::~QQmlObjectCreator()
247+ {
248+- if (sharedState.flag()) {
249++ if (topLevelCreator) {
250+ {
251+- QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
252++ QQmlObjectCreatorRecursionWatcher watcher(this);
253+ }
254+ for (int i = 0; i < sharedState->allCreatedBindings.count(); ++i) {
255+ QQmlAbstractBinding *b = sharedState->allCreatedBindings.at(i);
256+@@ -157,7 +158,6 @@ QQmlObjectCreator::~QQmlObjectCreator()
257+ QQmlComponentAttached *a = sharedState->componentAttached;
258+ a->rem();
259+ }
260+- delete sharedState.data();
261+ }
262+ }
263+
264+@@ -1172,7 +1172,7 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
265+ Q_ASSERT(phase == ObjectsCreated || phase == Finalizing);
266+ phase = Finalizing;
267+
268+- QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher(sharedState.data());
269++ QQmlObjectCreatorRecursionWatcher watcher(this);
270+ ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine));
271+
272+ {
273+@@ -1334,3 +1334,10 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
274+ }
275+
276+
277++
278++
279++QQmlObjectCreatorRecursionWatcher::QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator)
280++ : sharedState(creator->sharedState)
281++ , watcher(creator->sharedState.data())
282++{
283++}
284+diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
285+index 379a3b2..ad2d676 100644
286+--- a/src/qml/qml/qqmlobjectcreator_p.h
287++++ b/src/qml/qml/qqmlobjectcreator_p.h
288+@@ -57,7 +57,7 @@ struct QQmlTypeCompiler;
289+ class QQmlInstantiationInterrupt;
290+ struct QQmlVmeProfiler;
291+
292+-struct QQmlObjectCreatorSharedState
293++struct QQmlObjectCreatorSharedState : public QSharedData
294+ {
295+ QQmlContextData *rootContext;
296+ QQmlContextData *creationContext;
297+@@ -128,7 +128,8 @@ private:
298+ const QVector<QQmlPropertyCache *> &propertyCaches;
299+ const QVector<QByteArray> &vmeMetaObjectData;
300+ QHash<int, int> objectIndexToId;
301+- QFlagPointer<QQmlObjectCreatorSharedState> sharedState;
302++ QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
303++ bool topLevelCreator;
304+ void *activeVMEDataForRootContext;
305+
306+ QObject *_qobject;
307+@@ -142,6 +143,19 @@ private:
308+ QQmlVMEMetaObject *_vmeMetaObject;
309+ QQmlListProperty<void> _currentList;
310+ QV4::ExecutionContext *_qmlContext;
311++
312++ friend struct QQmlObjectCreatorRecursionWatcher;
313++};
314++
315++struct QQmlObjectCreatorRecursionWatcher
316++{
317++ QQmlObjectCreatorRecursionWatcher(QQmlObjectCreator *creator);
318++
319++ bool hasRecursed() const { return watcher.hasRecursed(); }
320++
321++private:
322++ QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState;
323++ QRecursionWatcher<QQmlObjectCreatorSharedState, &QQmlObjectCreatorSharedState::recursionNode> watcher;
324+ };
325+
326+ QT_END_NAMESPACE
327+--
328+2.0.1
329+
330
331=== added file 'debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch'
332--- debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch 1970-01-01 00:00:00 +0000
333+++ debian/patches/Fix-interaction-of-garbage-collector-with-JS-objects.patch 2014-08-05 16:09:22 +0000
334@@ -0,0 +1,335 @@
335+From 14bc8dc3f3016889cfcbdbe7309b09be7687ebe0 Mon Sep 17 00:00:00 2001
336+From: Simon Hausmann <simon.hausmann@digia.com>
337+Date: Wed, 14 May 2014 16:04:33 +0200
338+Subject: [PATCH] Fix interaction of garbage collector with JS objects during
339+ QML type instantiation
340+
341+It may happen that during the lengthy process of instantiating a tree of
342+objects for QML, the garbage collector runs.
343+
344+For objects created by QML we support different ownership models, for example
345+in QtQuick visual parents keep their visual children alive, despite perhaps a
346+lack of QObject parentship. That ownership becomes active once the QML
347+autoparent function has assigned the correct visual parent, which happens after
348+object instantiation (after QQmlObjectCreator).
349+
350+Similarly when a composite type is created, its QObject parent is only set
351+after all properties have been set. The root QObject is kept alive through a
352+special boolean, but if the sub-objects aren't children yet, their JS wrapper
353+might get deleted. For composite types with var properties, that also means
354+their var properties get deleted, such as the model property of TableView.qml
355+in the bug report.
356+
357+In the future we want to support creating QWidget hierarchies with QML, which
358+also for layouts may rely on a delayed parent assignment for layouts.
359+
360+To accommodate all this, this patch introduces an array on the JS stack that
361+keeps track of all JS wrappers for all QObjects created. This array is alive
362+during object tree creation. Afterwards, the different ownership models take
363+over, for example the auto parent function assigning a visual parent.
364+
365+This patch also fixes an off-by-one in the total object count calculation
366+for composite types, where when instantiating a composite type as a sub-object
367+we counted the sub composite's object count but forgot the object itself.
368+
369+Task-number: QTBUG-38835
370+Task-number: QTBUG-39966
371+Change-Id: I6104b2434510642081e0c54793ed296adeca7481
372+Reviewed-by: Lars Knoll <lars.knoll@digia.com>
373+---
374+ src/qml/compiler/qqmltypecompiler.cpp | 4 +-
375+ src/qml/qml/qqmlobjectcreator.cpp | 27 +++++++---
376+ src/qml/qml/qqmlobjectcreator_p.h | 1 +
377+ tests/auto/qml/qqmlecmascript/testtypes.cpp | 60 ++++++++++++++++++++++
378+ tests/auto/qml/qqmlecmascript/testtypes.h | 45 ++++++++++++++++
379+ .../auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 28 ++++++++++
380+ 6 files changed, 157 insertions(+), 8 deletions(-)
381+
382+diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
383+index 60a0829..dacaa14 100644
384+--- a/src/qml/compiler/qqmltypecompiler.cpp
385++++ b/src/qml/compiler/qqmltypecompiler.cpp
386+@@ -277,12 +277,12 @@ bool QQmlTypeCompiler::compile()
387+ if (qmlType->parserStatusCast() != -1)
388+ ++parserStatusCount;
389+ }
390++ ++objectCount;
391+ if (typeRef->component) {
392+ bindingCount += typeRef->component->totalBindingsCount;
393+ parserStatusCount += typeRef->component->totalParserStatusCount;
394+ objectCount += typeRef->component->totalObjectCount;
395+- } else
396+- ++objectCount;
397++ }
398+ }
399+ }
400+
401+diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
402+index 36c7dfb..1de467b 100644
403+--- a/src/qml/qml/qqmlobjectcreator.cpp
404++++ b/src/qml/qml/qqmlobjectcreator.cpp
405+@@ -96,6 +96,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile
406+ sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
407+ sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
408+ sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount);
409++ sharedState->allJavaScriptObjects = 0;
410+ sharedState->creationContext = creationContext;
411+ sharedState->rootContext = 0;
412+
413+@@ -195,6 +196,13 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
414+ sharedState->rootContext->isRootObjectInCreation = true;
415+ }
416+
417++ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
418++ QV4::Scope scope(v4);
419++
420++ Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator);
421++ if (topLevelCreator)
422++ sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount);
423++
424+ QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
425+ for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd();
426+ it != end; ++it) {
427+@@ -208,8 +216,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
428+ context->setIdPropertyData(mapping);
429+
430+ if (subComponentIndex == -1) {
431+- QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
432+- QV4::Scope scope(v4);
433+ QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count()));
434+ context->importedScripts = scripts;
435+ for (int i = 0; i < compiledData->scripts.count(); ++i) {
436+@@ -230,6 +236,9 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
437+ ddata->compiledData->addref();
438+ }
439+
440++ if (topLevelCreator)
441++ sharedState->allJavaScriptObjects = 0;
442++
443+ phase = CreatingObjectsPhase2;
444+
445+ if (interrupt && interrupt->shouldInterrupt())
446+@@ -258,8 +267,11 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance)
447+
448+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
449+ QV4::Scope valueScope(v4);
450+- QV4::ScopedValue scopeObjectProtector(valueScope, declarativeData->jsWrapper.value());
451+- Q_UNUSED(scopeObjectProtector);
452++
453++ Q_ASSERT(topLevelCreator);
454++ Q_ASSERT(!sharedState->allJavaScriptObjects);
455++ sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount);
456++
457+ QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
458+ QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
459+ QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
460+@@ -1150,9 +1162,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
461+ qSwap(_scopeObject, scopeObject);
462+
463+ QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine);
464++
465++ Q_ASSERT(sharedState->allJavaScriptObjects);
466++ QV4::ValueRef ref = QV4::ValueRef::fromRawValue(sharedState->allJavaScriptObjects++);
467++ ref = QV4::QObjectWrapper::wrap(v4, instance);
468++
469+ QV4::Scope valueScope(v4);
470+- QV4::ScopedValue scopeObjectProtector(valueScope, ddata ? ddata->jsWrapper.value() : 0);
471+- Q_UNUSED(scopeObjectProtector);
472+ QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject));
473+ QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, new (v4->memoryManager) QV4::QmlBindingWrapper(v4->rootContext, qmlScope));
474+ QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context();
475+diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
476+index ad2d676..fb4d71d 100644
477+--- a/src/qml/qml/qqmlobjectcreator_p.h
478++++ b/src/qml/qml/qqmlobjectcreator_p.h
479+@@ -64,6 +64,7 @@ struct QQmlObjectCreatorSharedState : public QSharedData
480+ QFiniteStack<QQmlAbstractBinding*> allCreatedBindings;
481+ QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
482+ QFiniteStack<QObject*> allCreatedObjects;
483++ QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
484+ QQmlComponentAttached *componentAttached;
485+ QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
486+ QQmlVmeProfiler profiler;
487+diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp
488+index eb06b9e..560d860 100644
489+--- a/tests/auto/qml/qqmlecmascript/testtypes.cpp
490++++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp
491+@@ -300,6 +300,62 @@ static QObject *create_singletonWithEnum(QQmlEngine *, QJSEngine *)
492+ return new SingletonWithEnum;
493+ }
494+
495++QObjectContainer::QObjectContainer()
496++ : widgetParent(0)
497++ , gcOnAppend(false)
498++{}
499++
500++QQmlListProperty<QObject> QObjectContainer::data()
501++{
502++ return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear);
503++}
504++
505++void QObjectContainer::children_append(QQmlListProperty<QObject> *prop, QObject *o)
506++{
507++ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
508++ that->dataChildren.append(o);
509++ QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*)));
510++
511++ if (that->gcOnAppend) {
512++ QQmlEngine *engine = qmlEngine(that);
513++ engine->collectGarbage();
514++ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
515++ QCoreApplication::processEvents();
516++ }
517++}
518++
519++int QObjectContainer::children_count(QQmlListProperty<QObject> *prop)
520++{
521++ return static_cast<QObjectContainer*>(prop->object)->dataChildren.count();
522++}
523++
524++QObject *QObjectContainer::children_at(QQmlListProperty<QObject> *prop, int index)
525++{
526++ return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index);
527++}
528++
529++void QObjectContainer::children_clear(QQmlListProperty<QObject> *prop)
530++{
531++ QObjectContainer *that = static_cast<QObjectContainer*>(prop->object);
532++ foreach (QObject *c, that->dataChildren)
533++ QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*)));
534++ that->dataChildren.clear();
535++}
536++
537++void QObjectContainer::childDestroyed(QObject *child) {
538++ dataChildren.removeAll(child);
539++}
540++
541++void FloatingQObject::classBegin()
542++{
543++ setParent(0);
544++}
545++
546++void FloatingQObject::componentComplete()
547++{
548++ Q_ASSERT(!parent());
549++}
550++
551+ void registerTypes()
552+ {
553+ qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias");
554+@@ -381,6 +437,10 @@ void registerTypes()
555+ qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi2",1,0,"Data",testImportOrder_api2);
556+
557+ qmlRegisterSingletonType<SingletonWithEnum>("Qt.test.singletonWithEnum", 1, 0, "SingletonWithEnum", create_singletonWithEnum);
558++
559++ qmlRegisterType<QObjectContainer>("Qt.test", 1, 0, "QObjectContainer");
560++ qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.test", 1, 0, "QObjectContainerWithGCOnAppend");
561++ qmlRegisterType<FloatingQObject>("Qt.test", 1, 0, "FloatingQObject");
562+ }
563+
564+ #include "testtypes.moc"
565+diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h
566+index 928d594..d5a1220 100644
567+--- a/tests/auto/qml/qqmlecmascript/testtypes.h
568++++ b/tests/auto/qml/qqmlecmascript/testtypes.h
569+@@ -1661,6 +1661,51 @@ public:
570+ };
571+ };
572+
573++// Like QtObject, but with default property
574++class QObjectContainer : public QObject
575++{
576++ Q_OBJECT
577++ Q_CLASSINFO("DefaultProperty", "data")
578++ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false)
579++public:
580++ QObjectContainer();
581++
582++ QQmlListProperty<QObject> data();
583++
584++ static void children_append(QQmlListProperty<QObject> *prop, QObject *o);
585++ static int children_count(QQmlListProperty<QObject> *prop);
586++ static QObject *children_at(QQmlListProperty<QObject> *prop, int index);
587++ static void children_clear(QQmlListProperty<QObject> *prop);
588++
589++ QList<QObject*> dataChildren;
590++ QWidget *widgetParent;
591++ bool gcOnAppend;
592++
593++protected slots:
594++ void childDestroyed(QObject *child);
595++};
596++
597++class QObjectContainerWithGCOnAppend : public QObjectContainer
598++{
599++ Q_OBJECT
600++public:
601++ QObjectContainerWithGCOnAppend()
602++ {
603++ gcOnAppend = true;
604++ }
605++};
606++
607++class FloatingQObject : public QObject, public QQmlParserStatus
608++{
609++ Q_OBJECT
610++ Q_INTERFACES(QQmlParserStatus)
611++public:
612++ FloatingQObject() {}
613++
614++ virtual void classBegin();
615++ virtual void componentComplete();
616++};
617++
618+ void registerTypes();
619+
620+ #endif // TESTTYPES_H
621+diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
622+index a1e36b4..a9486a8 100644
623+--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
624++++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
625+@@ -322,6 +322,7 @@ private slots:
626+ void varPropertyAccessOnObjectWithInvalidContext();
627+ void importedScriptsAccessOnObjectWithInvalidContext();
628+ void contextObjectOnLazyBindings();
629++ void garbageCollectionDuringCreation();
630+
631+ private:
632+ // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
633+@@ -7603,6 +7604,33 @@ void tst_qqmlecmascript::contextObjectOnLazyBindings()
634+ QCOMPARE(subObject->property("testValue").toInt(), int(42));
635+ }
636+
637++void tst_qqmlecmascript::garbageCollectionDuringCreation()
638++{
639++ QQmlComponent component(&engine);
640++ component.setData("import Qt.test 1.0\n"
641++ "QObjectContainerWithGCOnAppend {\n"
642++ " objectName: \"root\"\n"
643++ " FloatingQObject {\n"
644++ " objectName: \"parentLessChild\"\n"
645++ " property var blah;\n" // Ensure we have JS wrapper
646++ " }\n"
647++ "}\n",
648++ QUrl());
649++
650++ QScopedPointer<QObject> object(component.create());
651++ QVERIFY(!object.isNull());
652++
653++ QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data());
654++ QCOMPARE(container->dataChildren.count(), 1);
655++
656++ QObject *child = container->dataChildren.first();
657++ QQmlData *ddata = QQmlData::get(child);
658++ QVERIFY(!ddata->jsWrapper.isNullOrUndefined());
659++
660++ gc(engine);
661++ QCOMPARE(container->dataChildren.count(), 0);
662++}
663++
664+ QTEST_MAIN(tst_qqmlecmascript)
665+
666+ #include "tst_qqmlecmascript.moc"
667+--
668+2.0.1
669+
670
671=== removed file 'debian/patches/parenttosubcreator_qqmlobjectcreator.patch'
672--- debian/patches/parenttosubcreator_qqmlobjectcreator.patch 2014-07-01 08:22:15 +0000
673+++ debian/patches/parenttosubcreator_qqmlobjectcreator.patch 1970-01-01 00:00:00 +0000
674@@ -1,24 +0,0 @@
675-commit 249b1a73fdb01fc27e036fc4334925674c281793
676-Author: Albert Astals Cid <albert.astals@canonical.com>
677-Date: Mon Jun 30 17:22:55 2014 +0200
678-
679- Pass down parent to subCreator
680-
681- Otherwise the object might get garbage collected while it's being created
682-
683- Change-Id: I553c3432d5242bcd89723b72d8f8ae82577abaf9
684- Task-number: QTBUG-39966
685-
686-diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
687-index 36c7dfb..cceb9b2 100644
688---- a/src/qml/qml/qqmlobjectcreator.cpp
689-+++ b/src/qml/qml/qqmlobjectcreator.cpp
690-@@ -1076,7 +1076,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
691- }
692-
693- QQmlObjectCreator subCreator(context, typeRef->component, sharedState.data());
694-- instance = subCreator.create();
695-+ instance = subCreator.create(-1, parent);
696- if (!instance) {
697- errors += subCreator.errors;
698- return 0;
699
700=== modified file 'debian/patches/series'
701--- debian/patches/series 2014-07-07 08:45:33 +0000
702+++ debian/patches/series 2014-08-05 16:09:22 +0000
703@@ -6,5 +6,7 @@
704 v4_yarr_jit_push_pop_addressTempRegister.patch
705 fix_qqmlobjectcreator.patch
706 Implement-proper-support-for-layoutChange-in-QQmlDel.patch
707-parenttosubcreator_qqmlobjectcreator.patch
708+Fix-crash-when-deleting-component-in-Component.onCom.patch
709+Fix-interaction-of-garbage-collector-with-JS-objects.patch
710 Support-RFC2822Date-date-format-similar-to-V8.patch
711+8454a21b-Flickable-Cancel-interaction-on-interactive-changes.patch
712
713=== modified file 'debian/rules'
714--- debian/rules 2014-05-28 05:57:55 +0000
715+++ debian/rules 2014-08-05 16:09:22 +0000
716@@ -1,10 +1,17 @@
717 #!/usr/bin/make -f
718
719+include /usr/share/dpkg/default.mk
720+
721 # Uncomment this to turn on verbose mode.
722 #export DH_VERBOSE=1
723
724 DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
725
726+# Explicitly selecting a G{CC,++}-version here to avoid symbol changes
727+# because of the default gcc switch.
728+export CC=$(DEB_HOST_GNU_TYPE)-gcc-4.8
729+export CXX=$(DEB_HOST_GNU_TYPE)-g++-4.8
730+
731 export CFLAGS := $(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS)
732 export CXXFLAGS := $(shell dpkg-buildflags --get CXXFLAGS) $(shell dpkg-buildflags --get CPPFLAGS)
733 export LDFLAGS := $(shell dpkg-buildflags --get LDFLAGS) -Wl,--as-needed
734@@ -14,7 +21,7 @@
735 dh $@ --parallel --with pkgkde_symbolshelper --dbg-package=qtdeclarative5-dbg
736
737 override_dh_auto_configure:
738- qmake QT_BUILD_PARTS+=tests
739+ qmake QT_BUILD_PARTS+=tests QMAKE_CC=$(CC) QMAKE_CXX=$(CXX)
740
741 override_dh_auto_build-indep:
742 dh_auto_build -Smakefile -- html_docs

Subscribers

People subscribed via source and target branches