[new compiler] Cleanup object creator members
authorSimon Hausmann <simon.hausmann@digia.com>
Mon, 10 Feb 2014 19:12:18 +0000 (20:12 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Sun, 16 Feb 2014 21:08:40 +0000 (22:08 +0100)
Collect variables shared across recursive instances in a SharedData
structure, get rid of some other members.

Change-Id: I8d52fbb34820ce17d754b91c3fdee9e534a95753
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/qqmlcomponent.cpp
src/qml/qml/qqmlobjectcreator.cpp
src/qml/qml/qqmlobjectcreator_p.h

index 6abf805..b3d02cd 100644 (file)
@@ -992,7 +992,7 @@ QQmlComponentAttached *QQmlComponent::qmlAttachedProperties(QObject *obj)
     if (p->activeVME) { // XXX should only be allowed during begin
         a->add(&p->activeVME->componentAttached);
     } else if (p->activeObjectCreator) {
-        a->add(p->activeObjectCreator->componentAttached);
+        a->add(p->activeObjectCreator->componentAttachment());
     } else {
         QQmlData *d = QQmlData::get(obj);
         Q_ASSERT(d);
index eb6076b..2934c79 100644 (file)
@@ -80,70 +80,68 @@ static void removeBindingOnProperty(QObject *o, int index)
     if (binding) binding->destroy();
 }
 
-QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext, QQmlContextData *rootContext,
-                                   QFiniteStack<QQmlAbstractBinding *> *inheritedBindingStack, QFiniteStack<QQmlParserStatus *> *inheritedParserStatusStack)
-    : componentAttached(0)
-    , url(compiledData->url)
-    , engine(parentContext->engine)
-    , qmlUnit(compiledData->qmlUnit)
-    , jsUnit(compiledData->compilationUnit)
-    , parentContext(parentContext)
-    , creationContext(creationContext)
-    , context(0)
+QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext)
+    : compiledData(compiledData)
     , resolvedTypes(compiledData->resolvedTypes)
     , propertyCaches(compiledData->propertyCaches)
     , vmeMetaObjectData(compiledData->datas)
-    , allCreatedBindings(0)
-    , allParserStatusCallbacks(0)
-    , ownBindingAndParserStatusStacks(false)
-    , compiledData(compiledData)
-    , rootContext(rootContext)
-    , _qobject(0)
-    , _scopeObject(0)
-    , _valueTypeProperty(0)
-    , _compiledObject(0)
-    , _ddata(0)
-    , _propertyCache(0)
-    , _vmeMetaObject(0)
-    , _qmlContext(0)
 {
+    init(parentContext);
+
+    sharedState = new SharedState;
+    sharedState.setFlag(); // We own it, so we must delete it
+    sharedState->componentAttached = 0;
+    sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount);
+    sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount);
+    sharedState->creationContext = creationContext;
+    sharedState->rootContext = 0;
+}
+
+QmlObjectCreator::QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, SharedState *inheritedSharedState)
+    : compiledData(compiledData)
+    , resolvedTypes(compiledData->resolvedTypes)
+    , propertyCaches(compiledData->propertyCaches)
+    , vmeMetaObjectData(compiledData->datas)
+{
+    init(parentContext);
+
+    sharedState = inheritedSharedState;
+}
+
+void QmlObjectCreator::init(QQmlContextData *providedParentContext)
+{
+    parentContext = providedParentContext;
+    engine = parentContext->engine;
+
     if (!compiledData->isInitialized())
         compiledData->initialize(engine);
 
-    componentAttachedImpl = 0;
-    componentAttached = &componentAttachedImpl;
-
-    if (inheritedBindingStack) {
-        Q_ASSERT(rootContext);
-        Q_ASSERT(inheritedParserStatusStack);
-        allCreatedBindings = inheritedBindingStack;
-        allParserStatusCallbacks = inheritedParserStatusStack;
-        ownBindingAndParserStatusStacks = false;
-    } else {
-        ownBindingAndParserStatusStacks = true;
-        allCreatedBindings = new QFiniteStack<QQmlAbstractBinding*>;
-        allCreatedBindings->allocate(compiledData->totalBindingsCount);
-        allParserStatusCallbacks = new QFiniteStack<QQmlParserStatus*>;
-        allParserStatusCallbacks->allocate(compiledData->totalParserStatusCount);
-    }
+    qmlUnit = compiledData->qmlUnit;
+    context = 0;
+    _qobject = 0;
+    _scopeObject = 0;
+    _valueTypeProperty = 0;
+    _compiledObject = 0;
+    _ddata = 0;
+    _propertyCache = 0;
+    _vmeMetaObject = 0;
+    _qmlContext = 0;
 }
 
 QmlObjectCreator::~QmlObjectCreator()
 {
-    if (ownBindingAndParserStatusStacks) {
-        for (int i = 0; i < allCreatedBindings->count(); ++i) {
-            QQmlAbstractBinding *b = allCreatedBindings->at(i);
+    if (sharedState.flag()) {
+        for (int i = 0; i < sharedState->allCreatedBindings.count(); ++i) {
+            QQmlAbstractBinding *b = sharedState->allCreatedBindings.at(i);
             if (b)
                 b->m_mePtr = 0;
         }
-        for (int i = 0; i < allParserStatusCallbacks->count(); ++i) {
-            QQmlParserStatus *ps = allParserStatusCallbacks->at(i);
+        for (int i = 0; i < sharedState->allParserStatusCallbacks.count(); ++i) {
+            QQmlParserStatus *ps = sharedState->allParserStatusCallbacks.at(i);
             if (ps)
                 ps->d = 0;
         }
-
-        delete allCreatedBindings;
-        delete allParserStatusCallbacks;
+        delete sharedState.data();
     }
 }
 
@@ -151,9 +149,6 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
 {
     int objectToCreate;
 
-    Q_ASSERT(!ownBindingAndParserStatusStacks || allCreatedBindings->isEmpty());
-    Q_ASSERT(!ownBindingAndParserStatusStacks || allParserStatusCallbacks->isEmpty());
-
     if (subComponentIndex == -1) {
         objectIndexToId = compiledData->objectIndexToIdForRoot;
         objectToCreate = qmlUnit->indexOfRootObject;
@@ -171,9 +166,9 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
     context->imports->addref();
     context->setParent(parentContext);
 
-    if (!rootContext) {
-        rootContext = context;
-        rootContext->isRootObjectInCreation = true;
+    if (!sharedState->rootContext) {
+        sharedState->rootContext = context;
+        sharedState->rootContext->isRootObjectInCreation = true;
     }
 
     QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count());
@@ -197,8 +192,8 @@ QObject *QmlObjectCreator::create(int subComponentIndex, QObject *parent)
             QQmlScriptData *s = compiledData->scripts.at(i);
             scripts->putIndexed(i, s->scriptValueForContext(context));
         }
-    } else if (creationContext) {
-        context->importedScripts = creationContext->importedScripts;
+    } else if (sharedState->creationContext) {
+        context->importedScripts = sharedState->creationContext->importedScripts;
     }
 
     QObject *instance = createInstance(objectToCreate, parent);
@@ -302,7 +297,7 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
         QString string = binding->valueAsString(&qmlUnit->header);
         // Encoded dir-separators defeat QUrl processing - decode them first
         string.replace(QLatin1String("%2f"), QLatin1String("/"), Qt::CaseInsensitive);
-        QUrl value = string.isEmpty() ? QUrl() : this->url.resolved(QUrl(string));
+        QUrl value = string.isEmpty() ? QUrl() : compiledData->url.resolved(QUrl(string));
         // Apply URL interceptor
         if (engine->urlInterceptor())
             value = engine->urlInterceptor()->intercept(value, QQmlAbstractUrlInterceptor::UrlString);
@@ -497,7 +492,7 @@ void QmlObjectCreator::setPropertyValue(QQmlPropertyData *property, const QV4::C
         } else if (property->propType == qMetaTypeId<QList<QUrl> >()) {
             Q_ASSERT(binding->type == QV4::CompiledData::Binding::Type_String);
             QString urlString = binding->valueAsString(&qmlUnit->header);
-            QUrl u = urlString.isEmpty() ? QUrl() : this->url.resolved(QUrl(urlString));
+            QUrl u = urlString.isEmpty() ? QUrl() : compiledData->url.resolved(QUrl(urlString));
             QList<QUrl> value;
             value.append(u);
             argv[0] = reinterpret_cast<void *>(&value);
@@ -745,7 +740,7 @@ bool QmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4:
         removeBindingOnProperty(_bindingTarget, property->coreIndex);
 
     if (binding->type == QV4::CompiledData::Binding::Type_Script) {
-        QV4::Function *runtimeFunction = jsUnit->runtimeFunctions[binding->value.compiledScriptIndex];
+        QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex];
 
         QV4::Scope scope(_qmlContext);
         QV4::ScopedFunctionObject function(scope, QV4::FunctionObject::creatScriptFunction(_qmlContext, runtimeFunction));
@@ -783,8 +778,8 @@ bool QmlObjectCreator::setPropertyBinding(QQmlPropertyData *property, const QV4:
                 qmlBinding->addToObject();
             }
 
-            allCreatedBindings->push(qmlBinding);
-            qmlBinding->m_mePtr = &allCreatedBindings->top();
+            sharedState->allCreatedBindings.push(qmlBinding);
+            qmlBinding->m_mePtr = &sharedState->allCreatedBindings.top();
         }
         return true;
     }
@@ -909,7 +904,7 @@ void QmlObjectCreator::setupFunctions()
 
     const quint32 *functionIdx = _compiledObject->functionOffsetTable();
     for (quint32 i = 0; i < _compiledObject->nFunctions; ++i, ++functionIdx) {
-        QV4::Function *runtimeFunction = jsUnit->runtimeFunctions[*functionIdx];
+        QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[*functionIdx];
         const QString name = runtimeFunction->name->toQString();
 
         QQmlPropertyData *property = _propertyCache->property(name, _qobject, context);
@@ -924,7 +919,7 @@ void QmlObjectCreator::setupFunctions()
 void QmlObjectCreator::recordError(const QV4::CompiledData::Location &location, const QString &description)
 {
     QQmlError error;
-    error.setUrl(url);
+    error.setUrl(compiledData->url);
     error.setLine(location.line);
     error.setColumn(location.column);
     error.setDescription(description);
@@ -964,10 +959,10 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
 
             customParser = type->customParser();
 
-            if (rootContext->isRootObjectInCreation) {
+            if (sharedState->rootContext->isRootObjectInCreation) {
                 QQmlData *ddata = QQmlData::get(instance, /*create*/true);
                 ddata->rootObjectInCreation = true;
-                rootContext->isRootObjectInCreation = false;
+                sharedState->rootContext->isRootObjectInCreation = false;
             }
         } else {
             Q_ASSERT(typeRef->component);
@@ -976,8 +971,7 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
                 recordError(obj->location, tr("Composite Singleton Type %1 is not creatable").arg(stringAt(obj->inheritedTypeNameIndex)));
                 return 0;
             }
-            QmlObjectCreator subCreator(context, typeRef->component, creationContext, rootContext, allCreatedBindings, allParserStatusCallbacks);
-            subCreator.componentAttached = componentAttached;
+            QmlObjectCreator subCreator(context, typeRef->component, sharedState.data());
             instance = subCreator.create();
             if (!instance) {
                 errors += subCreator.errors;
@@ -1009,8 +1003,8 @@ QObject *QmlObjectCreator::createInstance(int index, QObject *parent)
 
     if (parserStatus) {
         parserStatus->classBegin();
-        allParserStatusCallbacks->push(parserStatus);
-        parserStatus->d = &allParserStatusCallbacks->top();
+        sharedState->allParserStatusCallbacks.push(parserStatus);
+        parserStatus->d = &sharedState->allParserStatusCallbacks.top();
     }
 
     QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(index);
@@ -1056,11 +1050,11 @@ QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrup
     QQmlTrace trace("VME Binding Enable");
     trace.event("begin binding eval");
 
-    while (!allCreatedBindings->isEmpty()) {
+    while (!sharedState->allCreatedBindings.isEmpty()) {
         if (interrupt.shouldInterrupt())
             return 0;
 
-        QQmlAbstractBinding *b = allCreatedBindings->pop();
+        QQmlAbstractBinding *b = sharedState->allCreatedBindings.pop();
         if (!b)
             continue;
         b->m_mePtr = 0;
@@ -1074,8 +1068,8 @@ QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrup
 
     if (true /* ### componentCompleteEnabled()*/) { // the qml designer does the component complete later
         QQmlTrace trace("VME Component Complete");
-        while (!allParserStatusCallbacks->isEmpty()) {
-            QQmlParserStatus *status = allParserStatusCallbacks->pop();
+        while (!sharedState->allParserStatusCallbacks.isEmpty()) {
+            QQmlParserStatus *status = sharedState->allParserStatusCallbacks.pop();
 
             if (status && status->d) {
                 status->d = 0;
@@ -1102,8 +1096,8 @@ QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrup
 
     {
     QQmlTrace trace("VME Component.onCompleted Callbacks");
-    while (componentAttachedImpl) {
-        QQmlComponentAttached *a = componentAttachedImpl;
+    while (sharedState->componentAttached) {
+        QQmlComponentAttached *a = sharedState->componentAttached;
         a->rem();
         QQmlData *d = QQmlData::get(a->parent());
         Q_ASSERT(d);
@@ -1117,7 +1111,7 @@ QQmlContextData *QmlObjectCreator::finalize(QQmlInstantiationInterrupt &interrup
     }
     }
 
-    return rootContext;
+    return sharedState->rootContext;
 }
 
 bool QmlObjectCreator::populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty)
index 68f2eae..70b12e5 100644 (file)
@@ -57,15 +57,16 @@ class QQmlInstantiationInterrupt;
 class QmlObjectCreator
 {
     Q_DECLARE_TR_FUNCTIONS(QmlObjectCreator)
+    struct SharedState;
 public:
-    QmlObjectCreator(QQmlContextData *contextData, QQmlCompiledData *compiledData, QQmlContextData *creationContext, QQmlContextData *rootContext = 0,
-                     QFiniteStack<QQmlAbstractBinding*> *inheritedBindingStack = 0, QFiniteStack<QQmlParserStatus*> *inheritedParserStatusStack = 0);
+    QmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext);
     ~QmlObjectCreator();
 
     QObject *create(int subComponentIndex = -1, QObject *parent = 0);
     QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
 
-    QQmlComponentAttached **componentAttached;
+    QQmlComponentAttached **componentAttachment() { return &sharedState->componentAttached; }
+
     QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
 
     QList<QQmlError> errors;
@@ -73,6 +74,10 @@ public:
     QQmlContextData *parentContextData() const { return parentContext; }
 
 private:
+    QmlObjectCreator(QQmlContextData *contextData, QQmlCompiledData *compiledData, SharedState *inheritedSharedState);
+
+    void init(QQmlContextData *parentContext);
+
     QObject *createInstance(int index, QObject *parent = 0);
 
     bool populateInstance(int index, QObject *instance, QQmlRefPointer<QQmlPropertyCache> cache, QObject *bindingTarget, QQmlPropertyData *valueTypeProperty);
@@ -85,23 +90,24 @@ private:
     QString stringAt(int idx) const { return qmlUnit->header.stringAt(idx); }
     void recordError(const QV4::CompiledData::Location &location, const QString &description);
 
-    QUrl url;
+    struct SharedState {
+        QQmlContextData *rootContext;
+        QQmlContextData *creationContext;
+        QFiniteStack<QQmlAbstractBinding*> allCreatedBindings;
+        QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
+        QQmlComponentAttached *componentAttached;
+    };
+
     QQmlEngine *engine;
+    QQmlCompiledData *compiledData;
     const QV4::CompiledData::QmlUnit *qmlUnit;
-    const QV4::CompiledData::CompilationUnit *jsUnit;
     QQmlContextData *parentContext;
-    QQmlContextData *creationContext;
     QQmlContextData *context;
-    const QHash<int, QQmlCompiledData::TypeReference*> resolvedTypes;
-    const QVector<QQmlPropertyCache *> propertyCaches;
-    const QVector<QByteArray> vmeMetaObjectData;
+    const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
+    const QVector<QQmlPropertyCache *> &propertyCaches;
+    const QVector<QByteArray> &vmeMetaObjectData;
     QHash<int, int> objectIndexToId;
-    QFiniteStack<QQmlAbstractBinding*> *allCreatedBindings;
-    QFiniteStack<QQmlParserStatus*> *allParserStatusCallbacks;
-    bool ownBindingAndParserStatusStacks;
-    QQmlCompiledData *compiledData;
-    QQmlContextData *rootContext;
-    QQmlComponentAttached *componentAttachedImpl;
+    QFlagPointer<SharedState> sharedState;
 
     QObject *_qobject;
     QObject *_scopeObject;