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
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// Qt-Security score:significant
4#ifndef QV4SCOPEDVALUE_P_H
5#define QV4SCOPEDVALUE_P_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 "qv4value_p.h"
20#include "qv4property_p.h"
22
23#ifdef V4_USE_VALGRIND
24#include <valgrind/memcheck.h>
25#endif
26
28
29#define SAVE_JS_STACK(ctx) Value *__jsStack = ctx->engine->jsStackTop
30#define CHECK_JS_STACK(ctx) Q_ASSERT(__jsStack == ctx->engine->jsStackTop)
31
32namespace QV4 {
33
34struct ScopedValue;
35
36inline bool hasExceptionOrIsInterrupted(ExecutionEngine *engine)
37{
38 return engine->hasException || engine->isInterrupted.loadRelaxed();
39}
40
41#define CHECK_EXCEPTION()
42 do {
43 if (hasExceptionOrIsInterrupted(scope.engine)) {
44 return QV4::Encode::undefined();
45 }
46 } while (false)
47
48#define RETURN_UNDEFINED()
49 return QV4::Encode::undefined()
50
51#define RETURN_RESULT(r)
52 return QV4::Encode(r)
53
54#define THROW_TYPE_ERROR()
55 return scope.engine->throwTypeError()
56
57#define THROW_GENERIC_ERROR(str)
58 return scope.engine->throwError(QString::fromUtf8(str))
59
60struct FunctionPrototype; // Used later for friending in Scope.
61struct Scope {
62 explicit Scope(ExecutionContext *ctx)
63 : engine(ctx->engine())
65 {
66 }
67
68 explicit Scope(ExecutionEngine *e)
69 : engine(e)
71 {
72 }
73
74 explicit Scope(const Managed *m)
75 : engine(m->engine())
77 {
78 }
79
80 ~Scope() {
81#ifndef QT_NO_DEBUG
82 Q_ASSERT(engine->jsStackTop >= mark);
83// Q_ASSERT(engine->currentContext < mark);
84 memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value));
85#endif
86#ifdef V4_USE_VALGRIND
87 VALGRIND_MAKE_MEM_UNDEFINED(mark, (engine->jsStackLimit - mark) * sizeof(Value));
88#endif
89 engine->jsStackTop = mark;
90 }
91
92 QML_NEARLY_ALWAYS_INLINE Value *construct(int nValues, const ReturnedValue& initialValue) const
93 {
95 for (int i = 0; i < nValues; ++i)
97 return ptr;
98 }
99
101 {
103 for (int i = 0; i < nValues; ++i)
104 ptr[i] = initialValue;
105 return ptr;
106 }
107
109 {
111 for (int i = 0; i < nValues; ++i)
113 return ptr;
114 }
115
117 {
118 PropertyKey *ptr = reinterpret_cast<PropertyKey*>(alloc(nValues));
119 for (int i = 0; i < nValues; ++i)
120 ptr[i] = initialValue;
121 return ptr;
122 }
123
128
129 bool hasException() const {
130 return engine->hasException;
131 }
132
134 Value *mark;
135
136private:
138 return engine->jsAlloca(nValues);
139 }
140
142
143 // The following are friended to allow access to a naked alloc.
144 // General usage of alloc is dangerous, and thus generally
145 // avoided, but in this case some more complex initialization
146 // patterns are used that don't sensibly fit into the various
147 // construct methods and further want to avoid the unnecessary
148 // writes that initializing the memory with a common value such as
149 // undefined would require.
150 friend FunctionPrototype;
151 template<typename Args>
152 friend CallData *callDatafromJS(const Scope &scope, const Args *args, const FunctionObject *f);
153};
154
156{
157 ScopedValue(const ScopedValue &) = default;
159
160 ScopedValue(const Scope &scope)
161 {
162 ptr = scope.construct(1, quint64(0));
163 }
164
165 ScopedValue(const Scope &scope, const Value &v)
166 {
167 ptr = scope.construct(1, v);
168 }
169
170 ScopedValue(const Scope &scope, Heap::Base *o)
171 {
172 ptr = scope.construct(1, o);
173 }
174
175 ScopedValue(const Scope &scope, Managed *m)
176 {
177 ptr = scope.construct(1, m->asReturnedValue());
178 }
179
180 ScopedValue(const Scope &scope, const ReturnedValue &v)
181 {
182 ptr = scope.construct(1, v);
183 }
184
185 ScopedValue &operator=(const Value &v) {
186 *ptr = v;
187 return *this;
188 }
189
191 ptr->setM(o);
192 return *this;
193 }
194
195 ScopedValue &operator=(Managed *m) {
196 *ptr = *m;
197 return *this;
198 }
199
200 ScopedValue &operator=(const ReturnedValue &v) {
201 ptr->setRawValue(v);
202 return *this;
203 }
204
206 *ptr = *other.ptr;
207 return *this;
208 }
209
210 Value *operator->() {
211 return ptr;
212 }
213
214 const Value *operator->() const {
215 return ptr;
216 }
217
218 operator Value *() { return ptr; }
219 operator const Value &() const { return *ptr; }
220
221 Value *ptr;
222};
223
224
226{
228 {
229 ptr = scope.construct(1, PropertyKey::invalid());
230 }
231
232 ScopedPropertyKey(const Scope &scope, const PropertyKey &v)
233 {
234 ptr = scope.construct(1, v);
235 }
236
238 *ptr = other;
239 return *this;
240 }
241
243 return ptr;
244 }
246 return *ptr;
247 }
248
249 bool operator==(const PropertyKey &other) const {
250 return *ptr == other;
251 }
252 bool operator==(const ScopedPropertyKey &other) const {
253 return *ptr == *other.ptr;
254 }
255 bool operator!=(const PropertyKey &other) const {
256 return *ptr != other;
257 }
258 bool operator!=(const ScopedPropertyKey &other) const {
259 return *ptr != *other.ptr;
260 }
261
263};
264
265
266template<typename T>
267struct Scoped
268{
270
271 QML_NEARLY_ALWAYS_INLINE Heap::Base *underlying(const Managed *p) {
272 return p ? p->m() : nullptr;
273 }
274
278
283
285 {
286 ptr = scope.construct(1, underlying(v.as<T>()));
287 }
288
290 {
291 Value v;
292 v = o;
293 ptr = scope.construct(1, underlying(v.as<T>()));
294 }
299
304
306 {
307 ptr = scope.construct(1, underlying(v ? v->as<T>() : nullptr));
308 }
309
314
316 {
318 }
319
321 {
322 ptr = scope.construct(1, t);
323 }
324
329
334
337 return *this;
338 }
339 Scoped<T> &operator=(typename T::Data *t) {
340 *ptr = t;
341 return *this;
342 }
343 Scoped<T> &operator=(const Value &v) {
344 setPointer(v.as<T>());
345 return *this;
346 }
348 setPointer(v ? v->as<T>() : nullptr);
349 return *this;
350 }
351
354 return *this;
355 }
356
358 setPointer(t);
359 return *this;
360 }
361
363 return static_cast<T *>(ptr->managed());
364 }
365 operator const Value &() const {
366 return *ptr;
367 }
368
369 T *operator->() {
370 return getPointer();
371 }
372
373 const T *operator->() const {
374 return getPointer();
375 }
376
377 explicit operator bool() const {
378 return ptr->m();
379 }
380
382 return reinterpret_cast<T *>(ptr);
383 }
384
385 const T *getPointer() const {
386 return reinterpret_cast<T *>(ptr);
387 }
388
390 return ptr;
391 }
392
396
398};
399
400inline Value &Value::operator =(const ScopedValue &v)
401{
402 _val = v.ptr->rawValue();
403 return *this;
404}
405
406template<typename T>
407inline Value &Value::operator=(const Scoped<T> &t)
408{
409 _val = t.ptr->rawValue();
410 return *this;
411}
412
414{
416 {
417 property = reinterpret_cast<Property*>(scope.constructUndefined(int(sizeof(Property) / sizeof(Value))));
418 }
419
420 Property *operator->() { return property; }
421 operator const Property *() const { return property; }
422 operator Property *() { return property; }
423
425};
426
427}
428
429QT_END_NAMESPACE
430
431#endif
ArrayElementLessThan(ExecutionEngine *engine, const Value &comparefn)
bool operator()(Value v1, Value v2) const
ReturnedValue operator*() const
Definition qv4value_p.h:477
OptionalReturnedValue(ReturnedValue v)
Definition qv4value_p.h:470
ReturnedValue operator->() const
Definition qv4value_p.h:476
DECLARE_HEAP_OBJECT(StrictArgumentsObject, Object)
DECLARE_EXPORTED_HEAP_OBJECT(Object, Base)
Definition qv4object_p.h:37
DECLARE_HEAP_OBJECT(ArgumentsObject, Object)
DECLARE_HEAP_OBJECT(MemberData, Base)
DECLARE_HEAP_OBJECT(ArrayData, Base)
Q_STATIC_ASSERT(std::is_trivial_v< ArrayData >)
CallResultDestination
Definition qjsvalue.h:23
Value Primitive
Definition qv4value_p.h:351
Scoped< FunctionObject > ScopedFunctionObject
void sortHelper(RandomAccessIterator start, RandomAccessIterator end, LessThan lessThan)
QVector< StackFrame > StackTrace
int qYouForgotTheQ_MANAGED_Macro(T, T)
bool hasExceptionOrIsInterrupted(ExecutionEngine *engine)
Scoped< Object > ScopedObject
ReturnedValue value_convert(ExecutionEngine *e, const Value &v)
Scoped< ArrayObject > ScopedArrayObject
Scoped< String > ScopedString
Scoped< StringOrSymbol > ScopedStringOrSymbol
void qYouForgotTheQ_MANAGED_Macro(T1, T2)
PropertyFlag
@ Attr_Invalid
@ Attr_NotConfigurable
@ Attr_Data
@ Attr_NotEnumerable
@ Attr_ReadOnly
@ Attr_NotWritable
@ Attr_ReadOnly_ButConfigurable
@ Attr_Accessor
CallData * callDatafromJS(const Scope &scope, const Args *args, const FunctionObject *f)
Definition qv4jscall_p.h:41
Q_STATIC_ASSERT(sizeof(CppStackFrame)==sizeof(JSTypesStackFrame))
Scoped< ExecutionContext > ScopedContext
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_RELOCATABLE_TYPE)
DEFINE_OBJECT_VTABLE(StrictArgumentsObject)
DEFINE_OBJECT_VTABLE(ArgumentsObject)
#define V4_ARRAYDATA(DataClass)
#define V4_MANAGED(DataClass, superClass)
#define V4_MANAGED_SIZE_TEST
#define V4_NEEDS_DESTROY
#define V4_MANAGED_ITSELF(DataClass, superClass)
#define Q_MANAGED_TYPE(type)
#define V4_INTERNALCLASS(c)
#define Q_MANAGED_CHECK
static qint64 virtualGetLength(const Managed *m)
static bool virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property *desc, PropertyAttributes attrs)
Heap::CallContext * context() const
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
static OwnPropertyKeyIterator * virtualOwnPropertyKeys(const Object *m, Value *target)
static bool isNonStrictArgumentsObject(Managed *m)
static bool virtualDeleteProperty(Managed *m, PropertyKey id)
static PropertyAttributes virtualGetOwnProperty(const Managed *m, PropertyKey id, Property *p)
bool isMapped(uint arg) const
static bool virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver)
static bool virtualDefineOwnProperty(Managed *m, PropertyKey id, const Property *p, PropertyAttributes attrs)
static qint64 virtualGetLength(const Managed *m)
QStringList toQStringList() const
void(* setAttribute)(Object *o, uint index, PropertyAttributes attrs)
bool(* putArray)(Object *o, uint index, const Value *values, uint n)
bool(* put)(Object *o, uint index, const Value &value)
void(* push_front)(Object *o, const Value *values, uint n)
ReturnedValue(* get)(const Heap::ArrayData *d, uint index)
bool(* del)(Object *o, uint index)
ReturnedValue(* pop_front)(Object *o)
static constexpr size_t offset
Definition qv4value_p.h:408
void set(EngineBase *e, HeapBasePtr b)
Definition qv4value_p.h:418
HeapBasePtr base()
Definition qv4value_p.h:409
void set(EngineBase *e, const Value &newVal)
Definition qv4value_p.h:415
void init(const QStringList &list)
void init(double val)
PropertyAttributes attributes(uint i) const
uint mappedIndex(uint index) const
void setData(EngineBase *e, uint index, Value newVal)
const Value & data(uint index) const
uint mappedIndex(uint index) const
PropertyAttributes attributes(uint i) const
static Heap::MemberData * allocate(QV4::ExecutionEngine *e, uint n, Heap::MemberData *old=nullptr)
const Value * data() const
void set(EngineBase *e, uint index, Value v)
const Value & operator[](uint idx) const
void set(EngineBase *e, uint index, Heap::Base *b)
uint size() const
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
const Value * operator->() const
bool isNull() const
const Value & operator*() const
void set(EngineBase *e, Value newVal)
bool operator==(const PropertyKey &other) const
static PropertyKey invalid()
bool operator!=(const PropertyKey &other) const
void setGetter(FunctionObject *g)
Heap::FunctionObject * getter() const
bool isSubset(const PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const
void setSetter(FunctionObject *s)
void fullyPopulated(PropertyAttributes *attrs)
bool isCompatible(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs) const
void copy(const Property *other, PropertyAttributes attrs)
void completed(PropertyAttributes *attrs)
Property(Heap::FunctionObject *getter, Heap::FunctionObject *setter)
Heap::FunctionObject * setter() const
void merge(PropertyAttributes &attrs, const Property *other, PropertyAttributes otherAttrs)
Scope(const Managed *m)
Scope(ExecutionEngine *e)
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)
SparseArrayNode * right
SparseArrayNode * left
SparseArrayNode * copy(SparseArray *d) const
SparseArrayNode * lowerBound(uint key)
const SparseArrayNode * previousNode() const
SparseArrayNode * parent() const
SparseArrayNode * nextNode()
SparseArrayNode * upperBound(uint key)
const SparseArrayNode * nextNode() const
SparseArrayNode * previousNode()
void setParent(SparseArrayNode *pp)
SparseArrayNode * upperBound(uint key)
SparseArrayNode * erase(SparseArrayNode *n)
void push_back(uint at, uint len)
SparseArrayNode * lowerBound(uint key)
const SparseArrayNode * begin() const
SparseArrayNode * insert(uint akey)
void push_front(uint at)
uint pop_back(uint len)
QList< int > keys() const
SparseArrayNode * findNode(uint akey) const
void freeTree(SparseArrayNode *root, int alignment)
const SparseArrayNode * end() const
uint nEntries() const
const Value * data() const
Definition qv4value_p.h:450
Value values[1]
Definition qv4value_p.h:431
void set(EngineBase *e, uint index, Value v)
Definition qv4value_p.h:440
void set(EngineBase *e, uint index, Value::HeapBasePtr b)
Definition qv4value_p.h:443
void mark(MarkStack *markStack)
Definition qv4value_p.h:454
Value::HeapBasePtr base()
Definition qv4value_p.h:433
const Value & operator[](uint index) const
Definition qv4value_p.h:446
static constexpr size_t offset
Definition qv4value_p.h:428