aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorMichael Brasser <mbrasser@ford.com>2019-01-03 16:28:16 -0600
committerMichael Brasser <michael.brasser@live.com>2019-03-20 18:55:39 +0000
commitf9dac6f900fde93014305854b1bf3a81d9e58b92 (patch)
tree66a5f73cdcefb41dca8cbd61d565748cef0ac037 /src/qml/qml
parentbb34abcc05d11f23c329f4c52aab638d991c1b98 (diff)
Accelerate lookup of singleton properties
Task-number: QTBUG-69898 Change-Id: Id03ba543fa293da2690099c3e6f94b2725de562f Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp61
-rw-r--r--src/qml/qml/qqmltypewrapper_p.h3
2 files changed, 64 insertions, 0 deletions
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index 4089a7f030..d30c225741 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -47,6 +47,8 @@
#include <private/qv4functionobject_p.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qv4identifiertable_p.h>
+#include <private/qv4lookup_p.h>
QT_BEGIN_NAMESPACE
@@ -169,6 +171,7 @@ static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *n
ReturnedValue QQmlTypeWrapper::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
{
+ // Keep this code in sync with ::virtualResolveLookupGetter
Q_ASSERT(m->as<QQmlTypeWrapper>());
if (!id.isString())
@@ -425,6 +428,64 @@ ReturnedValue QQmlTypeWrapper::virtualInstanceOf(const Object *typeObject, const
return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType));
}
+ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup)
+{
+ // Keep this code in sync with ::virtualGet
+ PropertyKey id = engine->identifierTable->asPropertyKey(engine->currentStackFrame->v4Function->compilationUnit->runtimeStrings[lookup->nameIndex]);
+ if (!id.isString())
+ return Object::virtualResolveLookupGetter(object, engine, lookup);
+ Scope scope(engine);
+
+ const QQmlTypeWrapper *This = static_cast<const QQmlTypeWrapper *>(object);
+ ScopedString name(scope, id.asStringOrSymbol());
+ QQmlContextData *qmlContext = engine->callingQmlContext();
+
+ Scoped<QQmlTypeWrapper> w(scope, static_cast<const QQmlTypeWrapper *>(This));
+ QQmlType type = w->d()->type();
+
+ if (type.isValid()) {
+
+ if (type.isSingleton()) {
+ QQmlEngine *e = engine->qmlEngine();
+ QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo();
+ siinfo->init(e);
+
+ QObject *qobjectSingleton = siinfo->qobjectApi(e);
+ if (qobjectSingleton) {
+
+ const bool includeEnums = w->d()->mode == Heap::QQmlTypeWrapper::IncludeEnums;
+ if (!includeEnums || !name->startsWithUpper()) {
+ QQmlData *ddata = QQmlData::get(qobjectSingleton, false);
+ if (ddata && ddata->propertyCache) {
+ ScopedValue val(scope, Value::fromReturnedValue(QV4::QObjectWrapper::wrap(engine, qobjectSingleton)));
+ QQmlPropertyData *property = ddata->propertyCache->property(name.getPointer(), qobjectSingleton, qmlContext);
+ if (property) {
+ lookup->qobjectLookup.ic = This->internalClass();
+ lookup->qobjectLookup.staticQObject = static_cast<Heap::QObjectWrapper *>(val->heapObject());
+ lookup->qobjectLookup.propertyCache = ddata->propertyCache;
+ lookup->qobjectLookup.propertyCache->addref();
+ lookup->qobjectLookup.propertyData = property;
+ lookup->getter = QV4::QObjectWrapper::lookupGetter;
+ return lookup->getter(lookup, engine, *This);
+ }
+ // Fall through to base implementation
+ }
+ // Fall through to base implementation
+ }
+ // Fall through to base implementation
+ }
+ // Fall through to base implementation
+ }
+ // Fall through to base implementation
+ }
+ return QV4::Object::virtualResolveLookupGetter(object, engine, lookup);
+}
+
+bool QQmlTypeWrapper::virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value)
+{
+ return Object::virtualResolveLookupSetter(object, engine, lookup, value);
+}
+
void Heap::QQmlScopedEnumWrapper::destroy()
{
QQmlType::derefHandle(typePrivate);
diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h
index fa1ad56902..44e82dec2b 100644
--- a/src/qml/qml/qqmltypewrapper_p.h
+++ b/src/qml/qml/qqmltypewrapper_p.h
@@ -111,6 +111,9 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object
static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlRefPointer<QQmlTypeNameCache> &, const QQmlImportRef *,
Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums);
+ static ReturnedValue virtualResolveLookupGetter(const Object *object, ExecutionEngine *engine, Lookup *lookup);
+ static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value);
+
protected:
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);