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 quintptr isConstant; // This is a bool, encoded as 0 or 1. Both values are ignored by gc
163 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
167 struct {
169 quintptr metaObject; // a (const QMetaObject* & 1) or nullptr
170 const QtPrivate::QMetaTypeInterface *metaType; // cannot use QMetaType; class must be trivial
173 bool isEnum;
175 struct {
180 struct {
185 struct {
190 struct {
191 // Same as protoLookup, as used for global lookups
197 struct {
201 struct {
207 struct {
211 };
212
215
216 uint nameIndex: 28; // Same number of bits we store in the compilation unit for name indices
217 uint forCall: 1; // Whether we are looking up a value in order to call it right away
218 uint asVariant: 1; // Whether all types are to be converted from/to QVariant
220
225
229
244
246
250
254
265
267 if (markDef.h1 && !(reinterpret_cast<quintptr>(markDef.h1) & 1))
269 if (markDef.h2 && !(reinterpret_cast<quintptr>(markDef.h2) & 1))
271 }
272
274 {
275 switch (call) {
302 default:
303 break;
304 }
305
307 }
308
324
329
331 {
332 switch (call) {
333 case Call::Getter0Inline:
334 return getter0Inline(this, engine, object);
340 return getter0MemberData(this, engine, object);
343 case Call::GetterAccessor:
344 return getterAccessor(this, engine, object);
347 case Call::GetterEnumValue:
350 return getterFallback(this, engine, object);
352 return getterFallbackMethod(this, engine, object);
353 case Call::GetterGeneric:
354 return getterGeneric(this, engine, object);
355 case Call::GetterIndexed:
356 return getterIndexed(this, engine, object);
357 case Call::GetterProto:
358 return getterProto(this, engine, object);
360 return getterProtoAccessor(this, engine, object);
364 return primitiveGetterProto(this, engine, object);
366 return getterProtoTwoClasses(this, engine, object);
368 return getterQObject(this, engine, object);
370 // TODO: more specific implementation for interpreter / JIT
371 return getterGeneric(this, engine, object);
373 return getterQObjectMethod(this, engine, object);
379 return stringLengthGetter(this, engine, object);
381 return getterValueType(this, engine, object);
382 case Call::GetterEnum:
383 return QQmlTypeWrapper::lookupEnum(this, engine, object);
384 default:
385 break;
386 }
387
389 }
390
392 {
393 switch (call) {
394 case Call::Setter0Inline:
395 return setter0Inline(this, engine, object, value);
397 return setter0MemberData(this, engine, object, value);
398 case Call::Setter0Setter0:
399 return setter0setter0(this, engine, object, value);
401 return arrayLengthSetter(this, engine, object, value);
403 return setterFallback(this, engine, object, value);
404 case Call::SetterGeneric:
405 return setterGeneric(this, engine, object, value);
406 case Call::SetterInsert:
407 return setterInsert(this, engine, object, value);
409 return setterQObject(this, engine, object, value);
411 // TODO: more specific implementation for interpreter / JIT
412 return setterFallback(this, engine, object, value);
413 default:
414 break;
415 }
416
418 }
419
442};
443
445
447 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData)
448{
449 lookup->releasePropertyCache();
450 Q_ASSERT(!ddata->propertyCache.isNull());
451 lookup->qobjectLookup.propertyCache = ddata->propertyCache.data();
452 lookup->qobjectLookup.propertyCache->addref();
453 lookup->qobjectLookup.propertyData = propertyData;
454}
455
457 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
458 const Object *self)
459{
460 setupQObjectLookup(lookup, ddata, propertyData);
461 lookup->qobjectLookup.ic.set(self->engine(), self->internalClass());
462}
463
464
466 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
467 const Object *self, const Object *qmlType)
468{
469 setupQObjectLookup(lookup, ddata, propertyData, self);
470 lookup->qobjectLookup.qmlTypeIc.set(self->engine(), qmlType->internalClass());
471}
472
473// template parameter is an ugly trick to avoid pulling in the QObjectMethod header here
474template<typename QObjectMethod = Heap::QObjectMethod>
476 Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData,
477 const Object *self, QObjectMethod *method)
478{
479 lookup->releasePropertyCache();
480 Q_ASSERT(!ddata->propertyCache.isNull());
481 auto engine = self->engine();
482 lookup->qobjectMethodLookup.method.set(engine, method);
483 lookup->qobjectMethodLookup.ic.set(engine, self->internalClass());
484 lookup->qobjectMethodLookup.propertyCache = ddata->propertyCache.data();
485 lookup->qobjectMethodLookup.propertyCache->addref();
486 lookup->qobjectMethodLookup.propertyData = propertyData;
487}
488
489inline bool qualifiesForMethodLookup(const QQmlPropertyData *propertyData)
490{
491 return propertyData->isFunction()
492 && !propertyData->isSignalHandler() // TODO: Optimize SignalHandler, too
493 && !propertyData->isVMEFunction() // Handled by QObjectLookup
494 && !propertyData->isVarProperty();
495}
496
497}
498
499QT_END_NAMESPACE
500
501#endif
Definition qjsvalue.h:23
void setupQObjectMethodLookup(Lookup *lookup, const QQmlData *ddata, const QQmlPropertyData *propertyData, const Object *self, QObjectMethod *method)
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 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)