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#ifndef QMLJS_MANAGED_H
4#define QMLJS_MANAGED_H
5
6//
7// W A R N I N G
8// -------------
9//
10// This file is not part of the Qt API. It exists purely as an
11// implementation detail. This header file may change from version to
12// version without notice, or even be removed.
13//
14// We mean it.
15//
16
17#include "qv4global_p.h"
18#include "qv4value_p.h"
19#include "qv4enginebase_p.h"
20#include <private/qv4heap_p.h>
21#include <private/qv4vtable_p.h>
22
23QT_BEGIN_NAMESPACE
24
25namespace QV4 {
26
27#define Q_MANAGED_CHECK \
28 template <typename Type> inline void qt_check_for_QMANAGED_macro(const Type *_q_argument) const \
29 { int i = qYouForgotTheQ_MANAGED_Macro(this, _q_argument); i = i + 1; }
30
31template <typename T>
32inline int qYouForgotTheQ_MANAGED_Macro(T, T) { return 0; }
33
34template <typename T1, typename T2>
35inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
36
37#define V4_MANAGED_SIZE_TEST void __dataTest() { static_assert (sizeof(*this) == sizeof(Managed), "Classes derived from Managed can't have own data members."); }
38
39#define V4_NEEDS_DESTROY static void virtualDestroy(QV4::Heap::Base *b) { static_cast<Data *>(b)->destroy(); }
40
41
42#define V4_MANAGED_ITSELF(DataClass, superClass) \
43 public: \
44 Q_MANAGED_CHECK \
45 typedef QV4::Heap::DataClass Data; \
46 typedef superClass SuperClass; \
47 static const QV4::VTable static_vtbl; \
48 static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
49 V4_MANAGED_SIZE_TEST \
50 QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \
51 QV4::Heap::DataClass *d() const { \
52 QV4::Heap::DataClass *dptr = d_unchecked(); \
53 dptr->_checkIsInitialized(); \
54 return dptr; \
55 }
56
57#define V4_MANAGED(DataClass, superClass) \
58 private: \
59 DataClass() = delete; \
60 Q_DISABLE_COPY(DataClass) \
61 V4_MANAGED_ITSELF(DataClass, superClass) \
62 Q_STATIC_ASSERT(std::is_trivial_v<QV4::Heap::DataClass>);
63
64#define Q_MANAGED_TYPE(type) \
65 public: \
66 enum { MyType = Type_##type };
67
68#define V4_INTERNALCLASS(c) \
69 static Heap::InternalClass *defaultInternalClass(QV4::EngineBase *e) \
70 { return e->internalClasses(QV4::EngineBase::Class_##c); }
71
72struct Q_QML_EXPORT Managed : Value, VTableBase
73{
74 V4_MANAGED_ITSELF(Base, Managed)
75 enum {
76 IsExecutionContext = false,
77 IsString = false,
78 IsStringOrSymbol = false,
79 IsObject = false,
80 IsTailCallable = false,
81 IsErrorObject = false,
82 IsArrayData = false
83 };
84private:
85 void *operator new(size_t);
86 Managed() = delete;
87 Q_DISABLE_COPY(Managed)
88
89public:
90 enum { NInlineProperties = 0 };
91
92 enum Type {
93 Type_Invalid,
94 Type_String,
95 Type_Object,
96 Type_Symbol,
97 Type_ArrayObject,
98 Type_FunctionObject,
99 Type_GeneratorObject,
100 Type_BooleanObject,
101 Type_NumberObject,
102 Type_StringObject,
103 Type_SymbolObject,
104 Type_DateObject,
105 Type_RegExpObject,
106 Type_ErrorObject,
107 Type_ArgumentsObject,
108 Type_JsonObject,
109 Type_MathObject,
110 Type_ProxyObject,
111 Type_UrlObject,
112 Type_UrlSearchParamsObject,
113
114 Type_ExecutionContext,
115 Type_InternalClass,
116 Type_SetIteratorObject,
117 Type_MapIteratorObject,
118 Type_ArrayIteratorObject,
119 Type_StringIteratorObject,
120 Type_ForInIterator,
121 Type_RegExp,
122
123 Type_V4Sequence,
124 Type_QmlListProperty,
125 Type_V4QObjectWrapper,
126 Type_QMLTypeWrapper,
127 Type_V4ReferenceObject,
128 Type_QMLValueTypeWrapper,
129 };
130 Q_MANAGED_TYPE(Invalid)
131
132 Heap::InternalClass *internalClass() const { return d()->internalClass; }
133 const VTable *vtable() const { return d()->internalClass->vtable; }
134 inline ExecutionEngine *engine() const { return internalClass()->engine; }
135
136 bool isV4SequenceType() const { return d()->internalClass->vtable->type == Type_V4Sequence; }
137 bool isV4QObjectWrapper() const { return d()->internalClass->vtable->type == Type_V4QObjectWrapper; }
138 bool isQmlListPropertyType() const { return d()->internalClass->vtable->type == Type_QmlListProperty; }
139 bool isArrayLike() const { return isArrayObject() || isV4SequenceType() || isQmlListPropertyType(); }
140
141 bool isArrayObject() const { return d()->internalClass->vtable->type == Type_ArrayObject; }
142 bool isStringObject() const { return d()->internalClass->vtable->type == Type_StringObject; }
143 bool isSymbolObject() const { return d()->internalClass->vtable->type == Type_SymbolObject; }
144
145 QString className() const;
146
147 bool isEqualTo(const Managed *other) const
148 { return d()->internalClass->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
149
150 bool inUse() const { return d()->inUse(); }
151 bool markBit() const { return d()->isMarked(); }
152 inline void mark(MarkStack *markStack);
153
154 Q_ALWAYS_INLINE Heap::Base *heapObject() const {
155 return m();
156 }
157
158 template<typename T> inline T *cast() {
159 return static_cast<T *>(this);
160 }
161 template<typename T> inline const T *cast() const {
162 return static_cast<const T *>(this);
163 }
164
165protected:
166 static bool virtualIsEqualTo(Managed *m, Managed *other);
167
168private:
169 friend class MemoryManager;
170 friend struct Identifiers;
171 friend struct ObjectIterator;
172};
173
174inline void Managed::mark(MarkStack *markStack)
175{
176 Q_ASSERT(m());
177 m()->mark(markStack);
178}
179
180template<>
181inline const Managed *Value::as() const {
182 return managed();
183}
184
185template<>
186inline const Object *Value::as() const {
187 return objectValue();
188}
189
190
191struct InternalClass : Managed
192{
193 V4_MANAGED_ITSELF(InternalClass, Managed)
194 Q_MANAGED_TYPE(InternalClass)
195 V4_INTERNALCLASS(Empty)
196 V4_NEEDS_DESTROY
197
198 Q_REQUIRED_RESULT Heap::InternalClass *changeVTable(const VTable *vt) {
199 return d()->changeVTable(vt);
200 }
201 Q_REQUIRED_RESULT Heap::InternalClass *changePrototype(Heap::Object *proto) {
202 return d()->changePrototype(proto);
203 }
204 Q_REQUIRED_RESULT Heap::InternalClass *addMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry = nullptr) {
205 return d()->addMember(identifier, data, entry);
206 }
207
208 Q_REQUIRED_RESULT Heap::InternalClass *changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry = nullptr) {
209 return d()->changeMember(identifier, data, entry);
210 }
211
212 void operator =(Heap::InternalClass *ic) {
213 Value::operator=(o: ic);
214 }
215};
216
217}
218
219
220QT_END_NAMESPACE
221
222#endif
223

source code of qtdeclarative/src/qml/jsruntime/qv4managed_p.h