| 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted by:
| 660 | ||||||||||||||||||
| 279 | } executed 252 times by 1 test: end of blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted 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 blockExecuted by:
| 98559 | ||||||||||||||||||
| Source code | Switch to Preprocessed file |