Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
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// Qt-Security score:significant
4#ifndef QV4LOOKUP_H
5#define QV4LOOKUP_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qv4engine_p.h"
19#include "qv4object_p.h"
22#include <private/qqmltypewrapper_p.h>
23#include <private/qv4mm_p.h>
24
26
27namespace QV4 {
28
29namespace Heap {
30 struct QObjectMethod;
31}
32
33template <typename T, int PhantomTag>
35
36// Note: We cannot hide the copy ctor and assignment operator of this class because it needs to
37// be trivially copyable. But you should never ever copy it. There are refcounted members
38// in there.
39struct Q_QML_EXPORT Lookup {
96
97 // NOTE: gc assumes the first two entries in the struct are pointers to heap objects or null
98 // or that the least significant bit is 1 (see the Lookup::markObjects function)
99 union {
100 struct {
106 struct {
112 struct {
115 const Value *data;
118 struct {
121 uint offset;
124 struct {
127 const Value *data;
128 const Value *data2;
130 struct {
131 // Make sure the next two values are in sync with protoLookup
134 const Value *data;
137 struct {
140 uint offset;
143 struct {
146 uint index;
147 uint unused;
149 struct {
151 HeapObjectWrapper<Heap::InternalClass, 6> qmlTypeIc; // only used when lookup goes through QQmlTypeWrapper
155 struct {
161 struct {
162 // NB: None of this is actually cache-able. The metaobject may change at any time.
163 // We invalidate this data every time the lookup is invoked and thereby force a
164 // re-initialization next time.
165
166 quintptr metaObject; // a (const QMetaObject* | 1) or nullptr
167 quintptr metaType; // a (const QtPrivate::QMetaTypeInterface* | 1) or nullptr
168
169 // If it was negative it would be invalid. So 31 bits are enough
171
172 // isConstant for getter lookups, isResettable for setter ones
174
177 struct {
179 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
180 const QtPrivate::QMetaTypeInterface *metaType; // cannot use QMetaType; class must be trivial
183 bool isEnum;
185 struct {
190 struct {
195 struct {
200 struct {
201 // Same as protoLookup, as used for global lookups
207 struct {
211 struct {
217 struct {
221 };
222
225
226 uint nameIndex: 28; // Same number of bits we store in the compilation unit for name indices
227 uint forCall: 1; // Whether we are looking up a value in order to call it right away
228 uint asVariant: 1; // Whether all types are to be converted from/to QVariant
230
235
239
254
256
260
264
275
277 if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1))
279 if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1))
281 }
282
284 {
285 switch (call) {
312 default:
313 break;
314 }
315
317 }
318
334
339
341 {
342 switch (call) {
343 case Call::Getter0Inline:
344 return getter0Inline(this, engine, object);
350 return getter0MemberData(this, engine, object);
353 case Call::GetterAccessor:
354 return getterAccessor(this, engine, object);
357 case Call::GetterEnumValue:
360 return getterFallback(this, engine, object);
362 return getterFallbackMethod(this, engine, object);
363 case Call::GetterGeneric:
364 return getterGeneric(this, engine, object);
365 case Call::GetterIndexed:
366 return getterIndexed(this, engine, object);
367 case Call::GetterProto:
368 return getterProto(this, engine, object);
370 return getterProtoAccessor(this, engine, object);
374 return primitiveGetterProto(this, engine, object);
376 return getterProtoTwoClasses(this, engine, object);
378 return getterQObject(this, engine, object);
380 // TODO: more specific implementation for interpreter / JIT
381 return getterGeneric(this, engine, object);
383 return getterQObjectMethod(this, engine, object);
389 return stringLengthGetter(this, engine, object);
391 return getterValueType(this, engine, object);
392 case Call::GetterEnum:
393 return QQmlTypeWrapper::lookupEnum(this, engine, object);
394 default:
395 break;
396 }
397
399 }
400
402 {
403 switch (call) {
404 case Call::Setter0Inline:
405 return setter0Inline(this, engine, object, value);
407 return setter0MemberData(this, engine, object, value);
408 case Call::Setter0Setter0:
409 return setter0setter0(this, engine, object, value);
411 return arrayLengthSetter(this, engine, object, value);
413 return setterFallback(this, engine, object, value);
414 case Call::SetterGeneric:
415 return setterGeneric(this, engine, object, value);
416 case Call::SetterInsert:
417 return setterInsert(this, engine, object, value);
419 return setterQObject(this, engine, object, value);
421 // TODO: more specific implementation for interpreter / JIT
422 return setterFallback(this, engine, object, value);
423 default:
424 break;
425 }
426
428 }
429
452};
453
455
457 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
458{
459 lookup->releasePropertyCache();
460 Q_ASSERT(!ddata->propertyCache.isNull());
461 lookup->qobjectLookup.propertyCache = ddata->propertyCache.data();
462 lookup->qobjectLookup.propertyCache->addref();
463 lookup->qobjectLookup.propertyData = propertyData;
464}
465
467 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
468 const Object *self)
469{
470 setupQObjectLookup(lookup, ddata, propertyData);
471 lookup->qobjectLookup.ic.set(self->engine(), self->internalClass());
472}
473
474
476 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
477 const Object *self, const Object *qmlType)
478{
479 setupQObjectLookup(lookup, ddata, propertyData, self);
480 lookup->qobjectLookup.qmlTypeIc.set(self->engine(), qmlType->internalClass());
481}
482
483// template parameter is an ugly trick to avoid pulling in the QObjectMethod header here
484template<typename QObjectMethod = Heap::QObjectMethod>
486 Lookup *lookup, const QQmlPropertyCache::ConstPtr &propertyCache,
487 const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
488{
489 lookup->releasePropertyCache();
490 Q_ASSERT(!propertyCache.isNull());
491 auto engine = self->engine();
492 lookup->qobjectMethodLookup.method.set(engine, method);
493 lookup->qobjectMethodLookup.ic.set(engine, self->internalClass());
494 lookup->qobjectMethodLookup.propertyCache = propertyCache.data();
495 lookup->qobjectMethodLookup.propertyCache->addref();
496 lookup->qobjectMethodLookup.propertyData = propertyData;
497}
498
499inline bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
500{
501 return propertyData->isFunction()
502 && !propertyData->isSignalHandler() // TODO: Optimize SignalHandler, too
503 && !propertyData->isVMEFunction() // Handled by QObjectLookup
504 && !propertyData->isVarProperty();
505}
506
507}
508
509QT_END_NAMESPACE
510
511#endif
Combined button and popup list for selecting options.
Definition qjsvalue.h:24
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, const Object *qmlType)
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
void setupQObjectMethodLookup(Lookup *lookup, const QQmlPropertyCache::ConstPtr &propertyCache, const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
void setupQObjectLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self)
static void setupProtoLookupTwoClasses(Lookup *lookup, const Lookup &first, const Lookup &second)
static void setupObjectLookupTwoClasses(Lookup *lookup, const Lookup &first, const Lookup &second)