Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/qml/jsruntime/qv4typedarray.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /**************************************************************************** | - | ||||||||||||||||||
2 | ** | - | ||||||||||||||||||
3 | ** Copyright (C) 2016 The Qt Company Ltd. | - | ||||||||||||||||||
4 | ** Contact: https://www.qt.io/licensing/ | - | ||||||||||||||||||
5 | ** | - | ||||||||||||||||||
6 | ** This file is part of the QtQml module of the Qt Toolkit. | - | ||||||||||||||||||
7 | ** | - | ||||||||||||||||||
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - | ||||||||||||||||||
9 | ** Commercial License Usage | - | ||||||||||||||||||
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - | ||||||||||||||||||
11 | ** accordance with the commercial license agreement provided with the | - | ||||||||||||||||||
12 | ** Software or, alternatively, in accordance with the terms contained in | - | ||||||||||||||||||
13 | ** a written agreement between you and The Qt Company. For licensing terms | - | ||||||||||||||||||
14 | ** and conditions see https://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
15 | ** information use the contact form at https://www.qt.io/contact-us. | - | ||||||||||||||||||
16 | ** | - | ||||||||||||||||||
17 | ** GNU Lesser General Public License Usage | - | ||||||||||||||||||
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - | ||||||||||||||||||
19 | ** General Public License version 3 as published by the Free Software | - | ||||||||||||||||||
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | - | ||||||||||||||||||
21 | ** packaging of this file. Please review the following information to | - | ||||||||||||||||||
22 | ** ensure the GNU Lesser General Public License version 3 requirements | - | ||||||||||||||||||
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | - | ||||||||||||||||||
24 | ** | - | ||||||||||||||||||
25 | ** GNU General Public License Usage | - | ||||||||||||||||||
26 | ** Alternatively, this file may be used under the terms of the GNU | - | ||||||||||||||||||
27 | ** General Public License version 2.0 or (at your option) the GNU General | - | ||||||||||||||||||
28 | ** Public license version 3 or any later version approved by the KDE Free | - | ||||||||||||||||||
29 | ** Qt Foundation. The licenses are as published by the Free Software | - | ||||||||||||||||||
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | - | ||||||||||||||||||
31 | ** included in the packaging of this file. Please review the following | - | ||||||||||||||||||
32 | ** information to ensure the GNU General Public License requirements will | - | ||||||||||||||||||
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | - | ||||||||||||||||||
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | - | ||||||||||||||||||
35 | ** | - | ||||||||||||||||||
36 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
37 | ** | - | ||||||||||||||||||
38 | ****************************************************************************/ | - | ||||||||||||||||||
39 | - | |||||||||||||||||||
40 | #include "qv4typedarray_p.h" | - | ||||||||||||||||||
41 | #include "qv4arrayiterator_p.h" | - | ||||||||||||||||||
42 | #include "qv4arraybuffer_p.h" | - | ||||||||||||||||||
43 | #include "qv4string_p.h" | - | ||||||||||||||||||
44 | #include "qv4jscall_p.h" | - | ||||||||||||||||||
45 | #include "qv4symbol_p.h" | - | ||||||||||||||||||
46 | - | |||||||||||||||||||
47 | #include <cmath> | - | ||||||||||||||||||
48 | - | |||||||||||||||||||
49 | using namespace QV4; | - | ||||||||||||||||||
50 | - | |||||||||||||||||||
51 | DEFINE_OBJECT_VTABLE(IntrinsicTypedArrayCtor); | - | ||||||||||||||||||
52 | DEFINE_OBJECT_VTABLE(IntrinsicTypedArrayPrototype); | - | ||||||||||||||||||
53 | DEFINE_OBJECT_VTABLE(TypedArrayCtor); | - | ||||||||||||||||||
54 | DEFINE_OBJECT_VTABLE(TypedArrayPrototype); | - | ||||||||||||||||||
55 | DEFINE_OBJECT_VTABLE(TypedArray); | - | ||||||||||||||||||
56 | - | |||||||||||||||||||
57 | Q_STATIC_ASSERT((int)ExecutionEngine::NTypedArrayTypes == (int)Heap::TypedArray::NTypes); | - | ||||||||||||||||||
58 | - | |||||||||||||||||||
59 | ReturnedValue Int8ArrayRead(const char *data, int index) | - | ||||||||||||||||||
60 | { | - | ||||||||||||||||||
61 | return Encode((int)(signed char)data[index]); executed 2866 times by 1 test: return Encode((int)(signed char)data[index]); Executed by:
| 2866 | ||||||||||||||||||
62 | } | - | ||||||||||||||||||
63 | - | |||||||||||||||||||
64 | void Int8ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
65 | { | - | ||||||||||||||||||
66 | signed char v = (signed char)value.toUInt32(); | - | ||||||||||||||||||
67 | if (e->hasException)
| 46-2890 | ||||||||||||||||||
68 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
69 | data[index] = v; | - | ||||||||||||||||||
70 | } executed 2890 times by 1 test: end of block Executed by:
| 2890 | ||||||||||||||||||
71 | - | |||||||||||||||||||
72 | ReturnedValue UInt8ArrayRead(const char *data, int index) | - | ||||||||||||||||||
73 | { | - | ||||||||||||||||||
74 | return Encode((int)(unsigned char)data[index]); executed 8704 times by 1 test: return Encode((int)(unsigned char)data[index]); Executed by:
| 8704 | ||||||||||||||||||
75 | } | - | ||||||||||||||||||
76 | - | |||||||||||||||||||
77 | void UInt8ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
78 | { | - | ||||||||||||||||||
79 | unsigned char v = (unsigned char)value.toUInt32(); | - | ||||||||||||||||||
80 | if (e->hasException)
| 46-34972 | ||||||||||||||||||
81 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
82 | data[index] = v; | - | ||||||||||||||||||
83 | } executed 34971 times by 2 tests: end of block Executed by:
| 34971 | ||||||||||||||||||
84 | - | |||||||||||||||||||
85 | void UInt8ClampedArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
86 | { | - | ||||||||||||||||||
87 | if (value.isInteger()) {
| 570-2289 | ||||||||||||||||||
88 | data[index] = (char)(unsigned char)qBound(0, value.integerValue(), 255); | - | ||||||||||||||||||
89 | return; executed 2289 times by 1 test: return; Executed by:
| 2289 | ||||||||||||||||||
90 | } | - | ||||||||||||||||||
91 | double d = value.toNumber(); | - | ||||||||||||||||||
92 | if (e->hasException)
| 46-524 | ||||||||||||||||||
93 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
94 | // ### is there a way to optimise this? | - | ||||||||||||||||||
95 | if (d <= 0 || std::isnan(d)) {
| 64-348 | ||||||||||||||||||
96 | data[index] = 0; | - | ||||||||||||||||||
97 | return; executed 240 times by 1 test: return; Executed by:
| 240 | ||||||||||||||||||
98 | } | - | ||||||||||||||||||
99 | if (d >= 255) {
| 124-160 | ||||||||||||||||||
100 | data[index] = (char)(255); | - | ||||||||||||||||||
101 | return; executed 124 times by 1 test: return; Executed by:
| 124 | ||||||||||||||||||
102 | } | - | ||||||||||||||||||
103 | double f = std::floor(d); | - | ||||||||||||||||||
104 | if (f + 0.5 < d) {
| 48-112 | ||||||||||||||||||
105 | data[index] = (unsigned char)(f + 1); | - | ||||||||||||||||||
106 | return; executed 48 times by 1 test: return; Executed by:
| 48 | ||||||||||||||||||
107 | } | - | ||||||||||||||||||
108 | if (d < f + 0.5) {
| 16-96 | ||||||||||||||||||
109 | data[index] = (unsigned char)(f); | - | ||||||||||||||||||
110 | return; executed 96 times by 1 test: return; Executed by:
| 96 | ||||||||||||||||||
111 | } | - | ||||||||||||||||||
112 | if (int(f) % 2) {
| 0-16 | ||||||||||||||||||
113 | // odd number | - | ||||||||||||||||||
114 | data[index] = (unsigned char)(f + 1); | - | ||||||||||||||||||
115 | return; never executed: return; | 0 | ||||||||||||||||||
116 | } | - | ||||||||||||||||||
117 | data[index] = (unsigned char)(f); | - | ||||||||||||||||||
118 | } executed 16 times by 1 test: end of block Executed by:
| 16 | ||||||||||||||||||
119 | - | |||||||||||||||||||
120 | ReturnedValue Int16ArrayRead(const char *data, int index) | - | ||||||||||||||||||
121 | { | - | ||||||||||||||||||
122 | return Encode((int)*(const short *)(data + index)); executed 2232 times by 1 test: return Encode((int)*(const short *)(data + index)); Executed by:
| 2232 | ||||||||||||||||||
123 | } | - | ||||||||||||||||||
124 | - | |||||||||||||||||||
125 | void Int16ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
126 | { | - | ||||||||||||||||||
127 | short v = (short)value.toInt32(); | - | ||||||||||||||||||
128 | if (e->hasException)
| 46-2912 | ||||||||||||||||||
129 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
130 | *(short *)(data + index) = v; | - | ||||||||||||||||||
131 | } executed 2912 times by 1 test: end of block Executed by:
| 2912 | ||||||||||||||||||
132 | - | |||||||||||||||||||
133 | ReturnedValue UInt16ArrayRead(const char *data, int index) | - | ||||||||||||||||||
134 | { | - | ||||||||||||||||||
135 | return Encode((int)*(const unsigned short *)(data + index)); executed 2201 times by 1 test: return Encode((int)*(const unsigned short *)(data + index)); Executed by:
| 2201 | ||||||||||||||||||
136 | } | - | ||||||||||||||||||
137 | - | |||||||||||||||||||
138 | void UInt16ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
139 | { | - | ||||||||||||||||||
140 | unsigned short v = (unsigned short)value.toInt32(); | - | ||||||||||||||||||
141 | if (e->hasException)
| 46-2916 | ||||||||||||||||||
142 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
143 | *(unsigned short *)(data + index) = v; | - | ||||||||||||||||||
144 | } executed 2916 times by 1 test: end of block Executed by:
| 2916 | ||||||||||||||||||
145 | - | |||||||||||||||||||
146 | ReturnedValue Int32ArrayRead(const char *data, int index) | - | ||||||||||||||||||
147 | { | - | ||||||||||||||||||
148 | return Encode(*(const int *)(data + index)); executed 2203 times by 1 test: return Encode(*(const int *)(data + index)); Executed by:
| 2203 | ||||||||||||||||||
149 | } | - | ||||||||||||||||||
150 | - | |||||||||||||||||||
151 | void Int32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
152 | { | - | ||||||||||||||||||
153 | int v = (int)value.toInt32(); | - | ||||||||||||||||||
154 | if (e->hasException)
| 46-2912 | ||||||||||||||||||
155 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
156 | *(int *)(data + index) = v; | - | ||||||||||||||||||
157 | } executed 2912 times by 1 test: end of block Executed by:
| 2912 | ||||||||||||||||||
158 | - | |||||||||||||||||||
159 | ReturnedValue UInt32ArrayRead(const char *data, int index) | - | ||||||||||||||||||
160 | { | - | ||||||||||||||||||
161 | return Encode(*(const unsigned int *)(data + index)); executed 2204 times by 1 test: return Encode(*(const unsigned int *)(data + index)); Executed by:
| 2204 | ||||||||||||||||||
162 | } | - | ||||||||||||||||||
163 | - | |||||||||||||||||||
164 | void UInt32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
165 | { | - | ||||||||||||||||||
166 | unsigned int v = (unsigned int)value.toUInt32(); | - | ||||||||||||||||||
167 | if (e->hasException)
| 46-2911 | ||||||||||||||||||
168 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
169 | *(unsigned int *)(data + index) = v; | - | ||||||||||||||||||
170 | } executed 2910 times by 1 test: end of block Executed by:
| 2910 | ||||||||||||||||||
171 | - | |||||||||||||||||||
172 | ReturnedValue Float32ArrayRead(const char *data, int index) | - | ||||||||||||||||||
173 | { | - | ||||||||||||||||||
174 | return Encode(*(const float *)(data + index)); executed 2460 times by 1 test: return Encode(*(const float *)(data + index)); Executed by:
| 2460 | ||||||||||||||||||
175 | } | - | ||||||||||||||||||
176 | - | |||||||||||||||||||
177 | void Float32ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
178 | { | - | ||||||||||||||||||
179 | float v = value.toNumber(); | - | ||||||||||||||||||
180 | if (e->hasException)
| 46-3186 | ||||||||||||||||||
181 | return; executed 46 times by 1 test: return; Executed by:
| 46 | ||||||||||||||||||
182 | *(float *)(data + index) = v; | - | ||||||||||||||||||
183 | } executed 3186 times by 1 test: end of block Executed by:
| 3186 | ||||||||||||||||||
184 | - | |||||||||||||||||||
185 | ReturnedValue Float64ArrayRead(const char *data, int index) | - | ||||||||||||||||||
186 | { | - | ||||||||||||||||||
187 | return Encode(*(const double *)(data + index)); executed 3456 times by 1 test: return Encode(*(const double *)(data + index)); Executed by:
| 3456 | ||||||||||||||||||
188 | } | - | ||||||||||||||||||
189 | - | |||||||||||||||||||
190 | void Float64ArrayWrite(ExecutionEngine *e, char *data, int index, const Value &value) | - | ||||||||||||||||||
191 | { | - | ||||||||||||||||||
192 | double v = value.toNumber(); | - | ||||||||||||||||||
193 | if (e->hasException)
| 60-6460 | ||||||||||||||||||
194 | return; executed 60 times by 1 test: return; Executed by:
| 60 | ||||||||||||||||||
195 | *(double *)(data + index) = v; | - | ||||||||||||||||||
196 | } executed 6460 times by 1 test: end of block Executed by:
| 6460 | ||||||||||||||||||
197 | - | |||||||||||||||||||
198 | const TypedArrayOperations operations[Heap::TypedArray::NTypes] = { | - | ||||||||||||||||||
199 | { 1, "Int8Array", Int8ArrayRead, Int8ArrayWrite }, | - | ||||||||||||||||||
200 | { 1, "Uint8Array", UInt8ArrayRead, UInt8ArrayWrite }, | - | ||||||||||||||||||
201 | { 1, "Uint8ClampedArray", UInt8ArrayRead, UInt8ClampedArrayWrite }, | - | ||||||||||||||||||
202 | { 2, "Int16Array", Int16ArrayRead, Int16ArrayWrite }, | - | ||||||||||||||||||
203 | { 2, "Uint16Array", UInt16ArrayRead, UInt16ArrayWrite }, | - | ||||||||||||||||||
204 | { 4, "Int32Array", Int32ArrayRead, Int32ArrayWrite }, | - | ||||||||||||||||||
205 | { 4, "Uint32Array", UInt32ArrayRead, UInt32ArrayWrite }, | - | ||||||||||||||||||
206 | { 4, "Float32Array", Float32ArrayRead, Float32ArrayWrite }, | - | ||||||||||||||||||
207 | { 8, "Float64Array", Float64ArrayRead, Float64ArrayWrite }, | - | ||||||||||||||||||
208 | }; | - | ||||||||||||||||||
209 | - | |||||||||||||||||||
210 | - | |||||||||||||||||||
211 | void Heap::TypedArrayCtor::init(QV4::ExecutionContext *scope, TypedArray::Type t) | - | ||||||||||||||||||
212 | { | - | ||||||||||||||||||
213 | Heap::FunctionObject::init(scope, QLatin1String(operations[t].name)); | - | ||||||||||||||||||
214 | type = t; | - | ||||||||||||||||||
215 | } executed 892477 times by 153 tests: end of block Executed by:
| 892477 | ||||||||||||||||||
216 | - | |||||||||||||||||||
217 | ReturnedValue TypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *) | - | ||||||||||||||||||
218 | { | - | ||||||||||||||||||
219 | Scope scope(f->engine()); | - | ||||||||||||||||||
220 | const TypedArrayCtor *that = static_cast<const TypedArrayCtor *>(f); | - | ||||||||||||||||||
221 | - | |||||||||||||||||||
222 | if (!argc || !argv[0].isObject()) {
| 2359-23119 | ||||||||||||||||||
223 | // ECMA 6 22.2.1.1 | - | ||||||||||||||||||
224 | qint64 l = argc ? argv[0].toIndex() : 0;
| 2359-3621 | ||||||||||||||||||
225 | if (scope.engine->hasException)
| 36-5939 | ||||||||||||||||||
226 | return Encode::undefined(); executed 36 times by 1 test: return Encode::undefined(); Executed by:
| 36 | ||||||||||||||||||
227 | // ### lift UINT_MAX restriction | - | ||||||||||||||||||
228 | if (l < 0 || l > UINT_MAX)
| 0-5834 | ||||||||||||||||||
229 | return scope.engine->throwRangeError(QLatin1String("Index out of range.")); executed 108 times by 1 test: return scope.engine->throwRangeError(QLatin1String("Index out of range.")); Executed by:
| 108 | ||||||||||||||||||
230 | uint len = (uint)l; | - | ||||||||||||||||||
231 | if (l != len)
| 0-5836 | ||||||||||||||||||
232 | scope.engine->throwRangeError(QStringLiteral("Non integer length for typed array.")); never executed: scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "Non integer length for typed array.")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "Non integer length for typed array." }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); never executed: return qstring_literal_temp; | 0 | ||||||||||||||||||
233 | uint byteLength = len * operations[that->d()->type].bytesPerElement; | - | ||||||||||||||||||
234 | Scoped<ArrayBuffer> buffer(scope, scope.engine->newArrayBuffer(byteLength)); | - | ||||||||||||||||||
235 | if (scope.engine->hasException)
| 0-5831 | ||||||||||||||||||
236 | return Encode::undefined(); never executed: return Encode::undefined(); | 0 | ||||||||||||||||||
237 | - | |||||||||||||||||||
238 | Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); | - | ||||||||||||||||||
239 | array->d()->buffer.set(scope.engine, buffer->d()); | - | ||||||||||||||||||
240 | array->d()->byteLength = byteLength; | - | ||||||||||||||||||
241 | array->d()->byteOffset = 0; | - | ||||||||||||||||||
242 | - | |||||||||||||||||||
243 | return array.asReturnedValue(); executed 5828 times by 1 test: return array.asReturnedValue(); Executed by:
| 5828 | ||||||||||||||||||
244 | } | - | ||||||||||||||||||
245 | Scoped<TypedArray> typedArray(scope, argc ? argv[0] : Primitive::undefinedValue()); | - | ||||||||||||||||||
246 | if (!!typedArray) {
| 568-18937 | ||||||||||||||||||
247 | // ECMA 6 22.2.1.2 | - | ||||||||||||||||||
248 | Scoped<ArrayBuffer> buffer(scope, typedArray->d()->buffer); | - | ||||||||||||||||||
249 | uint srcElementSize = typedArray->d()->type->bytesPerElement; | - | ||||||||||||||||||
250 | uint destElementSize = operations[that->d()->type].bytesPerElement; | - | ||||||||||||||||||
251 | uint byteLength = typedArray->d()->byteLength; | - | ||||||||||||||||||
252 | uint destByteLength = byteLength*destElementSize/srcElementSize; | - | ||||||||||||||||||
253 | - | |||||||||||||||||||
254 | Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(destByteLength)); | - | ||||||||||||||||||
255 | if (scope.engine->hasException)
| 0-568 | ||||||||||||||||||
256 | return Encode::undefined(); never executed: return Encode::undefined(); | 0 | ||||||||||||||||||
257 | - | |||||||||||||||||||
258 | Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); | - | ||||||||||||||||||
259 | array->d()->buffer.set(scope.engine, newBuffer->d()); | - | ||||||||||||||||||
260 | array->d()->byteLength = destByteLength; | - | ||||||||||||||||||
261 | array->d()->byteOffset = 0; | - | ||||||||||||||||||
262 | - | |||||||||||||||||||
263 | const char *src = buffer->d()->data->data() + typedArray->d()->byteOffset; | - | ||||||||||||||||||
264 | char *dest = newBuffer->d()->data->data(); | - | ||||||||||||||||||
265 | - | |||||||||||||||||||
266 | // check if src and new type have the same size. In that case we can simply memcpy the data | - | ||||||||||||||||||
267 | if (srcElementSize == destElementSize) {
| 252-316 | ||||||||||||||||||
268 | memcpy(dest, src, byteLength); | - | ||||||||||||||||||
269 | } else { executed 316 times by 1 test: end of block Executed by:
| 316 | ||||||||||||||||||
270 | // not same size, we need to loop | - | ||||||||||||||||||
271 | uint l = typedArray->length(); | - | ||||||||||||||||||
272 | TypedArrayRead read = typedArray->d()->type->read; | - | ||||||||||||||||||
273 | TypedArrayWrite write =array->d()->type->write; | - | ||||||||||||||||||
274 | for (uint i = 0; i < l; ++i) {
| 252-660 | ||||||||||||||||||
275 | Primitive val; | - | ||||||||||||||||||
276 | val.setRawValue(read(src, i*srcElementSize)); | - | ||||||||||||||||||
277 | write(scope.engine, dest, i*destElementSize, val); | - | ||||||||||||||||||
278 | } executed 660 times by 1 test: end of block Executed by:
| 660 | ||||||||||||||||||
279 | } executed 252 times by 1 test: end of block Executed by:
| 252 | ||||||||||||||||||
280 | - | |||||||||||||||||||
281 | return array.asReturnedValue(); executed 568 times by 1 test: return array.asReturnedValue(); Executed by:
| 568 | ||||||||||||||||||
282 | } | - | ||||||||||||||||||
283 | Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue()); | - | ||||||||||||||||||
284 | if (!!buffer) {
| 6061-12865 | ||||||||||||||||||
285 | // ECMA 6 22.2.1.4 | - | ||||||||||||||||||
286 | - | |||||||||||||||||||
287 | double dbyteOffset = argc > 1 ? argv[1].toInteger() : 0;
| 454-5607 | ||||||||||||||||||
288 | uint byteOffset = (uint)dbyteOffset; | - | ||||||||||||||||||
289 | uint elementSize = operations[that->d()->type].bytesPerElement; | - | ||||||||||||||||||
290 | if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength())
| 48-5989 | ||||||||||||||||||
291 | return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset")); executed 192 times by 1 test: return scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "new TypedArray: invalid byteOffset")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "new TypedArray: invalid byteOffset" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); Executed by:
executed 192 times by 1 test: return qstring_literal_temp; Executed by:
| 192 | ||||||||||||||||||
292 | - | |||||||||||||||||||
293 | uint byteLength; | - | ||||||||||||||||||
294 | if (argc < 3 || argv[2].isUndefined()) {
| 24-4550 | ||||||||||||||||||
295 | byteLength = buffer->byteLength() - byteOffset; | - | ||||||||||||||||||
296 | if (buffer->byteLength() < byteOffset || byteLength % elementSize)
| 0-1346 | ||||||||||||||||||
297 | return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); executed 48 times by 1 test: return scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "new TypedArray: invalid length")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "new TypedArray: invalid length" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); Executed by:
executed 48 times by 1 test: return qstring_literal_temp; Executed by:
| 48 | ||||||||||||||||||
298 | } else { executed 1298 times by 2 tests: end of block Executed by:
| 1298 | ||||||||||||||||||
299 | double l = qBound(0., argv[2].toInteger(), (double)UINT_MAX); | - | ||||||||||||||||||
300 | if (scope.engine->hasException)
| 76-4451 | ||||||||||||||||||
301 | return Encode::undefined(); executed 76 times by 1 test: return Encode::undefined(); Executed by:
| 76 | ||||||||||||||||||
302 | l *= elementSize; | - | ||||||||||||||||||
303 | if (buffer->byteLength() - byteOffset < l)
| 36-4415 | ||||||||||||||||||
304 | return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length")); executed 36 times by 1 test: return scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "new TypedArray: invalid length")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "new TypedArray: invalid length" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); Executed by:
executed 36 times by 1 test: return qstring_literal_temp; Executed by:
| 36 | ||||||||||||||||||
305 | byteLength = (uint)l; | - | ||||||||||||||||||
306 | } executed 4414 times by 1 test: end of block Executed by:
| 4414 | ||||||||||||||||||
307 | - | |||||||||||||||||||
308 | Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); | - | ||||||||||||||||||
309 | array->d()->buffer.set(scope.engine, buffer->d()); | - | ||||||||||||||||||
310 | array->d()->byteLength = byteLength; | - | ||||||||||||||||||
311 | array->d()->byteOffset = byteOffset; | - | ||||||||||||||||||
312 | return array.asReturnedValue(); executed 5713 times by 2 tests: return array.asReturnedValue(); Executed by:
| 5713 | ||||||||||||||||||
313 | } | - | ||||||||||||||||||
314 | - | |||||||||||||||||||
315 | // ECMA 6 22.2.1.3 | - | ||||||||||||||||||
316 | - | |||||||||||||||||||
317 | ScopedObject o(scope, argc ? argv[0] : Primitive::undefinedValue()); | - | ||||||||||||||||||
318 | uint l = (uint) qBound(0., ScopedValue(scope, o->get(scope.engine->id_length()))->toInteger(), (double)UINT_MAX); | - | ||||||||||||||||||
319 | if (scope.engine->hasException)
| 72-12805 | ||||||||||||||||||
320 | return scope.engine->throwTypeError(); executed 72 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 72 | ||||||||||||||||||
321 | - | |||||||||||||||||||
322 | uint elementSize = operations[that->d()->type].bytesPerElement; | - | ||||||||||||||||||
323 | size_t bufferSize; | - | ||||||||||||||||||
324 | if (mul_overflow(size_t(l), size_t(elementSize), &bufferSize))
| 0-12805 | ||||||||||||||||||
325 | return scope.engine->throwRangeError(QLatin1String("new TypedArray: invalid length")); never executed: return scope.engine->throwRangeError(QLatin1String("new TypedArray: invalid length")); | 0 | ||||||||||||||||||
326 | Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(bufferSize)); | - | ||||||||||||||||||
327 | if (scope.engine->hasException)
| 36-12765 | ||||||||||||||||||
328 | return Encode::undefined(); executed 36 times by 1 test: return Encode::undefined(); Executed by:
| 36 | ||||||||||||||||||
329 | - | |||||||||||||||||||
330 | Scoped<TypedArray> array(scope, TypedArray::create(scope.engine, that->d()->type)); | - | ||||||||||||||||||
331 | array->d()->buffer.set(scope.engine, newBuffer->d()); | - | ||||||||||||||||||
332 | array->d()->byteLength = l * elementSize; | - | ||||||||||||||||||
333 | array->d()->byteOffset = 0; | - | ||||||||||||||||||
334 | - | |||||||||||||||||||
335 | uint idx = 0; | - | ||||||||||||||||||
336 | char *b = newBuffer->d()->data->data(); | - | ||||||||||||||||||
337 | ScopedValue val(scope); | - | ||||||||||||||||||
338 | while (idx < l) {
| 12486-38153 | ||||||||||||||||||
339 | val = o->get(idx); | - | ||||||||||||||||||
340 | array->d()->type->write(scope.engine, b, 0, val); | - | ||||||||||||||||||
341 | if (scope.engine->hasException)
| 288-37869 | ||||||||||||||||||
342 | return Encode::undefined(); executed 288 times by 1 test: return Encode::undefined(); Executed by:
| 288 | ||||||||||||||||||
343 | ++idx; | - | ||||||||||||||||||
344 | b += elementSize; | - | ||||||||||||||||||
345 | } executed 37870 times by 2 tests: end of block Executed by:
| 37870 | ||||||||||||||||||
346 | - | |||||||||||||||||||
347 | - | |||||||||||||||||||
348 | return array.asReturnedValue(); executed 12487 times by 2 tests: return array.asReturnedValue(); Executed by:
| 12487 | ||||||||||||||||||
349 | } | - | ||||||||||||||||||
350 | - | |||||||||||||||||||
351 | ReturnedValue TypedArrayCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int) | - | ||||||||||||||||||
352 | { | - | ||||||||||||||||||
353 | return f->engine()->throwTypeError(QStringLiteral("calling a TypedArray constructor without new is invalid")); executed 252 times by 1 test: return f->engine()->throwTypeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "calling a TypedArray constructor without new is invalid")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "calling a TypedArray constructor without new is invalid" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }())); Executed by:
executed 252 times by 1 test: return qstring_literal_temp; Executed by:
| 252 | ||||||||||||||||||
354 | } | - | ||||||||||||||||||
355 | - | |||||||||||||||||||
356 | void Heap::TypedArray::init(Type t) | - | ||||||||||||||||||
357 | { | - | ||||||||||||||||||
358 | Object::init(); | - | ||||||||||||||||||
359 | type = operations + t; | - | ||||||||||||||||||
360 | arrayType = t; | - | ||||||||||||||||||
361 | } executed 24870 times by 2 tests: end of block Executed by:
| 24870 | ||||||||||||||||||
362 | - | |||||||||||||||||||
363 | Heap::TypedArray *TypedArray::create(ExecutionEngine *e, Heap::TypedArray::Type t) | - | ||||||||||||||||||
364 | { | - | ||||||||||||||||||
365 | Scope scope(e); | - | ||||||||||||||||||
366 | Scoped<InternalClass> ic(scope, e->newInternalClass(staticVTable(), e->typedArrayPrototype + t)); | - | ||||||||||||||||||
367 | return e->memoryManager->allocObject<TypedArray>(ic->d(), t); executed 24882 times by 2 tests: return e->memoryManager->allocObject<TypedArray>(ic->d(), t); Executed by:
| 24882 | ||||||||||||||||||
368 | } | - | ||||||||||||||||||
369 | - | |||||||||||||||||||
370 | ReturnedValue TypedArray::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty) | - | ||||||||||||||||||
371 | { | - | ||||||||||||||||||
372 | if (!id.isArrayIndex())
| 24199-51879 | ||||||||||||||||||
373 | return Object::virtualGet(m, id, receiver, hasProperty); executed 51876 times by 2 tests: return Object::virtualGet(m, id, receiver, hasProperty); Executed by:
| 51876 | ||||||||||||||||||
374 | - | |||||||||||||||||||
375 | uint index = id.asArrayIndex(); | - | ||||||||||||||||||
376 | Scope scope(static_cast<const Object *>(m)->engine()); | - | ||||||||||||||||||
377 | Scoped<TypedArray> a(scope, static_cast<const TypedArray *>(m)); | - | ||||||||||||||||||
378 | - | |||||||||||||||||||
379 | uint bytesPerElement = a->d()->type->bytesPerElement; | - | ||||||||||||||||||
380 | uint byteOffset = a->d()->byteOffset + index * bytesPerElement; | - | ||||||||||||||||||
381 | if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength()) {
| 432-23757 | ||||||||||||||||||
382 | if (hasProperty)
| 108-324 | ||||||||||||||||||
383 | *hasProperty = false; executed 108 times by 1 test: *hasProperty = false; Executed by:
| 108 | ||||||||||||||||||
384 | return Encode::undefined(); executed 432 times by 1 test: return Encode::undefined(); Executed by:
| 432 | ||||||||||||||||||
385 | } | - | ||||||||||||||||||
386 | if (hasProperty)
| 108-23649 | ||||||||||||||||||
387 | *hasProperty = true; executed 108 times by 1 test: *hasProperty = true; Executed by:
| 108 | ||||||||||||||||||
388 | return a->d()->type->read(a->d()->buffer->data->data(), byteOffset); executed 23752 times by 1 test: return a->d()->type->read(a->d()->buffer->data->data(), byteOffset); Executed by:
| 23752 | ||||||||||||||||||
389 | } | - | ||||||||||||||||||
390 | - | |||||||||||||||||||
391 | bool TypedArray::virtualPut(Managed *m, PropertyKey id, const Value &value, Value *receiver) | - | ||||||||||||||||||
392 | { | - | ||||||||||||||||||
393 | if (!id.isArrayIndex())
| 2759-18262 | ||||||||||||||||||
394 | return Object::virtualPut(m, id, value, receiver); executed 2759 times by 1 test: return Object::virtualPut(m, id, value, receiver); Executed by:
| 2759 | ||||||||||||||||||
395 | - | |||||||||||||||||||
396 | uint index = id.asArrayIndex(); | - | ||||||||||||||||||
397 | ExecutionEngine *v4 = static_cast<Object *>(m)->engine(); | - | ||||||||||||||||||
398 | if (v4->hasException)
| 0-18262 | ||||||||||||||||||
399 | return false; never executed: return false; | 0 | ||||||||||||||||||
400 | - | |||||||||||||||||||
401 | Scope scope(v4); | - | ||||||||||||||||||
402 | Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m)); | - | ||||||||||||||||||
403 | - | |||||||||||||||||||
404 | uint bytesPerElement = a->d()->type->bytesPerElement; | - | ||||||||||||||||||
405 | uint byteOffset = a->d()->byteOffset + index * bytesPerElement; | - | ||||||||||||||||||
406 | if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength())
| 38-18224 | ||||||||||||||||||
407 | return false; executed 38 times by 1 test: return false; Executed by:
| 38 | ||||||||||||||||||
408 | - | |||||||||||||||||||
409 | a->d()->type->write(scope.engine, a->d()->buffer->data->data(), byteOffset, value); | - | ||||||||||||||||||
410 | return true; executed 18224 times by 1 test: return true; Executed by:
| 18224 | ||||||||||||||||||
411 | } | - | ||||||||||||||||||
412 | - | |||||||||||||||||||
413 | void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor) | - | ||||||||||||||||||
414 | { | - | ||||||||||||||||||
415 | Scope scope(engine); | - | ||||||||||||||||||
416 | ScopedObject o(scope); | - | ||||||||||||||||||
417 | - | |||||||||||||||||||
418 | ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(3)); | - | ||||||||||||||||||
419 | ctor->defineReadonlyProperty(engine->id_prototype(), *this); | - | ||||||||||||||||||
420 | ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement)); executed 890617 times by 153 tests: return qstring_literal_temp; Executed by:
| 890617 | ||||||||||||||||||
421 | ctor->setPrototypeOf(engine->intrinsicTypedArrayCtor()); | - | ||||||||||||||||||
422 | - | |||||||||||||||||||
423 | setPrototypeOf(engine->intrinsicTypedArrayPrototype()); | - | ||||||||||||||||||
424 | defineDefaultProperty(engine->id_constructor(), (o = ctor)); | - | ||||||||||||||||||
425 | defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement)); executed 888809 times by 153 tests: return qstring_literal_temp; Executed by:
| 888809 | ||||||||||||||||||
426 | } executed 891567 times by 153 tests: end of block Executed by:
| 891567 | ||||||||||||||||||
427 | - | |||||||||||||||||||
428 | ReturnedValue IntrinsicTypedArrayPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
429 | { | - | ||||||||||||||||||
430 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||||||||
431 | const TypedArray *v = thisObject->as<TypedArray>(); | - | ||||||||||||||||||
432 | if (!v)
| 88-1739 | ||||||||||||||||||
433 | return v4->throwTypeError(); executed 88 times by 1 test: return v4->throwTypeError(); Executed by:
| 88 | ||||||||||||||||||
434 | - | |||||||||||||||||||
435 | return v->d()->buffer->asReturnedValue(); executed 1739 times by 2 tests: return v->d()->buffer->asReturnedValue(); Executed by:
| 1739 | ||||||||||||||||||
436 | } | - | ||||||||||||||||||
437 | - | |||||||||||||||||||
438 | ReturnedValue IntrinsicTypedArrayPrototype::method_get_byteLength(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
439 | { | - | ||||||||||||||||||
440 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||||||||
441 | const TypedArray *v = thisObject->as<TypedArray>(); | - | ||||||||||||||||||
442 | if (!v)
| 52-78 | ||||||||||||||||||
443 | return v4->throwTypeError(); executed 52 times by 1 test: return v4->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
444 | - | |||||||||||||||||||
445 | return Encode(v->d()->byteLength); executed 78 times by 2 tests: return Encode(v->d()->byteLength); Executed by:
| 78 | ||||||||||||||||||
446 | } | - | ||||||||||||||||||
447 | - | |||||||||||||||||||
448 | ReturnedValue IntrinsicTypedArrayPrototype::method_get_byteOffset(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
449 | { | - | ||||||||||||||||||
450 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||||||||
451 | const TypedArray *v = thisObject->as<TypedArray>(); | - | ||||||||||||||||||
452 | if (!v)
| 51-732 | ||||||||||||||||||
453 | return v4->throwTypeError(); executed 51 times by 1 test: return v4->throwTypeError(); Executed by:
| 51 | ||||||||||||||||||
454 | - | |||||||||||||||||||
455 | return Encode(v->d()->byteOffset); executed 732 times by 1 test: return Encode(v->d()->byteOffset); Executed by:
| 732 | ||||||||||||||||||
456 | } | - | ||||||||||||||||||
457 | - | |||||||||||||||||||
458 | ReturnedValue IntrinsicTypedArrayPrototype::method_get_length(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
459 | { | - | ||||||||||||||||||
460 | ExecutionEngine *v4 = b->engine(); | - | ||||||||||||||||||
461 | const TypedArray *v = thisObject->as<TypedArray>(); | - | ||||||||||||||||||
462 | if (!v)
| 52-24677 | ||||||||||||||||||
463 | return v4->throwTypeError(); executed 52 times by 1 test: return v4->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
464 | - | |||||||||||||||||||
465 | return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); executed 24679 times by 1 test: return Encode(v->d()->byteLength/v->d()->type->bytesPerElement); Executed by:
| 24679 | ||||||||||||||||||
466 | } | - | ||||||||||||||||||
467 | - | |||||||||||||||||||
468 | ReturnedValue IntrinsicTypedArrayPrototype::method_entries(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
469 | { | - | ||||||||||||||||||
470 | Scope scope(b); | - | ||||||||||||||||||
471 | Scoped<TypedArray> O(scope, thisObject); | - | ||||||||||||||||||
472 | if (!O)
| 52-72 | ||||||||||||||||||
473 | THROW_TYPE_ERROR(); executed 52 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
474 | - | |||||||||||||||||||
475 | Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); | - | ||||||||||||||||||
476 | ao->d()->iterationKind = IteratorKind::KeyValueIteratorKind; | - | ||||||||||||||||||
477 | return ao->asReturnedValue(); executed 72 times by 1 test: return ao->asReturnedValue(); Executed by:
| 72 | ||||||||||||||||||
478 | } | - | ||||||||||||||||||
479 | - | |||||||||||||||||||
480 | ReturnedValue IntrinsicTypedArrayPrototype::method_keys(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
481 | { | - | ||||||||||||||||||
482 | Scope scope(b); | - | ||||||||||||||||||
483 | Scoped<TypedArray> O(scope, thisObject); | - | ||||||||||||||||||
484 | if (!O)
| 52-76 | ||||||||||||||||||
485 | THROW_TYPE_ERROR(); executed 52 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
486 | - | |||||||||||||||||||
487 | Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); | - | ||||||||||||||||||
488 | ao->d()->iterationKind = IteratorKind::KeyIteratorKind; | - | ||||||||||||||||||
489 | return ao->asReturnedValue(); executed 76 times by 1 test: return ao->asReturnedValue(); Executed by:
| 76 | ||||||||||||||||||
490 | } | - | ||||||||||||||||||
491 | - | |||||||||||||||||||
492 | ReturnedValue IntrinsicTypedArrayPrototype::method_values(const FunctionObject *b, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
493 | { | - | ||||||||||||||||||
494 | Scope scope(b); | - | ||||||||||||||||||
495 | Scoped<TypedArray> O(scope, thisObject); | - | ||||||||||||||||||
496 | if (!O)
| 52-179 | ||||||||||||||||||
497 | THROW_TYPE_ERROR(); executed 52 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
498 | - | |||||||||||||||||||
499 | Scoped<ArrayIteratorObject> ao(scope, scope.engine->newArrayIteratorObject(O)); | - | ||||||||||||||||||
500 | ao->d()->iterationKind = IteratorKind::ValueIteratorKind; | - | ||||||||||||||||||
501 | return ao->asReturnedValue(); executed 180 times by 1 test: return ao->asReturnedValue(); Executed by:
| 180 | ||||||||||||||||||
502 | } | - | ||||||||||||||||||
503 | - | |||||||||||||||||||
504 | ReturnedValue IntrinsicTypedArrayPrototype::method_set(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||||||||
505 | { | - | ||||||||||||||||||
506 | Scope scope(b); | - | ||||||||||||||||||
507 | Scoped<TypedArray> a(scope, *thisObject); | - | ||||||||||||||||||
508 | if (!a)
| 96-5979 | ||||||||||||||||||
509 | return scope.engine->throwTypeError(); executed 96 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 96 | ||||||||||||||||||
510 | Scoped<ArrayBuffer> buffer(scope, a->d()->buffer); | - | ||||||||||||||||||
511 | if (!buffer)
| 0-5980 | ||||||||||||||||||
512 | scope.engine->throwTypeError(); never executed: scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
513 | - | |||||||||||||||||||
514 | double doffset = argc >= 2 ? argv[1].toInteger() : 0;
| 2461-3519 | ||||||||||||||||||
515 | if (scope.engine->hasException)
| 228-5753 | ||||||||||||||||||
516 | RETURN_UNDEFINED(); executed 228 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 228 | ||||||||||||||||||
517 | - | |||||||||||||||||||
518 | if (doffset < 0 || doffset >= UINT_MAX)
| 36-5537 | ||||||||||||||||||
519 | RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); executed 252 times by 1 test: return QV4::Encode(scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "TypedArray.set: out of range")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "TypedArray.set: out of range" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))); Executed by:
executed 252 times by 1 test: return qstring_literal_temp; Executed by:
| 252 | ||||||||||||||||||
520 | uint offset = (uint)doffset; | - | ||||||||||||||||||
521 | uint elementSize = a->d()->type->bytesPerElement; | - | ||||||||||||||||||
522 | - | |||||||||||||||||||
523 | Scoped<TypedArray> srcTypedArray(scope, argv[0]); | - | ||||||||||||||||||
524 | if (!srcTypedArray) {
| 2720-2780 | ||||||||||||||||||
525 | // src is a regular object | - | ||||||||||||||||||
526 | ScopedObject o(scope, argv[0].toObject(scope.engine)); | - | ||||||||||||||||||
527 | if (scope.engine->hasException || !o)
| 0-2708 | ||||||||||||||||||
528 | return scope.engine->throwTypeError(); executed 72 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 72 | ||||||||||||||||||
529 | - | |||||||||||||||||||
530 | double len = ScopedValue(scope, o->get(scope.engine->id_length()))->toNumber(); | - | ||||||||||||||||||
531 | uint l = (uint)len; | - | ||||||||||||||||||
532 | if (scope.engine->hasException || l != len)
| 0-2563 | ||||||||||||||||||
533 | return scope.engine->throwTypeError(); executed 144 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 144 | ||||||||||||||||||
534 | - | |||||||||||||||||||
535 | if (offset + l > a->length())
| 0-2564 | ||||||||||||||||||
536 | RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); never executed: return QV4::Encode(scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "TypedArray.set: out of range")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "TypedArray.set: out of range" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))); never executed: return qstring_literal_temp; | 0 | ||||||||||||||||||
537 | - | |||||||||||||||||||
538 | uint idx = 0; | - | ||||||||||||||||||
539 | char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; | - | ||||||||||||||||||
540 | ScopedValue val(scope); | - | ||||||||||||||||||
541 | while (idx < l) {
| 2448-3467 | ||||||||||||||||||
542 | val = o->get(idx); | - | ||||||||||||||||||
543 | a->d()->type->write(scope.engine, b, 0, val); | - | ||||||||||||||||||
544 | if (scope.engine->hasException)
| 116-3351 | ||||||||||||||||||
545 | RETURN_UNDEFINED(); executed 116 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 116 | ||||||||||||||||||
546 | ++idx; | - | ||||||||||||||||||
547 | b += elementSize; | - | ||||||||||||||||||
548 | } executed 3351 times by 1 test: end of block Executed by:
| 3351 | ||||||||||||||||||
549 | RETURN_UNDEFINED(); executed 2448 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 2448 | ||||||||||||||||||
550 | } | - | ||||||||||||||||||
551 | - | |||||||||||||||||||
552 | // src is a typed array | - | ||||||||||||||||||
553 | Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer); | - | ||||||||||||||||||
554 | if (!srcBuffer)
| 0-2720 | ||||||||||||||||||
555 | return scope.engine->throwTypeError(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
556 | - | |||||||||||||||||||
557 | uint l = srcTypedArray->length(); | - | ||||||||||||||||||
558 | if (offset + l > a->length())
| 108-2615 | ||||||||||||||||||
559 | RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"))); executed 108 times by 1 test: return QV4::Encode(scope.engine->throwRangeError(([]() noexcept -> QString { enum { Size = sizeof(u"" "TypedArray.set: out of range")/2 - 1 }; static const QStaticStringData<Size> qstring_literal = { { { { -1 } }, Size, 0, 0, sizeof(QStringData) }, u"" "TypedArray.set: out of range" }; QStringDataPtr holder = { qstring_literal.data_ptr() }; const QString qstring_literal_temp(holder); return qstring_literal_temp; }()))); Executed by:
executed 108 times by 1 test: return qstring_literal_temp; Executed by:
| 108 | ||||||||||||||||||
560 | - | |||||||||||||||||||
561 | char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize; | - | ||||||||||||||||||
562 | const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset; | - | ||||||||||||||||||
563 | if (srcTypedArray->d()->type == a->d()->type) {
| 1016-1598 | ||||||||||||||||||
564 | // same type of typed arrays, use memmove (as srcbuffer and buffer could be the same) | - | ||||||||||||||||||
565 | memmove(dest, src, srcTypedArray->d()->byteLength); | - | ||||||||||||||||||
566 | RETURN_UNDEFINED(); executed 1016 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 1016 | ||||||||||||||||||
567 | } | - | ||||||||||||||||||
568 | - | |||||||||||||||||||
569 | char *srcCopy = nullptr; | - | ||||||||||||||||||
570 | if (buffer->d() == srcBuffer->d()) {
| 108-1491 | ||||||||||||||||||
571 | // same buffer, need to take a temporary copy, to not run into problems | - | ||||||||||||||||||
572 | srcCopy = new char[srcTypedArray->d()->byteLength]; | - | ||||||||||||||||||
573 | memcpy(srcCopy, src, srcTypedArray->d()->byteLength); | - | ||||||||||||||||||
574 | src = srcCopy; | - | ||||||||||||||||||
575 | } executed 108 times by 1 test: end of block Executed by:
| 108 | ||||||||||||||||||
576 | - | |||||||||||||||||||
577 | // typed arrays of different kind, need to manually loop | - | ||||||||||||||||||
578 | uint srcElementSize = srcTypedArray->d()->type->bytesPerElement; | - | ||||||||||||||||||
579 | TypedArrayRead read = srcTypedArray->d()->type->read; | - | ||||||||||||||||||
580 | TypedArrayWrite write = a->d()->type->write; | - | ||||||||||||||||||
581 | for (uint i = 0; i < l; ++i) {
| 1600-1887 | ||||||||||||||||||
582 | Primitive val; | - | ||||||||||||||||||
583 | val.setRawValue(read(src, i*srcElementSize)); | - | ||||||||||||||||||
584 | write(scope.engine, dest, i*elementSize, val); | - | ||||||||||||||||||
585 | } executed 1886 times by 1 test: end of block Executed by:
| 1886 | ||||||||||||||||||
586 | - | |||||||||||||||||||
587 | if (srcCopy)
| 108-1492 | ||||||||||||||||||
588 | delete [] srcCopy; executed 108 times by 1 test: delete [] srcCopy; Executed by:
| 108 | ||||||||||||||||||
589 | - | |||||||||||||||||||
590 | RETURN_UNDEFINED(); executed 1600 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 1600 | ||||||||||||||||||
591 | } | - | ||||||||||||||||||
592 | - | |||||||||||||||||||
593 | ReturnedValue IntrinsicTypedArrayPrototype::method_subarray(const FunctionObject *builtin, const Value *thisObject, const Value *argv, int argc) | - | ||||||||||||||||||
594 | { | - | ||||||||||||||||||
595 | Scope scope(builtin); | - | ||||||||||||||||||
596 | Scoped<TypedArray> a(scope, *thisObject); | - | ||||||||||||||||||
597 | - | |||||||||||||||||||
598 | if (!a)
| 52-4202 | ||||||||||||||||||
599 | return scope.engine->throwTypeError(); executed 52 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 52 | ||||||||||||||||||
600 | - | |||||||||||||||||||
601 | Scoped<ArrayBuffer> buffer(scope, a->d()->buffer); | - | ||||||||||||||||||
602 | if (!buffer)
| 0-4203 | ||||||||||||||||||
603 | return scope.engine->throwTypeError(); never executed: return scope.engine->throwTypeError(); | 0 | ||||||||||||||||||
604 | - | |||||||||||||||||||
605 | int len = a->length(); | - | ||||||||||||||||||
606 | double b = argc > 0 ? argv[0].toInteger() : 0;
| 0-4207 | ||||||||||||||||||
607 | if (b < 0)
| 972-3233 | ||||||||||||||||||
608 | b = len + b; executed 972 times by 1 test: b = len + b; Executed by:
| 972 | ||||||||||||||||||
609 | uint begin = (uint)qBound(0., b, (double)len); | - | ||||||||||||||||||
610 | - | |||||||||||||||||||
611 | double e = argc < 2 || argv[1].isUndefined() ? len : argv[1].toInteger();
| 36-2486 | ||||||||||||||||||
612 | if (e < 0)
| 828-3379 | ||||||||||||||||||
613 | e = len + e; executed 828 times by 1 test: e = len + e; Executed by:
| 828 | ||||||||||||||||||
614 | uint end = (uint)qBound(0., e, (double)len); | - | ||||||||||||||||||
615 | if (end < begin)
| 144-4062 | ||||||||||||||||||
616 | end = begin; executed 144 times by 1 test: end = begin; Executed by:
| 144 | ||||||||||||||||||
617 | - | |||||||||||||||||||
618 | if (scope.engine->hasException)
| 216-3991 | ||||||||||||||||||
619 | RETURN_UNDEFINED(); executed 216 times by 1 test: return QV4::Encode::undefined(); Executed by:
| 216 | ||||||||||||||||||
620 | - | |||||||||||||||||||
621 | int newLen = end - begin; | - | ||||||||||||||||||
622 | - | |||||||||||||||||||
623 | ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor())); | - | ||||||||||||||||||
624 | if (!constructor)
| 536-3453 | ||||||||||||||||||
625 | return scope.engine->throwTypeError(); executed 535 times by 1 test: return scope.engine->throwTypeError(); Executed by:
| 535 | ||||||||||||||||||
626 | - | |||||||||||||||||||
627 | Value *arguments = scope.alloc(3); | - | ||||||||||||||||||
628 | arguments[0] = buffer; | - | ||||||||||||||||||
629 | arguments[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement); | - | ||||||||||||||||||
630 | arguments[2] = Encode(newLen); | - | ||||||||||||||||||
631 | return constructor->callAsConstructor(arguments, 3); executed 3455 times by 1 test: return constructor->callAsConstructor(arguments, 3); Executed by:
| 3455 | ||||||||||||||||||
632 | } | - | ||||||||||||||||||
633 | - | |||||||||||||||||||
634 | ReturnedValue IntrinsicTypedArrayPrototype::method_get_toStringTag(const FunctionObject *, const Value *thisObject, const Value *, int) | - | ||||||||||||||||||
635 | { | - | ||||||||||||||||||
636 | const TypedArray *a = thisObject->as<TypedArray>(); | - | ||||||||||||||||||
637 | if (!a)
| 64-1731 | ||||||||||||||||||
638 | return Encode::undefined(); executed 64 times by 1 test: return Encode::undefined(); Executed by:
| 64 | ||||||||||||||||||
639 | - | |||||||||||||||||||
640 | return a->engine()->newString(QString::fromLatin1(a->d()->type->name))->asReturnedValue(); executed 1731 times by 1 test: return a->engine()->newString(QString::fromLatin1(a->d()->type->name))->asReturnedValue(); Executed by:
| 1731 | ||||||||||||||||||
641 | } | - | ||||||||||||||||||
642 | - | |||||||||||||||||||
643 | ReturnedValue IntrinsicTypedArrayCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *, int, const Value *) | - | ||||||||||||||||||
644 | { | - | ||||||||||||||||||
645 | return f->engine()->throwTypeError(); executed 24 times by 1 test: return f->engine()->throwTypeError(); Executed by:
| 24 | ||||||||||||||||||
646 | } | - | ||||||||||||||||||
647 | - | |||||||||||||||||||
648 | ReturnedValue IntrinsicTypedArrayCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int) | - | ||||||||||||||||||
649 | { | - | ||||||||||||||||||
650 | return f->engine()->throwTypeError(); executed 24 times by 1 test: return f->engine()->throwTypeError(); Executed by:
| 24 | ||||||||||||||||||
651 | } | - | ||||||||||||||||||
652 | - | |||||||||||||||||||
653 | void IntrinsicTypedArrayPrototype::init(ExecutionEngine *engine, IntrinsicTypedArrayCtor *ctor) | - | ||||||||||||||||||
654 | { | - | ||||||||||||||||||
655 | ctor->defineReadonlyProperty(engine->id_prototype(), *this); | - | ||||||||||||||||||
656 | ctor->defineReadonlyConfigurableProperty(engine->id_length(), Primitive::fromInt32(0)); | - | ||||||||||||||||||
657 | ctor->addSymbolSpecies(); | - | ||||||||||||||||||
658 | - | |||||||||||||||||||
659 | defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, nullptr); executed 98273 times by 153 tests: return qstring_literal_temp; Executed by:
| 98273 | ||||||||||||||||||
660 | defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, nullptr); executed 98167 times by 153 tests: return qstring_literal_temp; Executed by:
| 98167 | ||||||||||||||||||
661 | defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, nullptr); executed 98915 times by 153 tests: return qstring_literal_temp; Executed by:
| 98915 | ||||||||||||||||||
662 | defineAccessorProperty(QStringLiteral("length"), method_get_length, nullptr); executed 98694 times by 153 tests: return qstring_literal_temp; Executed by:
| 98694 | ||||||||||||||||||
663 | - | |||||||||||||||||||
664 | defineDefaultProperty(QStringLiteral("entries"), method_entries, 0); executed 98975 times by 153 tests: return qstring_literal_temp; Executed by:
| 98975 | ||||||||||||||||||
665 | defineDefaultProperty(QStringLiteral("keys"), method_keys, 0); executed 98983 times by 153 tests: return qstring_literal_temp; Executed by:
| 98983 | ||||||||||||||||||
666 | defineDefaultProperty(QStringLiteral("set"), method_set, 1); executed 98854 times by 153 tests: return qstring_literal_temp; Executed by:
| 98854 | ||||||||||||||||||
667 | defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0); executed 98900 times by 153 tests: return qstring_literal_temp; Executed by:
| 98900 | ||||||||||||||||||
668 | - | |||||||||||||||||||
669 | Scope scope(engine); | - | ||||||||||||||||||
670 | ScopedString valuesString(scope, engine->newIdentifier(QStringLiteral("values"))); executed 98814 times by 153 tests: return qstring_literal_temp; Executed by:
| 98814 | ||||||||||||||||||
671 | ScopedObject values(scope, FunctionObject::createBuiltinFunction(engine, valuesString, method_values, 0)); | - | ||||||||||||||||||
672 | defineDefaultProperty(QStringLiteral("values"), values); executed 98409 times by 153 tests: return qstring_literal_temp; Executed by:
| 98409 | ||||||||||||||||||
673 | defineDefaultProperty(engine->symbol_iterator(), values); | - | ||||||||||||||||||
674 | - | |||||||||||||||||||
675 | defineAccessorProperty(engine->symbol_toStringTag(), method_get_toStringTag, nullptr); | - | ||||||||||||||||||
676 | } executed 98559 times by 153 tests: end of block Executed by:
| 98559 | ||||||||||||||||||
Source code | Switch to Preprocessed file |