diff options
author | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-05-24 21:26:33 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@theqtcompany.com> | 2016-05-24 21:50:29 +0200 |
commit | 0837453ef90f5d5f569702aa1c7620648dae2c00 (patch) | |
tree | 43a35f937dfcca3f467d4deafe2800d01f0859da /src | |
parent | 9ff09fb283cd130fb717769b44f54bfbb28efd8a (diff) | |
parent | 0ba6dffd96a0dda8e3938b09395075c19e46644b (diff) |
Merge remote-tracking branch 'origin/dev' into HEAD
Change-Id: If91e0e28d004f1db978dcab393f189743bb69cd5
Diffstat (limited to 'src')
68 files changed, 312 insertions, 391 deletions
diff --git a/src/imports/builtins/builtins.pro b/src/imports/builtins/builtins.pro new file mode 100644 index 0000000000..112555b6de --- /dev/null +++ b/src/imports/builtins/builtins.pro @@ -0,0 +1,19 @@ +TEMPLATE = aux + +QMLTYPEFILE = builtins.qmltypes + +# install rule +builtins.files = $$QMLTYPEFILE +builtins.path = $$[QT_INSTALL_QML] +INSTALLS += builtins + +# copy to build directory +!prefix_build: COPIES += builtins + +# qmltypes target +!cross_compile:if(build_pass|!debug_and_release) { + qtPrepareTool(QMLPLUGINDUMP, qmlplugindump) + + qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE + QMAKE_EXTRA_TARGETS += qmltypes +} diff --git a/src/imports/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes index cca1c20d54..cca1c20d54 100644 --- a/src/imports/builtins.qmltypes +++ b/src/imports/builtins/builtins.qmltypes diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 67a357f909..9e3cdf3f42 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ + builtins \ qtqml \ folderlistmodel \ localstorage \ @@ -22,35 +23,3 @@ qtHaveModule(quick) { } qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel - - -QMLTYPEFILE = builtins.qmltypes - -# install rule -builtins.files = $$QMLTYPEFILE -builtins.path = $$[QT_INSTALL_QML] -INSTALLS += builtins - -# copy to build directory -!force_independent:if(!debug_and_release|!build_all|CONFIG(release, debug|release)) { - defineReplace(qmlModStripSrcDir) { - return($$relative_path($$1, $$_PRO_FILE_PWD_)) - } - - qmltypes2build.input = QMLTYPEFILE - qmltypes2build.output = $$[QT_INSTALL_QML]/${QMAKE_FUNC_FILE_IN_qmlModStripSrcDir} - !contains(TEMPLATE, vc.*): qmltypes2build.variable_out = PRE_TARGETDEPS - qmltypes2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} - qmltypes2build.name = COPY ${QMAKE_FILE_IN} - qmltypes2build.CONFIG = no_link no_clean - - QMAKE_EXTRA_COMPILERS += qmltypes2build -} - -# qmltypes target -!cross_compile:if(build_pass|!debug_and_release) { - qtPrepareTool(QMLPLUGINDUMP, qmlplugindump) - - qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE - QMAKE_EXTRA_TARGETS += qmltypes -} diff --git a/src/particles/qquickv4particledata_p.h b/src/particles/qquickv4particledata_p.h index 0d88f0f9cc..437491ff42 100644 --- a/src/particles/qquickv4particledata_p.h +++ b/src/particles/qquickv4particledata_p.h @@ -52,7 +52,7 @@ // #include <private/qv8engine_p.h> - +#include <private/qv4persistent_p.h> #include <private/qv4value_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index 9e1c8af3e6..a639cfb71e 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) -Q_QML_IMPORT_DEBUG_PLUGIN(QQuickProfilerAdapterFactory) QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index a6d93e85ae..cbde86e389 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -81,8 +81,6 @@ QT_BEGIN_NAMESPACE */ Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection) -Q_QML_IMPORT_DEBUG_PLUGIN(QTcpServerConnectionFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QLocalClientConnectionFactory) const int protocolVersion = 1; diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h index 4b94e79d40..9bcd63127a 100644 --- a/src/qml/animations/qanimationgroupjob_p.h +++ b/src/qml/animations/qanimationgroupjob_p.h @@ -52,6 +52,7 @@ // #include "private/qabstractanimationjob_p.h" +#include <QtCore/qdebug.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index 097d072734..0d98aa6e54 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -137,7 +137,6 @@ bool QQmlTypeCompiler::compile() customParsers.insert(it.key(), customParser); } - compiledData->metaObjects.reserve(document->objects.count()); compiledData->propertyCaches.reserve(document->objects.count()); { @@ -336,32 +335,17 @@ int QQmlTypeCompiler::rootObjectIndex() const return document->indexOfRootObject; } -void QQmlTypeCompiler::setPropertyCaches(const QVector<QQmlPropertyCache *> &caches) +void QQmlTypeCompiler::setPropertyCaches(const QQmlPropertyCacheVector &caches) { compiledData->propertyCaches = caches; Q_ASSERT(caches.count() >= document->indexOfRootObject); - if (compiledData->rootPropertyCache) - compiledData->rootPropertyCache->release(); - compiledData->rootPropertyCache = caches.at(document->indexOfRootObject); - compiledData->rootPropertyCache->addref(); } -const QVector<QQmlPropertyCache *> &QQmlTypeCompiler::propertyCaches() const +const QQmlPropertyCacheVector &QQmlTypeCompiler::propertyCaches() const { return compiledData->propertyCaches; } -void QQmlTypeCompiler::setVMEMetaObjects(const QVector<QByteArray> &metaObjects) -{ - Q_ASSERT(compiledData->metaObjects.isEmpty()); - compiledData->metaObjects = metaObjects; -} - -QVector<QByteArray> *QQmlTypeCompiler::vmeMetaObjects() const -{ - return &compiledData->metaObjects; -} - QHash<int, int> *QQmlTypeCompiler::objectIndexToIdForRoot() { return &compiledData->objectIndexToIdForRoot; @@ -435,7 +419,7 @@ QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlTypeCompiler *typeCompile QQmlPropertyCacheCreator::~QQmlPropertyCacheCreator() { for (int i = 0; i < propertyCaches.count(); ++i) - if (QQmlPropertyCache *cache = propertyCaches.at(i)) + if (QQmlPropertyCache *cache = propertyCaches.at(i).data()) cache->release(); propertyCaches.clear(); } @@ -443,12 +427,10 @@ QQmlPropertyCacheCreator::~QQmlPropertyCacheCreator() bool QQmlPropertyCacheCreator::buildMetaObjects() { propertyCaches.resize(qmlObjects.count()); - vmeMetaObjects.resize(qmlObjects.count()); if (!buildMetaObjectRecursively(compiler->rootObjectIndex(), /*referencing object*/-1, /*instantiating binding*/0)) return false; - compiler->setVMEMetaObjects(vmeMetaObjects); compiler->setPropertyCaches(propertyCaches); propertyCaches.clear(); @@ -463,7 +445,7 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r QQmlPropertyData *instantiatingProperty = 0; if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty) { Q_ASSERT(referencingObjectIndex >= 0); - QQmlPropertyCache *parentCache = propertyCaches.at(referencingObjectIndex); + QQmlPropertyCache *parentCache = propertyCaches.at(referencingObjectIndex).data(); Q_ASSERT(parentCache); Q_ASSERT(instantiatingBinding->propertyNameIndex != 0); @@ -494,7 +476,7 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r // because interceptors can't go to the shared value type instances. if (instantiatingProperty && QQmlValueTypeFactory::isValueType(instantiatingProperty->propType)) { needVMEMetaObject = false; - if (!ensureMetaObject(referencingObjectIndex)) + if (!ensureVMEMetaObject(referencingObjectIndex)) return false; } break; @@ -557,12 +539,14 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r if (!createMetaObject(objectIndex, obj, baseTypeCache)) return false; } else { + if (QQmlPropertyCache *oldCache = propertyCaches.at(objectIndex).data()) + oldCache->release(); propertyCaches[objectIndex] = baseTypeCache; baseTypeCache->addref(); } } - if (propertyCaches.at(objectIndex)) { + if (propertyCaches.at(objectIndex).data()) { for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) if (binding->type >= QV4::CompiledData::Binding::Type_Object) { if (!buildMetaObjectRecursively(binding->value.objectIndex, objectIndex, binding)) @@ -573,9 +557,10 @@ bool QQmlPropertyCacheCreator::buildMetaObjectRecursively(int objectIndex, int r return true; } -bool QQmlPropertyCacheCreator::ensureMetaObject(int objectIndex) +bool QQmlPropertyCacheCreator::ensureVMEMetaObject(int objectIndex) { - if (!vmeMetaObjects.at(objectIndex).isEmpty()) + const bool willCreateVMEMetaObject = propertyCaches.at(objectIndex).flag(); + if (willCreateVMEMetaObject) return true; const QmlIR::Object *obj = qmlObjects.at(objectIndex); QQmlCompiledData::TypeReference *typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex); @@ -589,7 +574,12 @@ bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QmlIR::Ob QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(obj->propertyCount() + obj->aliasCount(), obj->functionCount() + obj->propertyCount() + obj->aliasCount() + obj->signalCount(), obj->signalCount() + obj->propertyCount() + obj->aliasCount()); + + if (QQmlPropertyCache *oldCache = propertyCaches.at(objectIndex).data()) + oldCache->release(); propertyCaches[objectIndex] = cache; + // Indicate that this object also needs a VME meta-object at run-time + propertyCaches[objectIndex].setFlag(); struct TypeData { QV4::CompiledData::Property::Type dtype; @@ -659,10 +649,6 @@ bool QQmlPropertyCacheCreator::createMetaObject(int objectIndex, const QmlIR::Ob COMPILE_EXCEPTION(a, tr("Cannot override FINAL property")); } - typedef QQmlVMEMetaData VMD; - - vmeMetaObjects[objectIndex] = QByteArray(sizeof(QQmlVMEMetaData) + obj->aliasCount() * sizeof(VMD::AliasData), 0); - int effectivePropertyIndex = cache->propertyIndexCacheStart; int effectiveMethodIndex = cache->methodIndexCacheStart; @@ -878,7 +864,7 @@ bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclaratio { for (int objectIndex = 0; objectIndex < qmlObjects.count(); ++objectIndex) { const QmlIR::Object * const obj = qmlObjects.at(objectIndex); - QQmlPropertyCache *cache = propertyCaches.at(objectIndex); + QQmlPropertyCache *cache = propertyCaches.at(objectIndex).data(); if (!cache) continue; if (QQmlCustomParser *customParser = customParsers.value(obj->inheritedTypeNameIndex)) { @@ -1086,7 +1072,7 @@ QQmlEnumTypeResolver::QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler) bool QQmlEnumTypeResolver::resolveEnumBindings() { for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i); + QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); if (!propertyCache) continue; const QmlIR::Object *obj = qmlObjects.at(i); @@ -1272,7 +1258,7 @@ QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler) void QQmlAliasAnnotator::annotateBindingsToAliases() { for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i); + QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); if (!propertyCache) continue; @@ -1304,7 +1290,7 @@ void QQmlScriptStringScanner::scan() { const int scriptStringMetaType = qMetaTypeId<QQmlScriptString>(); for (int i = 0; i < qmlObjects.count(); ++i) { - QQmlPropertyCache *propertyCache = propertyCaches.at(i); + QQmlPropertyCache *propertyCache = propertyCaches.at(i).data(); if (!propertyCache) continue; @@ -1341,7 +1327,6 @@ QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(QQmlTypeCompiler *t , _objectIndexToIdInScope(0) , resolvedTypes(typeCompiler->resolvedTypes()) , propertyCaches(typeCompiler->propertyCaches()) - , vmeMetaObjectData(typeCompiler->vmeMetaObjects()) , objectIndexToIdForRoot(typeCompiler->objectIndexToIdForRoot()) , objectIndexToIdPerComponent(typeCompiler->objectIndexToIdPerComponent()) { @@ -1366,7 +1351,7 @@ void QQmlComponentAndAliasResolver::findAndRegisterImplicitComponents(const QmlI if (targetType->metaObject() == &QQmlComponent::staticMetaObject) continue; } else if (tr->component) { - if (tr->component->rootPropertyCache->firstCppMetaObject() == &QQmlComponent::staticMetaObject) + if (tr->component->rootPropertyCache()->firstCppMetaObject() == &QQmlComponent::staticMetaObject) continue; } @@ -1436,7 +1421,7 @@ bool QQmlComponentAndAliasResolver::resolve() const int objCountWithoutSynthesizedComponents = qmlObjects->count(); for (int i = 0; i < objCountWithoutSynthesizedComponents; ++i) { const QmlIR::Object *obj = qmlObjects->at(i); - QQmlPropertyCache *cache = propertyCaches.at(i); + QQmlPropertyCache *cache = propertyCaches.at(i).data(); if (obj->inheritedTypeNameIndex == 0 && !cache) continue; @@ -1554,12 +1539,11 @@ bool QQmlComponentAndAliasResolver::resolveAliases() foreach (int objectIndex, _objectsWithAliases) { const QmlIR::Object *obj = qmlObjects->at(objectIndex); - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex); + QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); Q_ASSERT(propertyCache); int effectiveSignalIndex = propertyCache->signalHandlerIndexCacheStart + propertyCache->propertyIndexCache.count(); int effectivePropertyIndex = propertyCache->propertyIndexCacheStart + propertyCache->propertyIndexCache.count(); - int effectiveAliasIndex = 0; int aliasIndex = 0; for (QmlIR::Alias *alias = obj->firstAlias(); alias; alias = alias->next, ++aliasIndex) { @@ -1587,7 +1571,6 @@ bool QQmlComponentAndAliasResolver::resolveAliases() property = QStringRef(&aliasPropertyValue, 0, aliasPropertyValue.length()); int propIdx = -1; - int notifySignal = -1; int type = 0; bool writable = false; bool resettable = false; @@ -1607,7 +1590,7 @@ bool QQmlComponentAndAliasResolver::resolveAliases() alias->flags |= QV4::CompiledData::Alias::AliasPointsToPointerObject; propertyFlags |= QQmlPropertyData::IsQObjectDerived; } else { - QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex); + QQmlPropertyCache *targetCache = propertyCaches.at(targetObjectIndex).data(); Q_ASSERT(targetCache); QmlIR::PropertyResolver resolver(targetCache); @@ -1622,7 +1605,6 @@ bool QQmlComponentAndAliasResolver::resolveAliases() writable = targetProperty->isWritable(); resettable = targetProperty->isResettable(); - notifySignal = targetProperty->notifyIndex; if (!subProperty.isEmpty()) { const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(type); @@ -1662,15 +1644,6 @@ bool QQmlComponentAndAliasResolver::resolveAliases() } alias->encodedMetaPropertyIndex = propIdx; - QQmlVMEMetaData::AliasData aliasData = { notifySignal }; - - typedef QQmlVMEMetaData VMD; - QByteArray &dynamicData = (*vmeMetaObjectData)[objectIndex]; - Q_ASSERT(!dynamicData.isEmpty()); - VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); - *(vmd->aliasData() + effectiveAliasIndex++) = aliasData; - - Q_ASSERT(dynamicData.isDetached()); if (!(alias->flags & QV4::CompiledData::Property::IsReadOnly) && writable) propertyFlags |= QQmlPropertyData::IsWritable; @@ -1754,7 +1727,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD return validateObject(componentBinding->value.objectIndex, componentBinding); } - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex); + QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); if (!propertyCache) return true; @@ -2348,7 +2321,7 @@ bool QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, co } else if (property->isQList()) { const int listType = enginePrivate->listType(property->propType); if (!QQmlMetaType::isInterface(listType)) { - QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex); + QQmlPropertyCache *source = propertyCaches.at(binding->value.objectIndex).data(); if (!canCoerce(listType, source)) { recordError(binding->valueLocation, tr("Cannot assign object to list property \"%1\"").arg(propertyName)); return false; @@ -2375,7 +2348,7 @@ bool QQmlPropertyValidator::validateObjectBinding(QQmlPropertyData *property, co bool isAssignable = false; // Determine isAssignable value if (propertyMetaObject) { - QQmlPropertyCache *c = propertyCaches.at(binding->value.objectIndex); + QQmlPropertyCache *c = propertyCaches.at(binding->value.objectIndex).data(); while (c && !isAssignable) { isAssignable |= c == propertyMetaObject; c = c->parent(); @@ -2435,7 +2408,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject, const QHash<int, i const QmlIR::Object *obj = qmlObjects.at(objectIndex); m.name = stringAt(obj->idIndex); m.idIndex = idIt.value(); - m.type = propertyCaches.at(objectIndex); + m.type = propertyCaches.at(objectIndex).data(); QQmlCompiledData::TypeReference *tref = resolvedTypes.value(obj->inheritedTypeNameIndex); if (tref && tref->isFullyDynamicType) @@ -2444,7 +2417,7 @@ bool QQmlJSCodeGenerator::compileComponent(int contextObject, const QHash<int, i idMapping << m; } } - v4CodeGen->beginContextScope(idMapping, propertyCaches.at(contextObject)); + v4CodeGen->beginContextScope(idMapping, propertyCaches.at(contextObject).data()); if (!compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject)) return false; @@ -2459,7 +2432,7 @@ bool QQmlJSCodeGenerator::compileJavaScriptCodeInObjectsRecursively(int objectIn QmlIR::Object *object = qmlObjects.at(objectIndex); if (object->functionsAndExpressions->count > 0) { - QQmlPropertyCache *scopeObject = propertyCaches.at(scopeObjectIndex); + QQmlPropertyCache *scopeObject = propertyCaches.at(scopeObjectIndex).data(); v4CodeGen->beginObjectScope(scopeObject); QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile; @@ -2512,7 +2485,7 @@ void QQmlDefaultPropertyMerger::mergeDefaultProperties() void QQmlDefaultPropertyMerger::mergeDefaultProperties(int objectIndex) { - QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex); + QQmlPropertyCache *propertyCache = propertyCaches.at(objectIndex).data(); if (!propertyCache) return; diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 273ba01a88..968902dae1 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -99,10 +99,8 @@ public: QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes(); QList<QmlIR::Object*> *qmlObjects(); int rootObjectIndex() const; - void setPropertyCaches(const QVector<QQmlPropertyCache *> &caches); - const QVector<QQmlPropertyCache *> &propertyCaches() const; - void setVMEMetaObjects(const QVector<QByteArray> &metaObjects); - QVector<QByteArray> *vmeMetaObjects() const; + void setPropertyCaches(const QQmlPropertyCacheVector &caches); + const QQmlPropertyCacheVector &propertyCaches() const; QHash<int, int> *objectIndexToIdForRoot(); QHash<int, QHash<int, int> > *objectIndexToIdPerComponent(); QHash<int, QBitArray> *customParserBindings(); @@ -149,15 +147,14 @@ public: bool buildMetaObjects(); protected: bool buildMetaObjectRecursively(int objectIndex, int referencingObjectIndex, const QV4::CompiledData::Binding *instantiatingBinding); - bool ensureMetaObject(int objectIndex); + bool ensureVMEMetaObject(int objectIndex); bool createMetaObject(int objectIndex, const QmlIR::Object *obj, QQmlPropertyCache *baseTypeCache); QQmlEnginePrivate *enginePrivate; const QList<QmlIR::Object*> &qmlObjects; const QQmlImports *imports; QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes; - QVector<QByteArray> vmeMetaObjects; - QVector<QQmlPropertyCache*> propertyCaches; + QQmlPropertyCacheVector propertyCaches; }; // "Converts" signal expressions to full-fleged function declarations with @@ -181,7 +178,7 @@ private: const QHash<int, QQmlCustomParser*> &customParsers; const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; const QSet<QString> &illegalNames; - const QVector<QQmlPropertyCache*> &propertyCaches; + const QQmlPropertyCacheVector &propertyCaches; }; // ### This will go away when the codegen resolves all enums to constant expressions @@ -208,7 +205,7 @@ private: const QList<QmlIR::Object*> &qmlObjects; - const QVector<QQmlPropertyCache *> propertyCaches; + const QQmlPropertyCacheVector propertyCaches; const QQmlImports *imports; QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes; }; @@ -236,7 +233,7 @@ public: void annotateBindingsToAliases(); private: const QList<QmlIR::Object*> &qmlObjects; - const QVector<QQmlPropertyCache *> propertyCaches; + const QQmlPropertyCacheVector propertyCaches; }; class QQmlScriptStringScanner : public QQmlCompilePass @@ -248,7 +245,7 @@ public: private: const QList<QmlIR::Object*> &qmlObjects; - const QVector<QQmlPropertyCache *> propertyCaches; + const QQmlPropertyCacheVector propertyCaches; }; class QQmlComponentAndAliasResolver : public QQmlCompilePass @@ -282,8 +279,7 @@ protected: QList<int> _objectsWithAliases; QHash<int, QQmlCompiledData::TypeReference*> *resolvedTypes; - QVector<QQmlPropertyCache *> propertyCaches; - QVector<QByteArray> *vmeMetaObjectData; + QQmlPropertyCacheVector propertyCaches; QHash<int, int> *objectIndexToIdForRoot; QHash<int, QHash<int, int> > *objectIndexToIdPerComponent; }; @@ -312,7 +308,7 @@ private: const QV4::CompiledData::Unit *qmlUnit; const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; const QHash<int, QQmlCustomParser*> &customParsers; - const QVector<QQmlPropertyCache *> &propertyCaches; + const QQmlPropertyCacheVector &propertyCaches; const QHash<int, QHash<int, int> > objectIndexToIdPerComponent; QHash<int, QBitArray> *customParserBindingsPerObject; @@ -340,7 +336,7 @@ private: const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; const QHash<int, QQmlCustomParser*> &customParsers; const QList<QmlIR::Object*> &qmlObjects; - const QVector<QQmlPropertyCache *> &propertyCaches; + const QQmlPropertyCacheVector &propertyCaches; QmlIR::JSCodeGen * const v4CodeGen; }; @@ -355,7 +351,7 @@ private: void mergeDefaultProperties(int objectIndex); const QList<QmlIR::Object*> &qmlObjects; - const QVector<QQmlPropertyCache*> &propertyCaches; + const QQmlPropertyCacheVector &propertyCaches; }; class QQmlJavaScriptBindingExpressionSimplificationPass : public QQmlCompilePass, public QV4::IR::StmtVisitor diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index e6d1a218ad..23440e7529 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -54,14 +54,9 @@ QT_BEGIN_NAMESPACE // Connectors. We could add more plugins here, and distinguish by arguments to instance() Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugConnector) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebugServerFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlNativeDebugConnectorFactory) // Services Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugService) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory) int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7; diff --git a/src/qml/debugger/qqmldebugpluginmanager_p.h b/src/qml/debugger/qqmldebugpluginmanager_p.h index 2bcaf78972..8f52b65b17 100644 --- a/src/qml/debugger/qqmldebugpluginmanager_p.h +++ b/src/qml/debugger/qqmldebugpluginmanager_p.h @@ -74,15 +74,6 @@ QT_BEGIN_NAMESPACE #else // QT_NO_QML_DEBUGGER -#ifdef QT_STATIC -#define Q_QML_IMPORT_DEBUG_PLUGIN(className)\ - QT_END_NAMESPACE\ - Q_IMPORT_PLUGIN(className)\ - QT_BEGIN_NAMESPACE -#else -#define Q_QML_IMPORT_DEBUG_PLUGIN(className) -#endif // QT_STATIC - #define Q_QML_DEBUG_PLUGIN_LOADER(interfaceName)\ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, interfaceName##Loader,\ (interfaceName##Factory_iid, QLatin1String("/qmltooling")))\ diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf index 500754ead4..74b61fd6e1 100644 --- a/src/qml/doc/qtqml.qdocconf +++ b/src/qml/doc/qtqml.qdocconf @@ -4,7 +4,7 @@ project = QtQml description = Qt QML Reference Documentation version = $QT_VERSION -examplesinstallpath = qtdeclarative/qml +examplesinstallpath = qml qhp.projects = QtQml diff --git a/src/qml/jsapi/qjsengine.cpp b/src/qml/jsapi/qjsengine.cpp index 257dd357fd..09e8bbda55 100644 --- a/src/qml/jsapi/qjsengine.cpp +++ b/src/qml/jsapi/qjsengine.cpp @@ -50,6 +50,7 @@ #include "private/qv4runtime_p.h" #include <private/qqmlbuiltinfunctions_p.h> #include <private/qqmldebugconnector_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <QtCore/qdatetime.h> #include <QtCore/qmetaobject.h> diff --git a/src/qml/jsapi/qjsvalue.cpp b/src/qml/jsapi/qjsvalue.cpp index edb23d94db..4860908bd3 100644 --- a/src/qml/jsapi/qjsvalue.cpp +++ b/src/qml/jsapi/qjsvalue.cpp @@ -54,7 +54,7 @@ #include "private/qv8engine_p.h" #include <private/qv4mm_p.h> #include <private/qv4scopedvalue_p.h> - +#include <private/qv4qobjectwrapper_p.h> /*! \since 5.0 diff --git a/src/qml/jsapi/qjsvalue_p.h b/src/qml/jsapi/qjsvalue_p.h index 9caeccec9d..25afd9275c 100644 --- a/src/qml/jsapi/qjsvalue_p.h +++ b/src/qml/jsapi/qjsvalue_p.h @@ -56,7 +56,6 @@ #include <private/qv4value_p.h> #include <private/qv4string_p.h> #include <private/qv4engine_p.h> -#include <private/qv4object_p.h> #include <private/qflagpointer_p.h> #include <private/qv4mm_p.h> #include <private/qv4persistent_p.h> diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index f51f677636..2e6773a927 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -247,7 +247,7 @@ struct WithContext : public ExecutionContext V4_MANAGED(WithContext, ExecutionContext) }; -struct QmlContext : public ExecutionContext +struct Q_QML_EXPORT QmlContext : public ExecutionContext { V4_MANAGED(QmlContext, ExecutionContext) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 55ea1f91c3..d603a1982a 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -111,85 +111,8 @@ static ReturnedValue throwTypeError(CallContext *ctx) return ctx->engine()->throwTypeError(); } -const int MinimumStackSize = 256; // in kbytes - -QT_WARNING_PUSH -QT_WARNING_DISABLE_MSVC(4172) // MSVC 2015: warning C4172: returning address of local variable or temporary: dummy - -quintptr getStackLimit() -{ - quintptr stackLimit; -#if USE(PTHREADS) && !OS(QNX) -# if OS(DARWIN) - pthread_t thread_self = pthread_self(); - void *stackTop = pthread_get_stackaddr_np(thread_self); - stackLimit = reinterpret_cast<quintptr>(stackTop); - quintptr size = 0; - if (pthread_main_np()) { - rlimit limit; - getrlimit(RLIMIT_STACK, &limit); - size = limit.rlim_cur; - } else - size = pthread_get_stacksize_np(thread_self); - stackLimit -= size; -# elif defined(__hppa) - // On some architectures the stack grows upwards. All of these are rather exotic, so simply assume - // everything is fine there. - // Known examples: - // -HP PA-RISC - stackLimit = 0; - -# else - pthread_attr_t attr; -#if HAVE(PTHREAD_NP_H) && OS(FREEBSD) - // on FreeBSD pthread_attr_init() must be called otherwise getting the attrs crashes - if (pthread_attr_init(&attr) == 0 && pthread_attr_get_np(pthread_self(), &attr) == 0) { -#else - if (pthread_getattr_np(pthread_self(), &attr) == 0) { -#endif - void *stackBottom = Q_NULLPTR; - size_t stackSize = 0; - - pthread_attr_getstack(&attr, &stackBottom, &stackSize); - pthread_attr_destroy(&attr); - -# if defined(Q_OS_ANDROID) - // Bionic pretends that the main thread has a tiny stack; work around it - if (gettid() == getpid()) { - rlimit limit; - getrlimit(RLIMIT_STACK, &limit); - stackBottom = reinterpret_cast<void*>(reinterpret_cast<quintptr>(stackBottom) + stackSize - limit.rlim_cur); - } -# endif - - stackLimit = reinterpret_cast<quintptr>(stackBottom); - } else { - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024; - } - -# endif -// This is wrong. StackLimit is the currently committed stack size, not the real end. -// only way to get that limit is apparently by using VirtualQuery (Yuck) -//#elif OS(WINDOWS) -// PNT_TIB tib = (PNT_TIB)NtCurrentTeb(); -// stackLimit = static_cast<quintptr>(tib->StackLimit); -#else - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - // (Note: triggers warning C4172 as of MSVC 2015, returning address of local variable) - stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024; -#endif - - // 256k slack - return stackLimit + MinimumStackSize*1024; -} - -QT_WARNING_POP +#ifdef V4_BOOTSTRAP QJSEngine *ExecutionEngine::jsEngine() const { return v8Engine->publicEngine(); @@ -199,10 +122,14 @@ QQmlEngine *ExecutionEngine::qmlEngine() const { return v8Engine->engine(); } +#endif // V4_BOOTSTRAP + +qint32 ExecutionEngine::maxCallDepth = -1; ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) : current(0) , hasException(false) + , callDepth(0) , memoryManager(new QV4::MemoryManager(this)) , executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) @@ -219,6 +146,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , regExpCache(0) , m_multiplyWrappedQObjects(0) { + if (maxCallDepth == -1) { + bool ok = false; + maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); + if (!ok || maxCallDepth <= 0) { + maxCallDepth = 1234; + } + } + Q_ASSERT(maxCallDepth > 0); + MemoryManager::GCBlocker gcBlocker(memoryManager); if (!factory) { @@ -267,9 +203,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // set up stack limits jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value); - cStackLimit = getStackLimit(); - if (!recheckCStackLimits()) - qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize); identifierTable = new IdentifierTable(this); @@ -1103,22 +1036,6 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError() return error; } -bool ExecutionEngine::recheckCStackLimits() -{ - int dummy; -#ifdef Q_OS_WIN - // ### this is only required on windows, where we currently use heuristics to get the stack limit - if (cStackLimit - reinterpret_cast<quintptr>(&dummy) > 128*1024) - // we're more then 128k away from our stack limit, assume the thread has changed, and - // call getStackLimit -#endif - // this can happen after a thread change - cStackLimit = getStackLimit(); - - return (reinterpret_cast<quintptr>(&dummy) >= cStackLimit); -} - - // Variant conversion code typedef QSet<QV4::Heap::Object *> V4ObjectSet; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 57a5952a6d..933241ea27 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -58,6 +58,10 @@ #include "qv4runtimeapi_p.h" #include <private/qintrusivelist_p.h> +#ifndef V4_BOOTSTRAP +# include <private/qv8engine_p.h> +#endif + namespace WTF { class BumpPointerAllocator; class PageAllocation; @@ -82,15 +86,11 @@ namespace CompiledData { struct CompilationUnit; } -#define CHECK_STACK_LIMITS(v4) \ - if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast<quintptr>(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \ - else \ - return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded.")) - - struct Q_QML_EXPORT ExecutionEngine { private: + static qint32 maxCallDepth; + friend struct ExecutionContextSaver; friend struct ExecutionContext; friend struct Heap::ExecutionContext; @@ -99,6 +99,7 @@ public: Value *jsStackTop; quint32 hasException; + qint32 callDepth; MemoryManager *memoryManager; ExecutableAllocator *executableAllocator; @@ -108,7 +109,6 @@ public: ExecutionContext *currentContext; Value *jsStackLimit; - quintptr cStackLimit; Runtime runtime; @@ -142,8 +142,13 @@ public: Function *globalCode; +#ifdef V4_BOOTSTRAP QJSEngine *jsEngine() const; QQmlEngine *qmlEngine() const; +#else // !V4_BOOTSTRAP + QJSEngine *jsEngine() const { return v8Engine->publicEngine(); } + QQmlEngine *qmlEngine() const { return v8Engine->engine(); } +#endif // V4_BOOTSTRAP QV8Engine *v8Engine; enum JSObjects { @@ -440,8 +445,6 @@ public: InternalClass *newClass(const InternalClass &other); - bool recheckCStackLimits(); - // Exception handling Value *exceptionValue; StackTrace exceptionStackTrace; @@ -474,13 +477,19 @@ public: QV4::ReturnedValue metaTypeToJS(int type, const void *data); void assertObjectBelongsToEngine(const Heap::Base &baseObject); + + bool checkStackLimits(ReturnedValue &exception); }; // This is a trick to tell the code generators that functions taking a NoThrowContext won't // throw exceptions and therefore don't need a check after the call. +#ifndef V4_BOOTSTRAP struct NoThrowEngine : public ExecutionEngine { }; +#else +struct NoThrowEngine; +#endif inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context) @@ -526,7 +535,7 @@ inline Heap::QmlContext *ExecutionEngine::qmlContext() const if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer) ctx = parentContext(currentContext)->d(); - if (!ctx->outer) + if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer) return 0; while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext) @@ -562,7 +571,26 @@ inline void Value::mark(ExecutionEngine *e) o->mark(e); } +#define CHECK_STACK_LIMITS(v4) { ReturnedValue e; if ((v4)->checkStackLimits(e)) return e; } \ + ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); +struct ExecutionEngineCallDepthRecorder +{ + ExecutionEngine *ee; + + ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; } + ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; } +}; + +inline bool ExecutionEngine::checkStackLimits(ReturnedValue &exception) +{ + if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) { + exception = throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); + return true; + } + + return false; +} } // namespace QV4 diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp index 5528409b40..9fe8224736 100644 --- a/src/qml/jsruntime/qv4mathobject.cpp +++ b/src/qml/jsruntime/qv4mathobject.cpp @@ -86,18 +86,10 @@ Heap::MathObject::MathObject() m->defineDefaultProperty(QStringLiteral("tan"), QV4::MathObject::method_tan, 1); } -#ifdef Q_OS_ANDROID -// C++11's std::copysign is missing in the std namespace, so get it from the root namespace (math.h) static Q_ALWAYS_INLINE double copySign(double x, double y) { return ::copysign(x, y); } -#else // Ok, we have a proper C++11 standard library -static Q_ALWAYS_INLINE double copySign(double x, double y) -{ - return std::copysign(x, y); -} -#endif ReturnedValue MathObject::method_abs(CallContext *context) { diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 35fcd00eb7..c888f1e44c 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -561,7 +561,7 @@ void QObjectWrapper::setProperty(ExecutionEngine *engine, QObject *object, QQmlP } } -ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) +ReturnedValue QObjectWrapper::wrap_slowPath(ExecutionEngine *engine, QObject *object) { if (QQmlData::wasDeleted(object)) return QV4::Encode::null(); @@ -572,10 +572,7 @@ ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) Scope scope(engine); - if (ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isUndefined()) { - // We own the JS object - return ddata->jsWrapper.value(); - } else if (ddata->jsWrapper.isUndefined() && + if (ddata->jsWrapper.isUndefined() && (ddata->jsEngineId == engine->m_engineId || // We own the QObject ddata->jsEngineId == 0 || // No one owns the QObject !ddata->hasTaintedV4Object)) { // Someone else has used the QObject, but it isn't tainted diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 0186a8381a..d53bb88d20 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -146,8 +146,27 @@ protected: static ReturnedValue method_connect(CallContext *ctx); static ReturnedValue method_disconnect(CallContext *ctx); + +private: + static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object); }; +inline ReturnedValue QObjectWrapper::wrap(ExecutionEngine *engine, QObject *object) +{ + if (Q_LIKELY(!QQmlData::wasDeleted(object))) { + QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object)); + if (Q_LIKELY(priv->declarativeData)) { + auto ddata = static_cast<QQmlData *>(priv->declarativeData); + if (Q_LIKELY(ddata->jsEngineId == engine->m_engineId && !ddata->jsWrapper.isUndefined())) { + // We own the JS object + return ddata->jsWrapper.value(); + } + } + } + + return wrap_slowPath(engine, object); +} + struct QQmlValueTypeWrapper; struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index b7543692d5..8f377dd664 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include "qv4global_p.h" +#include "qv4engine_p.h" #include "qv4runtime_p.h" #ifndef V4_BOOTSTRAP #include "qv4object_p.h" diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index 807fbe2f0e..975d100ef4 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -65,6 +65,8 @@ QT_BEGIN_NAMESPACE +class QQmlAccessors; + #undef QV4_COUNT_RUNTIME_FUNCTIONS namespace QV4 { @@ -102,7 +104,6 @@ enum TypeHint { STRING_HINT }; - struct Q_QML_PRIVATE_EXPORT RuntimeHelpers { static ReturnedValue objectDefaultValue(const Object *object, int typeHint); static ReturnedValue toPrimitive(const Value &value, int typeHint); diff --git a/src/qml/jsruntime/qv4serialize.cpp b/src/qml/jsruntime/qv4serialize.cpp index f803f2fb06..14def49d0a 100644 --- a/src/qml/jsruntime/qv4serialize.cpp +++ b/src/qml/jsruntime/qv4serialize.cpp @@ -48,6 +48,7 @@ #include <private/qv4regexpobject_p.h> #include <private/qv4sequenceobject_p.h> #include <private/qv4objectproto_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 514bdafb48..a8d9b0fa71 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -56,11 +56,7 @@ #include "qv4global_p.h" #include <private/qv4heap_p.h> -/* We cannot rely on QT_POINTER_SIZE to be set correctly on host builds. In qmldevtools the Value objects - are only used to store primitives, never object pointers. So we can use the 64-bit encoding. */ -#ifdef V4_BOOTSTRAP -#define QV4_USE_64_BIT_VALUE_ENCODING -#elif QT_POINTER_SIZE == 8 +#if QT_POINTER_SIZE == 8 #define QV4_USE_64_BIT_VALUE_ENCODING #endif diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp index 743a11d31e..444c0a37e0 100644 --- a/src/qml/jsruntime/qv4variantobject.cpp +++ b/src/qml/jsruntime/qv4variantobject.cpp @@ -42,6 +42,7 @@ #include "qv4objectproto_p.h" #include <private/qqmlvaluetypewrapper_p.h> #include <private/qv8engine_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp index b03edc9020..f423a7d452 100644 --- a/src/qml/qml/qqmlboundsignal.cpp +++ b/src/qml/qml/qqmlboundsignal.cpp @@ -55,6 +55,7 @@ #include "qqmlinfo.h" #include <private/qv4value_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <QtCore/qdebug.h> diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp index 28d599a593..1037b5da51 100644 --- a/src/qml/qml/qqmlcompileddata.cpp +++ b/src/qml/qml/qqmlcompileddata.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE QQmlCompiledData::QQmlCompiledData(QQmlEngine *engine) : engine(engine), importCache(0), metaTypeId(-1), listMetaTypeId(-1), isRegisteredWithEngine(false), - rootPropertyCache(0), totalBindingsCount(0), totalParserStatusCount(0) + totalBindingsCount(0), totalParserStatusCount(0) { Q_ASSERT(engine); } @@ -86,18 +86,15 @@ QQmlCompiledData::~QQmlCompiledData() qDeleteAll(resolvedTypes); resolvedTypes.clear(); - for (int ii = 0; ii < propertyCaches.count(); ++ii) - if (propertyCaches.at(ii)) - propertyCaches.at(ii)->release(); - for (int ii = 0; ii < scripts.count(); ++ii) scripts.at(ii)->release(); if (importCache) importCache->release(); - if (rootPropertyCache) - rootPropertyCache->release(); + for (int ii = 0; ii < propertyCaches.count(); ++ii) + if (propertyCaches.at(ii).data()) + propertyCaches.at(ii)->release(); } void QQmlCompiledData::clear() @@ -112,7 +109,7 @@ QQmlPropertyCache *QQmlCompiledData::TypeReference::propertyCache() const if (type) return typePropertyCache; else - return component->rootPropertyCache; + return component->rootPropertyCache(); } /*! @@ -127,7 +124,7 @@ QQmlPropertyCache *QQmlCompiledData::TypeReference::createPropertyCache(QQmlEngi typePropertyCache->addref(); return typePropertyCache; } else { - return component->rootPropertyCache; + return component->rootPropertyCache(); } } @@ -149,7 +146,7 @@ void QQmlCompiledData::TypeReference::doDynamicTypeCheck() else if (type) mo = type->metaObject(); else if (component) - mo = component->rootPropertyCache->firstCppMetaObject(); + mo = component->rootPropertyCache()->firstCppMetaObject(); isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo); } diff --git a/src/qml/qml/qqmlcompiler_p.h b/src/qml/qml/qqmlcompiler_p.h index cbe70a7077..c2b244f5e3 100644 --- a/src/qml/qml/qqmlcompiler_p.h +++ b/src/qml/qml/qqmlcompiler_p.h @@ -80,6 +80,10 @@ class QQmlComponent; class QQmlContext; class QQmlContextData; +// The vector is indexed by QV4::CompiledData::Object index and the flag +// indicates whether instantiation of the object requires a VME meta-object. +typedef QVector<QFlagPointer<QQmlPropertyCache>> QQmlPropertyCacheVector; + // ### Merge with QV4::CompiledData::CompilationUnit class Q_AUTOTEST_EXPORT QQmlCompiledData : public QQmlRefCount, public QQmlCleanup { @@ -122,9 +126,8 @@ public: // map from name index QHash<int, TypeReference*> resolvedTypes; - QQmlPropertyCache *rootPropertyCache; - QVector<QByteArray> metaObjects; - QVector<QQmlPropertyCache *> propertyCaches; + QQmlPropertyCache *rootPropertyCache() const { return propertyCaches.at(compilationUnit->data->indexOfRootObject).data(); } + QQmlPropertyCacheVector propertyCaches; QList<QQmlScriptData *> scripts; QQmlRefPointer<QV4::CompiledData::CompilationUnit> compilationUnit; @@ -139,7 +142,7 @@ public: int totalObjectCount; // Number of objects explicitly instantiated bool isComponent(int objectIndex) const { return objectIndexToIdPerComponent.contains(objectIndex); } - bool isCompositeType() const { return !metaObjects.at(compilationUnit->data->indexOfRootObject).isEmpty(); } + bool isCompositeType() const { return propertyCaches.at(compilationUnit->data->indexOfRootObject).flag(); } bool isInitialized() const { return hasEngine(); } void initialize(QQmlEngine *); diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 6aa3710731..eb4f590222 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -60,6 +60,7 @@ #include <private/qv4script_p.h> #include <private/qv4scopedvalue_p.h> #include <private/qv4objectiterator_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <QStack> #include <QStringList> @@ -1068,6 +1069,7 @@ struct QmlIncubatorObject : Object { QPointer<QObject> parent; QV4::Value valuemap; QV4::Value statusChanged; + Pointer<Heap::QmlContext> qmlContext; }; } @@ -1182,7 +1184,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) */ -static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value &o, const QV4::Value &v) +static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v) { QV4::Scope scope(engine); QV4::ScopedObject object(scope); @@ -1193,6 +1195,9 @@ static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value if (engine->hasException) return; + QV4::ExecutionContextSaver saver(scope); + engine->pushContext(qmlContext); + while (1) { name = it.nextPropertyNameAsString(val); if (!name) @@ -1266,8 +1271,10 @@ void QQmlComponent::createObject(QQmlV4Function *args) QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4, rv)); Q_ASSERT(object->isObject()); - if (!valuemap->isUndefined()) - setInitialProperties(v4, object, valuemap); + if (!valuemap->isUndefined()) { + QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext()); + setInitialProperties(v4, qmlContext, object, valuemap); + } d->completeCreate(); @@ -1384,6 +1391,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) if (!valuemap->isUndefined()) r->d()->valuemap = valuemap; + r->d()->qmlContext = v4->qmlContext(); r->d()->parent = parent; QQmlIncubator *incubator = r->d()->incubator.data(); @@ -1397,7 +1405,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) } // XXX used by QSGLoader -void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate) +void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate) { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(ep->v8engine()); @@ -1407,7 +1415,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu Q_ASSERT(object->as<QV4::Object>()); if (!valuemap.isUndefined()) - setInitialProperties(v4engine, object, valuemap); + setInitialProperties(v4engine, qmlContext, object, valuemap); } QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) @@ -1484,6 +1492,7 @@ QQmlComponentExtension::~QQmlComponentExtension() QV4::Heap::QmlIncubatorObject::QmlIncubatorObject(QQmlIncubator::IncubationMode m) : valuemap(QV4::Primitive::undefinedValue()) , statusChanged(QV4::Primitive::undefinedValue()) + , qmlContext(0) { incubator.reset(new QQmlComponentIncubator(this, m)); } @@ -1496,7 +1505,8 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o) QV4::ExecutionEngine *v4 = engine(); QV4::Scope scope(v4); QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o)); - setInitialProperties(v4, obj, d()->valuemap); + QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, d()->qmlContext); + setInitialProperties(v4, qmlCtxt, obj, d()->valuemap); } } @@ -1505,6 +1515,8 @@ void QV4::QmlIncubatorObject::markObjects(QV4::Heap::Base *that, QV4::ExecutionE QmlIncubatorObject::Data *o = static_cast<QmlIncubatorObject::Data *>(that); o->valuemap.mark(e); o->statusChanged.mark(e); + if (o->qmlContext) + o->qmlContext->mark(e); Object::markObjects(that, e); } diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index ba2982d76d..039b267433 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -86,7 +86,7 @@ public: QObject *beginCreate(QQmlContextData *); void completeCreate(); - void initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate); + void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate); QQmlTypeData *typeData; virtual void typeDataReady(QQmlTypeData *); diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 8613c78f6d..2d0ebad764 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -53,6 +53,7 @@ #include <private/qqmllistwrapper_p.h> #include <private/qqmljavascriptexpression_p.h> #include <private/qjsvalue_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE @@ -105,14 +106,23 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr QV4::ExecutionEngine *v4 = resource->engine(); QV4::Scope scope(v4); + // In V8 the JS global object would come _before_ the QML global object, + // so simulate that here. + bool hasProp; + QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp)); + if (hasProp) { + if (hasProperty) + *hasProperty = hasProp; + return result->asReturnedValue(); + } + if (resource->d()->isNullWrapper) return Object::get(m, name, hasProperty); if (v4->callingQmlContext() != resource->d()->context) return Object::get(m, name, hasProperty); - bool hasProp; - QV4::ScopedValue result(scope, Object::get(m, name, &hasProp)); + result = Object::get(m, name, &hasProp); if (hasProp) { if (hasProperty) *hasProperty = hasProp; diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h index d2c7ecdea2..ca7fcf1d75 100644 --- a/src/qml/qml/qqmlcontextwrapper_p.h +++ b/src/qml/qml/qqmlcontextwrapper_p.h @@ -54,21 +54,13 @@ #include <QtCore/qglobal.h> #include <private/qtqmlglobal_p.h> -#include <private/qv4value_p.h> #include <private/qv4object_p.h> #include <private/qqmlcontext_p.h> -#include <private/qv4functionobject_p.h> QT_BEGIN_NAMESPACE namespace QV4 { -namespace CompiledData { -struct Function; -} - -struct QmlContextWrapper; - namespace Heap { struct QmlContextWrapper : Object { diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index 8d0fb22866..b3a0baffb4 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -43,6 +43,7 @@ #include <private/qqmljavascriptexpression_p.h> #include <private/qv4value_p.h> #include <private/qv4qobjectwrapper_p.h> +#include <private/qqmlcontextwrapper_p.h> #include <QQmlError> diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 99ae367773..2baca619cc 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -2227,7 +2227,7 @@ QQmlMetaObject QQmlEnginePrivate::rawMetaObjectForType(int t) const Locker locker(this); QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return QQmlMetaObject((*iter)->rootPropertyCache); + return QQmlMetaObject((*iter)->rootPropertyCache()); } else { QQmlType *type = QQmlMetaType::qmlType(t); return QQmlMetaObject(type?type->baseMetaObject():0); @@ -2239,7 +2239,7 @@ QQmlMetaObject QQmlEnginePrivate::metaObjectForType(int t) const Locker locker(this); QHash<int, QQmlCompiledData *>::ConstIterator iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return QQmlMetaObject((*iter)->rootPropertyCache); + return QQmlMetaObject((*iter)->rootPropertyCache()); } else { QQmlType *type = QQmlMetaType::qmlType(t); return QQmlMetaObject(type?type->metaObject():0); @@ -2251,7 +2251,7 @@ QQmlPropertyCache *QQmlEnginePrivate::propertyCacheForType(int t) Locker locker(this); QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return (*iter)->rootPropertyCache; + return (*iter)->rootPropertyCache(); } else { QQmlType *type = QQmlMetaType::qmlType(t); locker.unlock(); @@ -2264,7 +2264,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) Locker locker(this); QHash<int, QQmlCompiledData*>::ConstIterator iter = m_compositeTypes.constFind(t); if (iter != m_compositeTypes.cend()) { - return (*iter)->rootPropertyCache; + return (*iter)->rootPropertyCache(); } else { QQmlType *type = QQmlMetaType::qmlType(t); locker.unlock(); @@ -2274,7 +2274,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) void QQmlEnginePrivate::registerInternalCompositeType(QQmlCompiledData *data) { - QByteArray name = data->rootPropertyCache->className(); + QByteArray name = data->rootPropertyCache()->className(); QByteArray ptr = name + '*'; QByteArray lst = "QQmlListProperty<" + name + '>'; diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp index 069dadd1c9..8ba4b5eba1 100644 --- a/src/qml/qml/qqmljavascriptexpression.cpp +++ b/src/qml/qml/qqmljavascriptexpression.cpp @@ -47,6 +47,7 @@ #include <private/qv4errorobject_p.h> #include <private/qv4scopedvalue_p.h> #include <private/qqmlglobal_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp index f203dd3607..5c35866274 100644 --- a/src/qml/qml/qqmllistwrapper.cpp +++ b/src/qml/qml/qqmllistwrapper.cpp @@ -44,6 +44,7 @@ #include <qv4objectiterator_p.h> #include <private/qv4functionobject_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 6769a9a123..652a3ca0d4 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -56,6 +56,7 @@ #include <QtCore/qlocale.h> #include <QtCore/qobject.h> #include <private/qqmlglobal_p.h> +#include <private/qv4object_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 1c5a7ad8c1..f3f4c41775 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -494,7 +494,7 @@ QQmlType *QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const if (!td || !td->isComplete()) return 0; QQmlCompiledData *cd = td->compiledData(); - const QMetaObject *mo = cd->rootPropertyCache->firstCppMetaObject(); + const QMetaObject *mo = cd->rootPropertyCache()->firstCppMetaObject(); return QQmlMetaType::qmlType(mo); } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 8d3c5962bd..86693af3d3 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -43,6 +43,7 @@ #include <private/qqmlvmemetaobject_p.h> #include <private/qv4function_p.h> #include <private/qv4functionobject_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <private/qqmlcontextwrapper_p.h> #include <private/qqmlbinding_p.h> #include <private/qqmlstringconverters_p.h> @@ -73,7 +74,6 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , compiledData(compiledData) , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) - , vmeMetaObjectData(compiledData->metaObjects) , activeVMEDataForRootContext(activeVMEDataForRootContext) { init(parentContext); @@ -98,7 +98,6 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile , compiledData(compiledData) , resolvedTypes(compiledData->resolvedTypes) , propertyCaches(compiledData->propertyCaches) - , vmeMetaObjectData(compiledData->metaObjects) , activeVMEDataForRootContext(0) { init(parentContext); @@ -1151,7 +1150,7 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo return instance; } - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index).data(); Q_ASSERT(!cache.isNull()); if (installPropertyCache) { if (ddata->propertyCache) @@ -1282,14 +1281,14 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject * QV4::Scope valueScope(v4); QV4::ScopedValue scopeObjectProtector(valueScope); - QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(_compiledObjectIndex); + QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(_compiledObjectIndex).data(); QQmlVMEMetaObject *vmeMetaObject = 0; - const QByteArray data = vmeMetaObjectData.value(_compiledObjectIndex); - if (!data.isEmpty()) { + const bool needVMEMetaObject = propertyCaches.at(_compiledObjectIndex).flag(); + if (needVMEMetaObject) { Q_ASSERT(!cache.isNull()); // install on _object - vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, reinterpret_cast<const QQmlVMEMetaData*>(data.constData()), compiledData->compilationUnit, _compiledObjectIndex); + vmeMetaObject = new QQmlVMEMetaObject(_qobject, cache, compiledData->compilationUnit, _compiledObjectIndex); if (_ddata->propertyCache) _ddata->propertyCache->release(); _ddata->propertyCache = cache; diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 3d743954c9..8045281cbb 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -142,8 +142,7 @@ private: QQmlGuardedContextData parentContext; QQmlContextData *context; const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes; - const QVector<QQmlPropertyCache *> &propertyCaches; - const QVector<QByteArray> &vmeMetaObjectData; + const QQmlPropertyCacheVector &propertyCaches; QHash<int, int> objectIndexToId; QExplicitlySharedDataPointer<QQmlObjectCreatorSharedState> sharedState; bool topLevelCreator; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index c6299a1720..4ec3dfe6a5 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -980,7 +980,7 @@ struct CachedLoader { } void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const { - loader->m_thread->loadWithCachedUnit(blob, unit); + loader->m_thread->loadWithCachedUnitAsync(blob, unit); } }; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 33fe655368..7892555f08 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -47,6 +47,7 @@ #include <private/qjsvalue_p.h> #include <private/qv4functionobject_p.h> #include <private/qv4objectproto_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index fdac41a420..5cb346a462 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -51,6 +51,7 @@ #include <private/qv4variantobject_p.h> #include <private/qv4alloca_p.h> #include <private/qv4objectiterator_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index b0b7995ae2..8697a291e2 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -55,6 +55,7 @@ #include <private/qv4variantobject_p.h> #include <private/qv4functionobject_p.h> #include <private/qv4scopedvalue_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE @@ -149,15 +150,23 @@ void QQmlVMEMetaObjectEndpoint::tryConnect() metaObject->activate(metaObject->object, sigIdx, 0); } else { const QV4::CompiledData::Alias *aliasData = &metaObject->compiledObject->aliasTable()[aliasId]; - QQmlVMEMetaData::AliasData *d = metaObject->metaData->aliasData() + aliasId; if (!aliasData->isObjectAlias()) { QQmlContextData *ctxt = metaObject->ctxt; QObject *target = ctxt->idValues[aliasData->targetObjectId].data(); if (!target) return; - if (d->notifySignal != -1) - connect(target, d->notifySignal, ctxt->engine); + QQmlData *targetDData = QQmlData::get(target, /*create*/false); + if (!targetDData) + return; + int coreIndex; + QQmlPropertyData::decodeValueTypePropertyIndex(aliasData->encodedMetaPropertyIndex, &coreIndex); + const QQmlPropertyData *pd = targetDData->propertyCache->property(coreIndex); + if (!pd) + return; + + if (pd->notifyIndex != -1) + connect(target, pd->notifyIndex, ctxt->engine); } metaObject.setFlag(); @@ -305,10 +314,9 @@ QAbstractDynamicMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObje } QQmlVMEMetaObject::QQmlVMEMetaObject(QObject *obj, - QQmlPropertyCache *cache, - const QQmlVMEMetaData *meta, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId) + QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId) : QQmlInterceptorMetaObject(obj, cache), - ctxt(QQmlData::get(obj, true)->outerContext), metaData(meta), + ctxt(QQmlData::get(obj, true)->outerContext), aliasEndpoints(0), compilationUnit(qmlCompilationUnit), compiledObject(0) { cache->addref(); @@ -733,9 +741,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * case QV4::CompiledData::Property::Quaternion: Q_ASSERT(fallbackMetaType != QMetaType::UnknownType); if (QV4::MemberData *md = propertyAndMethodStorageAsMemberData()) { - QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); - if (v) - QQml_valueTypeProvider()->readValueType(v->d()->data, a[0], fallbackMetaType); + QVariant propertyAsVariant; + if (QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>()) + propertyAsVariant = v->d()->data; + QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], fallbackMetaType); } break; case QV4::CompiledData::Property::Var: diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h index f9f9ec47af..75e7ed6cb1 100644 --- a/src/qml/qml/qqmlvmemetaobject_p.h +++ b/src/qml/qml/qqmlvmemetaobject_p.h @@ -74,20 +74,6 @@ QT_BEGIN_NAMESPACE -struct QQmlVMEMetaData -{ - // Make sure this structure is always aligned to int - int dummy; - - struct AliasData { - int notifySignal; - }; - - AliasData *aliasData() const { - return (AliasData *)(((char *)const_cast<QQmlVMEMetaData *>(this)) + sizeof(QQmlVMEMetaData)); - } -}; - class QQmlVMEMetaObject; class QQmlVMEVariantQObjectPtr : public QQmlGuard<QObject> { @@ -147,7 +133,7 @@ class QQmlVMEMetaObjectEndpoint; class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject { public: - QQmlVMEMetaObject(QObject *obj, QQmlPropertyCache *cache, const QQmlVMEMetaData *data, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId); + QQmlVMEMetaObject(QObject *obj, QQmlPropertyCache *cache, QV4::CompiledData::CompilationUnit *qmlCompilationUnit, int qmlObjectId); ~QQmlVMEMetaObject(); bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const; @@ -169,7 +155,6 @@ protected: public: QQmlGuardedContextData ctxt; - const QQmlVMEMetaData *metaData; inline int propOffset() const; inline int methodOffset() const; inline int signalOffset() const; diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 1f42cbf983..54c29b4b8a 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -63,6 +63,7 @@ #include <private/qv4mm_p.h> #include <private/qv4jsonobject_p.h> #include <private/qv4objectproto_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <QtCore/qstring.h> #include <QtCore/qdatetime.h> diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index d8b0ef79f8..e08ff3b979 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -70,6 +70,7 @@ #include <private/qv4value_p.h> #include <private/qv4dateobject_p.h> #include <private/qv4objectiterator_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <private/qv4mm_p.h> #include <private/qv4objectproto_p.h> #include <private/qv4globalobject_p.h> diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index c5041c54e0..390831609b 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -60,16 +60,13 @@ #include <QtCore/QElapsedTimer> #include <QtCore/QThreadStorage> -#include <qjsengine.h> +#include <QtQml/qjsengine.h> #include "private/qintrusivelist_p.h" -#include <private/qqmlpropertycache_p.h> -#include <private/qv4qobjectwrapper_p.h> #include <private/qv4value_p.h> -#include <private/qv4object_p.h> #include <private/qv4identifier_p.h> -#include <private/qqmlcontextwrapper_p.h> +#include <private/qv4context_p.h> #include <private/qqmldelayedcallqueue_p.h> QT_BEGIN_NAMESPACE @@ -77,6 +74,7 @@ QT_BEGIN_NAMESPACE namespace QV4 { struct ArrayObject; struct ExecutionEngine; + struct QObjectMethod; } #define V4THROW_ERROR(string) \ diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index 76e55f718d..bf9fd99f19 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -41,7 +41,7 @@ #define QQMLDATAMODEL_P_P_H #include "qqmldelegatemodel_p.h" - +#include <private/qv4qobjectwrapper_p.h> #include <QtQml/qqmlcontext.h> #include <QtQml/qqmlincubator.h> diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h index 431e6aca9f..d3ff032ae9 100644 --- a/src/qml/types/qqmllistmodel_p_p.h +++ b/src/qml/types/qqmllistmodel_p_p.h @@ -54,6 +54,7 @@ #include "qqmllistmodel_p.h" #include <private/qqmlengine_p.h> #include <private/qqmlopenmetaobject_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <qqml.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/types/qqmllistmodelworkeragent_p.h b/src/qml/types/qqmllistmodelworkeragent_p.h index f9872a6ad4..1a891c0f25 100644 --- a/src/qml/types/qqmllistmodelworkeragent_p.h +++ b/src/qml/types/qqmllistmodelworkeragent_p.h @@ -53,6 +53,7 @@ #include <qqml.h> +#include <QEvent> #include <QMutex> #include <QWaitCondition> diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 235b532dbb..0a820b79db 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -57,6 +57,7 @@ #include <QtQuick/qquickwindow.h> #include <QtGui/qvector3d.h> #include <QtQml/private/qqmlglobal_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <algorithm> diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index 932f7663c3..a56d098717 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -54,6 +54,11 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item) { } +QWindow *QAccessibleQuickItem::window() const +{ + return item()->window(); +} + int QAccessibleQuickItem::childCount() const { return childItems().count(); diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h index d6792b0850..7445fd1400 100644 --- a/src/quick/accessible/qaccessiblequickitem_p.h +++ b/src/quick/accessible/qaccessiblequickitem_p.h @@ -66,70 +66,73 @@ class QAccessibleQuickItem : public QAccessibleObject, public QAccessibleActionI public: QAccessibleQuickItem(QQuickItem *item); - QRect rect() const; + QWindow *window() const Q_DECL_OVERRIDE; + + QRect rect() const Q_DECL_OVERRIDE; QRect viewRect() const; bool clipsChildren() const; - QAccessibleInterface *childAt(int x, int y) const; + QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE; - QAccessibleInterface *parent() const; - QAccessibleInterface *child(int index) const; - int childCount() const; - int indexOfChild(const QAccessibleInterface *iface) const; + QAccessibleInterface *parent() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + int childCount() const Q_DECL_OVERRIDE; + int indexOfChild(const QAccessibleInterface *iface) const Q_DECL_OVERRIDE; QList<QQuickItem *> childItems() const; - QAccessible::State state() const; - QAccessible::Role role() const; - QString text(QAccessible::Text) const; + QAccessible::State state() const Q_DECL_OVERRIDE; + QAccessible::Role role() const Q_DECL_OVERRIDE; + QString text(QAccessible::Text) const Q_DECL_OVERRIDE; bool isAccessible() const; // Action Interface - QStringList actionNames() const; - void doAction(const QString &actionName); - QStringList keyBindingsForAction(const QString &actionName) const; + QStringList actionNames() const Q_DECL_OVERRIDE; + void doAction(const QString &actionName) Q_DECL_OVERRIDE; + QStringList keyBindingsForAction(const QString &actionName) const Q_DECL_OVERRIDE; // Value Interface - QVariant currentValue() const; - void setCurrentValue(const QVariant &value); - QVariant maximumValue() const; - QVariant minimumValue() const; - QVariant minimumStepSize() const; + QVariant currentValue() const Q_DECL_OVERRIDE; + void setCurrentValue(const QVariant &value) Q_DECL_OVERRIDE; + QVariant maximumValue() const Q_DECL_OVERRIDE; + QVariant minimumValue() const Q_DECL_OVERRIDE; + QVariant minimumStepSize() const Q_DECL_OVERRIDE; // Text Interface - void selection(int selectionIndex, int *startOffset, int *endOffset) const; - int selectionCount() const; - void addSelection(int startOffset, int endOffset); - void removeSelection(int selectionIndex); - void setSelection(int selectionIndex, int startOffset, int endOffset); + void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int selectionCount() const Q_DECL_OVERRIDE; + void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE; + void removeSelection(int selectionIndex) Q_DECL_OVERRIDE; + void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE; // cursor - int cursorPosition() const; - void setCursorPosition(int position); + int cursorPosition() const Q_DECL_OVERRIDE; + void setCursorPosition(int position) Q_DECL_OVERRIDE; // text - QString text(int startOffset, int endOffset) const; + QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE; QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const; + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const; + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType, - int *startOffset, int *endOffset) const; - int characterCount() const; + int *startOffset, int *endOffset) const Q_DECL_OVERRIDE; + int characterCount() const Q_DECL_OVERRIDE; // character <-> geometry - QRect characterRect(int /* offset */) const { return QRect(); } - int offsetAtPoint(const QPoint & /* point */) const { return -1; } + QRect characterRect(int /* offset */) const Q_DECL_OVERRIDE { return QRect(); } + int offsetAtPoint(const QPoint & /* point */) const Q_DECL_OVERRIDE { return -1; } - void scrollToSubstring(int /* startIndex */, int /* endIndex */) {} - QString attributes(int /* offset */, int *startOffset, int *endOffset) const { *startOffset = 0; *endOffset = 0; return QString(); } + void scrollToSubstring(int /* startIndex */, int /* endIndex */) Q_DECL_OVERRIDE {} + QString attributes(int /* offset */, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE + { *startOffset = 0; *endOffset = 0; return QString(); } QTextDocument *textDocument() const; protected: QQuickItem *item() const { return static_cast<QQuickItem*>(object()); } - void *interface_cast(QAccessible::InterfaceType t); + void *interface_cast(QAccessible::InterfaceType t) Q_DECL_OVERRIDE; private: QTextDocument *m_doc; diff --git a/src/quick/designer/qqmldesignermetaobject.cpp b/src/quick/designer/qqmldesignermetaobject.cpp index 63b4102b10..23a29d5831 100644 --- a/src/quick/designer/qqmldesignermetaobject.cpp +++ b/src/quick/designer/qqmldesignermetaobject.cpp @@ -79,20 +79,6 @@ struct MetaPropertyData { QVector<QPair<QVariant, bool> > m_data; }; -static QQmlVMEMetaData* fakeMetaData() -{ - return new QQmlVMEMetaData; -} - -static const QQmlVMEMetaData* vMEMetaDataForObject(QObject *object) -{ - QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object); - if (metaObject) - return metaObject->metaData; - - return fakeMetaData(); -} - static QQmlPropertyCache *cacheForObject(QObject *object, QQmlEngine *engine) { QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object); @@ -147,7 +133,7 @@ void QQmlDesignerMetaObject::init(QObject *object, QQmlEngine *engine) } QQmlDesignerMetaObject::QQmlDesignerMetaObject(QObject *object, QQmlEngine *engine) - : QQmlVMEMetaObject(object, cacheForObject(object, engine), vMEMetaDataForObject(object), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1), + : QQmlVMEMetaObject(object, cacheForObject(object, engine), /*qml compilation unit*/nullptr, /*qmlObjectId*/-1), m_context(engine->contextForObject(object)), m_data(new MetaPropertyData), m_cache(0) diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 131cd758a5..fae2eeae2e 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -4,7 +4,7 @@ project = QtQuick description = Qt Quick Reference Documentation version = $QT_VERSION -examplesinstallpath = qtdeclarative/quick +examplesinstallpath = quick qhp.projects = QtQuick diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 9ca986501c..7ffb715346 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -55,6 +55,7 @@ #include <private/qv4value_p.h> #include <private/qv4functionobject_p.h> #include <private/qv4scopedvalue_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/context2d/qquickcanvasitem_p.h b/src/quick/items/context2d/qquickcanvasitem_p.h index b99fcf869d..4f94393a45 100644 --- a/src/quick/items/context2d/qquickcanvasitem_p.h +++ b/src/quick/items/context2d/qquickcanvasitem_p.h @@ -53,6 +53,7 @@ #include <QtQuick/qquickitem.h> #include <private/qv8engine_p.h> +#include <private/qqmlrefcount_p.h> #include <QtCore/QThread> #include <QtGui/QImage> diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 7e7b1fa062..93ca8e9358 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -58,6 +58,7 @@ #include <private/qv4domerrors_p.h> #include <private/qv4engine_p.h> #include <private/qv4object_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <private/qquickwindow_p.h> #include <private/qv4value_p.h> diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h index 818db0868c..cfb62ee052 100644 --- a/src/quick/items/context2d/qquickcontext2d_p.h +++ b/src/quick/items/context2d/qquickcontext2d_p.h @@ -66,6 +66,7 @@ #include <QtCore/QWaitCondition> #include <private/qv4value_p.h> +#include <private/qv4persistent_p.h> //#define QQUICKCONTEXT2D_DEBUG //enable this for just DEBUG purpose! diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ae138d7ceb..1853a1d948 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1402,15 +1402,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) break; case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse case Qt::ScrollUpdate: - if (d->scrollingPhase) { + if (d->scrollingPhase) d->pressed = true; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); - } +#ifdef Q_OS_OSX + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif break; case Qt::ScrollEnd: d->pressed = false; d->scrollingPhase = false; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); d->draggingEnding(); event->accept(); returnToBounds(); diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index c04a526bd0..a168b43fd1 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -44,6 +44,7 @@ #include <QtQuick/private/qsgcontext_p.h> #include <private/qsgadaptationlayer_p.h> +#include <private/qnumeric_p.h> #include <QtCore/qmath.h> #include <QtGui/qpainter.h> diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index d6fdf5795e..d0d10a5849 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -71,6 +71,7 @@ #include <private/qv4engine_p.h> #include <private/qv4object_p.h> +#include <private/qv4qobjectwrapper_p.h> #include <private/qdebug_p.h> #ifndef QT_NO_CURSOR diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index c1126d9b12..63c9558d7a 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -583,6 +583,7 @@ void QQuickLoader::setSource(QQmlV4Function *args) d->disposeInitialPropertyValues(); d->initialPropertyValues.set(args->v4engine(), ipv); } + d->qmlCallingContext.set(scope.engine, scope.engine->qmlContext()); setSource(sourceUrl, false); // already cleared and set ipv above. } @@ -651,7 +652,8 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) Q_ASSERT(v4); QV4::Scope scope(v4); QV4::ScopedValue ipv(scope, initialPropertyValues.value()); - d->initializeObjectWithInitialProperties(ipv, obj); + QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); + d->initializeObjectWithInitialProperties(qmlContext, ipv, obj); } void QQuickLoaderIncubator::statusChanged(Status status) diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h index ad05bb00ec..9ef89a74d6 100644 --- a/src/quick/items/qquickloader_p_p.h +++ b/src/quick/items/qquickloader_p_p.h @@ -108,6 +108,7 @@ public: QQmlContext *itemContext; QQuickLoaderIncubator *incubator; QV4::PersistentValue initialPropertyValues; + QV4::PersistentValue qmlCallingContext; bool updatingSize: 1; bool active : 1; bool loadingFromSource : 1; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 65044d33d4..648929c8cd 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -650,6 +650,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) emit q->lineCountChanged(); } + if (qFuzzyIsNull(q->width())) { + layout.setText(QString()); + textHasChanged = true; + } + QFontMetricsF fm(font); qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : qCeil(fm.height()) * lineHeight(); *baseline = fm.ascent(); diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index b6431666bf..26a540455e 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1176,17 +1176,20 @@ void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) void QQuickWidget::showEvent(QShowEvent *) { Q_D(QQuickWidget); - d->updatePending = false; if (!d->useSoftwareRenderer) { d->createContext(); - if (d->offscreenWindow->openglContext()) + if (d->offscreenWindow->openglContext()) { d->render(true); - else + if (d->updatePending) { + d->updatePending = false; + update(); + } + } else { triggerUpdate(); + } } else { triggerUpdate(); } - QWindowPrivate *offscreenPrivate = QWindowPrivate::get(d->offscreenWindow); if (!offscreenPrivate->visible) { offscreenPrivate->visible = true; |