Qt 6.x
The Qt SDK
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
24
25namespace QV4 {
26
27namespace Heap {
28 struct QObjectMethod;
29}
30
31// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to
32// be trivially copyable. But you should never ever copy it. There are refcounted members
33// in there.
34struct Q_QML_PRIVATE_EXPORT Lookup {
35 union {
38 ReturnedValue (*qmlContextPropertyGetter)(Lookup *l, ExecutionEngine *engine, Value *thisObject);
39 bool (*setter)(Lookup *l, ExecutionEngine *engine, Value &object, const Value &v);
40 };
41 // NOTE: gc assumes the first two entries in the struct are pointers to heap objects or null
42 // or that the least significant bit is 1 (see the Lookup::markObjects function)
43 union {
44 struct {
49 } markDef;
50 struct {
52 quintptr unused;
55 } objectLookup;
56 struct {
59 const Value *data;
60 } protoLookup;
61 struct {
66 } objectLookupTwoClasses;
67 struct {
68 quintptr protoId;
70 const Value *data;
71 const Value *data2;
72 } protoLookupTwoClasses;
73 struct {
74 // Make sure the next two values are in sync with protoLookup
75 quintptr protoId;
76 Heap::Object *proto;
77 const Value *data;
79 } primitiveLookup;
80 struct {
82 quintptr protoId;
85 } insertionLookup;
86 struct {
87 quintptr _unused;
89 uint index;
90 uint unused;
91 } indexedLookup;
92 struct {
94 Heap::InternalClass *qmlTypeIc; // only used when lookup goes through QQmlTypeWrapper
97 } qobjectLookup;
98 struct {
100 Heap::QObjectMethod *method;
101 const QQmlPropertyCache *propertyCache;
102 const QQmlPropertyData *propertyData;
103 } qobjectMethodLookup;
104 struct {
105 quintptr isConstant; // This is a bool, encoded as 0 or 1. Both values are ignored by gc
106 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
109 } qobjectFallbackLookup;
110 struct {
112 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
113 const QtPrivate::QMetaTypeInterface *metaType; // cannot use QMetaType; class must be trivial
116 bool isEnum;
117 } qgadgetLookup;
118 struct {
120 quintptr unused2;
122 } qmlContextScriptLookup;
123 struct {
125 quintptr unused2;
127 } qmlContextSingletonLookup;
128 struct {
129 quintptr unused1;
130 quintptr unused2;
132 } qmlContextIdObjectLookup;
133 struct {
134 // Same as protoLookup, as used for global lookups
138 ReturnedValue (*getterTrampoline)(Lookup *l, ExecutionEngine *engine);
139 } qmlContextGlobalLookup;
140 struct {
142 quintptr unused2;
143 } qmlTypeLookup;
144 struct {
146 quintptr unused;
148 const QtPrivate::QMetaTypeInterface *metaType;
149 } qmlEnumValueLookup;
150 struct {
152 Heap::Object *qmlScopedEnumWrapper;
153 } qmlScopedEnumWrapperLookup;
154 };
155
156 uint nameIndex: 28; // Same number of bits we store in the compilation unit for name indices
157 uint forCall: 1; // Whether we are looking up a value in order to call it right away
159
160 ReturnedValue resolveGetter(ExecutionEngine *engine, const Object *object);
161 ReturnedValue resolvePrimitiveGetter(ExecutionEngine *engine, const Value &object);
162 ReturnedValue resolveGlobalGetter(ExecutionEngine *engine);
163 void resolveProtoGetter(PropertyKey name, const Heap::Object *proto);
164
165 static ReturnedValue getterGeneric(Lookup *l, ExecutionEngine *engine, const Value &object);
166 static ReturnedValue getterTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
167 static ReturnedValue getterFallback(Lookup *l, ExecutionEngine *engine, const Value &object);
168 static ReturnedValue getterFallbackAsVariant(Lookup *l, ExecutionEngine *engine, const Value &object);
169
170 static ReturnedValue getter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
171 static ReturnedValue getter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
172 static ReturnedValue getterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
173 static ReturnedValue getter0Inlinegetter0Inline(Lookup *l, ExecutionEngine *engine, const Value &object);
174 static ReturnedValue getter0Inlinegetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
175 static ReturnedValue getter0MemberDatagetter0MemberData(Lookup *l, ExecutionEngine *engine, const Value &object);
176 static ReturnedValue getterProtoTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
177 static ReturnedValue getterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
178 static ReturnedValue getterProtoAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
179 static ReturnedValue getterProtoAccessorTwoClasses(Lookup *l, ExecutionEngine *engine, const Value &object);
180 static ReturnedValue getterIndexed(Lookup *l, ExecutionEngine *engine, const Value &object);
181 static ReturnedValue getterQObject(Lookup *l, ExecutionEngine *engine, const Value &object);
182 static ReturnedValue getterQObjectAsVariant(Lookup *l, ExecutionEngine *engine, const Value &object);
183 static ReturnedValue getterQObjectMethod(Lookup *l, ExecutionEngine *engine, const Value &object);
184
185 static ReturnedValue primitiveGetterProto(Lookup *l, ExecutionEngine *engine, const Value &object);
186 static ReturnedValue primitiveGetterAccessor(Lookup *l, ExecutionEngine *engine, const Value &object);
187 static ReturnedValue stringLengthGetter(Lookup *l, ExecutionEngine *engine, const Value &object);
188
189 static ReturnedValue globalGetterGeneric(Lookup *l, ExecutionEngine *engine);
190 static ReturnedValue globalGetterProto(Lookup *l, ExecutionEngine *engine);
191 static ReturnedValue globalGetterProtoAccessor(Lookup *l, ExecutionEngine *engine);
192
193 bool resolveSetter(ExecutionEngine *engine, Object *object, const Value &value);
194 static bool setterGeneric(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
195 Q_NEVER_INLINE static bool setterTwoClasses(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
196 static bool setterFallback(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
197 static bool setterFallbackAsVariant(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
198 static bool setter0MemberData(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
199 static bool setter0Inline(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
200 static bool setter0setter0(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
201 static bool setterInsert(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
202 static bool setterQObject(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
203 static bool setterQObjectAsVariant(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
204 static bool arrayLengthSetter(Lookup *l, ExecutionEngine *engine, Value &object, const Value &value);
205
206 void markObjects(MarkStack *stack) {
207 if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1))
208 markDef.h1->mark(stack);
209 if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1))
210 markDef.h2->mark(stack);
211 }
212
213 void clear() {
214 memset(&markDef, 0, sizeof(markDef));
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());
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 = 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 = qmlType->internalClass();
268}
269
271 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
272 const Object *self, Heap::QObjectMethod *method)
273{
274 lookup->releasePropertyCache();
275 Q_ASSERT(!ddata->propertyCache.isNull());
277 lookup->qobjectMethodLookup.ic = self->internalClass();
280 lookup->qobjectMethodLookup.propertyData = propertyData;
281}
282
283inline bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
284{
285 return propertyData->isFunction()
286 && !propertyData->isSignalHandler() // TODO: Optimize SignalHandler, too
287 && !propertyData->isVMEFunction() // Handled by QObjectLookup
288 && !propertyData->isVarProperty();
289}
290
291}
292
294
295#endif
QQmlPropertyCache::ConstPtr propertyCache
Definition qqmldata_p.h:195
bool isVarProperty() const
bool isVMEFunction() const
bool isSignalHandler() const
void addref() const
T * data() const
bool isNull() const
Combined button and popup list for selecting options.
\qmltype Particle \inqmlmodule QtQuick.Particles
quint64 ReturnedValue
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
void setupQObjectMethodLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, Heap::QObjectMethod *method)
bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
#define Q_STATIC_ASSERT(Condition)
Definition qassert.h:105
#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:43
size_t quintptr
Definition qtypes.h:72
unsigned int uint
Definition qtypes.h:29
obj metaObject() -> className()
QJSEngine engine
[0]
Heap::QObjectMethod * method
quintptr _unused
Definition qv4lookup_p.h:58
Heap::Base * h1
Definition qv4lookup_p.h:45
const QQmlPropertyData * propertyData
Definition qv4lookup_p.h:96
QV4::ReturnedValue singletonValue
struct QV4::Lookup::@576::@601 qobjectLookup
quint16 coreIndex
quintptr reserved1
ReturnedValue encodedEnumValue
Heap::Base * h2
Definition qv4lookup_p.h:46
Heap::Base * qmlTypeWrapper
quintptr unused
Definition qv4lookup_p.h:47
Heap::InternalClass * ic2
Definition qv4lookup_p.h:63
quintptr type
Definition qv4lookup_p.h:78
quintptr protoId2
Definition qv4lookup_p.h:69
quintptr unused1
const QtPrivate::QMetaTypeInterface * metaType
quintptr isConstant
Heap::Base * singletonObject
Heap::Object * proto
Definition qv4lookup_p.h:76
Heap::InternalClass * qmlTypeIc
Definition qv4lookup_p.h:94
const Value * data2
Definition qv4lookup_p.h:71
quintptr _unused2
Definition qv4lookup_p.h:88
quintptr unused2
Definition qv4lookup_p.h:48
Heap::InternalClass * newClass
Definition qv4lookup_p.h:81
quintptr reserved2
quintptr metaObject
void releasePropertyCache()
quintptr protoId
Definition qv4lookup_p.h:57
quintptr reserved3
Heap::InternalClass * ic
Definition qv4lookup_p.h:51
void markObjects(MarkStack *stack)
const Value * data
Definition qv4lookup_p.h:59
struct QV4::Lookup::@576::@602 qobjectMethodLookup
const QQmlPropertyCache * propertyCache
Definition qv4lookup_p.h:95
Heap::Object * qmlScopedEnumWrapper
Heap::InternalClass * internalClass() const