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 QV4PERSISTENT_H
4#define QV4PERSISTENT_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 "qv4value_p.h"
18#include "qv4managed_p.h"
19
20QT_BEGIN_NAMESPACE
21
22namespace QV4 {
23
24struct Q_QML_EXPORT PersistentValueStorage
25{
26 PersistentValueStorage(ExecutionEngine *engine);
27 ~PersistentValueStorage();
28
29 Value *allocate();
30 static void free(Value *v)
31 {
32 if (v)
33 freeUnchecked(v);
34 }
35
36 void mark(MarkStack *markStack);
37
38 struct Iterator {
39 Iterator(void *p, int idx);
40 Iterator(const Iterator &o);
41 Iterator & operator=(const Iterator &o);
42 ~Iterator();
43 void *p;
44 int index;
45 Iterator &operator++();
46 bool operator !=(const Iterator &other) {
47 return p != other.p || index != other.index;
48 }
49 Value &operator *();
50 };
51 Iterator begin() { return Iterator(firstPage, 0); }
52 Iterator end() { return Iterator(nullptr, 0); }
53
54 static ExecutionEngine *getEngine(const Value *v);
55
56 ExecutionEngine *engine;
57 void *firstPage;
58private:
59 static void freeUnchecked(Value *v);
60 static void freePage(void *page);
61};
62
63class Q_QML_EXPORT PersistentValue
64{
65public:
66 constexpr PersistentValue() noexcept = default;
67 PersistentValue(const PersistentValue &other);
68 PersistentValue &operator=(const PersistentValue &other);
69
70 PersistentValue(PersistentValue &&other) noexcept : val(std::exchange(obj&: other.val, new_val: nullptr)) {}
71 void swap(PersistentValue &other) noexcept { qt_ptr_swap(lhs&: val, rhs&: other.val); }
72 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(PersistentValue)
73 ~PersistentValue() { PersistentValueStorage::free(v: val); }
74
75 PersistentValue &operator=(const WeakValue &other);
76 PersistentValue &operator=(Object *object);
77
78 PersistentValue(ExecutionEngine *engine, const Value &value);
79 PersistentValue(ExecutionEngine *engine, ReturnedValue value);
80 PersistentValue(ExecutionEngine *engine, Object *object);
81
82 void set(ExecutionEngine *engine, const Value &value);
83 void set(ExecutionEngine *engine, ReturnedValue value);
84 void set(ExecutionEngine *engine, Heap::Base *obj);
85
86 ReturnedValue value() const {
87 return (val ? val->asReturnedValue() : Encode::undefined());
88 }
89 Value *valueRef() const {
90 return val;
91 }
92 Managed *asManaged() const {
93 if (!val)
94 return nullptr;
95 return val->managed();
96 }
97 template<typename T>
98 T *as() const {
99 if (!val)
100 return nullptr;
101 return val->as<T>();
102 }
103
104 ExecutionEngine *engine() const {
105 if (!val)
106 return nullptr;
107 return PersistentValueStorage::getEngine(v: val);
108 }
109
110 bool isUndefined() const { return !val || val->isUndefined(); }
111 bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
112 void clear() {
113 PersistentValueStorage::free(v: val);
114 val = nullptr;
115 }
116 bool isEmpty() { return !val; }
117
118private:
119 Value *val = nullptr;
120};
121
122class Q_QML_EXPORT WeakValue
123{
124public:
125 WeakValue() {}
126 WeakValue(const WeakValue &other);
127 WeakValue(ExecutionEngine *engine, const Value &value);
128 WeakValue &operator=(const WeakValue &other);
129 ~WeakValue();
130
131 void set(ExecutionEngine *engine, const Value &value)
132 {
133 if (!val)
134 allocVal(engine);
135 *val = value;
136 }
137
138 void set(ExecutionEngine *engine, ReturnedValue value)
139 {
140 if (!val)
141 allocVal(engine);
142 *val = value;
143 }
144
145 void set(ExecutionEngine *engine, Heap::Base *obj)
146 {
147 if (!val)
148 allocVal(engine);
149 *val = obj;
150 }
151
152 ReturnedValue value() const {
153 return (val ? val->asReturnedValue() : Encode::undefined());
154 }
155 Value *valueRef() const {
156 return val;
157 }
158 Managed *asManaged() const {
159 if (!val)
160 return nullptr;
161 return val->managed();
162 }
163 template <typename T>
164 T *as() const {
165 if (!val)
166 return nullptr;
167 return val->as<T>();
168 }
169
170 ExecutionEngine *engine() const {
171 if (!val)
172 return nullptr;
173 return PersistentValueStorage::getEngine(v: val);
174 }
175
176 bool isUndefined() const { return !val || val->isUndefined(); }
177 bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
178 void clear() { free(); }
179
180 void markOnce(MarkStack *markStack);
181
182private:
183 Value *val = nullptr;
184
185private:
186 Q_NEVER_INLINE void allocVal(ExecutionEngine *engine);
187
188 void free();
189};
190
191} // namespace QV4
192
193QT_END_NAMESPACE
194
195#endif
196

source code of qtdeclarative/src/qml/jsruntime/qv4persistent_p.h