1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 BasysKom GmbH.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtQml module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#ifndef QQMLVMEMETAOBJECT_P_H
42#define QQMLVMEMETAOBJECT_P_H
43
44//
45// W A R N I N G
46// -------------
47//
48// This file is not part of the Qt API. It exists purely as an
49// implementation detail. This header file may change from version to
50// version without notice, or even be removed.
51//
52// We mean it.
53//
54
55#include "qqml.h"
56
57#include <QtCore/QMetaObject>
58#include <QtCore/QBitArray>
59#include <QtCore/QPair>
60#include <QtCore/QDate>
61#include <QtCore/qlist.h>
62#include <QtCore/qdebug.h>
63
64#include <private/qobject_p.h>
65
66#include "qqmlguard_p.h"
67#include "qqmlcontext_p.h"
68
69#include <private/qflagpointer_p.h>
70
71#include <private/qv4object_p.h>
72#include <private/qv4value_p.h>
73#include <private/qqmlpropertyvalueinterceptor_p.h>
74
75QT_BEGIN_NAMESPACE
76
77class QQmlVMEMetaObject;
78class QQmlVMEVariantQObjectPtr : public QQmlGuard<QObject>
79{
80public:
81 inline QQmlVMEVariantQObjectPtr();
82 inline ~QQmlVMEVariantQObjectPtr() override;
83
84 inline void objectDestroyed(QObject *) override;
85 inline void setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index);
86
87 QQmlVMEMetaObject *m_target;
88 int m_index;
89};
90
91
92class Q_QML_PRIVATE_EXPORT QQmlInterceptorMetaObject : public QAbstractDynamicMetaObject
93{
94public:
95 QQmlInterceptorMetaObject(QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache);
96 ~QQmlInterceptorMetaObject() override;
97
98 void registerInterceptor(QQmlPropertyIndex index, QQmlPropertyValueInterceptor *interceptor);
99
100 static QQmlInterceptorMetaObject *get(QObject *obj);
101
102 QAbstractDynamicMetaObject *toDynamicMetaObject(QObject *o) override;
103
104 // Used by auto-tests for inspection
105 QQmlPropertyCache *propertyCache() const { return cache.data(); }
106
107 bool intercepts(QQmlPropertyIndex propertyIndex) const
108 {
109 for (auto it = interceptors; it; it = it->m_next) {
110 if (it->m_propertyIndex == propertyIndex)
111 return true;
112 }
113 if (auto parentInterceptor = ((parent.isT1() && parent.flag()) ? static_cast<QQmlInterceptorMetaObject *>(parent.asT1()) : nullptr))
114 return parentInterceptor->intercepts(propertyIndex);
115 return false;
116 }
117
118protected:
119 int metaCall(QObject *o, QMetaObject::Call c, int id, void **a) override;
120 bool intercept(QMetaObject::Call c, int id, void **a);
121
122public:
123 QObject *object;
124 QQmlRefPointer<QQmlPropertyCache> cache;
125 QBiPointer<QDynamicMetaObjectData, const QMetaObject> parent;
126
127 QQmlPropertyValueInterceptor *interceptors;
128 bool hasAssignedMetaObjectData;
129};
130
131inline QQmlInterceptorMetaObject *QQmlInterceptorMetaObject::get(QObject *obj)
132{
133 if (obj) {
134 if (QQmlData *data = QQmlData::get(obj)) {
135 if (data->hasInterceptorMetaObject)
136 return static_cast<QQmlInterceptorMetaObject *>(QObjectPrivate::get(obj)->metaObject);
137 }
138 }
139
140 return nullptr;
141}
142
143class QQmlVMEMetaObjectEndpoint;
144class Q_QML_PRIVATE_EXPORT QQmlVMEMetaObject : public QQmlInterceptorMetaObject
145{
146public:
147 QQmlVMEMetaObject(QV4::ExecutionEngine *engine, QObject *obj, const QQmlRefPointer<QQmlPropertyCache> &cache, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &qmlCompilationUnit, int qmlObjectId);
148 ~QQmlVMEMetaObject() override;
149
150 bool aliasTarget(int index, QObject **target, int *coreIndex, int *valueTypeIndex) const;
151 QV4::ReturnedValue vmeMethod(int index) const;
152 void setVmeMethod(int index, const QV4::Value &function);
153 QV4::ReturnedValue vmeProperty(int index) const;
154 void setVMEProperty(int index, const QV4::Value &v);
155
156 void connectAliasSignal(int index, bool indexInSignalRange);
157
158 static inline QQmlVMEMetaObject *get(QObject *o);
159 static QQmlVMEMetaObject *getForProperty(QObject *o, int coreIndex);
160 static QQmlVMEMetaObject *getForMethod(QObject *o, int coreIndex);
161 static QQmlVMEMetaObject *getForSignal(QObject *o, int coreIndex);
162
163protected:
164 int metaCall(QObject *o, QMetaObject::Call _c, int _id, void **_a) override;
165
166public:
167 QV4::ExecutionEngine *engine;
168 QQmlGuardedContextData ctxt;
169
170 inline int propOffset() const;
171 inline int methodOffset() const;
172 inline int signalOffset() const;
173 inline int signalCount() const;
174
175 QQmlVMEMetaObjectEndpoint *aliasEndpoints;
176
177 QV4::WeakValue propertyAndMethodStorage;
178 QV4::MemberData *propertyAndMethodStorageAsMemberData() const;
179
180 int readPropertyAsInt(int id) const;
181 bool readPropertyAsBool(int id) const;
182 double readPropertyAsDouble(int id) const;
183 QString readPropertyAsString(int id) const;
184 QSizeF readPropertyAsSizeF(int id) const;
185 QPointF readPropertyAsPointF(int id) const;
186 QUrl readPropertyAsUrl(int id) const;
187 QDate readPropertyAsDate(int id) const;
188 QDateTime readPropertyAsDateTime(int id);
189 QRectF readPropertyAsRectF(int id) const;
190 QObject *readPropertyAsQObject(int id) const;
191 QList<QObject *> *readPropertyAsList(int id) const;
192
193 void writeProperty(int id, int v);
194 void writeProperty(int id, bool v);
195 void writeProperty(int id, double v);
196 void writeProperty(int id, const QString& v);
197 void writeProperty(int id, const QPointF& v);
198 void writeProperty(int id, const QSizeF& v);
199 void writeProperty(int id, const QUrl& v);
200 void writeProperty(int id, const QDate& v);
201 void writeProperty(int id, const QDateTime& v);
202 void writeProperty(int id, const QRectF& v);
203 void writeProperty(int id, QObject *v);
204
205 void ensureQObjectWrapper();
206
207 void mark(QV4::MarkStack *markStack);
208
209 void connectAlias(int aliasId);
210
211 QV4::ReturnedValue method(int) const;
212
213 QV4::ReturnedValue readVarProperty(int) const;
214 void writeVarProperty(int, const QV4::Value &);
215 QVariant readPropertyAsVariant(int) const;
216 void writeProperty(int, const QVariant &);
217
218 inline QQmlVMEMetaObject *parentVMEMetaObject() const;
219
220 void activate(QObject *, int, void **);
221
222 QList<QQmlVMEVariantQObjectPtr *> varObjectGuards;
223
224 QQmlVMEVariantQObjectPtr *getQObjectGuardForProperty(int) const;
225
226
227 // keep a reference to the compilation unit in order to still
228 // do property access when the context has been invalidated.
229 QQmlRefPointer<QV4::ExecutableCompilationUnit> compilationUnit;
230 const QV4::CompiledData::Object *compiledObject;
231};
232
233QQmlVMEMetaObject *QQmlVMEMetaObject::get(QObject *obj)
234{
235 if (obj) {
236 if (QQmlData *data = QQmlData::get(obj)) {
237 if (data->hasVMEMetaObject)
238 return static_cast<QQmlVMEMetaObject *>(QObjectPrivate::get(obj)->metaObject);
239 }
240 }
241
242 return nullptr;
243}
244
245int QQmlVMEMetaObject::propOffset() const
246{
247 return cache->propertyOffset();
248}
249
250int QQmlVMEMetaObject::methodOffset() const
251{
252 return cache->methodOffset();
253}
254
255int QQmlVMEMetaObject::signalOffset() const
256{
257 return cache->signalOffset();
258}
259
260int QQmlVMEMetaObject::signalCount() const
261{
262 return cache->signalCount();
263}
264
265QQmlVMEMetaObject *QQmlVMEMetaObject::parentVMEMetaObject() const
266{
267 if (parent.isT1() && parent.flag())
268 return static_cast<QQmlVMEMetaObject *>(parent.asT1());
269
270 return nullptr;
271}
272
273QT_END_NAMESPACE
274
275#endif // QQMLVMEMETAOBJECT_P_H
276