Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qv4value.cpp
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
5
#
include
<
qv4runtime_p
.
h
>
6
#
include
<
qv4propertykey_p
.
h
>
7
#
include
<
qv4string_p
.
h
>
8
#
include
<
qv4symbol_p
.
h
>
9
#
include
<
qv4object_p
.
h
>
10
#
include
<
qv4objectproto_p
.
h
>
11
#
include
<
private
/
qv4mm_p
.
h
>
12
13
#
include
<
wtf
/
MathExtras
.
h
>
14
15
using
namespace
QV4;
16
17
int
Value::toUInt16()
const
18
{
19
if
(integerCompatible())
20
return
(ushort)(uint)integerValue();
21
22
double
number = toNumber();
23
24
double
D16 = 65536.0;
25
if
((number >= 0 && number < D16))
26
return
static_cast
<ushort>(number);
27
28
if
(!std::isfinite(number))
29
return
+0;
30
31
double
d = ::floor(::fabs(number));
32
if
(std::signbit(number))
33
d = -d;
34
35
number = ::fmod(d , D16);
36
37
if
(number < 0)
38
number += D16;
39
40
return
(
unsigned
short
)number;
41
}
42
43
bool
Value::toBooleanImpl(Value val)
44
{
45
if
(val.isManagedOrUndefined()) {
46
Heap::Base *b = val.m();
47
if
(!b)
48
return
false
;
49
if
(b->internalClass->vtable->isString)
50
return
static_cast
<Heap::String *>(b)->length() > 0;
51
return
true
;
52
}
53
54
// double
55
double
d = val.doubleValue();
56
return
d && !std::isnan(d);
57
}
58
59
double
Value::toNumberImpl(Value val)
60
{
61
switch
(val.type()) {
62
case
QV4::Value::Undefined_Type:
63
return
std::numeric_limits<
double
>::quiet_NaN();
64
case
QV4::Value::Managed_Type:
65
if
(String *s = val.stringValue())
66
return
RuntimeHelpers::stringToNumber(s->toQString());
67
if
(val.isSymbol()) {
68
Managed &m =
static_cast
<Managed &>(val);
69
m.engine()->throwTypeError();
70
return
0;
71
}
72
{
73
Q_ASSERT(val.isObject());
74
Scope scope(val.objectValue()->engine());
75
ScopedValue protectThis(scope, val);
76
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(val, NUMBER_HINT));
77
if
(scope.hasException())
78
return
0;
79
return
prim->toNumber();
80
}
81
case
QV4::Value::Null_Type:
82
case
QV4::Value::Boolean_Type:
83
case
QV4::Value::Integer_Type:
84
return
val.int_32();
85
default
:
// double
86
Q_UNREACHABLE();
87
}
88
}
89
90
static
QString
primitiveToQString
(
const
Value *value)
91
{
92
switch
(value->type()) {
93
case
Value::Empty_Type:
94
Q_ASSERT(!
"empty Value encountered"
);
95
Q_UNREACHABLE_RETURN(QString());
96
case
Value::Undefined_Type:
97
return
QStringLiteral(
"undefined"
);
98
case
Value::Null_Type:
99
return
QStringLiteral(
"null"
);
100
case
Value::Boolean_Type:
101
if
(value->booleanValue())
102
return
QStringLiteral(
"true"
);
103
else
104
return
QStringLiteral(
"false"
);
105
case
Value::Managed_Type:
106
Q_UNREACHABLE_RETURN(QString());
107
case
Value::Integer_Type: {
108
QString str;
109
RuntimeHelpers::numberToString(&str, (
double
)value->int_32(), 10);
110
return
str;
111
}
112
case
Value::Double_Type: {
113
QString str;
114
RuntimeHelpers::numberToString(&str, value->doubleValue(), 10);
115
return
str;
116
}
117
}
// switch
118
119
Q_UNREACHABLE_RETURN(QString());
120
}
121
122
123
QString Value::toQStringNoThrow()
const
124
{
125
if
(isManaged()) {
126
if
(String *s = stringValue())
127
return
s->toQString();
128
if
(Symbol *s = symbolValue())
129
return
s->descriptiveString();
130
131
Q_ASSERT(isObject());
132
Scope scope(objectValue()->engine());
133
ScopedValue ex(scope);
134
bool
caughtException =
false
;
135
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*
this
, STRING_HINT));
136
if
(scope.hasException()) {
137
ex = scope.engine->catchException();
138
caughtException =
true
;
139
}
else
if
(prim->isPrimitive()) {
140
return
prim->toQStringNoThrow();
141
}
142
143
// Can't nest try/catch due to CXX ABI limitations for foreign exception nesting.
144
if
(caughtException) {
145
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(ex, STRING_HINT));
146
if
(scope.hasException()) {
147
ex = scope.engine->catchException();
148
}
else
if
(prim->isPrimitive()) {
149
return
prim->toQStringNoThrow();
150
}
151
}
152
153
return
QString();
154
}
155
156
return
primitiveToQString(
this
);
157
}
158
159
QString Value::toQString()
const
160
{
161
if
(isManaged()) {
162
if
(String *s = stringValue())
163
return
s->toQString();
164
165
if
(isSymbol()) {
166
static_cast
<
const
Managed *>(
this
)->engine()->throwTypeError();
167
return
QString();
168
}
169
170
Q_ASSERT(isObject());
171
Scope scope(objectValue()->engine());
172
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*
this
, STRING_HINT));
173
return
prim->toQString();
174
}
175
176
return
primitiveToQString(
this
);
177
}
178
179
QString Value::toQString(
bool
*ok)
const
180
{
181
if
(isManaged()) {
182
if
(String *s = stringValue()) {
183
*ok =
true
;
184
return
s->toQString();
185
}
186
187
if
(isSymbol()) {
188
static_cast
<
const
Managed *>(
this
)->engine()->throwTypeError();
189
*ok =
false
;
190
return
QString();
191
}
192
193
Q_ASSERT(isObject());
194
Scope scope(objectValue()->engine());
195
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(*
this
, STRING_HINT));
196
197
if
(scope.hasException()) {
198
*ok =
false
;
199
return
QString();
200
}
201
202
return
prim->toQString(ok);
203
}
204
205
return
primitiveToQString(
this
);
206
}
207
208
QV4::PropertyKey Value::toPropertyKey(ExecutionEngine *e)
const
209
{
210
if
(isInteger() && int_32() >= 0)
211
return
PropertyKey::fromArrayIndex(
static_cast
<uint>(int_32()));
212
if
(isStringOrSymbol()) {
213
Scope scope(e);
214
ScopedStringOrSymbol s(scope,
this
);
215
return
s->toPropertyKey();
216
}
217
Scope scope(e);
218
ScopedValue v(scope, RuntimeHelpers::toPrimitive(*
this
, STRING_HINT));
219
if
(!v->isStringOrSymbol())
220
v = v->toString(e);
221
if
(e->hasException)
222
return
PropertyKey::invalid();
223
ScopedStringOrSymbol s(scope, v);
224
return
s->toPropertyKey();
225
}
226
227
bool
Value::sameValue(Value other)
const
{
228
if
(_val == other._val)
229
return
true
;
230
String *s = stringValue();
231
String *os = other.stringValue();
232
if
(s && os)
233
return
s->isEqualTo(os);
234
if
(isInteger() && other.isDouble())
235
return
int_32() ? (
double
(int_32()) == other.doubleValue())
236
: (other.doubleValue() == 0 && !std::signbit(other.doubleValue()));
237
if
(isDouble() && other.isInteger())
238
return
other.int_32() ? (doubleValue() ==
double
(other.int_32()))
239
: (doubleValue() == 0 && !std::signbit(doubleValue()));
240
if
(isManaged())
241
return
other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
242
return
false
;
243
}
244
245
bool
Value::sameValueZero(Value other)
const
{
246
if
(_val == other._val)
247
return
true
;
248
String *s = stringValue();
249
String *os = other.stringValue();
250
if
(s && os)
251
return
s->isEqualTo(os);
252
if
(isInteger() && other.isDouble())
253
return
double
(int_32()) == other.doubleValue();
254
if
(isDouble() && other.isInteger())
255
return
other.int_32() == doubleValue();
256
if
(isDouble() && other.isDouble()) {
257
if
(doubleValue() == 0 && other.doubleValue() == 0) {
258
return
true
;
259
}
260
}
261
if
(isManaged())
262
return
other.isManaged() && cast<Managed>()->isEqualTo(other.cast<Managed>());
263
return
false
;
264
}
265
266
Heap::String *Value::toString(ExecutionEngine *e, Value val)
267
{
268
return
RuntimeHelpers::convertToString(e, val);
269
}
270
271
Heap::Object *Value::toObject(ExecutionEngine *e, Value val)
272
{
273
return
RuntimeHelpers::convertToObject(e, val);
274
}
275
276
uint Value::asArrayLength(
bool
*ok)
const
277
{
278
*ok =
true
;
279
if
(isInteger()) {
280
if
(int_32() >= 0) {
281
return
(uint)int_32();
282
}
else
{
283
*ok =
false
;
284
return
UINT_MAX;
285
}
286
}
287
if
(isNumber()) {
288
double
d = doubleValue();
289
uint idx = (uint)d;
290
if
(idx != d) {
291
*ok =
false
;
292
return
UINT_MAX;
293
}
294
return
idx;
295
}
296
if
(String *s = stringValue())
297
return
s->toUInt(ok);
298
299
uint idx = toUInt32();
300
double
d = toNumber();
301
if
(d != idx) {
302
*ok =
false
;
303
return
UINT_MAX;
304
}
305
return
idx;
306
}
primitiveToQString
static QString primitiveToQString(const Value *value)
Definition
qv4value.cpp:90
qtdeclarative
src
qml
jsruntime
qv4value.cpp
Generated on
for Qt by
1.18.0