diff options
Diffstat (limited to 'src/qml/jsruntime/qv4qmetaobjectwrapper.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4qmetaobjectwrapper.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/qml/jsruntime/qv4qmetaobjectwrapper.cpp b/src/qml/jsruntime/qv4qmetaobjectwrapper.cpp new file mode 100644 index 0000000000..6521c98dbf --- /dev/null +++ b/src/qml/jsruntime/qv4qmetaobjectwrapper.cpp @@ -0,0 +1,111 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qv4qmetaobjectwrapper_p.h" + +#include <private/qqmlobjectorgadget_p.h> +#include <private/qv4jscall_p.h> +#include <private/qv4qobjectwrapper_p.h> + +QT_BEGIN_NAMESPACE + +using namespace Qt::StringLiterals; + +namespace QV4 { + +void Heap::QMetaObjectWrapper::init(const QMetaObject *metaObject) +{ + FunctionObject::init(); + m_metaObject = metaObject; +} + +void Heap::QMetaObjectWrapper::destroy() +{ + delete[] m_constructors; + FunctionObject::destroy(); +} + +ReturnedValue QMetaObjectWrapper::create(ExecutionEngine *engine, const QMetaObject* metaObject) { + + Scope scope(engine); + Scoped<QMetaObjectWrapper> mo(scope, engine->memoryManager->allocate<QMetaObjectWrapper>(metaObject)->asReturnedValue()); + mo->init(engine); + return mo->asReturnedValue(); +} + +void QMetaObjectWrapper::init(ExecutionEngine *) { + const QMetaObject &mo = *d()->metaObject(); + + for (int i = 0; i < mo.enumeratorCount(); i++) { + QMetaEnum Enum = mo.enumerator(i); + for (int k = 0; k < Enum.keyCount(); k++) { + const char* key = Enum.key(k); + const int value = Enum.value(k); + defineReadonlyProperty(QLatin1String(key), Value::fromInt32(value)); + } + } +} + +ReturnedValue QMetaObjectWrapper::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) +{ + Q_ASSERT(f->as<QMetaObjectWrapper>()); + return construct(static_cast<const QMetaObjectWrapper*>(f)->d(), argv, argc); +} + +ReturnedValue QMetaObjectWrapper::constructInternal( + const QMetaObject *mo, const QQmlPropertyData *constructors, Heap::FunctionObject *d, + const Value *argv, int argc) +{ + ExecutionEngine *v4 = d->internalClass->engine; + + if (!constructors) { + return v4->throwTypeError(QLatin1String(mo->className()) + + QLatin1String(" has no invokable constructor")); + } + + Scope scope(v4); + ScopedObject object(scope); + JSCallData cData(nullptr, argv, argc); + CallData *callData = cData.callData(scope); + + const QQmlObjectOrGadget objectOrGadget(mo); + + const auto callType = [](QMetaType metaType) { + return metaType.flags() & QMetaType::PointerToQObject + ? QMetaObject::CreateInstance + : QMetaObject::ConstructInPlace; + }; + + const int constructorCount = mo->constructorCount(); + if (constructorCount == 1) { + object = QObjectMethod::callPrecise( + objectOrGadget, constructors[0], v4, callData, + callType(constructors[0].propType())); + } else if (const QQmlPropertyData *ctor = QObjectMethod::resolveOverloaded( + objectOrGadget, constructors, constructorCount, v4, callData)) { + object = QObjectMethod::callPrecise( + objectOrGadget, *ctor, v4, callData, callType(ctor->propType())); + } + + if (object) { + Scoped<FunctionObject> functionObject(scope, d); + object->defineDefaultProperty(v4->id_constructor(), functionObject); + object->setPrototypeOf(functionObject); + } + + return object.asReturnedValue(); +} + +bool QMetaObjectWrapper::virtualIsEqualTo(Managed *a, Managed *b) +{ + const QMetaObjectWrapper *aMetaObject = a->as<QMetaObjectWrapper>(); + Q_ASSERT(aMetaObject); + const QMetaObjectWrapper *bMetaObject = b->as<QMetaObjectWrapper>(); + return bMetaObject && aMetaObject->metaObject() == bMetaObject->metaObject(); +} + +DEFINE_OBJECT_VTABLE(QMetaObjectWrapper); + +} // namespace QV4 + +QT_END_NAMESPACE |