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
qv4referenceobject_p.h
Go to the documentation of this file.
1// Copyright (C) 2022 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
5#ifndef QV4REFERENCEOBJECT_P_H
6#define QV4REFERENCEOBJECT_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qv4object_p.h>
20#include <private/qv4stackframe_p.h>
21#include <private/qqmlnotifier_p.h>
22#include <private/qv4qobjectwrapper_p.h>
23
25
26namespace QV4 {
27namespace Heap {
28
29struct ReferenceObject;
31 ReferenceObjectEndpoint(ReferenceObject* reference)
33 reference(reference)
34 {}
35
36 ReferenceObject* reference;
37};
38
39#define ReferenceObjectMembers(class, Member)
40 Member(class, Pointer, Object *, m_object)
41
42DECLARE_HEAP_OBJECT(ReferenceObject, Object) {
43 DECLARE_MARKOBJECTS(ReferenceObject);
44
45 enum Flag : quint8 {
46 NoFlag = 0,
47 CanWriteBack = 1 << 0,
48 IsVariant = 1 << 1,
49 EnforcesLocation = 1 << 2,
50 IsDirty = 1 << 3,
51 IsAlwaysDirty = 1 << 4,
52 };
53 Q_DECLARE_FLAGS(Flags, Flag);
54
55 void init(Object *object, int property, Flags flags)
56 {
57 setObject(object);
58 m_property = property;
59 m_flags = flags;
60
61 setDirty(true);
62 if (CppStackFrame *frame = internalClass->engine->currentStackFrame)
63 setLocation(frame->v4Function, frame->statementNumber());
64 else
65 setLocation(nullptr, -1);
66 Object::init();
67 }
68
69 Flags flags() const { return Flags(m_flags); }
70
71 Object *object() const { return m_object.get(); }
72 void setObject(Object *object) { m_object.set(internalClass->engine, object); }
73
74 int property() const { return m_property; }
75
76 bool canWriteBack() const { return hasFlag(CanWriteBack); }
77 bool isVariant() const { return hasFlag(IsVariant); }
78 bool enforcesLocation() const { return hasFlag(EnforcesLocation); }
79
80 void setLocation(const Function *function, quint16 statement)
81 {
82 m_function = function;
83 m_statementIndex = statement;
84 }
85
86 const Function *function() const { return m_function; }
87 quint16 statementIndex() const { return m_statementIndex; }
88
89 bool isAttachedToProperty() const
90 {
91 if (enforcesLocation()) {
92 if (CppStackFrame *frame = internalClass->engine->currentStackFrame) {
93 if (frame->v4Function != function() || frame->statementNumber() != statementIndex())
94 return false;
95 } else {
96 return false;
97 }
98 }
99
100 return true;
101 }
102
103 bool isReference() const { return m_object; }
104
105 bool isDirty() const { return hasFlag(IsDirty); }
106 void setDirty(bool dirty) { setFlag(IsDirty, dirty); }
107
108 bool isAlwaysDirty() const { return hasFlag(IsAlwaysDirty); }
109 void setAlwaysDirty(bool alwaysDirty) { setFlag(IsAlwaysDirty, alwaysDirty); }
110
111 bool isConnected() {
112 return (referenceEndpoint && referenceEndpoint->isConnected()) || bindableNotifier;
113 }
114
115 void destroy() {
116 // If we allocated any connection then we must have connected
117 // to the destroyed signal too, and we should clean it up.
118 if (referenceEndpoint || bindableNotifier) {
119 QObject::disconnect(*reinterpret_cast<QMetaObject::Connection*>(&onDelete));
120 std::destroy_at(reinterpret_cast<QMetaObject::Connection*>(&onDelete));
121 }
122
123 if (referenceEndpoint)
124 delete referenceEndpoint;
125
126 if (bindableNotifier)
127 delete bindableNotifier;
128 }
129
130 void connectToNotifySignal(QObject *obj, int property, QQmlEngine *engine);
131 void connectToBindable(QObject *obj, int property, QQmlEngine *engine);
132
133private:
134
135 bool hasFlag(Flag flag) const
136 {
137 return m_flags & quint8(flag);
138 }
139
140 void setFlag(Flag flag, bool set)
141 {
142 m_flags = set ? (m_flags | quint8(flag)) : (m_flags & ~quint8(flag));
143 }
144
145 const Function *m_function;
146 int m_property;
147 quint16 m_statementIndex;
148 quint8 m_flags;
149 ReferenceObjectEndpoint* referenceEndpoint;
150 QPropertyNotifier* bindableNotifier;
151 // We need to store an handle if we connect to the destroyed
152 // signal so that we can disconnect from it. To avoid yet
153 // another allocation, considering that
154 // QMetaObject::Connection is not trivial, we store it in
155 // block memory.
156 alignas(alignof(QMetaObject::Connection))
157 std::byte onDelete[sizeof(QMetaObject::Connection)];
158};
159
161
162} // namespace Heap
163
164
165struct ReferenceObject : public Object
166{
167 V4_OBJECT2(ReferenceObject, Object)
170
171public:
172 static constexpr const int AllProperties = -1;
173
174 static bool shouldConnect(Heap::ReferenceObject *ref);
175 static void connect(Heap::ReferenceObject *ref);
176
177 template<typename HeapObject>
178 static bool readReference(HeapObject *ref)
179 {
180 if (!ref->object())
181 return false;
182
183 if (!ref->isDirty())
184 return true;
185
186 QV4::Scope scope(ref->internalClass->engine);
187 QV4::ScopedObject object(scope, ref->object());
188
189 if (!ref->isConnected() && shouldConnect(ref))
190 connect(ref);
191
192 bool wasRead = false;
193 if (ref->isVariant()) {
194 QVariant variant;
195 void *a[] = { &variant };
196 wasRead = object->metacall(QMetaObject::ReadProperty, ref->property(), a)
197 && ref->setVariant(variant);
198 } else {
199 void *a[] = { ref->storagePointer() };
200 wasRead = object->metacall(QMetaObject::ReadProperty, ref->property(), a);
201 }
202
203 ref->setDirty(!ref->isConnected() || !wasRead);
204 return wasRead;
205 }
206
207 template<typename HeapObject>
208 static bool writeBack(HeapObject *ref, int internalIndex = AllProperties)
209 {
210 if (!ref->object() || !ref->canWriteBack())
211 return false;
212
213 QV4::Scope scope(ref->internalClass->engine);
214 QV4::ScopedObject object(scope, ref->object());
215
216 int flags = QQmlPropertyData::HasInternalIndex;
217 int status = -1;
218 if (ref->isVariant()) {
219 QVariant variant = ref->toVariant();
220 void *a[] = { &variant, nullptr, &status, &flags, &internalIndex };
221 return object->metacall(QMetaObject::WriteProperty, ref->property(), a);
222 }
223
224 void *a[] = { ref->storagePointer(), nullptr, &status, &flags, &internalIndex };
225 return object->metacall(QMetaObject::WriteProperty, ref->property(), a);
226 }
227
228 template<typename HeapObject>
229 static HeapObject *detached(HeapObject *ref)
230 {
231 if (ref->object() && !ref->enforcesLocation() && !readReference(ref))
232 return ref; // It's dead. No point in detaching it anymore
233
234 return ref->detached();
235 }
236};
237
238} // namespace QV4
239
240QT_END_NAMESPACE
241
242#endif // QV4REFERENCEOBJECT_P_H
Combined button and popup list for selecting options.
DECLARE_HEAP_OBJECT(DateObject, ReferenceObject)
Definition qjsvalue.h:24
bool ReferenceObject::readReference< Heap::DateObject >(Heap::DateObject *ref)
Scoped< Object > ScopedObject
bool ReferenceObject::writeBack< Heap::DateObject >(Heap::DateObject *ref, int internalIndex)
DEFINE_OBJECT_VTABLE(DateObject)
DEFINE_OBJECT_VTABLE(DateCtor)
static bool InLeapYear(double t)
static const double msPerDay
static double DayFromYear(double y)
static QString ToString(double t, double localTZA)
static double UTC(double t, double localTZA)
static const double msPerSecond
static double ParseString(const QString &s, double localTZA)
static QString ToUTCString(double t)
static int msFromTime(double t)
static double DaysInYear(double y)
static QString ToLocaleTimeString(double t)
static const double msPerHour
static double YearFromTime(double t)
static QDateTime ToDateTime(double t, QTimeZone zone)
static QString ToTimeString(double t)
static double getLocalTZA()
static double TimeWithinDay(double t)
static double TimeFromYear(double y)
static QString ToLocaleDateString(double t)
static double DayFromMonth(double month, double leap)
static double WeekDay(double t)
static const double SecondsPerMinute
static double MakeDate(double day, double time)
static double MakeDay(double year, double month, double day)
static double DaylightSavingTA(double t, double localTZA)
static QString ToLocaleString(double t)
static double DayWithinYear(double t)
static const double HoursPerDay
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
static double MonthFromTime(double t)
static int HourFromTime(double t)
static int SecFromTime(double t)
static double Day(double t)
static double TimeClip(double t)
static int MinFromTime(double t)
static QString ToDateString(double t)
static double MakeTime(double hour, double min, double sec, double ms)
static const double msPerMinute
static double DateFromTime(double t)
static double LocalTime(double t, double localTZA)
static const double MinutesPerHour
static double currentTime()
#define V4_NEEDS_DESTROY
#define Q_MANAGED_TYPE(type)
#define RETURN_RESULT(r)
static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int)
static QDate dateTimeToDate(const QDateTime &dateTime)
static QString dateTimeToString(const QDateTime &dateTime, ExecutionEngine *engine)
static QDateTime timestampToDateTime(double timestamp, QTimeZone zone=QTimeZone::LocalTime)
static QDateTime stringToDateTime(const QString &string, ExecutionEngine *engine)
static double dateTimeToNumber(const QDateTime &dateTime)
QString toString() const
static double componentsToTimestamp(double year, double month, double day, double hours, double mins, double secs, double ms, ExecutionEngine *v4)
static ReturnedValue method_setMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_UTC(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getTimezoneOffset(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleTimeString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDay(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toISOString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static void timezoneUpdated(ExecutionEngine *e)
static ReturnedValue method_setUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toDateString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCMonth(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_symbolToPrimitive(const FunctionObject *f, const Value *thisObject, const Value *, int)
static ReturnedValue method_getTime(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_valueOf(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_parse(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toJSON(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toUTCString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_toLocaleString(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getDate(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getUTCFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getFullYear(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_now(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getMilliseconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_getHours(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static ReturnedValue method_setUTCMinutes(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
static double getThisDate(ExecutionEngine *v4, const Value *thisObject)
static ReturnedValue method_setSeconds(const FunctionObject *, const Value *thisObject, const Value *argv, int argc)
QDate toQDate() const
operator double() const
bool withReadonlyStoragePointer(Function function)
QVariant toVariant() const
bool withWriteonlyStoragePointer(Function function, ExecutionEngine *engine)
void init(QTime time, ExecutionEngine *engine)
static constexpr quint64 MaxDateVal
void init(QDate date)
void init(const QDateTime &dateTime)
Date & operator=(double value)
QTime toQTime() const
QDateTime toQDateTime() const
void init(double value)
void init(Date date)
void init(QV4::ExecutionEngine *engine)
ReferenceObjectEndpoint(ReferenceObject *reference)
An object that keeps track of the provenance of its owned value, allowing to reflect mutations on the...
static bool writeBack(HeapObject *ref, int internalIndex=AllProperties)
static bool shouldConnect(Heap::ReferenceObject *ref)
static bool readReference(HeapObject *ref)
static HeapObject * detached(HeapObject *ref)
static void connect(Heap::ReferenceObject *ref)