Skip to content

Instantly share code, notes, and snippets.

@torarnv
Created October 12, 2023 14:23
Show Gist options
  • Save torarnv/7dce7bca8283b6d284490d26a15f5717 to your computer and use it in GitHub Desktop.
Save torarnv/7dce7bca8283b6d284490d26a15f5717 to your computer and use it in GitHub Desktop.
commit 27c2403b8d4cc507151875a2bfea0e9e08ccf919
Author: Tor Arne Vestbø <[email protected]>
Date: Wed Oct 11 16:05:56 2023 +0200
WIP on reversting object creation
Change-Id: I14bcd7efd5e4a9839ee343f99ef2964d4165785f
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index dc4f25c22d5..a018ba38fde 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -67,9 +67,9 @@ QQmlObjectCreator::QQmlObjectCreator(
init(std::move(parentContext));
sharedState->componentAttached = nullptr;
- sharedState->allCreatedBindings.allocate(compilationUnit->totalBindingsCount());
- sharedState->allParserStatusCallbacks.allocate(compilationUnit->totalParserStatusCount());
- sharedState->allCreatedObjects.allocate(compilationUnit->totalObjectCount());
+ sharedState->allCreatedBindings.reserve(compilationUnit->totalBindingsCount());
+ sharedState->allParserStatusCallbacks.reserve(compilationUnit->totalParserStatusCount());
+ sharedState->allCreatedObjects.reserve(compilationUnit->totalObjectCount());
sharedState->allJavaScriptObjects = nullptr;
sharedState->creationContext = creationContext;
sharedState->rootContext.reset();
@@ -986,7 +986,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper
if (!qmlBinding->setTarget(bindingTarget, *targetProperty, subprop) && targetProperty->isAlias())
return false;
- sharedState->allCreatedBindings.push(qmlBinding);
+ sharedState->allCreatedBindings.append(qmlBinding);
if (bindingProperty->isAlias()) {
QQmlPropertyPrivate::setBinding(qmlBinding.data(), QQmlPropertyPrivate::DontEnable);
@@ -1264,7 +1264,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
sharedState->rootContext->setRootObjectInCreation(false);
}
- sharedState->allCreatedObjects.push(instance);
+ sharedState->allCreatedObjects.append(instance);
} else {
const auto compilationUnit = typeRef->compilationUnit();
Q_ASSERT(compilationUnit);
@@ -1346,8 +1346,8 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
// push() the profiler state here, together with the parserStatus, as we'll pop() them
// together, too.
Q_QML_OC_PROFILE(sharedState->profiler, sharedState->profiler.push(obj));
- sharedState->allParserStatusCallbacks.push(parserStatus);
- parserStatus->d = &sharedState->allParserStatusCallbacks.top();
+ sharedState->allParserStatusCallbacks.append(parserStatus);
+ parserStatus->d = &sharedState->allParserStatusCallbacks.last();
}
// Register the context object in the context early on in order for pending binding
@@ -1445,7 +1445,7 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
*/
while (!sharedState->allCreatedBindings.isEmpty()) {
- QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.pop();
+ QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.takeFirst();
Q_ASSERT(b);
// skip, if b is not added to an object
if (!b->isAddedToObject())
@@ -1500,7 +1500,7 @@ bool QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrupt)
if (QQmlVME::componentCompleteEnabled()) { // the qml designer does the component complete later
while (!sharedState->allParserStatusCallbacks.isEmpty()) {
QQmlObjectCompletionProfiler profiler(&sharedState->profiler);
- QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop();
+ QQmlParserStatus *status = sharedState->allParserStatusCallbacks.takeFirst();
if (status && status->d) {
status->d = nullptr;
@@ -1545,7 +1545,7 @@ void QQmlObjectCreator::clear()
Q_ASSERT(phase != Startup);
while (!sharedState->allCreatedObjects.isEmpty()) {
- auto object = sharedState->allCreatedObjects.pop();
+ auto object = sharedState->allCreatedObjects.takeFirst();
if (engine->objectOwnership(object) != QQmlEngine::CppOwnership) {
delete object;
}
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 0e73feeac4f..3361e7b40ac 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -88,9 +88,9 @@ struct QQmlObjectCreatorSharedState final : QQmlRefCounted<QQmlObjectCreatorShar
{
QQmlRefPointer<QQmlContextData> rootContext;
QQmlRefPointer<QQmlContextData> creationContext;
- QFiniteStack<QQmlAbstractBinding::Ptr> allCreatedBindings;
- QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
- QFiniteStack<QQmlGuard<QObject> > allCreatedObjects;
+ QList<QQmlAbstractBinding::Ptr> allCreatedBindings;
+ QList<QQmlParserStatus*> allParserStatusCallbacks;
+ QList<QQmlGuard<QObject>> allCreatedObjects;
QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
QQmlComponentAttached *componentAttached;
QList<QQmlFinalizerHook *> finalizeHooks;
@@ -138,7 +138,7 @@ public:
{
return parentContext.contextData();
}
- QFiniteStack<QQmlGuard<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
+ QList<QQmlGuard<QObject> > &allCreatedObjects() { return sharedState->allCreatedObjects; }
RequiredProperties *requiredProperties() {return &sharedState->requiredProperties;}
bool componentHadTopLevelRequiredProperties() const {return sharedState->hadTopLevelRequiredProperties;}
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 3b9bf80940d..fccef128f21 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -52,7 +52,7 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
{
clear();
- QFiniteStack<QQmlGuard<QObject> > &objects = creator->allCreatedObjects();
+ QList<QQmlGuard<QObject> > &objects = creator->allCreatedObjects();
m_objectCount = objects.count();
m_objects = new QQmlGuard<QObject>[m_objectCount];
for (int ii = 0; ii < m_objectCount; ++ii)
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 6913c62603f..0829a92aaa8 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -923,7 +923,7 @@ void tst_qqmlecmascript::bindingLoop()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("bindingLoop.qml"));
- QString warning = component.url().toString() + ":9:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\"";
+ QString warning = component.url().toString() + ":5:9: QML MyQmlObject: Binding loop detected for property \"stringProperty\"";
QTest::ignoreMessage(QtWarningMsg, warning.toLatin1().constData());
QScopedPointer<QObject> object(component.create());
QVERIFY2(object, qPrintable(component.errorString()));
diff --git a/tests/auto/qml/qqmlengine/data/lockedRootObject.qml b/tests/auto/qml/qqmlengine/data/lockedRootObject.qml
index 5a677b62cb9..30088b7fec1 100644
--- a/tests/auto/qml/qqmlengine/data/lockedRootObject.qml
+++ b/tests/auto/qml/qqmlengine/data/lockedRootObject.qml
@@ -37,17 +37,6 @@ QtObject {
}
}
- property string prototypeTrick: {
- // Cannot change prototypes of locked objects
- try {
- SyntaxError.prototype.setPrototypeOf({
- toLocaleString : function() { return "not a SyntaxError"}
- });
- } finally {
- return (new SyntaxError).toLocaleString();
- }
- }
-
property string shadowMethod1: {
// Can override Object.prototype methods meant to be changed
try {
@@ -105,4 +94,15 @@ QtObject {
return (new URIError).hasOwnProperty("foobar");
}
}
+
+ property string prototypeTrick: {
+ // Cannot change prototypes of locked objects
+ try {
+ SyntaxError.prototype.setPrototypeOf({
+ toLocaleString : function() { return "not a SyntaxError"}
+ });
+ } finally {
+ return (new SyntaxError).toLocaleString();
+ }
+ }
}
diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
index b0fb3b17e1e..90bba7f94da 100644
--- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
+++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp
@@ -1704,13 +1704,13 @@ void tst_qqmlengine::lockedRootObject()
QCOMPARE(o->property("errorName").toString(), QStringLiteral("MyError2"));
QCOMPARE(o->property("mathMax").toInt(), 4);
QCOMPARE(o->property("extendGlobal").toInt(), 32);
- QCOMPARE(o->property("prototypeTrick").toString(), QStringLiteral("SyntaxError"));
QCOMPARE(o->property("shadowMethod1").toString(), QStringLiteral("not a TypeError"));
QCOMPARE(o->property("shadowMethod2").toBool(), false);
QCOMPARE(o->property("changeObjectProto1").toString(), QStringLiteral("not an Object"));
QCOMPARE(o->property("changeObjectProto2").toBool(), false);
QCOMPARE(o->property("defineProperty1").toString(), QStringLiteral("not a URIError"));
QCOMPARE(o->property("defineProperty2").toBool(), false);
+ QCOMPARE(o->property("prototypeTrick").toString(), QStringLiteral("SyntaxError"));
}
void tst_qqmlengine::crossReferencingSingletonsDeletion()
diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
index 1baf61574e5..884441621f6 100644
--- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
+++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
@@ -1112,7 +1112,7 @@ void tst_qqmlincubator::selfDelete()
// We have to cheat and manually remove it from the creator->allCreatedObjects
// otherwise we will do a double delete
QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubator);
- incubatorPriv->creator->allCreatedObjects().pop();
+ incubatorPriv->creator->allCreatedObjects().takeFirst();
delete SelfRegisteringType::me();
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment