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};
235
236template<>
238{
239 _val = value._val;
240 return *this;
241}
242
243template<typename Managed>
245{
246 *static_cast<Value *>(this) = m;
247 return *this;
248}
249
250template<>
252{
253 return *static_cast<Value *>(this);
254}
255
256template<>
257inline const Value &StaticValue::asValue<Value>() const
258{
259 return *static_cast<const Value *>(this);
260}
261
262template<>
264{
265 return static_cast<Value *>(static_cast<StaticValue *>(args));
266}
267
268template<>
269inline const Value *CallData::argValues<Value>() const
270{
271 return static_cast<const Value *>(static_cast<const StaticValue *>(args));
272}
273
274template<typename HeapBase>
279
281{
283 if (o)
284 o->mark(markStack);
285}
286
287inline bool Value::isString() const
288{
290 return b && b->internalClass->vtable->isString;
291}
292
294{
297}
298
299bool Value::isSymbol() const
300{
303}
304
305inline bool Value::isObject() const
306
307{
309 return b && b->internalClass->vtable->isObject;
310}
311
312inline bool Value::isFunctionObject() const
313{
315 if (!b)
316 return false;
319}
320
321inline bool Value::isPrimitive() const
322{
323 return !isObject();
324}
325
326inline double Value::toNumber() const
327{
328 if (isInteger())
329 return int_32();
330 if (isDouble())
331 return doubleValue();
332 return toNumberImpl();
333}
334
336{
337 if (isInteger() || isDouble())
338 return asReturnedValue();
339 Value v;
341 return v.asReturnedValue();
342}
343
344inline
346{
347 return Value::fromHeapObject(const_cast<Value::HeapBasePtr>(this)).asReturnedValue();
348}
349
350// For source compat with older code in other modules
351using Primitive = Value;
352
353template<typename T>
354ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
355
356inline int Value::toInt32() const
357{
359 return int_32();
360
361 if (Q_LIKELY(isDouble()))
363
365}
366
367inline unsigned int Value::toUInt32() const
368{
369 return static_cast<unsigned int>(toInt32());
370}
371
372inline qint64 Value::toLength() const
373{
375 return int_32() < 0 ? 0 : int_32();
376 double i = Value::toInteger(isDouble() ? doubleValue() : toNumberImpl());
377 if (i <= 0)
378 return 0;
379 if (i > (static_cast<qint64>(1) << 53) - 1)
380 return (static_cast<qint64>(1) << 53) - 1;
381 return static_cast<qint64>(i);
382}
383
384inline qint64 Value::toIndex() const
385{
386 qint64 idx;
388 idx = int_32();
389 } else {
390 idx = static_cast<qint64>(Value::toInteger(isDouble() ? doubleValue() : toNumberImpl()));
391 }
392 if (idx > (static_cast<qint64>(1) << 53) - 1)
393 idx = -1;
394 return idx;
395}
396
397inline double Value::toInteger() const
398{
399 if (integerCompatible())
400 return int_32();
401
403}
404
405
406template <size_t o>
407struct HeapValue : Value {
408 static constexpr size_t offset = o;
410 HeapBasePtr base = reinterpret_cast<HeapBasePtr>(this) - (offset/sizeof(Heap::Base));
411 Q_ASSERT(base->inUse());
412 return base;
413 }
414
415 void set(EngineBase *e, const Value &newVal) {
416 WriteBarrier::write(e, base(), data_ptr(), newVal.asReturnedValue());
417 }
418 void set(EngineBase *e, HeapBasePtr b) {
419 WriteBarrier::write(e, base(), data_ptr(), b->asReturnedValue());
420 }
421 void set(EngineBase *e, ReturnedValue rv) {
422 WriteBarrier::write(e, base(), data_ptr(), rv);
423 }
424};
425
426template <size_t o>
428 static constexpr size_t offset = o;
429 uint size;
430 uint alloc;
431 Value values[1];
432
434 Value::HeapBasePtr base = reinterpret_cast<Value::HeapBasePtr>(this)
435 - (offset/sizeof(Heap::Base));
436 Q_ASSERT(base->inUse());
437 return base;
438 }
439
440 void set(EngineBase *e, uint index, Value v) {
441 WriteBarrier::write(e, base(), values[index].data_ptr(), v.asReturnedValue());
442 }
443 void set(EngineBase *e, uint index, Value::HeapBasePtr b) {
444 WriteBarrier::write(e, base(), values[index].data_ptr(), Value::fromHeapObject(b).asReturnedValue());
445 }
446 inline const Value &operator[] (uint index) const {
447 Q_ASSERT(index < alloc);
448 return values[index];
449 }
450 inline const Value *data() const {
451 return values;
452 }
453
454 void mark(MarkStack *markStack) {
455 for (Value *v = values, *end = values + alloc; v < end; ++v)
456 v->mark(markStack);
457 }
458};
459
460// It's really important that the offset of values in this structure is
461// constant across all architecture, otherwise JIT cross-compiled code will
462// have wrong offsets between host and target.
464
466 ReturnedValue value;
467public:
468
470 explicit OptionalReturnedValue(ReturnedValue v)
471 : value(v)
472 {
473 Q_ASSERT(!Value::fromReturnedValue(v).isEmpty());
474 }
475
476 ReturnedValue operator->() const { return value; }
477 ReturnedValue operator*() const { return value; }
478 explicit operator bool() const { return !Value::fromReturnedValue(value).isEmpty(); }
479};
480
481}
482
483QT_END_NAMESPACE
484
485#endif // QV4VALUE_DEF_P_H
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)
CallResultDestination
Definition qjsvalue.h:23
Value Primitive
Definition qv4value_p.h:351
Scoped< FunctionObject > ScopedFunctionObject
QVector< StackFrame > StackTrace
int qYouForgotTheQ_MANAGED_Macro(T, T)
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(QObjectPrivate::ConnectionList, 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: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)
PropertyKey next(const Object *o, Property *pd=nullptr, PropertyAttributes *attrs=nullptr) override
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