Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4lookup_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#ifndef QV4LOOKUP_H
4#define QV4LOOKUP_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 "qv4engine_p.h"
18#include "qv4object_p.h"
19#include "qv4internalclass_p.h"
20#include "qv4qmlcontext_p.h"
21#include <private/qqmltypewrapper_p.h>
22#include <private/qv4mm_p.h>
23
25
26namespace QV4 {
27
28namespace Heap {
29 struct QObjectMethod;
30}
31
32template <typename T, int PhantomTag>
34
35// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to
36// be trivially copyable. But you should never ever copy it. There are refcounted members
37// in there.
38struct Q_QML_EXPORT Lookup {
39 union {
42 ReturnedValue (*qmlContextPropertyGetter)(Lookup *l, ExecutionEngine *engine, Value *thisObject);
43 bool (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v);
44 };
45 // NOTE: gc assumes the first two entries in the struct are pointers to heap objects or null
46 // or that the least significant bit is 1 (see the Lookup::markObjects function)
47 union {
48 struct {
53 } markDef;
54 struct {
55 HeapObjectWrapper<Heap::InternalClass, 0> ic;
56 quintptr unused;
59 } objectLookup;
60 struct {
63 const Value *data;
64 } protoLookup;
65 struct {
66 HeapObjectWrapper<Heap::InternalClass, 1> ic;
67 HeapObjectWrapper<Heap::InternalClass, 2> ic2;
70 } objectLookupTwoClasses;
71 struct {
72 quintptr protoId;
74 const Value *data;
75 const Value *data2;
76 } protoLookupTwoClasses;
77 struct {
78 // Make sure the next two values are in sync with protoLookup
79 quintptr protoId;
80 HeapObjectWrapper<Heap::Object, 3> proto;
81 const Value *data;
83 } primitiveLookup;
84 struct {
85 HeapObjectWrapper<Heap::InternalClass, 4> newClass;
86 quintptr protoId;
89 } insertionLookup;
90 struct {
91 quintptr _unused;
93 uint index;
94 uint unused;
95 } indexedLookup;
96 struct {
97 HeapObjectWrapper<Heap::InternalClass, 5> ic;
98 HeapObjectWrapper<Heap::InternalClass, 6> qmlTypeIc; // only used when lookup goes through QQmlTypeWrapper
101 } qobjectLookup;
102 struct {
103 HeapObjectWrapper<Heap::InternalClass, 7> ic;
104 HeapObjectWrapper<Heap::QObjectMethod, 8> method;
105 const QQmlPropertyCache *propertyCache;
106 const QQmlPropertyData *propertyData;
107 } qobjectMethodLookup;
108 struct {
109 quintptr isConstant; // This is a bool, encoded as 0 or 1. Both values are ignored by gc
110 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
113 } qobjectFallbackLookup;
114 struct {
115 HeapObjectWrapper<Heap::InternalClass, 9> ic;
116 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
117 const QtPrivate::QMetaTypeInterface *metaType; // cannot use QMetaType; class must be trivial
120 bool isEnum;
121 } qgadgetLookup;
122 struct {
124 quintptr unused2;
126 } qmlContextScriptLookup;
127 struct {
128 HeapObjectWrapper<Heap::Base, 10> singletonObject;
129 quintptr unused2;
131 } qmlContextSingletonLookup;
132 struct {
133 quintptr unused1;
134 quintptr unused2;
136 } qmlContextIdObjectLookup;
137 struct {
138 // Same as protoLookup, as used for global lookups
142 ReturnedValue (*getterTrampoline)(Lookup *l, ExecutionEngine *engine);
143 } qmlContextGlobalLookup;
144 struct {
145 HeapObjectWrapper<Heap::Base, 11> qmlTypeWrapper;
146 quintptr unused2;
147 } qmlTypeLookup;
148 struct {
149 HeapObjectWrapper<Heap::InternalClass, 12> ic;
150 quintptr unused;
152 const QtPrivate::QMetaTypeInterface *metaType;
153 } qmlEnumValueLookup;
154 struct {
155 HeapObjectWrapper<Heap::InternalClass, 13> ic;
156 HeapObjectWrapper<Heap::Object, 14> qmlScopedEnumWrapper;
157 } qmlScopedEnumWrapperLookup;
158 };
159
160 uint nameIndex: 28; // Same number of bits we store in the compilation unit for name indices
161 uint forCall: 1; // Whether we are looking up a value in order to call it right away
163
164 ReturnedValue resolveGetter(ExecutionEngine *engine, const Object *object);
165 ReturnedValue resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object);
166 ReturnedValue resolveGlobalGetter(ExecutionEngine *engine);
167 void resolveProtoGetter(PropertyKey name, const Heap::Object *proto);
168
169 static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object);
170 static ReturnedValue getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
171 static ReturnedValue getterFallback(Lookup *l, ExecutionEngine *engine, const Value &object);
172 static ReturnedValue getterFallbackAsVariant(Lookup *l, ExecutionEngine *engine, const Value &object);
173
174 static ReturnedValue getter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
175 static ReturnedValue getter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
176 static ReturnedValue getterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
177 static ReturnedValue getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
178 static ReturnedValue getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
179 static ReturnedValue getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
180 static ReturnedValue getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
181 static ReturnedValue getterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
182 static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
183 static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
184 static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object);
185 static ReturnedValue getterQObject(Lookup *l, ExecutionEngine *engine, const Value &object);
186 static ReturnedValue getterQObjectAsVariant(Lookup *l, ExecutionEngine *engine, const Value &object);
187 static ReturnedValue getterQObjectMethod(Lookup *l, ExecutionEngine *engine, const Value &object);
188
189 static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
190 static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
191 static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
192
193 static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine);
194 static ReturnedValue globalGetterProto(Lookup *l, ExecutionEngine *engine);
195 static ReturnedValue globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine);
196
197 bool resolveSetter(ExecutionEngine *engine, Object *object, const Value &value);
198 static bool setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
199 Q_NEVER_INLINE static bool setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
200 static bool setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
201 static bool setterFallbackAsVariant(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
202 static bool setter0MemberData(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
203 static bool setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
204 static bool setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
205 static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
206 static bool setterQObject(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
207 static bool setterQObjectAsVariant(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
208 static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
209
210 void markObjects(MarkStack *stack) {
211 if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1))
212 markDef.h1->mark(stack);
213 if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1))
214 markDef.h2->mark(stack);
215 }
216
218 {
219 if (getter == getterQObject
220 || getter == QQmlTypeWrapper::lookupSingletonProperty
221 || setter == setterQObject
222 || qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectProperty
223 || qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectProperty
224 || getter == getterQObjectAsVariant
225 || setter == setterQObjectAsVariant) {
226 if (const QQmlPropertyCache *pc = qobjectLookup.propertyCache)
227 pc->release();
228 } else if (getter == getterQObjectMethod
229 || getter == QQmlTypeWrapper::lookupSingletonMethod
230 || qmlContextPropertyGetter == QQmlContextWrapper::lookupScopeObjectMethod
231 || qmlContextPropertyGetter == QQmlContextWrapper::lookupContextObjectMethod) {
232 if (const QQmlPropertyCache *pc = qobjectMethodLookup.propertyCache)
233 pc->release();
234 }
235 }
236};
237
238Q_STATIC_ASSERT(std::is_standard_layout<Lookup>::value);
239// Ensure that these offsets are always at this point to keep generated code compatible
240// across 32-bit and 64-bit (matters when cross-compiling).
241Q_STATIC_ASSERT(offsetof(Lookup, getter) == 0);
242
244 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
245{
246 lookup->releasePropertyCache();
247 Q_ASSERT(!ddata->propertyCache.isNull());
248 lookup->qobjectLookup.propertyCache = ddata->propertyCache.data();
249 lookup->qobjectLookup.propertyCache->addref();
250 lookup->qobjectLookup.propertyData = propertyData;
251}
252
254 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
255 const Object *self)
256{
257 setupQObjectLookup(lookup, ddata, propertyData);
258 lookup->qobjectLookup.ic.set(self->engine(), self->internalClass());
259}
260
261
263 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
264 const Object *self, const Object *qmlType)
265{
266 setupQObjectLookup(lookup, ddata, propertyData, self);
267 lookup->qobjectLookup.qmlTypeIc.set(self->engine(), qmlType->internalClass());
268}
269
270// template parameter is an ugly trick to avoid pulling in the QObjectMethod header here
271template<typename QObjectMethod = Heap::QObjectMethod>
273 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
274 const Object *self, QObjectMethod *method)
275{
276 lookup->releasePropertyCache();
277 Q_ASSERT(!ddata->propertyCache.isNull());
278 auto engine = self->engine();
279 lookup->qobjectMethodLookup.method.set(engine, method);
280 lookup->qobjectMethodLookup.ic.set(engine, self->internalClass());
281 lookup->qobjectMethodLookup.propertyCache = ddata->propertyCache.data();
282 lookup->qobjectMethodLookup.propertyCache->addref();
283 lookup->qobjectMethodLookup.propertyData = propertyData;
284}
285
286inline bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
287{
288 return propertyData->isFunction()
289 && !propertyData->isSignalHandler() // TODO: Optimize SignalHandler, too
290 && !propertyData->isVMEFunction() // Handled by QObjectLookup
291 && !propertyData->isVarProperty();
292}
293
294}
295
297
298#endif
bool isVarProperty() const
bool isVMEFunction() const
bool isSignalHandler() const
Combined button and popup list for selecting options.
void setupQObjectMethodLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
quint64 ReturnedValue
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
#define Q_STATIC_ASSERT(Condition)
Definition qassert.h:108
#define Q_NEVER_INLINE
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLsizei const GLfloat * v
[13]
GLuint index
[2]
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLuint name
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned short quint16
Definition qtypes.h:48
size_t quintptr
Definition qtypes.h:167
unsigned int uint
Definition qtypes.h:34
obj metaObject() -> className()
QJSEngine engine
[0]
quintptr _unused
Definition qv4lookup_p.h:62
HeapObjectWrapper< Heap::InternalClass, 4 > newClass
Definition qv4lookup_p.h:85
Heap::Base * h1
Definition qv4lookup_p.h:49
const QQmlPropertyData * propertyData
QV4::ReturnedValue singletonValue
HeapObjectWrapper< Heap::InternalClass, 12 > ic
HeapObjectWrapper< Heap::Base, 11 > qmlTypeWrapper
HeapObjectWrapper< Heap::InternalClass, 9 > ic
quint16 coreIndex
quintptr reserved1
ReturnedValue encodedEnumValue
HeapObjectWrapper< Heap::InternalClass, 13 > ic
Heap::Base * h2
Definition qv4lookup_p.h:50
HeapObjectWrapper< Heap::QObjectMethod, 8 > method
quintptr unused
Definition qv4lookup_p.h:51
quintptr type
Definition qv4lookup_p.h:82
quintptr protoId2
Definition qv4lookup_p.h:73
quintptr unused1
struct QV4::Lookup::@584::@598 qobjectLookup
HeapObjectWrapper< Heap::InternalClass, 5 > ic
Definition qv4lookup_p.h:97
const QtPrivate::QMetaTypeInterface * metaType
quintptr isConstant
HeapObjectWrapper< Heap::Base, 10 > singletonObject
HeapObjectWrapper< Heap::Object, 14 > qmlScopedEnumWrapper
HeapObjectWrapper< Heap::InternalClass, 7 > ic
const Value * data2
Definition qv4lookup_p.h:75
quintptr _unused2
Definition qv4lookup_p.h:92
quintptr unused2
Definition qv4lookup_p.h:52
HeapObjectWrapper< Heap::InternalClass, 0 > ic
Definition qv4lookup_p.h:55
quintptr reserved2
quintptr metaObject
HeapObjectWrapper< Heap::InternalClass, 2 > ic2
Definition qv4lookup_p.h:67
void releasePropertyCache()
HeapObjectWrapper< Heap::InternalClass, 1 > ic
Definition qv4lookup_p.h:66
quintptr protoId
Definition qv4lookup_p.h:61
struct QV4::Lookup::@584::@599 qobjectMethodLookup
quintptr reserved3
HeapObjectWrapper< Heap::Object, 3 > proto
Definition qv4lookup_p.h:80
void markObjects(MarkStack *stack)
const Value * data
Definition qv4lookup_p.h:63
const QQmlPropertyCache * propertyCache
Definition qv4lookup_p.h:99
HeapObjectWrapper< Heap::InternalClass, 6 > qmlTypeIc
Definition qv4lookup_p.h:98
Heap::InternalClass * internalClass() const