diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/animations/qabstractanimationjob.cpp | 41 | ||||
-rw-r--r-- | src/qml/animations/qabstractanimationjob_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 7 | ||||
-rw-r--r-- | src/qml/jit/qv4assemblercommon.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4assemblercommon_p.h | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4baselineassembler.cpp | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4baselineassembler_p.h | 4 | ||||
-rw-r--r-- | src/qml/jit/qv4baselinejit.cpp | 5 | ||||
-rw-r--r-- | src/qml/jit/qv4baselinejit_p.h | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup.cpp | 113 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4lookup_p.h | 48 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 19 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmltypedata.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 7 | ||||
-rw-r--r-- | src/qml/qtqmlglobal_p.h | 22 |
20 files changed, 237 insertions, 105 deletions
diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index f3c12bce3f..e15771531a 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -65,6 +65,30 @@ QQmlAnimationTimer::QQmlAnimationTimer() : { } +void QQmlAnimationTimer::unsetJobTimer(QAbstractAnimationJob *animation) +{ + if (!animation) + return; + if (animation->m_timer == this) + animation->m_timer = nullptr; + + if (animation->isGroup()) { + QAnimationGroupJob *group = static_cast<QAnimationGroupJob *>(animation); + for (auto *child = group->firstChild(); child; child = child->nextSibling()) + unsetJobTimer(child); + } +} + +QQmlAnimationTimer::~QQmlAnimationTimer() +{ + for (const auto &animation : qAsConst(animations)) + unsetJobTimer(animation); + for (const auto &animation : qAsConst(animationsToStart)) + unsetJobTimer(animation); + for (const auto &animation : qAsConst(runningPauseAnimations)) + unsetJobTimer(animation); +} + QQmlAnimationTimer *QQmlAnimationTimer::instance(bool create) { QQmlAnimationTimer *inst; @@ -216,6 +240,7 @@ void QQmlAnimationTimer::registerRunningAnimation(QAbstractAnimationJob *animati void QQmlAnimationTimer::unregisterRunningAnimation(QAbstractAnimationJob *animation) { + unsetJobTimer(animation); if (animation->userControlDisabled()) return; @@ -282,8 +307,10 @@ QAbstractAnimationJob::~QAbstractAnimationJob() Q_ASSERT(m_state == Stopped); if (oldState == Running) { - Q_ASSERT(QQmlAnimationTimer::instance() == m_timer); - m_timer->unregisterAnimation(this); + if (m_timer) { + Q_ASSERT(QQmlAnimationTimer::instance(false) == m_timer); + m_timer->unregisterAnimation(this); + } } Q_ASSERT(!m_hasRegisteredTimer); } @@ -308,8 +335,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) if (m_loopCount == 0) return; - if (!m_timer) - m_timer = QQmlAnimationTimer::instance(); + if (!m_timer) // don't create a timer just to stop the animation + m_timer = QQmlAnimationTimer::instance(newState != Stopped); + Q_ASSERT(m_timer || newState == Stopped); State oldState = m_state; int oldCurrentTime = m_currentTime; @@ -337,8 +365,9 @@ void QAbstractAnimationJob::setState(QAbstractAnimationJob::State newState) if (oldState == Running) { if (newState == Paused && m_hasRegisteredTimer) m_timer->ensureTimerUpdate(); - //the animation, is not running any more - m_timer->unregisterAnimation(this); + // the animation is not running any more + if (m_timer) + m_timer->unregisterAnimation(this); } else if (newState == Running) { m_timer->registerAnimation(this, isTopLevel); } diff --git a/src/qml/animations/qabstractanimationjob_p.h b/src/qml/animations/qabstractanimationjob_p.h index 9490070246..1010f0f392 100644 --- a/src/qml/animations/qabstractanimationjob_p.h +++ b/src/qml/animations/qabstractanimationjob_p.h @@ -207,6 +207,8 @@ private: QQmlAnimationTimer(); public: + ~QQmlAnimationTimer(); // must be destructible by QThreadStorage + static QQmlAnimationTimer *instance(); static QQmlAnimationTimer *instance(bool create); @@ -252,6 +254,7 @@ private: void registerRunningAnimation(QAbstractAnimationJob *animation); void unregisterRunningAnimation(QAbstractAnimationJob *animation); + void unsetJobTimer(QAbstractAnimationJob *animation); int closestPauseAnimationTimeToFinish(); }; diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 2ad85ab910..36b7f68de9 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1901,6 +1901,12 @@ QVector<int> JSCodeGen::generateJSCodeForFunctionsAndBindings(const QList<Compil scan.enterEnvironment(f.parentNode, QV4::Compiler::ContextType::Binding, qmlName(f)); } + /* We do not want to visit the whole function, as we already called enterQmlFunction + However, there might be a function defined as a default argument of the function. + That needs to be considered, too, so we call handleTopLevelFunctionFormals to + deal with them. + */ + scan.handleTopLevelFunctionFormals(function); scan(function ? function->body : f.node); scan.leaveEnvironment(); } diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index e39aa2454e..56172e2ea5 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -83,6 +83,13 @@ public: ScanFunctions(Codegen *cg, const QString &sourceCode, ContextType defaultProgramType); void operator()(QQmlJS::AST::Node *node); + // see comment at its call site in generateJSCodeForFunctionsAndBindings + // for why this function is necessary + void handleTopLevelFunctionFormals(QQmlJS::AST::FunctionExpression *node) { + if (node && node->formals) + node->formals->accept(this); + } + void enterGlobalEnvironment(ContextType compilationMode); void enterEnvironment(QQmlJS::AST::Node *node, ContextType compilationMode, const QString &name); diff --git a/src/qml/jit/qv4assemblercommon.cpp b/src/qml/jit/qv4assemblercommon.cpp index 95070fbb96..b090fc7597 100644 --- a/src/qml/jit/qv4assemblercommon.cpp +++ b/src/qml/jit/qv4assemblercommon.cpp @@ -51,6 +51,8 @@ #include <assembler/LinkBuffer.h> #include <WTFStubs.h> +#if QT_CONFIG(qml_jit) + #undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES QT_BEGIN_NAMESPACE @@ -370,3 +372,5 @@ void PlatformAssemblerCommon::storeInt32AsValue(int srcInt, Address destAddr) } // QV4 namepsace QT_END_NAMESPACE + +#endif // QT_CONFIG(qml_jit) diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index ead1e757de..c3b1eb34eb 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -58,7 +58,7 @@ #include <wtf/Vector.h> #include <assembler/MacroAssembler.h> -QT_REQUIRE_CONFIG(qml_jit); +#if QT_CONFIG(qml_jit) QT_BEGIN_NAMESPACE @@ -740,4 +740,6 @@ private: QT_END_NAMESPACE +#endif // QT_CONFIG(qml_jit) + #endif // QV4PLATFORMASSEMBLER_P_H diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp index dd6a40afe0..7ad131335e 100644 --- a/src/qml/jit/qv4baselineassembler.cpp +++ b/src/qml/jit/qv4baselineassembler.cpp @@ -55,6 +55,8 @@ #undef ENABLE_ALL_ASSEMBLERS_FOR_REFACTORING_PURPOSES +#if QT_CONFIG(qml_jit) + QT_BEGIN_NAMESPACE namespace QV4 { namespace JIT { @@ -1619,3 +1621,5 @@ void BaselineAssembler::ret() } // QV4 namepsace QT_END_NAMESPACE + +#endif // QT_CONFIG(qml_jit) diff --git a/src/qml/jit/qv4baselineassembler_p.h b/src/qml/jit/qv4baselineassembler_p.h index c2c735282b..c6fdab51c5 100644 --- a/src/qml/jit/qv4baselineassembler_p.h +++ b/src/qml/jit/qv4baselineassembler_p.h @@ -55,7 +55,7 @@ #include <private/qv4function_p.h> #include <QHash> -QT_REQUIRE_CONFIG(qml_jit); +#if QT_CONFIG(qml_jit) QT_BEGIN_NAMESPACE @@ -182,4 +182,6 @@ private: QT_END_NAMESPACE +#endif // QT_CONFIG(qml_jit) + #endif // QV4BASELINEASSEMBLER_P_H diff --git a/src/qml/jit/qv4baselinejit.cpp b/src/qml/jit/qv4baselinejit.cpp index d329a5afec..45150cfffd 100644 --- a/src/qml/jit/qv4baselinejit.cpp +++ b/src/qml/jit/qv4baselinejit.cpp @@ -42,6 +42,8 @@ #include <private/qv4lookup_p.h> #include <private/qv4generatorobject_p.h> +#if QT_CONFIG(qml_jit) + QT_USE_NAMESPACE using namespace QV4; using namespace QV4::JIT; @@ -930,3 +932,6 @@ void BaselineJIT::endInstruction(Instr::Type instr) { Q_UNUSED(instr); } + +#endif // QT_CONFIG(qml_jit) + diff --git a/src/qml/jit/qv4baselinejit_p.h b/src/qml/jit/qv4baselinejit_p.h index 284faf0ff0..2b0913169e 100644 --- a/src/qml/jit/qv4baselinejit_p.h +++ b/src/qml/jit/qv4baselinejit_p.h @@ -56,7 +56,7 @@ #include <private/qv4instr_moth_p.h> #include <private/qv4bytecodehandler_p.h> -QT_REQUIRE_CONFIG(qml_jit); +#if QT_CONFIG(qml_jit) QT_BEGIN_NAMESPACE @@ -220,4 +220,6 @@ private: QT_END_NAMESPACE +#endif // QT_CONFIG(qml_jit) + #endif // QV4JIT_P_H diff --git a/src/qml/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index 2c54388100..5eb0e889b0 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -296,24 +296,8 @@ void ExecutableCompilationUnit::unlink() propertyCaches.clear(); if (runtimeLookups) { - for (uint i = 0; i < data->lookupTableSize; ++i) { - QV4::Lookup &l = runtimeLookups[i]; - if (l.getter == QV4::QObjectWrapper::lookupGetter - || l.getter == QQmlTypeWrapper::lookupSingletonProperty) { - if (QQmlPropertyCache *pc = l.qobjectLookup.propertyCache) - pc->release(); - } else if (l.getter == QQmlValueTypeWrapper::lookupGetter - || l.getter == QQmlTypeWrapper::lookupSingletonProperty) { - if (QQmlPropertyCache *pc = l.qgadgetLookup.propertyCache) - pc->release(); - } - - if (l.qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty - || l.qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty) { - if (QQmlPropertyCache *pc = l.qobjectLookup.propertyCache) - pc->release(); - } - } + for (uint i = 0; i < data->lookupTableSize; ++i) + runtimeLookups[i].releasePropertyCache(); } dependentScripts.clear(); diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp index d3ea50867a..db6fb39695 100644 --- a/src/qml/jsruntime/qv4lookup.cpp +++ b/src/qml/jsruntime/qv4lookup.cpp @@ -41,6 +41,7 @@ #include "qv4jscall_p.h" #include "qv4string_p.h" #include <private/qv4identifiertable_p.h> +#include <private/qv4qobjectwrapper_p.h> QT_BEGIN_NAMESPACE @@ -144,47 +145,76 @@ ReturnedValue Lookup::getterGeneric(Lookup *l, ExecutionEngine *engine, const Va return l->resolvePrimitiveGetter(engine, object); } +static inline void setupObjectLookupTwoClasses(Lookup *l, const Lookup &first, const Lookup &second) +{ + Heap::InternalClass *ic1 = first.objectLookup.ic; + const uint offset1 = first.objectLookup.offset; + Heap::InternalClass *ic2 = second.objectLookup.ic; + const uint offset2 = second.objectLookup.offset; + + l->objectLookupTwoClasses.ic = ic1; + l->objectLookupTwoClasses.ic2 = ic2; + l->objectLookupTwoClasses.offset = offset1; + l->objectLookupTwoClasses.offset2 = offset2; +} + +static inline void setupProtoLookupTwoClasses(Lookup *l, const Lookup &first, const Lookup &second) +{ + const quintptr protoId1 = first.protoLookup.protoId; + const Value *data1 = first.protoLookup.data; + const quintptr protoId2 = second.protoLookup.protoId; + const Value *data2 = second.protoLookup.data; + + l->protoLookupTwoClasses.protoId = protoId1; + l->protoLookupTwoClasses.protoId2 = protoId2; + l->protoLookupTwoClasses.data = data1; + l->protoLookupTwoClasses.data2 = data2; +} + ReturnedValue Lookup::getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object) { if (const Object *o = object.as<Object>()) { - Lookup first = *l; - Lookup second = *l; - ReturnedValue result = second.resolveGetter(engine, o); - - if (first.getter == getter0Inline && (second.getter == getter0Inline || second.getter == getter0MemberData)) { - l->objectLookupTwoClasses.ic = first.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = second.objectLookup.ic; - l->objectLookupTwoClasses.offset = first.objectLookup.offset; - l->objectLookupTwoClasses.offset2 = second.objectLookup.offset; - l->getter = second.getter == getter0Inline ? getter0Inlinegetter0Inline : getter0Inlinegetter0MemberData; + // Do the resolution on a second lookup, then merge. + Lookup second; + memset(&second, 0, sizeof(Lookup)); + second.nameIndex = l->nameIndex; + second.getter = getterGeneric; + const ReturnedValue result = second.resolveGetter(engine, o); + + if (l->getter == getter0Inline + && (second.getter == getter0Inline || second.getter == getter0MemberData)) { + setupObjectLookupTwoClasses(l, *l, second); + l->getter = (second.getter == getter0Inline) + ? getter0Inlinegetter0Inline + : getter0Inlinegetter0MemberData; return result; } - if (first.getter == getter0MemberData && (second.getter == getter0Inline || second.getter == getter0MemberData)) { - l->objectLookupTwoClasses.ic = second.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = first.objectLookup.ic; - l->objectLookupTwoClasses.offset = second.objectLookup.offset; - l->objectLookupTwoClasses.offset2 = first.objectLookup.offset; - l->getter = second.getter == getter0Inline ? getter0Inlinegetter0MemberData : getter0MemberDatagetter0MemberData; + + if (l->getter == getter0MemberData + && (second.getter == getter0Inline || second.getter == getter0MemberData)) { + setupObjectLookupTwoClasses(l, second, *l); + l->getter = (second.getter == getter0Inline) + ? getter0Inlinegetter0MemberData + : getter0MemberDatagetter0MemberData; return result; } - if (first.getter == getterProto && second.getter == getterProto) { - l->protoLookupTwoClasses.protoId = first.protoLookup.protoId; - l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId; - l->protoLookupTwoClasses.data = first.protoLookup.data; - l->protoLookupTwoClasses.data2 = second.protoLookup.data; + + + if (l->getter == getterProto && second.getter == getterProto) { + setupProtoLookupTwoClasses(l, *l, second); l->getter = getterProtoTwoClasses; return result; } - if (first.getter == getterProtoAccessor && second.getter == getterProtoAccessor) { - l->protoLookupTwoClasses.protoId = first.protoLookup.protoId; - l->protoLookupTwoClasses.protoId2 = second.protoLookup.protoId; - l->protoLookupTwoClasses.data = first.protoLookup.data; - l->protoLookupTwoClasses.data2 = second.protoLookup.data; + + if (l->getter == getterProtoAccessor && second.getter == getterProtoAccessor) { + setupProtoLookupTwoClasses(l, *l, second); l->getter = getterProtoAccessorTwoClasses; return result; } + // If any of the above options were true, the propertyCache was inactive. + second.releasePropertyCache(); } l->getter = getterFallback; @@ -371,7 +401,19 @@ ReturnedValue Lookup::getterIndexed(Lookup *l, ExecutionEngine *engine, const Va } l->getter = getterFallback; return getterFallback(l, engine, object); +} +ReturnedValue Lookup::getterQObject(Lookup *lookup, ExecutionEngine *engine, const Value &object) +{ + const auto revertLookup = [lookup, engine, &object]() { + lookup->qobjectLookup.propertyCache->release(); + lookup->qobjectLookup.propertyCache = nullptr; + lookup->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(lookup, engine, object); + }; + + return QObjectWrapper::lookupGetterImpl( + lookup, engine, object, /*useOriginalProperty*/ false, revertLookup); } ReturnedValue Lookup::primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object) @@ -463,23 +505,30 @@ bool Lookup::setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, co bool Lookup::setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value) { - Lookup first = *l; - Lookup second = *l; + // A precondition of this method is that l->objectLookup is the active variant of the union. + Q_ASSERT(l->setter == setter0MemberData || l->setter == setter0Inline); if (object.isObject()) { + + // As l->objectLookup is active, we can stash some members here, before resolving. + Heap::InternalClass *ic = l->objectLookup.ic; + const uint index = l->objectLookup.index; + if (!l->resolveSetter(engine, static_cast<Object *>(&object), value)) { l->setter = setterFallback; return false; } if (l->setter == Lookup::setter0MemberData || l->setter == Lookup::setter0Inline) { - l->objectLookupTwoClasses.ic = first.objectLookup.ic; - l->objectLookupTwoClasses.ic2 = second.objectLookup.ic; - l->objectLookupTwoClasses.offset = first.objectLookup.index; - l->objectLookupTwoClasses.offset2 = second.objectLookup.index; + l->objectLookupTwoClasses.ic = ic; + l->objectLookupTwoClasses.ic2 = ic; + l->objectLookupTwoClasses.offset = index; + l->objectLookupTwoClasses.offset2 = index; l->setter = setter0setter0; return true; } + + l->releasePropertyCache(); } l->setter = setterFallback; diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index 31c90b31f6..6241a81850 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -56,11 +56,17 @@ #include "qv4context_p.h" #include "qv4object_p.h" #include "qv4internalclass_p.h" +#include "qv4qmlcontext_p.h" +#include <private/qqmltypewrapper_p.h> +#include <private/qqmlvaluetypewrapper_p.h> QT_BEGIN_NAMESPACE namespace QV4 { +// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to +// be trivially copyable. But you should never ever copy it. There are refcounted members +// in there. struct Q_QML_PRIVATE_EXPORT Lookup { union { ReturnedValue (*getter)(Lookup *l, ExecutionEngine *engine, const Value &object); @@ -187,6 +193,7 @@ struct Q_QML_PRIVATE_EXPORT Lookup { static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object); + static ReturnedValue getterQObject(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object); static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object); @@ -216,6 +223,20 @@ struct Q_QML_PRIVATE_EXPORT Lookup { void clear() { memset(&markDef, 0, sizeof(markDef)); } + + void releasePropertyCache() + { + if (getter == getterQObject + || getter == QQmlTypeWrapper::lookupSingletonProperty + || qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty + || qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty) { + if (QQmlPropertyCache *pc = qobjectLookup.propertyCache) + pc->release(); + } else if (getter == QQmlValueTypeWrapper::lookupGetter) { + if (QQmlPropertyCache *pc = qgadgetLookup.propertyCache) + pc->release(); + } + } }; Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value); @@ -223,6 +244,33 @@ Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value); // across 32-bit and 64-bit (matters when cross-compiling). Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0); +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData) +{ + lookup->releasePropertyCache(); + Q_ASSERT(ddata->propertyCache != nullptr); + lookup->qobjectLookup.propertyCache = ddata->propertyCache; + lookup->qobjectLookup.propertyCache->addref(); + lookup->qobjectLookup.propertyData = propertyData; +} + +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData, + const Object *self) +{ + lookup->qobjectLookup.ic = self->internalClass(); + setupQObjectLookup(lookup, ddata, propertyData); +} + + +inline void setupQObjectLookup( + Lookup *lookup, const QQmlData *ddata, QQmlPropertyData *propertyData, + const Object *self, const Object *qmlType) +{ + lookup->qobjectLookup.qmlTypeIc = qmlType->internalClass(); + setupQObjectLookup(lookup, ddata, propertyData, self); +} + } QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 6eece147a6..be6c614eda 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -294,11 +294,7 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r QQmlData *ddata = QQmlData::get(scopeObject, false); if (ddata && ddata->propertyCache) { ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, scopeObject))); - const QObjectWrapper *That = static_cast<const QObjectWrapper *>(val->objectValue()); - lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = propertyData; + QV4::setupQObjectLookup(lookup, ddata, propertyData, val->objectValue()); lookup->qmlContextPropertyGetter = QQmlContextWrapper::lookupScopeObjectProperty; } } @@ -326,11 +322,8 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r QQmlData *ddata = QQmlData::get(context->contextObject, false); if (ddata && ddata->propertyCache) { ScopedValue val(scope, base ? *base : Value::fromReturnedValue(QV4::QObjectWrapper::wrap(v4, context->contextObject))); - const QObjectWrapper *That = static_cast<const QObjectWrapper *>(val->objectValue()); - lookup->qobjectLookup.ic = That->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = propertyData; + QV4::setupQObjectLookup(lookup, ddata, propertyData, + val->objectValue()); lookup->qmlContextPropertyGetter = contextGetterFunction; } } else if (originalLookup) { diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 9899c9274e..e57cdd8278 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -875,26 +875,11 @@ ReturnedValue QObjectWrapper::virtualResolveLookupGetter(const Object *object, E return QV4::Object::virtualResolveLookupGetter(object, engine, lookup); } - lookup->qobjectLookup.ic = This->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = property; - lookup->getter = QV4::QObjectWrapper::lookupGetter; + QV4::setupQObjectLookup(lookup, ddata, property, This); + lookup->getter = QV4::Lookup::getterQObject; return lookup->getter(lookup, engine, *object); } -ReturnedValue QObjectWrapper::lookupGetter(Lookup *lookup, ExecutionEngine *engine, const Value &object) -{ - const auto revertLookup = [lookup, engine, &object]() { - lookup->qobjectLookup.propertyCache->release(); - lookup->qobjectLookup.propertyCache = nullptr; - lookup->getter = Lookup::getterGeneric; - return Lookup::getterGeneric(lookup, engine, object); - }; - - return lookupGetterImpl(lookup, engine, object, /*useOriginalProperty*/ false, revertLookup); -} - bool QObjectWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value) { diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index ac9cad2bdb..10ba79a5e9 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -183,7 +183,7 @@ struct Q_QML_EXPORT QObjectWrapper : public Object static ReturnedValue getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property); static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup); - static ReturnedValue lookupGetter(Lookup *l, ExecutionEngine *engine, const Value &object); + template <typename ReversalFunctor> static ReturnedValue lookupGetterImpl(Lookup *l, ExecutionEngine *engine, const Value &object, bool useOriginalProperty, ReversalFunctor revert); static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index 9eb81e566e..92bd369ccc 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -598,12 +598,8 @@ QObject *QQmlProperty::object() const */ QQmlProperty &QQmlProperty::operator=(const QQmlProperty &other) { - if (d) - d->release(); - d = other.d; - if (d) - d->addref(); - + QQmlProperty copied(other); + qSwap(d, copied.d); return *this; } diff --git a/src/qml/qml/qqmltypedata.cpp b/src/qml/qml/qqmltypedata.cpp index 92a90ea677..ebd139b6a9 100644 --- a/src/qml/qml/qqmltypedata.cpp +++ b/src/qml/qml/qqmltypedata.cpp @@ -211,18 +211,12 @@ bool QQmlTypeData::tryLoadFromDiskCache() } } - QQmlType containingType; - auto containingTypeName = finalUrl().fileName().split(QLatin1Char('.')).first(); - int major = -1, minor = -1; - QQmlImportNamespace *ns = nullptr; - m_importCache.resolveType(containingTypeName, &containingType, &major, &minor, &ns); for (auto&& ic: ics) { QString const nameString = m_compiledData->stringAt(ic.nameIndex); - QByteArray const name = nameString.toUtf8(); auto importUrl = finalUrl(); importUrl.setFragment(QString::number(ic.objectIndex)); auto import = new QQmlImportInstance(); - m_importCache.addInlineComponentImport(import, nameString, importUrl, containingType); + m_importCache.addInlineComponentImport(import, nameString, importUrl, QQmlType()); } return true; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index fa5d36503d..175de8b936 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -458,11 +458,8 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext); if (property) { ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton))); - lookup->qobjectLookup.qmlTypeIc = This->internalClass(); - lookup->qobjectLookup.ic = val->objectValue()->internalClass(); - lookup->qobjectLookup.propertyCache = ddata->propertyCache; - lookup->qobjectLookup.propertyCache->addref(); - lookup->qobjectLookup.propertyData = property; + setupQObjectLookup(lookup, ddata, property, + val->objectValue(), This); lookup->getter = QQmlTypeWrapper::lookupSingletonProperty; return lookup->getter(lookup, engine, *object); } diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h index 7b0910fa13..76479431dc 100644 --- a/src/qml/qtqmlglobal_p.h +++ b/src/qml/qtqmlglobal_p.h @@ -70,4 +70,26 @@ GHS_KEEP_REFERENCE(qml_register_types_QtQml); # define Q_QML_AUTOTEST_EXPORT #endif +// When doing macOS universal builds, JIT needs to be disabled for the ARM slice. +// Because both arm and x86_64 slices are built in one clang frontend invocation +// we need this hack to ensure each backend invocation sees the correct value +// of the feature definition. + +// Unset dummy value +#undef QT_QML_JIT_SUPPORTED_IMPL +// Compute per-arch value and save in extra define +#if QT_CONFIG(qml_jit) && !(defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM)) +# define QT_QML_JIT_SUPPORTED_IMPL 1 +#else +# define QT_QML_JIT_SUPPORTED_IMPL 0 +#endif +// Unset original feature value +#undef QT_FEATURE_qml_jit +// Set new value based on previous computation +#if QT_QML_JIT_SUPPORTED_IMPL +# define QT_FEATURE_qml_jit 1 +#else +# define QT_FEATURE_qml_jit -1 +#endif + #endif // QTQMLGLOBAL_P_H |