1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39#ifndef QV4PERSISTENT_H
40#define QV4PERSISTENT_H
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51//
52
53#include "qv4value_p.h"
54#include "qv4managed_p.h"
55
56QT_BEGIN_NAMESPACE
57
58namespace QV4 {
59
60struct Q_QML_EXPORT PersistentValueStorage
61{
62 PersistentValueStorage(ExecutionEngine *engine);
63 ~PersistentValueStorage();
64
65 Value *allocate();
66 static void free(Value *e);
67
68 void mark(MarkStack *markStack);
69
70 struct Iterator {
71 Iterator(void *p, int idx);
72 Iterator(const Iterator &o);
73 Iterator & operator=(const Iterator &o);
74 ~Iterator();
75 void *p;
76 int index;
77 Iterator &operator++();
78 bool operator !=(const Iterator &other) {
79 return p != other.p || index != other.index;
80 }
81 Value &operator *();
82 };
83 Iterator begin() { return Iterator(firstPage, 0); }
84 Iterator end() { return Iterator(nullptr, 0); }
85
86 static ExecutionEngine *getEngine(Value *v);
87
88 ExecutionEngine *engine;
89 void *firstPage;
90private:
91 static void freePage(void *page);
92};
93
94class Q_QML_EXPORT PersistentValue
95{
96public:
97 PersistentValue() {}
98 PersistentValue(const PersistentValue &other);
99 PersistentValue &operator=(const PersistentValue &other);
100 PersistentValue &operator=(const WeakValue &other);
101 PersistentValue &operator=(Object *object);
102 ~PersistentValue();
103
104 PersistentValue(ExecutionEngine *engine, const Value &value);
105 PersistentValue(ExecutionEngine *engine, ReturnedValue value);
106 PersistentValue(ExecutionEngine *engine, Object *object);
107
108 void set(ExecutionEngine *engine, const Value &value);
109 void set(ExecutionEngine *engine, ReturnedValue value);
110 void set(ExecutionEngine *engine, Heap::Base *obj);
111
112 ReturnedValue value() const {
113 return (val ? val->asReturnedValue() : Encode::undefined());
114 }
115 Value *valueRef() const {
116 return val;
117 }
118 Managed *asManaged() const {
119 if (!val)
120 return nullptr;
121 return val->managed();
122 }
123 template<typename T>
124 T *as() const {
125 if (!val)
126 return nullptr;
127 return val->as<T>();
128 }
129
130 ExecutionEngine *engine() const {
131 if (!val)
132 return nullptr;
133 return PersistentValueStorage::getEngine(val);
134 }
135
136 bool isUndefined() const { return !val || val->isUndefined(); }
137 bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
138 void clear() {
139 PersistentValueStorage::free(val);
140 val = nullptr;
141 }
142 bool isEmpty() { return !val; }
143
144private:
145 Value *val = nullptr;
146};
147
148class Q_QML_EXPORT WeakValue
149{
150public:
151 WeakValue() {}
152 WeakValue(const WeakValue &other);
153 WeakValue(ExecutionEngine *engine, const Value &value);
154 WeakValue &operator=(const WeakValue &other);
155 ~WeakValue();
156
157 void set(ExecutionEngine *engine, const Value &value)
158 {
159 if (!val)
160 allocVal(engine);
161 *val = value;
162 }
163
164 void set(ExecutionEngine *engine, ReturnedValue value)
165 {
166 if (!val)
167 allocVal(engine);
168 *val = value;
169 }
170
171 void set(ExecutionEngine *engine, Heap::Base *obj)
172 {
173 if (!val)
174 allocVal(engine);
175 *val = obj;
176 }
177
178 ReturnedValue value() const {
179 return (val ? val->asReturnedValue() : Encode::undefined());
180 }
181 Value *valueRef() const {
182 return val;
183 }
184 Managed *asManaged() const {
185 if (!val)
186 return nullptr;
187 return val->managed();
188 }
189 template <typename T>
190 T *as() const {
191 if (!val)
192 return nullptr;
193 return val->as<T>();
194 }
195
196 ExecutionEngine *engine() const {
197 if (!val)
198 return nullptr;
199 return PersistentValueStorage::getEngine(val);
200 }
201
202 bool isUndefined() const { return !val || val->isUndefined(); }
203 bool isNullOrUndefined() const { return !val || val->isNullOrUndefined(); }
204 void clear() { free(); }
205
206 void markOnce(MarkStack *markStack);
207
208private:
209 Value *val = nullptr;
210
211private:
212 Q_NEVER_INLINE void allocVal(ExecutionEngine *engine);
213
214 void free();
215};
216
217} // namespace QV4
218
219QT_END_NAMESPACE
220
221#endif
222