3#ifndef QV4STATICVALUE_P_H
4#define QV4STATICVALUE_P_H
17#include <qjsnumbercoercion.h>
19#include <QtCore/private/qnumeric_p.h>
20#include <private/qtqmlglobal_p.h>
25#define QV4_NEARLY_ALWAYS_INLINE Q_ALWAYS_INLINE
27#define QV4_NEARLY_ALWAYS_INLINE inline
57 template<
typename Value>
60 template<
typename Value>
63 template<
typename Value>
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
132#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
137 static inline int tagOffset() {
return 0; }
151 setTagValue(quint32(QuickType::Integer), quint32(i));
157 setTagValue(quint32(QuickType::Empty), 0);
258 const quint64 masked = _val & DoubleMask;
259 if (masked >= DoubleDiscriminator)
266 Q_ASSERT((_val & tagBitMask(TagBit::Unmanaged)) == 0);
270 const Type ret = Type(tag());
282 inline bool isEmpty()
const {
return tag() == quint32(ValueTypeInternal::Empty); }
283 inline bool isNull()
const {
return tag() == quint32(ValueTypeInternal::Null); }
284 inline bool isBoolean()
const {
return tag() == quint32(ValueTypeInternal::Boolean); }
285 inline bool isInteger()
const {
return tag() == quint32(ValueTypeInternal::Integer); }
299 return (_val & DoubleMask) >= DoubleDiscriminator;
312 return (_val & NumberMask) >= NumberDiscriminator;
327 return (_val >> IsIntegerOrBool_Shift) == IsIntegerOrBool_Value;
332 return (_val >> IsIntegerConvertible_Shift) == IsIntegerConvertible_Value;
345 switch (QuickType(tag())) {
347 case QuickType::MinusNaN:
355 return isInteger() && int_32() >= 0;
361 const quint64 unmasked = _val ^ EncodeMask;
362 memcpy(&d, &unmasked, 8);
372 _val = (quint64(std::signbit(d) ? QuickType::MinusNaN : QuickType::NaN) << Tag_Shift);
375 memcpy(&_val, &d, 8);
383 if (tag() == quint32(QuickType::Integer))
396 int i = QJSNumberCoercion::toInteger(d);
397 return (i == d && !(d == 0 && std::signbit(d)));
401 if (tag() == quint32(QuickType::Integer))
417 setTagValue(quint32(QuickType::Integer), value());
422 if (integerCompatible())
423 return static_cast<
bool>(int_32());
430 return d && !std::isnan(d);
441 return QJSNumberCoercion::toInteger(doubleValue());
448 Q_UNREACHABLE_RETURN(0);
471 if (i < uint(std::numeric_limits<
int>::max())) {
481 return QJSNumberCoercion::roundTowards0(d);
486 return QJSNumberCoercion::toInteger(d);
498#if QT_POINTER_SIZE == 8
508#if 0
&& defined(Q_OS_ANDROID) && defined(Q_PROCESSOR_ARM_64)
519#elif defined(Q_PROCESSOR_IA64)
525#elif defined(Q_PROCESSOR_SPARC_64)
600#elif QT_POINTER_SIZE == 4
616# error "unsupported pointer size"
634 val = StaticValue::fromDouble(d).asReturnedValue();
641 val = StaticValue::fromUInt32(i).asReturnedValue();
652 template<
typename HeapBase>
653 explicit Encode(HeapBase *o);
657 val = o->asReturnedValue();
672 explicit Encode(
void *);
Q_STATIC_ASSERT(sizeof(CppStackFrame)==sizeof(JSTypesStackFrame))
#define QV4_NEARLY_ALWAYS_INLINE
static ReturnedValue smallestNumber(double d)
constexpr Encode(StaticValue v)
static constexpr ReturnedValue undefined()
constexpr operator ReturnedValue() const
static constexpr ReturnedValue null()
QV4_NEARLY_ALWAYS_INLINE constexpr void setTagValue(quint32 tag, quint32 value)
StaticValue & operator=(ReturnedValue v)
QV4_NEARLY_ALWAYS_INLINE constexpr quint64 rawValue() const
static constexpr quint64 DoubleMask
quint64 quickType() const
static bool integerCompatible(StaticValue a, StaticValue b)
const Value & asValue() const
static StaticValue fromDouble(double d)
bool isManagedOrUndefined() const
static int toInt32(double d)
StaticValue & operator=(const Value &)
static constexpr StaticValue fromBoolean(bool b)
QuickType ValueTypeInternal
constexpr ReturnedValue asReturnedValue() const
static constexpr quint64 NumberDiscriminator
static QV4_NEARLY_ALWAYS_INLINE bool isInt32(double d)
static constexpr quint64 IntOrBoolMask
static double toInteger(double d)
static constexpr quint64 Upper3Mask
static constexpr quint64 IntCompatMask
QV4_NEARLY_ALWAYS_INLINE double doubleValue() const
static constexpr quint64 DoubleDiscriminator
QV4_NEARLY_ALWAYS_INLINE void setDouble(double d)
bool isPositiveInt() const
static constexpr StaticValue fromInt32(int i)
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 value() const
static StaticValue fromUInt32(uint i)
QV4_NEARLY_ALWAYS_INLINE constexpr void setInt_32(int i)
static constexpr quint64 EncodeMask
bool integerCompatible() const
static constexpr quint64 tagBitMask(TagBit bit)
QV4_NEARLY_ALWAYS_INLINE uint uint_32() const
static constexpr quint64 ManagedMask
static constexpr StaticValue emptyValue()
static constexpr quint64 NumberMask
bool tryIntegerConversion()
static constexpr quint64 Lower5Mask
static constexpr quint64 tagValue(quint32 tag, quint32 value)
@ IsIntegerConvertible_Value
@ IsIntegerConvertible_Shift
static unsigned int toUInt32(double d)
static constexpr StaticValue undefinedValue()
QV4_NEARLY_ALWAYS_INLINE constexpr void setRawValue(quint64 raw)
bool isNullOrUndefined() const
constexpr StaticValue(quint64 val)
QV4_NEARLY_ALWAYS_INLINE constexpr quint32 tag() const
bool booleanValue() const
QV4_NEARLY_ALWAYS_INLINE constexpr int int_32() const
ReturnedValue * data_ptr()
static constexpr quint64 ExponentMask
static constexpr StaticValue nullValue()
static bool bothDouble(StaticValue a, StaticValue b)
static constexpr quint64 Top1Mask
QV4_NEARLY_ALWAYS_INLINE constexpr void setTag(quint32 tag)
static constexpr StaticValue fromReturnedValue(ReturnedValue val)
QV4_NEARLY_ALWAYS_INLINE constexpr void setEmpty()
QV4_NEARLY_ALWAYS_INLINE constexpr quint64 & rawValueRef()