1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#ifndef QV4VTABLE_P_H
40#define QV4VTABLE_P_H
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include "qv4global_p.h"
54
55QT_BEGIN_NAMESPACE
56
57namespace QV4 {
58
59struct Lookup;
60
61struct Q_QML_PRIVATE_EXPORT OwnPropertyKeyIterator {
62 virtual ~OwnPropertyKeyIterator() = 0;
63 virtual PropertyKey next(const Object *o, Property *p = nullptr, PropertyAttributes *attrs = nullptr) = 0;
64};
65
66struct VTable
67{
68 typedef void (*Destroy)(Heap::Base *);
69 typedef void (*MarkObjects)(Heap::Base *, MarkStack *markStack);
70 typedef bool (*IsEqualTo)(Managed *m, Managed *other);
71
72 typedef ReturnedValue (*Get)(const Managed *, PropertyKey id, const Value *receiver, bool *hasProperty);
73 typedef bool (*Put)(Managed *, PropertyKey id, const Value &value, Value *receiver);
74 typedef bool (*DeleteProperty)(Managed *m, PropertyKey id);
75 typedef bool (*HasProperty)(const Managed *m, PropertyKey id);
76 typedef PropertyAttributes (*GetOwnProperty)(const Managed *m, PropertyKey id, Property *p);
77 typedef bool (*DefineOwnProperty)(Managed *m, PropertyKey id, const Property *p, PropertyAttributes attrs);
78 typedef bool (*IsExtensible)(const Managed *);
79 typedef bool (*PreventExtensions)(Managed *);
80 typedef Heap::Object *(*GetPrototypeOf)(const Managed *);
81 typedef bool (*SetPrototypeOf)(Managed *, const Object *);
82 typedef qint64 (*GetLength)(const Managed *m);
83 typedef OwnPropertyKeyIterator *(*OwnPropertyKeys)(const Object *m, Value *target);
84 typedef ReturnedValue (*InstanceOf)(const Object *typeObject, const Value &var);
85
86 typedef ReturnedValue (*Call)(const FunctionObject *, const Value *thisObject, const Value *argv, int argc);
87 typedef ReturnedValue (*CallAsConstructor)(const FunctionObject *, const Value *argv, int argc, const Value *newTarget);
88
89 typedef ReturnedValue (*ResolveLookupGetter)(const Object *, ExecutionEngine *, Lookup *);
90 typedef bool (*ResolveLookupSetter)(Object *, ExecutionEngine *, Lookup *, const Value &);
91
92 const VTable * const parent;
93 quint16 inlinePropertyOffset;
94 quint16 nInlineProperties;
95 quint8 isExecutionContext;
96 quint8 isString;
97 quint8 isObject;
98 quint8 isFunctionObject;
99 quint8 isErrorObject;
100 quint8 isArrayData;
101 quint8 isStringOrSymbol;
102 quint8 type;
103 quint8 unused[4];
104 const char *className;
105
106 Destroy destroy;
107 MarkObjects markObjects;
108 IsEqualTo isEqualTo;
109
110 Get get;
111 Put put;
112 DeleteProperty deleteProperty;
113 HasProperty hasProperty;
114 GetOwnProperty getOwnProperty;
115 DefineOwnProperty defineOwnProperty;
116 IsExtensible isExtensible;
117 PreventExtensions preventExtensions;
118 GetPrototypeOf getPrototypeOf;
119 SetPrototypeOf setPrototypeOf;
120 GetLength getLength;
121 OwnPropertyKeys ownPropertyKeys;
122 InstanceOf instanceOf;
123
124 Call call;
125 CallAsConstructor callAsConstructor;
126
127 ResolveLookupGetter resolveLookupGetter;
128 ResolveLookupSetter resolveLookupSetter;
129};
130
131
132struct VTableBase {
133protected:
134 static constexpr VTable::Destroy virtualDestroy = nullptr;
135 static constexpr VTable::IsEqualTo virtualIsEqualTo = nullptr;
136
137 static constexpr VTable::Get virtualGet = nullptr;
138 static constexpr VTable::Put virtualPut = nullptr;
139 static constexpr VTable::DeleteProperty virtualDeleteProperty = nullptr;
140 static constexpr VTable::HasProperty virtualHasProperty = nullptr;
141 static constexpr VTable::GetOwnProperty virtualGetOwnProperty = nullptr;
142 static constexpr VTable::DefineOwnProperty virtualDefineOwnProperty = nullptr;
143 static constexpr VTable::IsExtensible virtualIsExtensible = nullptr;
144 static constexpr VTable::PreventExtensions virtualPreventExtensions = nullptr;
145 static constexpr VTable::GetPrototypeOf virtualGetPrototypeOf = nullptr;
146 static constexpr VTable::SetPrototypeOf virtualSetPrototypeOf = nullptr;
147 static constexpr VTable::GetLength virtualGetLength = nullptr;
148 static constexpr VTable::OwnPropertyKeys virtualOwnPropertyKeys = nullptr;
149 static constexpr VTable::InstanceOf virtualInstanceOf = nullptr;
150
151 static constexpr VTable::Call virtualCall = nullptr;
152 static constexpr VTable::CallAsConstructor virtualCallAsConstructor = nullptr;
153
154 static constexpr VTable::ResolveLookupGetter virtualResolveLookupGetter = nullptr;
155 static constexpr VTable::ResolveLookupSetter virtualResolveLookupSetter = nullptr;
156};
157
158#define DEFINE_MANAGED_VTABLE_INT(classname, parentVTable) \
159{ \
160 parentVTable, \
161 (sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \
162 (sizeof(classname::Data) + (classname::NInlineProperties*sizeof(QV4::Value)) + QV4::Chunk::SlotSize - 1)/QV4::Chunk::SlotSize*QV4::Chunk::SlotSize/sizeof(QV4::Value) \
163 - (sizeof(classname::Data) + sizeof(QV4::Value) - 1)/sizeof(QV4::Value), \
164 classname::IsExecutionContext, \
165 classname::IsString, \
166 classname::IsObject, \
167 classname::IsFunctionObject, \
168 classname::IsErrorObject, \
169 classname::IsArrayData, \
170 classname::IsStringOrSymbol, \
171 classname::MyType, \
172 { 0, 0, 0, 0 }, \
173 #classname, \
174 \
175 classname::virtualDestroy, \
176 classname::Data::markObjects, \
177 classname::virtualIsEqualTo, \
178 \
179 classname::virtualGet, \
180 classname::virtualPut, \
181 classname::virtualDeleteProperty, \
182 classname::virtualHasProperty, \
183 classname::virtualGetOwnProperty, \
184 classname::virtualDefineOwnProperty, \
185 classname::virtualIsExtensible, \
186 classname::virtualPreventExtensions, \
187 classname::virtualGetPrototypeOf, \
188 classname::virtualSetPrototypeOf, \
189 classname::virtualGetLength, \
190 classname::virtualOwnPropertyKeys, \
191 classname::virtualInstanceOf, \
192 \
193 classname::virtualCall, \
194 classname::virtualCallAsConstructor, \
195 \
196 classname::virtualResolveLookupGetter, \
197 classname::virtualResolveLookupSetter \
198}
199
200#define DEFINE_MANAGED_VTABLE(classname) \
201const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, 0)
202
203#define V4_OBJECT2(DataClass, superClass) \
204 private: \
205 DataClass() Q_DECL_EQ_DELETE; \
206 Q_DISABLE_COPY(DataClass) \
207 public: \
208 Q_MANAGED_CHECK \
209 typedef QV4::Heap::DataClass Data; \
210 typedef superClass SuperClass; \
211 static const QV4::VTable static_vtbl; \
212 static inline const QV4::VTable *staticVTable() { return &static_vtbl; } \
213 V4_MANAGED_SIZE_TEST \
214 QV4::Heap::DataClass *d_unchecked() const { return static_cast<QV4::Heap::DataClass *>(m()); } \
215 QV4::Heap::DataClass *d() const { \
216 QV4::Heap::DataClass *dptr = d_unchecked(); \
217 dptr->_checkIsInitialized(); \
218 return dptr; \
219 } \
220 Q_STATIC_ASSERT(std::is_trivial< QV4::Heap::DataClass >::value);
221
222#define V4_PROTOTYPE(p) \
223 static QV4::Object *defaultPrototype(QV4::ExecutionEngine *e) \
224 { return e->p(); }
225
226
227#define DEFINE_OBJECT_VTABLE_BASE(classname) \
228 const QV4::VTable classname::static_vtbl = DEFINE_MANAGED_VTABLE_INT(classname, (std::is_same<classname::SuperClass, Object>::value) ? nullptr : &classname::SuperClass::static_vtbl)
229
230#define DEFINE_OBJECT_VTABLE(classname) \
231DEFINE_OBJECT_VTABLE_BASE(classname)
232
233#define DEFINE_OBJECT_TEMPLATE_VTABLE(classname) \
234template<> DEFINE_OBJECT_VTABLE_BASE(classname)
235
236}
237
238QT_END_NAMESPACE
239
240#endif
241