diff options
author | Liang Qi <liang.qi@qt.io> | 2016-08-13 00:41:58 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-08-13 00:41:58 +0200 |
commit | d54d28981c90d23d7fa0cfc5a9e3049e3e4df6b5 (patch) | |
tree | 0eb2f54f16b014f6eaa362095393d1bd058adb52 /tests/auto/qml/qqmlecmascript | |
parent | 580f2872f09cf7ad83ec9ae5dca686683a3cac80 (diff) | |
parent | 6f15de1d2da9c83d7fca1d5c8243c0d69a1390ee (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
src/qml/compiler/qv4isel_moth.cpp
src/qml/compiler/qv4ssa_p.h
tests/benchmarks/qml/qqmlimage/qqmlimage.pro
tests/benchmarks/qml/qqmlimage/tst_qqmlimage.cpp
Change-Id: Iad11ce7fdf0c6d200fdebc16a94081bd8069a87a
Diffstat (limited to 'tests/auto/qml/qqmlecmascript')
-rw-r--r-- | tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 102 |
2 files changed, 105 insertions, 0 deletions
diff --git a/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml new file mode 100644 index 0000000000..8bb0a3554e --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/DestructionHelper.qml @@ -0,0 +1,3 @@ +import Test 1.0 +WeakReferenceMutator { +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 2c9f08c82a..b6d2e303cb 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -44,6 +44,8 @@ #include <private/qv4scopedvalue_p.h> #include <private/qv4alloca_p.h> #include <private/qv4runtime_p.h> +#include <private/qv4object_p.h> +#include <private/qqmlcomponentattached_p.h> #ifdef Q_CC_MSVC #define NO_INLINE __declspec(noinline) @@ -282,6 +284,7 @@ private slots: void replaceBinding(); void deleteRootObjectInCreation(); void onDestruction(); + void onDestructionViaGC(); void bindingSuppression(); void signalEmitted(); void threadSignal(); @@ -7150,6 +7153,105 @@ void tst_qqmlecmascript::onDestruction() } } +class WeakReferenceMutator : public QObject +{ + Q_OBJECT +public: + WeakReferenceMutator() + : resultPtr(Q_NULLPTR) + , weakRef(Q_NULLPTR) + {} + + void init(QV4::ExecutionEngine *v4, QV4::WeakValue *weakRef, bool *resultPtr) + { + QV4::QObjectWrapper::wrap(v4, this); + QQmlEngine::setObjectOwnership(this, QQmlEngine::JavaScriptOwnership); + + this->resultPtr = resultPtr; + this->weakRef = weakRef; + + QObject::connect(QQmlComponent::qmlAttachedProperties(this), &QQmlComponentAttached::destruction, this, &WeakReferenceMutator::reviveFirstWeakReference); + } + +private slots: + void reviveFirstWeakReference() { + *resultPtr = weakRef->valueRef() && weakRef->isNullOrUndefined(); + if (!*resultPtr) + return; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(qmlEngine(this)); + weakRef->set(v4, v4->newObject()); + *resultPtr = weakRef->valueRef() && !weakRef->isNullOrUndefined(); + } + +public: + bool *resultPtr; + + QV4::WeakValue *weakRef; +}; + +QT_BEGIN_NAMESPACE + +namespace QV4 { + +namespace Heap { +struct WeakReferenceSentinel : public Object { + WeakReferenceSentinel(WeakValue *weakRef, bool *resultPtr) + : weakRef(weakRef) + , resultPtr(resultPtr) { + + } + + ~WeakReferenceSentinel() { + *resultPtr = weakRef->isNullOrUndefined(); + } + + WeakValue *weakRef; + bool *resultPtr; +}; +} // namespace Heap + +struct WeakReferenceSentinel : public Object { + V4_OBJECT2(WeakReferenceSentinel, Object) + V4_NEEDS_DESTROY +}; + +} // namespace QV4 + +QT_END_NAMESPACE + +DEFINE_OBJECT_VTABLE(QV4::WeakReferenceSentinel); + +void tst_qqmlecmascript::onDestructionViaGC() +{ + qmlRegisterType<WeakReferenceMutator>("Test", 1, 0, "WeakReferenceMutator"); + + QQmlEngine engine; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(&engine); + + QQmlComponent component(&engine, testFileUrl("DestructionHelper.qml")); + + QScopedPointer<QV4::WeakValue> weakRef; + + bool mutatorResult = false; + bool sentinelResult = false; + + { + weakRef.reset(new QV4::WeakValue); + weakRef->set(v4, v4->newObject()); + QVERIFY(!weakRef->isNullOrUndefined()); + + QPointer<WeakReferenceMutator> weakReferenceMutator = qobject_cast<WeakReferenceMutator *>(component.create()); + QVERIFY2(!weakReferenceMutator.isNull(), qPrintable(component.errorString())); + weakReferenceMutator->init(v4, weakRef.data(), &mutatorResult); + + v4->memoryManager->allocObject<QV4::WeakReferenceSentinel>(weakRef.data(), &sentinelResult); + } + gc(engine); + + QVERIFY2(mutatorResult, "We failed to re-assign the weak reference a new value during GC"); + QVERIFY2(sentinelResult, "The weak reference was not cleared properly"); +} + struct EventProcessor : public QObject { Q_OBJECT |