diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2019-08-30 13:22:43 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2019-09-06 10:34:08 +0200 |
commit | 81ac3bd856e7c6ead21fc2efc34cdf52cd9196b1 (patch) | |
tree | 857629b38df9f52d6e02c095af9248a0783a1705 | |
parent | f2262b10e23cc4f90838067bc658807ab8c8d3a8 (diff) |
Implement lookups for enums
Task-number: QTBUG-77237
Change-Id: Ibe8fe8044b96d9d4b7a1a31b432daa886edbd799
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4lookup_p.h | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 56 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper_p.h | 2 |
3 files changed, 67 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4lookup_p.h b/src/qml/jsruntime/qv4lookup_p.h index fb4c5f6864..31c90b31f6 100644 --- a/src/qml/jsruntime/qv4lookup_p.h +++ b/src/qml/jsruntime/qv4lookup_p.h @@ -155,6 +155,15 @@ struct Q_QML_PRIVATE_EXPORT Lookup { Heap::Object *qmlTypeWrapper; quintptr unused2; } qmlTypeLookup; + struct { + Heap::InternalClass *ic; + quintptr unused; + ReturnedValue encodedEnumValue; + } qmlEnumValueLookup; + struct { + Heap::InternalClass *ic; + Heap::Object *qmlScopedEnumWrapper; + } qmlScopedEnumWrapperLookup; }; uint nameIndex; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 931f37b35a..ef4a628a04 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -476,6 +476,34 @@ ReturnedValue QQmlTypeWrapper::virtualResolveLookupGetter(const Object *object, } // Fall through to base implementation } + + if (name->startsWithUpper()) { + bool ok = false; + int value = type.enumValue(QQmlEnginePrivate::get(engine->qmlEngine()), name, &ok); + if (ok) { + lookup->qmlEnumValueLookup.ic = This->internalClass(); + lookup->qmlEnumValueLookup.encodedEnumValue + = QV4::Value::fromInt32(value).asReturnedValue(); + lookup->getter = QQmlTypeWrapper::lookupEnumValue; + return lookup->getter(lookup, engine, *object); + } + + value = type.scopedEnumIndex(QQmlEnginePrivate::get(engine->qmlEngine()), name, &ok); + if (ok) { + Scoped<QQmlScopedEnumWrapper> enumWrapper( + scope, engine->memoryManager->allocate<QQmlScopedEnumWrapper>()); + enumWrapper->d()->typePrivate = type.priv(); + QQmlType::refHandle(enumWrapper->d()->typePrivate); + enumWrapper->d()->scopeEnumIndex = value; + + lookup->qmlScopedEnumWrapperLookup.ic = This->internalClass(); + lookup->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper + = static_cast<Heap::Object*>(enumWrapper->heapObject()); + lookup->getter = QQmlTypeWrapper::lookupScopedEnum; + return enumWrapper.asReturnedValue(); + } + // Fall through to base implementation + } // Fall through to base implementation } return QV4::Object::virtualResolveLookupGetter(object, engine, lookup); @@ -519,6 +547,34 @@ ReturnedValue QQmlTypeWrapper::lookupSingletonProperty(Lookup *l, ExecutionEngin return QObjectWrapper::lookupGetterImpl(l, engine, obj, /*useOriginalProperty*/ true, revertLookup); } +ReturnedValue QQmlTypeWrapper::lookupEnumValue(Lookup *l, ExecutionEngine *engine, const Value &base) +{ + auto *o = static_cast<Heap::Object *>(base.heapObject()); + if (!o || o->internalClass != l->qmlEnumValueLookup.ic) { + l->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(l, engine, base); + } + + return l->qmlEnumValueLookup.encodedEnumValue; +} + +ReturnedValue QQmlTypeWrapper::lookupScopedEnum(Lookup *l, ExecutionEngine *engine, const Value &base) +{ + Scope scope(engine); + Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, static_cast<Heap::QQmlScopedEnumWrapper *>( + l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper)); + + auto *o = static_cast<Heap::Object *>(base.heapObject()); + if (!o || o->internalClass != l->qmlScopedEnumWrapperLookup.ic) { + QQmlType::derefHandle(enumWrapper->d()->typePrivate); + l->qmlScopedEnumWrapperLookup.qmlScopedEnumWrapper = nullptr; + l->getter = Lookup::getterGeneric; + return Lookup::getterGeneric(l, engine, base); + } + + return enumWrapper.asReturnedValue(); +} + void Heap::QQmlScopedEnumWrapper::destroy() { QQmlType::derefHandle(typePrivate); diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 6b51f421b3..7dc3f55310 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -115,6 +115,8 @@ struct Q_QML_EXPORT QQmlTypeWrapper : Object static bool virtualResolveLookupSetter(Object *object, ExecutionEngine *engine, Lookup *lookup, const Value &value); static ReturnedValue lookupSingletonProperty(Lookup *l, ExecutionEngine *engine, const Value &base); + static ReturnedValue lookupEnumValue(Lookup *l, ExecutionEngine *engine, const Value &base); + static ReturnedValue lookupScopedEnum(Lookup *l, ExecutionEngine *engine, const Value &base); protected: static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty); |