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
qv4value_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 QV4VALUE_P_H
5#define QV4VALUE_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 <limits.h>
19#include <cmath>
20
21#include <QtCore/QString>
22#include "qv4global_p.h"
23#include <private/qv4heap_p.h>
24#include <private/qv4internalclass_p.h>
25#include <private/qv4staticvalue_p.h>
26
27#include <private/qnumeric_p.h>
28#include <private/qv4calldata_p.h>
29
30QT_BEGIN_NAMESPACE
31
32namespace QV4 {
33
34namespace Heap {
35 struct Base;
36}
37
38struct Q_QML_EXPORT Value : public StaticValue
39{
41
43 {
44 return {staticValue._val};
45 }
46
47 static constexpr Value undefined()
48 {
50 }
51
52 inline bool isString() const;
53 inline bool isStringOrSymbol() const;
54 inline bool isSymbol() const;
55 inline bool isObject() const;
56 inline bool isFunctionObject() const;
57
59 if (!isString())
60 return nullptr;
61 return reinterpret_cast<String *>(const_cast<Value *>(this));
62 }
64 if (!isStringOrSymbol())
65 return nullptr;
66 return reinterpret_cast<StringOrSymbol *>(const_cast<Value *>(this));
67 }
69 if (!isSymbol())
70 return nullptr;
71 return reinterpret_cast<Symbol *>(const_cast<Value *>(this));
72 }
74 if (!isObject())
75 return nullptr;
76 return reinterpret_cast<Object*>(const_cast<Value *>(this));
77 }
79 if (!isManaged())
80 return nullptr;
81 return reinterpret_cast<Managed*>(const_cast<Value *>(this));
82 }
84 return isManagedOrUndefined() ? m() : nullptr;
85 }
86
88 {
89 Value v;
90 v.setM(m);
91 return v;
92 }
93
94 int toUInt16() const;
95 inline int toInt32() const;
96 inline unsigned int toUInt32() const;
97 qint64 toLength() const;
98 inline qint64 toIndex() const;
99
100 bool toBoolean() const {
101 if (integerCompatible())
102 return static_cast<bool>(int_32());
103
104 return toBooleanImpl(*this);
105 }
106 static bool toBooleanImpl(Value val);
107 double toInteger() const;
108 inline ReturnedValue convertedToNumber() const;
109 inline double toNumber() const;
110 static double toNumberImpl(Value v);
111 double toNumberImpl() const { return toNumberImpl(*this); }
112
114 QString toQString() const;
115 QString toQString(bool *ok) const;
116
118 if (isString())
119 return reinterpret_cast<Heap::String *>(m());
120 return toString(e, *this);
121 }
123
126 if (isObject())
127 return reinterpret_cast<Heap::Object *>(m());
128 return toObject(e, *this);
129 }
131
132 inline bool isPrimitive() const;
133
134 template <typename T>
135 const T *as() const {
136 if (!isManaged())
137 return nullptr;
138
140#if !defined(QT_NO_QOBJECT_CHECK)
141 static_cast<const T *>(this)->qt_check_for_QMANAGED_macro(static_cast<const T *>(this));
142#endif
143 const VTable *vt = m()->internalClass->vtable;
144 while (vt) {
145 if (vt == T::staticVTable())
146 return static_cast<const T *>(this);
147 vt = vt->parent;
148 }
149 return nullptr;
150 }
151 template <typename T>
152 T *as() {
153 if (isManaged())
154 return const_cast<T *>(const_cast<const Value *>(this)->as<T>());
155 else
156 return nullptr;
157 }
158
159 template<typename T> inline T *cast() {
160 return static_cast<T *>(managed());
161 }
162 template<typename T> inline const T *cast() const {
163 return static_cast<const T *>(managed());
164 }
165
166 uint asArrayLength(bool *ok) const;
167
172
173 // As per ES specs
174 bool sameValue(Value other) const;
175 bool sameValueZero(Value other) const;
176
177 inline void mark(MarkStack *markStack);
178
179 static double toInteger(double d) { return StaticValue::toInteger(d); }
180 static int toInt32(double d) { return StaticValue::toInt32(d); }
181 static unsigned int toUInt32(double d) { return StaticValue::toUInt32(d); }
182 inline static constexpr Value emptyValue()
183 {
185 }
186 static inline constexpr Value fromBoolean(bool b)
187 {
189 }
190 static inline constexpr Value fromInt32(int i)
191 {
193 }
194 inline static constexpr Value undefinedValue()
195 {
197 }
198 static inline constexpr Value nullValue()
199 {
201 }
202 static inline Value fromDouble(double d)
203 {
205 }
206 static inline Value fromUInt32(uint i)
207 {
209 }
210
211 Value &operator =(const ScopedValue &v);
213 {
215 return *this;
216 }
218 if (!m) {
219 setM(nullptr);
220 } else {
221 _val = reinterpret_cast<Value *>(m)->_val;
222 }
223 return *this;
224 }
226 setM(o);
227 return *this;
228 }
229
230 template<typename T>
231 Value &operator=(const Scoped<T> &t);
232};
233static_assert(std::is_trivially_copyable_v<Value>);
235static_assert(sizeof(Value) == sizeof(StaticValue));
236
237template<>
239{
240 _val = value._val;
241 return *this;
242}
243
244template<typename Managed>
246{
247 *static_cast<Value *>(this) = m;
248 return *this;
249}
250
251template<>
253{
254 return *static_cast<Value *>(this);
255}
256
257template<>
258inline const Value &StaticValue::asValue<Value>() const
259{
260 return *static_cast<const Value *>(this);
261}
262
263template<>
265{
266 return static_cast<Value *>(static_cast<StaticValue *>(args));
267}
268
269template<>
270inline const Value *CallData::argValues<Value>() const
271{
272 return static_cast<const Value *>(static_cast<const StaticValue *>(args));
273}
274
275template<typename HeapBase>
280
282{
284 if (o)
285 o->mark(markStack);
286}
287
288inline bool Value::isString() const
289{
291 return b && b->internalClass->vtable->isString;
292}
293
295{
298}
299
300bool Value::isSymbol() const
301{
304}
305
306inline bool Value::isObject() const
307
308{
310 return b && b->internalClass->vtable->isObject;
311}
312
313inline bool Value::isFunctionObject() const
314{
316 if (!b)
317 return false;
320}
321
322inline bool Value::isPrimitive() const
323{
324 return !isObject();
325}
326
327inline double Value::toNumber() const
328{
329 if (isInteger())
330 return int_32();
331 if (isDouble())
332 return doubleValue();
333 return toNumberImpl();
334}
335
337{
338 if (isInteger() || isDouble())
339 return asReturnedValue();
340 Value v;
342 return v.asReturnedValue();
343}
344
345inline
347{
348 return Value::fromHeapObject(const_cast<Value::HeapBasePtr>(this)).asReturnedValue();
349}
350
351// For source compat with older code in other modules
352using Primitive = Value;
353
354template<typename T>
355ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
356
357inline int Value::toInt32() const
358{
360 return int_32();
361
362 if (Q_LIKELY(isDouble()))
364
366}
367
368inline unsigned int Value::toUInt32() const
369{
370 return static_cast<unsigned int>(toInt32());
371}
372
373inline qint64 Value::toLength() const
374{
376 return int_32() < 0 ? 0 : int_32();
377 double i = Value::toInteger(isDouble() ? doubleValue() : toNumberImpl());
378 if (i <= 0)
379 return 0;
380 if (i > (static_cast<qint64>(1) << 53) - 1)
381 return (static_cast<qint64>(1) << 53) - 1;
382 return static_cast<qint64>(i);
383}
384
385inline qint64 Value::toIndex() const
386{
387 qint64 idx;
389 idx = int_32();
390 } else {
391 idx = static_cast<qint64>(Value::toInteger(isDouble() ? doubleValue() : toNumberImpl()));
392 }
393 if (idx > (static_cast<qint64>(1) << 53) - 1)
394 idx = -1;
395 return idx;
396}
397
398inline double Value::toInteger() const
399{
400 if (integerCompatible())
401 return int_32();
402
404}
405
406
407template <size_t o>
408struct HeapValue : Value {
409 static constexpr size_t offset = o;
411 HeapBasePtr base = reinterpret_cast<HeapBasePtr>(this) - (offset/sizeof(Heap::Base));
412 Q_ASSERT(base->inUse());
413 return base;
414 }
415
416 void set(EngineBase *e, const Value &newVal) {
417 WriteBarrier::write(e, base(), data_ptr(), newVal.asReturnedValue());
418 }
419 void set(EngineBase *e, HeapBasePtr b) {
420 WriteBarrier::write(e, base(), data_ptr(), b->asReturnedValue());
421 }
422 void set(EngineBase *e, ReturnedValue rv) {
423 WriteBarrier::write(e, base(), data_ptr(), rv);
424 }
425};
426
427template <size_t o>
429 static constexpr size_t offset = o;
430 uint size;
431 uint alloc;
432 Value values[1];
433
435 Value::HeapBasePtr base = reinterpret_cast<Value::HeapBasePtr>(this)
436 - (offset/sizeof(Heap::Base));
437 Q_ASSERT(base->inUse());
438 return base;
439 }
440
441 void set(EngineBase *e, uint index, Value v) {
442 WriteBarrier::write(e, base(), values[index].data_ptr(), v.asReturnedValue());
443 }
444 void set(EngineBase *e, uint index, Value::HeapBasePtr b) {
445 WriteBarrier::write(e, base(), values[index].data_ptr(), Value::fromHeapObject(b).asReturnedValue());
446 }
447 inline const Value &operator[] (uint index) const {
448 Q_ASSERT(index < alloc);
449 return values[index];
450 }
451 inline const Value *data() const {
452 return values;
453 }
454
455 void mark(MarkStack *markStack) {
456 for (Value *v = values, *end = values + alloc; v < end; ++v)
457 v->mark(markStack);
458 }
459};
460
461// It's really important that the offset of values in this structure is
462// constant across all architecture, otherwise JIT cross-compiled code will
463// have wrong offsets between host and target.
464Q_STATIC_ASSERT(offsetof(ValueArray<0>, values) == 8);
465
467 ReturnedValue value;
468public:
469
471 explicit OptionalReturnedValue(ReturnedValue v)
472 : value(v)
473 {
474 Q_ASSERT(!Value::fromReturnedValue(v).isEmpty());
475 }
476
477 ReturnedValue operator->() const { return value; }
478 ReturnedValue operator*() const { return value; }
479 explicit operator bool() const { return !Value::fromReturnedValue(value).isEmpty(); }
480};
481
482}
483
484QT_END_NAMESPACE
485
486#endif // QV4VALUE_DEF_P_H
ReturnedValue operator*() const
Definition qv4value_p.h:478
OptionalReturnedValue(ReturnedValue v)
Definition qv4value_p.h:471
ReturnedValue operator->() const
Definition qv4value_p.h:477
Combined button and popup list for selecting options.
DECLARE_HEAP_OBJECT(StrictArgumentsObject, Object)
DECLARE_EXPORTED_HEAP_OBJECT(Object, Base)
Definition qv4object_p.h:37
DECLARE_HEAP_OBJECT(ArgumentsObject, Object)
CallResultDestination
Definition qjsvalue.h:24
Value Primitive
Definition qv4value_p.h:352
Scoped< FunctionObject > ScopedFunctionObject
int qYouForgotTheQ_MANAGED_Macro(T, T)
QList< StackFrame > StackTrace
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
Q_STATIC_ASSERT(sizeof(CppStackFrame)==sizeof(JSTypesStackFrame))
Scoped< ExecutionContext > ScopedContext
Q_DECLARE_TYPEINFO(QDateTime::Data, Q_RELOCATABLE_TYPE)
DEFINE_OBJECT_VTABLE(StrictArgumentsObject)
DEFINE_OBJECT_VTABLE(ArgumentsObject)
#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
static constexpr size_t offset
Definition qv4value_p.h:409
void set(EngineBase *e, HeapBasePtr b)
Definition qv4value_p.h:419
HeapBasePtr base()
Definition qv4value_p.h:410
void set(EngineBase *e, const Value &newVal)
Definition qv4value_p.h:416
void init(const QStringList &list)
void init(double val)
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
const Value * data() const
Definition qv4value_p.h:451
Value values[1]
Definition qv4value_p.h:432
void set(EngineBase *e, uint index, Value v)
Definition qv4value_p.h:441
void set(EngineBase *e, uint index, Value::HeapBasePtr b)
Definition qv4value_p.h:444
void mark(MarkStack *markStack)
Definition qv4value_p.h:455
Value::HeapBasePtr base()
Definition qv4value_p.h:434
const Value & operator[](uint index) const
Definition qv4value_p.h:447
static constexpr size_t offset
Definition qv4value_p.h:429