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_PRIVATE_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 IsFunctionObject = 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
126 };
127 Q_MANAGED_TYPE(Invalid)
128
129 Heap::InternalClass *internalClass() const { return d()->internalClass; }
130 const VTable *vtable() const { return d()->internalClass->vtable; }
131 inline ExecutionEngine *engine() const { return internalClass()->engine; }
132
133 bool isV4SequenceType() const { return d()->internalClass->vtable->type == Type_V4Sequence; }
134 bool isQmlListPropertyType() const { return d()->internalClass->vtable->type == Type_QmlListProperty; }
135 bool isArrayLike() const { return isArrayObject() || isV4SequenceType() || isQmlListPropertyType(); }
136
137 bool isArrayObject() const { return d()->internalClass->vtable->type == Type_ArrayObject; }
138 bool isStringObject() const { return d()->internalClass->vtable->type == Type_StringObject; }
139 bool isSymbolObject() const { return d()->internalClass->vtable->type == Type_SymbolObject; }
140
141 QString className() const;
142
143 bool isEqualTo(const Managed *other) const
144 { return d()->internalClass->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
145
146 bool inUse() const { return d()->inUse(); }
147 bool markBit() const { return d()->isMarked(); }
148 inline void mark(MarkStack *markStack);
149
150 Q_ALWAYS_INLINE Heap::Base *heapObject() const {
151 return m();
152 }
153
154 template<typename T> inline T *cast() {
155 return static_cast<T *>(this);
156 }
157 template<typename T> inline const T *cast() const {
158 return static_cast<const T *>(this);
159 }
160
161protected:
162 static bool virtualIsEqualTo(Managed *m, Managed *other);
163
164private:
165 friend class MemoryManager;
166 friend struct Identifiers;
167 friend struct ObjectIterator;
168};
169
170inline void Managed::mark(MarkStack *markStack)
171{
172 Q_ASSERT(m());
173 m()->mark(markStack);
174}
175
176template<>
177inline const Managed *Value::as() const {
178 return managed();
179}
180
181template<>
182inline const Object *Value::as() const {
183 return objectValue();
184}
185
186
187struct InternalClass : Managed
188{
189 V4_MANAGED_ITSELF(InternalClass, Managed)
190 Q_MANAGED_TYPE(InternalClass)
191 V4_INTERNALCLASS(Empty)
192 V4_NEEDS_DESTROY
193
194 Q_REQUIRED_RESULT Heap::InternalClass *changeVTable(const VTable *vt) {
195 return d()->changeVTable(vt);
196 }
197 Q_REQUIRED_RESULT Heap::InternalClass *changePrototype(Heap::Object *proto) {
198 return d()->changePrototype(proto);
199 }
200 Q_REQUIRED_RESULT Heap::InternalClass *addMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry = nullptr) {
201 return d()->addMember(identifier, data, entry);
202 }
203
204 Q_REQUIRED_RESULT Heap::InternalClass *changeMember(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry = nullptr) {
205 return d()->changeMember(identifier, data, entry);
206 }
207
208 void operator =(Heap::InternalClass *ic) {
209 Value::operator=(o: ic);
210 }
211};
212
213}
214
215
216QT_END_NAMESPACE
217
218#endif
219

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