// 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 #include #include 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 mo(scope, engine->memoryManager->allocate(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()); return construct(static_cast(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(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(); Q_ASSERT(aMetaObject); const QMetaObjectWrapper *bMetaObject = b->as(); return bMetaObject && aMetaObject->metaObject() == bMetaObject->metaObject(); } DEFINE_OBJECT_VTABLE(QMetaObjectWrapper); } // namespace QV4 QT_END_NAMESPACE