Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qv4scopedvalue_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#ifndef QV4SCOPEDVALUE_P_H
4#define QV4SCOPEDVALUE_P_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 "qv4engine_p.h"
18#include "qv4value_p.h"
19#include "qv4property_p.h"
20#include "qv4propertykey_p.h"
21
22#ifdef V4_USE_VALGRIND
23#include <valgrind/memcheck.h>
24#endif
25
27
28#define SAVE_JS_STACK(ctx) Value *__jsStack = ctx->engine->jsStackTop
29#define CHECK_JS_STACK(ctx) Q_ASSERT(__jsStack == ctx->engine->jsStackTop)
30
31namespace QV4 {
32
33struct ScopedValue;
34
36{
37 return engine->hasException || engine->isInterrupted.loadRelaxed();
38}
39
40#define CHECK_EXCEPTION() \
41 do { \
42 if (hasExceptionOrIsInterrupted(scope.engine)) { \
43 return QV4::Encode::undefined(); \
44 } \
45 } while (false)
46
47#define RETURN_UNDEFINED() \
48 return QV4::Encode::undefined()
49
50#define RETURN_RESULT(r) \
51 return QV4::Encode(r)
52
53#define THROW_TYPE_ERROR() \
54 return scope.engine->throwTypeError()
55
56#define THROW_GENERIC_ERROR(str) \
57 return scope.engine->throwError(QString::fromUtf8(str))
58
59struct Scope {
61 : engine(ctx->engine())
62 , mark(engine->jsStackTop)
63 {
64 }
65
67 : engine(e)
68 , mark(engine->jsStackTop)
69 {
70 }
71
72 explicit Scope(const Managed *m)
73 : engine(m->engine())
74 , mark(engine->jsStackTop)
75 {
76 }
77
79#ifndef QT_NO_DEBUG
81// Q_ASSERT(engine->currentContext < mark);
82 memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
83#endif
84#ifdef V4_USE_VALGRIND
85 VALGRIND_MAKE_MEM_UNDEFINED(mark, (engine->jsStackLimit - mark) * sizeof(Value));
86#endif
88 }
89
90 enum AllocMode {
93 /* Be careful when using Uninitialized, the stack has to be fully initialized before calling into the memory manager again */
95 };
96
97 template <AllocMode mode = Undefined>
98 Value *alloc(qint64 nValues) const = delete; // use safeForAllocLength
99
100 template <AllocMode mode = Undefined>
102 {
103 Value *ptr = engine->jsAlloca(nValues);
104 switch (mode) {
105 case Undefined:
106 for (int i = 0; i < nValues; ++i)
108 break;
109 case Empty:
110 for (int i = 0; i < nValues; ++i)
112 break;
113 case Uninitialized:
114 break;
115 }
116 return ptr;
117 }
118 template <AllocMode mode = Undefined>
120 {
121 Value *ptr = engine->jsAlloca(1);
122 switch (mode) {
123 case Undefined:
125 break;
126 case Empty:
128 break;
129 case Uninitialized:
130 break;
131 }
132 return ptr;
133 }
134
135 bool hasException() const {
136 return engine->hasException;
137 }
138
141
142private:
143 Q_DISABLE_COPY(Scope)
144};
145
147{
148 ScopedValue(const ScopedValue &) = default;
150
151 ScopedValue(const Scope &scope)
152 {
153 ptr = scope.alloc<Scope::Uninitialized>();
154 ptr->setRawValue(0);
155 }
156
157 ScopedValue(const Scope &scope, const Value &v)
158 {
159 ptr = scope.alloc<Scope::Uninitialized>();
160 *ptr = v;
161 }
162
164 {
165 ptr = scope.alloc<Scope::Uninitialized>();
166 ptr->setM(o);
167 }
168
169 ScopedValue(const Scope &scope, Managed *m)
170 {
171 ptr = scope.alloc<Scope::Uninitialized>();
172 ptr->setRawValue(m->asReturnedValue());
173 }
174
175 ScopedValue(const Scope &scope, const ReturnedValue &v)
176 {
177 ptr = scope.alloc<Scope::Uninitialized>();
178 ptr->setRawValue(v);
179 }
180
182 *ptr = v;
183 return *this;
184 }
185
187 ptr->setM(o);
188 return *this;
189 }
190
192 *ptr = *m;
193 return *this;
194 }
195
197 ptr->setRawValue(v);
198 return *this;
199 }
200
202 *ptr = *other.ptr;
203 return *this;
204 }
205
207 return ptr;
208 }
209
210 const Value *operator->() const {
211 return ptr;
212 }
213
214 operator Value *() { return ptr; }
215 operator const Value &() const { return *ptr; }
216
218};
219
220
222{
224 {
225 ptr = reinterpret_cast<PropertyKey *>(scope.alloc<Scope::Uninitialized>());
227 }
228
229 ScopedPropertyKey(const Scope &scope, const PropertyKey &v)
230 {
231 ptr = reinterpret_cast<PropertyKey *>(scope.alloc<Scope::Uninitialized>());
232 *ptr = v;
233 }
234
236 *ptr = other;
237 return *this;
238 }
239
241 return ptr;
242 }
243 operator PropertyKey() const {
244 return *ptr;
245 }
246
247 bool operator==(const PropertyKey &other) const {
248 return *ptr == other;
249 }
250 bool operator==(const ScopedPropertyKey &other) const {
251 return *ptr == *other.ptr;
252 }
253 bool operator!=(const PropertyKey &other) const {
254 return *ptr != other;
255 }
256 bool operator!=(const ScopedPropertyKey &other) const {
257 return *ptr != *other.ptr;
258 }
259
261};
262
263
264template<typename T>
265struct Scoped
266{
268
270 ptr->setM(p ? p->m() : nullptr);
271 }
272
274 {
275 ptr = scope.alloc<Scope::Undefined>();
276 }
277
279 {
280 ptr = scope.alloc<Scope::Uninitialized>();
281 setPointer(v.as<T>());
282 }
284 {
285 Value v;
286 v = o;
287 ptr = scope.alloc<Scope::Uninitialized>();
288 setPointer(v.as<T>());
289 }
291 {
292 ptr = scope.alloc<Scope::Uninitialized>();
293 setPointer(v.ptr->as<T>());
294 }
295
297 {
298 ptr = scope.alloc<Scope::Uninitialized>();
299 ptr->setRawValue(value_convert<T>(scope.engine, v));
300 }
301
303 {
304 ptr = scope.alloc<Scope::Uninitialized>();
305 setPointer(v ? v->as<T>() : nullptr);
306 }
307
309 {
310 ptr = scope.alloc<Scope::Uninitialized>();
311 setPointer(t);
312 }
313
314 QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const T *t)
315 {
316 ptr = scope.alloc<Scope::Uninitialized>();
317 setPointer(t);
318 }
319
320 QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, typename T::Data *t)
321 {
322 ptr = scope.alloc<Scope::Uninitialized>();
323 *ptr = t;
324 }
325
331
333 {
334 ptr = scope.alloc<Scope::Uninitialized>();
335 ptr->setRawValue(value_convert<T>(scope.engine, QV4::Value::fromReturnedValue(v)));
336 }
337
338 Scoped<T> &operator=(Heap::Base *o) {
340 return *this;
341 }
342 Scoped<T> &operator=(typename T::Data *t) {
343 *ptr = t;
344 return *this;
345 }
346 Scoped<T> &operator=(const Value &v) {
347 setPointer(v.as<T>());
348 return *this;
349 }
350 Scoped<T> &operator=(Value *v) {
351 setPointer(v ? v->as<T>() : nullptr);
352 return *this;
353 }
354
355 Scoped<T> &operator=(const ReturnedValue &v) {
357 return *this;
358 }
359
360 Scoped<T> &operator=(T *t) {
361 setPointer(t);
362 return *this;
363 }
364
365 operator T *() {
366 return static_cast<T *>(ptr->managed());
367 }
368 operator const Value &() const {
369 return *ptr;
370 }
371
373 return getPointer();
374 }
375
376 const T *operator->() const {
377 return getPointer();
378 }
379
380 explicit operator bool() const {
381 return ptr->m();
382 }
383
385 return reinterpret_cast<T *>(ptr);
386 }
387
388 const T *getPointer() const {
389 return reinterpret_cast<T *>(ptr);
390 }
391
393 return ptr;
394 }
395
399
401};
402
404{
405 _val = v.ptr->rawValue();
406 return *this;
407}
408
409template<typename T>
410inline Value &Value::operator=(const Scoped<T> &t)
411{
412 _val = t.ptr->rawValue();
413 return *this;
414}
415
417{
419 {
420 property = reinterpret_cast<Property*>(scope.alloc(int(sizeof(Property) / sizeof(Value))));
421 }
422
424 operator const Property *() const { return property; }
425 operator Property *() { return property; }
426
428};
429
430}
431
433
434#endif
bool isInterrupted() const
EGLContext ctx
Combined button and popup list for selecting options.
quint64 ReturnedValue
bool hasExceptionOrIsInterrupted(ExecutionEngine *engine)
static ControlElement< T > * ptr(QWidget *widget)
GLsizei const GLfloat * v
[13]
GLenum mode
const GLfloat * m
GLdouble GLdouble t
Definition qopenglext.h:243
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define QML_NEARLY_ALWAYS_INLINE
long long qint64
Definition qtypes.h:60
QSharedPointer< T > other(t)
[5]
QJSEngine engine
[0]
QML_NEARLY_ALWAYS_INLINE Value * jsAlloca(int nValues)
static PropertyKey invalid()
Value * alloc(qint64 nValues) const =delete
bool hasException() const
QML_NEARLY_ALWAYS_INLINE Value * alloc() const
QML_NEARLY_ALWAYS_INLINE Value * alloc(int nValues) const
Scope(const Managed *m)
Scope(ExecutionEngine *e)
ExecutionEngine * engine
Scope(ExecutionContext *ctx)
ScopedPropertyKey & operator=(const PropertyKey &other)
ScopedPropertyKey(const Scope &scope)
ScopedPropertyKey(const Scope &scope, const PropertyKey &v)
bool operator==(const PropertyKey &other) const
bool operator==(const ScopedPropertyKey &other) const
bool operator!=(const ScopedPropertyKey &other) const
bool operator!=(const PropertyKey &other) const
ScopedProperty(Scope &scope)
ScopedValue(const Scope &scope, Managed *m)
ScopedValue & operator=(Managed *m)
ScopedValue & operator=(const Value &v)
ScopedValue(const Scope &scope, const Value &v)
ScopedValue(ScopedValue &&)=default
ScopedValue(const Scope &scope)
ScopedValue(const ScopedValue &)=default
ScopedValue(const Scope &scope, const ReturnedValue &v)
ScopedValue & operator=(const ScopedValue &other)
const Value * operator->() const
ScopedValue(const Scope &scope, Heap::Base *o)
ScopedValue & operator=(const ReturnedValue &v)
ScopedValue & operator=(Heap::Base *o)
Scoped< T > & operator=(typename T::Data *t)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const ScopedValue &v)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const Value &v)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, T *t)
Scoped< T > & operator=(Value *v)
Scoped< T > & operator=(const ReturnedValue &v)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const Value &v, ConvertType)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const ReturnedValue &v, ConvertType)
Scoped< T > & operator=(Heap::Base *o)
Scoped< T > & operator=(const Value &v)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const T *t)
QML_NEARLY_ALWAYS_INLINE void setPointer(const Managed *p)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const Value *v)
const T * getPointer() const
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, const ReturnedValue &v)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope)
const T * operator->() const
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, typename T::Data *t)
QML_NEARLY_ALWAYS_INLINE Scoped(const Scope &scope, Heap::Base *o)
Scoped< T > & operator=(T *t)
QML_NEARLY_ALWAYS_INLINE ReturnedValue asReturnedValue() const
QV4_NEARLY_ALWAYS_INLINE constexpr quint64 rawValue() const
QV4_NEARLY_ALWAYS_INLINE constexpr void setRawValue(quint64 raw)
QML_NEARLY_ALWAYS_INLINE ManagedPtr managed() const
Definition qv4value_p.h:75
static constexpr Value undefinedValue()
Definition qv4value_p.h:191
Value & operator=(const ScopedValue &v)
static Value fromHeapObject(HeapBasePtr m)
Definition qv4value_p.h:84
static constexpr Value fromReturnedValue(ReturnedValue val)
Definition qv4value_p.h:165
static constexpr Value emptyValue()
Definition qv4value_p.h:179