1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// 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();
this->metaObject = metaObject;
constructors = nullptr;
constructorCount = 0;
}
void Heap::QMetaObjectWrapper::destroy()
{
delete[] constructors;
}
void Heap::QMetaObjectWrapper::ensureConstructorsCache() {
const int count = metaObject->constructorCount();
if (constructorCount != count) {
delete[] constructors;
constructorCount = count;
if (count == 0) {
constructors = nullptr;
return;
}
constructors = new QQmlPropertyData[count];
for (int i = 0; i < count; ++i) {
QMetaMethod method = metaObject->constructor(i);
QQmlPropertyData &d = constructors[i];
d.load(method);
d.setCoreIndex(i);
}
}
}
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 *)
{
const QMetaObjectWrapper *This = static_cast<const QMetaObjectWrapper*>(f);
return This->constructInternal(argv, argc);
}
ReturnedValue QMetaObjectWrapper::constructInternal(const Value *argv, int argc) const
{
d()->ensureConstructorsCache();
ExecutionEngine *v4 = engine();
const QMetaObject* mo = d()->metaObject;
if (d()->constructorCount == 0) {
return v4->throwTypeError(QLatin1String(mo->className())
+ QLatin1String(" has no invokable constructor"));
}
Scope scope(v4);
Scoped<QObjectWrapper> object(scope);
JSCallData cData(nullptr, argv, argc);
CallData *callData = cData.callData(scope);
const QQmlObjectOrGadget objectOrGadget(mo);
if (d()->constructorCount == 1) {
object = QObjectMethod::callPrecise(
objectOrGadget, d()->constructors[0], v4, callData, QMetaObject::CreateInstance);
} else if (const QQmlPropertyData *ctor = QObjectMethod::resolveOverloaded(
objectOrGadget, d()->constructors, d()->constructorCount, v4, callData)) {
object = QObjectMethod::callPrecise(
objectOrGadget, *ctor, v4, callData, QMetaObject::CreateInstance);
}
if (object) {
Scoped<QMetaObjectWrapper> metaObject(scope, this);
object->defineDefaultProperty(v4->id_constructor(), metaObject);
object->setPrototypeOf(const_cast<QMetaObjectWrapper*>(this));
}
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
|