Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qv4qobjectwrapper_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant
4
5#ifndef QV4QOBJECTWRAPPER_P_H
6#define QV4QOBJECTWRAPPER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qbipointer_p.h>
20#include <private/qintrusivelist_p.h>
21#include <private/qqmldata_p.h>
22#include <private/qv4functionobject_p.h>
23#include <private/qv4lookup_p.h>
24#include <private/qv4value_p.h>
25
26#include <QtCore/qglobal.h>
27#include <QtCore/qmetatype.h>
28#include <QtCore/qhash.h>
29
30#include <utility>
31
33
35
36class QObject;
37class QQmlData;
38class QQmlPropertyCache;
40class QQmlObjectOrGadget;
41
42namespace QV4 {
44
45namespace Heap {
46
47struct QQmlValueTypeWrapper;
48
51 {
52 Object::init();
54 }
55
56 void destroy() {
57 qObj.destroy();
58 Object::destroy();
59 }
60
61 QObject *object() const { return qObj.data(); }
63
64private:
66};
67
68#define QObjectMethodMembers(class, Member)
69 Member(class, Pointer, Object *, wrapper)
70
71DECLARE_EXPORTED_HEAP_OBJECT(QObjectMethod, FunctionObject) {
72 DECLARE_MARKOBJECTS(QObjectMethod)
73
74 QQmlPropertyData *methods;
75 alignas(alignof(QQmlPropertyData)) std::byte _singleMethod[sizeof(QQmlPropertyData)];
76 int methodCount;
77 int index;
78
79 void init(QV4::ExecutionEngine *engine, Object *wrapper, int index);
80 void destroy()
81 {
82 if (methods != reinterpret_cast<const QQmlPropertyData *>(&_singleMethod))
83 delete[] methods;
84 FunctionObject::destroy();
85 }
86
87 void ensureMethodsCache(const QMetaObject *thisMeta);
88 QString name() const;
89
90 const QMetaObject *metaObject() const;
91 QObject *object() const;
92
93 bool isDetached() const;
94 bool isAttachedTo(QObject *o) const;
95
96 enum ThisObjectMode {
97 Invalid,
98 Included,
99 Explicit,
100 };
101
102 QV4::Heap::QObjectMethod::ThisObjectMode checkThisObject(const QMetaObject *thisMeta) const;
103};
104
106 void init(QObject *object, int signalIndex);
107 void destroy() {
108 qObj.destroy();
109 Object::destroy();
110 }
112
113 QObject *object() const { return qObj.data(); }
114 void setObject(QObject *o) { qObj = o; }
115
116private:
117 QV4QPointer<QObject> qObj;
118};
119
120}
121
122struct Q_QML_EXPORT QObjectWrapper : public Object
123{
127
135
137
139
140 const QMetaObject *metaObject() const
141 {
142 if (QObject *o = object())
143 return o->metaObject();
144 return nullptr;
145 }
146
147 QObject *object() const { return d()->object(); }
148
151 Flags flags, bool *hasProperty = nullptr) const;
152
156 bool *hasProperty = nullptr, const QQmlPropertyData **property = nullptr);
157
158 static bool setQmlProperty(
161
162 Q_NODISCARD_X("Use ensureWrapper if you don't need the return value")
164 Q_NODISCARD_X("Throwing the const wrapper away can cause it to be garbage collected")
168
169 using Object::get;
170
173 static void setProperty(
175 const QQmlPropertyData *property, const Value &value);
176
177 void destroyObject(bool lastCall);
178
182
184
191 static bool virtualResolveLookupSetter(
194
195 static int virtualMetacall(Object *object, QMetaObject::Call call, int index, void **a);
196
197 static QString objectToString(
199
200protected:
201 static bool virtualIsEqualTo(Managed *that, Managed *o);
203
204 static const QQmlPropertyData *findProperty(
207
211
213 const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
214 static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver);
216
218 const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
220 const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
221
222private:
225};
226
228
229// We generally musn't pass ReturnedValue as arguments to other functions.
230// In this case, we do it solely for marking purposes so it's fine.
241
243{
245 return QV4::Encode::null();
246
247 auto ddata = QQmlData::get(object);
249 // We own the JS object
250 return ddata->jsWrapper.value();
251 }
252
253 const auto rv = wrap_slowPath(engine, object);
255 return rv;
256}
257
258// Unfortunately we still need a non-const QObject* here because QQmlData needs to register itself in QObjectPrivate.
268
269inline bool canConvert(const QQmlPropertyCache *fromMo, const QQmlPropertyCache *toMo)
270{
271 while (fromMo) {
272 if (fromMo == toMo)
273 return true;
274 fromMo = fromMo->parent().data();
275 }
276 return false;
277}
278
279template <typename ReversalFunctor>
283{
284 // we can safely cast to a QV4::Object here. If object is something else,
285 // the internal class won't match
286 Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
287 if (!o || o->internalClass != lookup->qobjectLookup.ic)
288 return revertLookup();
289
290 Heap::QObjectWrapper *This = static_cast<Heap::QObjectWrapper *>(o);
291 QObject *qobj = This->object();
293 return QV4::Encode::undefined();
294
295 QQmlData *ddata = QQmlData::get(qobj, /*create*/false);
296 if (!ddata)
297 return revertLookup();
298
301 // If the property is overridden and the lookup allows overrides to be considered,
302 // we have to revert here and redo the lookup from scratch.
304 && ((flags & AllowOverride)
305 || property->isFunction()
306 || property->isSignalHandler())) {
307 return revertLookup();
308 }
309
311 return revertLookup();
312 }
313
315}
316
317template <typename ReversalFunctor>
321{
322 // we can safely cast to a QV4::Object here. If object is something else,
323 // the internal class won't match
324 Heap::Object *o = static_cast<Heap::Object *>(object.heapObject());
326 return revertLookup();
327
328 Heap::QObjectWrapper *This = static_cast<Heap::QObjectWrapper *>(o);
329 QObject *qobj = This->object();
331 return QV4::Encode::undefined();
332
333 QQmlData *ddata = QQmlData::get(qobj, /*create*/false);
334 if (!ddata)
335 return revertLookup();
336
340 return revertLookup();
341
343 return revertLookup();
344 }
345
347 if (method->isDetached())
348 return method->asReturnedValue();
349 }
350
351 if (!property) // was toString() or destroy()
352 return revertLookup();
353
356 if (!v->as<QObjectMethod>())
357 return revertLookup();
358
360 return v->asReturnedValue();
361}
362
363struct QQmlValueTypeWrapper;
364
365struct Q_QML_EXPORT QObjectMethod : public QV4::FunctionObject
366{
369
370 enum { DestroyMethod = -1, ToStringMethod = -2 };
371
373 static ReturnedValue create(
375 static ReturnedValue create(
378
379 int methodIndex() const { return d()->index; }
380 QObject *object() const { return d()->object(); }
381
384 QV4::ExecutionEngine *ctx, QObject *o, const Value *args, int argc) const;
385 bool method_destroy(
386 QV4::ExecutionEngine *engine, QObject *o, int delay) const;
387
389 const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
390 static void virtualCallWithMetaTypes(
392 void **argv, const QMetaType *types, int argc);
393
395 const Value *thisObject, const Value *argv, int argc) const;
397 QObject *thisObject, void **argv, const QMetaType *types, int argc) const;
398
399 static std::pair<QObject *, int> extractQtMethod(const QV4::FunctionObject *function);
400
401 static bool isExactMatch(
402 const QMetaMethod &method, void **argv, int argc, const QMetaType *types);
403
404private:
405 friend struct QMetaObjectWrapper;
406
410
413 void **argv, int argc, const QMetaType *types);
414
419};
420
421struct Q_QML_EXPORT QmlSignalHandler : public QV4::Object
422{
426
427 int signalIndex() const { return d()->signalIndex; }
428 QObject *object() const { return d()->object(); }
429
430 ReturnedValue call(const Value *thisObject, const Value *argv, int argc) const;
431
432 static void initProto(ExecutionEngine *v4);
433};
434
436
439{
441public:
444
446
447 ConstIterator begin() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constBegin(); }
448 Iterator begin() { return QHash<QObjectBiPointer, QV4::WeakValue>::begin(); }
449 ConstIterator end() const { return QHash<QObjectBiPointer, QV4::WeakValue>::constEnd(); }
450 Iterator end() { return QHash<QObjectBiPointer, QV4::WeakValue>::end(); }
451
452 template<typename Pointer>
453 void insert(Pointer key, Heap::Object *value)
454 {
455 QHash<QObjectBiPointer, WeakValue>::operator[](key).set(value->internalClass->engine, value);
456 connect(key, SIGNAL(destroyed(QObject*)), this, SLOT(removeDestroyedObject(QObject*)));
457 }
458
459 template<typename Pointer>
460 ReturnedValue value(Pointer key) const
461 {
462 ConstIterator it = find(key);
463 return it == end()
464 ? QV4::WeakValue().value()
465 : it->value();
466 }
467
469
470 template<typename Pointer>
471 void remove(Pointer key)
472 {
473 Iterator it = find(key);
474 if (it == end())
475 return;
476 erase(it);
477 }
478
479 template<typename Pointer>
480 void mark(Pointer key, MarkStack *markStack)
481 {
482 Iterator it = find(key);
483 if (it == end())
484 return;
485 it->markOnce(markStack);
486 }
487
488private Q_SLOTS:
490};
491
492}
493
494QT_END_NAMESPACE
495
496#endif // QV4QOBJECTWRAPPER_P_H
QV4::ExecutionEngine * engine
Definition qv4mm_p.h:484
void insert(Pointer key, Heap::Object *value)
void mark(Pointer key, MarkStack *markStack)
QHash< QObjectBiPointer, QV4::WeakValue >::Iterator Iterator
ReturnedValue value(Pointer key) const
Combined button and popup list for selecting options.
DECLARE_EXPORTED_HEAP_OBJECT(QObjectMethod, FunctionObject)
Definition qjsvalue.h:24
bool canConvert(const QQmlPropertyCache *fromMo, const QQmlPropertyCache *toMo)
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)
#define V4_NEEDS_DESTROY
#define Q_MANAGED_TYPE(type)
void init(QObject *object, int signalIndex)
Iterator & operator=(const Iterator &o)
bool operator!=(const Iterator &other)
static ExecutionEngine * getEngine(const Value *v)
static void free(Value *v)
void mark(MarkStack *markStack)
const SparseArrayNode * begin() const
const SparseArrayNode * end() const