1 /*
2 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/base/typed_array_helper-inl.h"
17 #include "ecmascript/builtins/builtins_arraybuffer.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_array.h"
20 #include "ecmascript/tests/test_helper.h"
21
22 using namespace panda::ecmascript;
23 using namespace panda::ecmascript::base;
24
25 namespace panda::test {
26 class TypedArrayHelperTest : public BaseTestWithScope<false> {
27 };
28
CreateTypedArrayCallInfo(JSThread * thread,const JSHandle<TaggedArray> & array,DataViewType type)29 EcmaRuntimeCallInfo *CreateTypedArrayCallInfo(JSThread *thread, const JSHandle<TaggedArray> &array, DataViewType type)
30 {
31 auto vm = thread->GetEcmaVM();
32 auto env = vm->GetGlobalEnv();
33 JSHandle<JSTaggedValue> jsarray(JSArray::CreateArrayFromList(thread, array));
34 JSHandle<JSFunction> arrayFunc;
35 switch (type) {
36 case DataViewType::BIGINT64: {
37 arrayFunc = JSHandle<JSFunction>(env->GetBigInt64ArrayFunction());
38 break;
39 }
40 case DataViewType::BIGUINT64: {
41 arrayFunc = JSHandle<JSFunction>(env->GetBigUint64ArrayFunction());
42 break;
43 }
44 case DataViewType::FLOAT32: {
45 arrayFunc = JSHandle<JSFunction>(env->GetFloat32ArrayFunction());
46 break;
47 }
48 case DataViewType::FLOAT64: {
49 arrayFunc = JSHandle<JSFunction>(env->GetFloat64ArrayFunction());
50 break;
51 }
52 case DataViewType::INT16: {
53 arrayFunc = JSHandle<JSFunction>(env->GetInt16ArrayFunction());
54 break;
55 }
56 case DataViewType::INT32: {
57 arrayFunc = JSHandle<JSFunction>(env->GetInt32ArrayFunction());
58 break;
59 }
60 case DataViewType::INT8: {
61 arrayFunc = JSHandle<JSFunction>(env->GetInt8ArrayFunction());
62 break;
63 }
64 case DataViewType::UINT16: {
65 arrayFunc = JSHandle<JSFunction>(env->GetUint16ArrayFunction());
66 break;
67 }
68 case DataViewType::UINT32: {
69 arrayFunc = JSHandle<JSFunction>(env->GetUint32ArrayFunction());
70 break;
71 }
72 case DataViewType::UINT8: {
73 arrayFunc = JSHandle<JSFunction>(env->GetUint8ArrayFunction());
74 break;
75 }
76 case DataViewType::UINT8_CLAMPED: {
77 arrayFunc = JSHandle<JSFunction>(env->GetUint8ClampedArrayFunction());
78 break;
79 }
80 default: {
81 JSHandle<JSTaggedValue> undefined(thread, JSTaggedValue::Undefined());
82 arrayFunc = JSHandle<JSFunction>(undefined);
83 break;
84 }
85 }
86 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
87 EcmaRuntimeCallInfo* ecmaRuntimeCallInfo =
88 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*arrayFunc), 6); // 6 : arguments length
89 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue(*arrayFunc));
90 ecmaRuntimeCallInfo->SetThis(JSTaggedValue(*globalObject));
91 ecmaRuntimeCallInfo->SetCallArg(0, jsarray.GetTaggedValue());
92 return ecmaRuntimeCallInfo;
93 }
94
CreateArrayList(JSThread * thread,JSHandle<JSTaggedValue> & arrayVal)95 void CreateArrayList(JSThread *thread, JSHandle<JSTaggedValue> &arrayVal)
96 {
97 auto factory = thread->GetEcmaVM()->GetFactory();
98 JSHandle<TaggedArray> array(factory->NewTaggedArray(0));
99 EcmaRuntimeCallInfo *argv = CreateTypedArrayCallInfo(thread, array, DataViewType::UINT32);
100 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledUint32ArrayString();
101 auto prev = TestHelper::SetupFrame(thread, argv);
102 JSHandle<JSTaggedValue> uint32Array(
103 thread, TypedArrayHelper::TypedArrayConstructor(argv, constructorName, DataViewType::UINT32));
104 TestHelper::TearDownFrame(thread, prev);
105 arrayVal = uint32Array;
106 }
107
HWTEST_F_L0(TypedArrayHelperTest,TypedArrayConstructor)108 HWTEST_F_L0(TypedArrayHelperTest, TypedArrayConstructor)
109 {
110 auto factory = thread->GetEcmaVM()->GetFactory();
111 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
112 array->Set(thread, 0, JSTaggedValue(-129)); // Int8 min minus 1
113 array->Set(thread, 1, JSTaggedValue(-128)); // Int8 min
114 array->Set(thread, 2, JSTaggedValue(128)); // Int8 max plus 1
115 EcmaRuntimeCallInfo* argv = CreateTypedArrayCallInfo(thread, array, DataViewType::INT8);
116 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledInt8ArrayString();
117 auto prev = TestHelper::SetupFrame(thread, argv);
118 JSHandle<JSTaggedValue> int8Array(thread, TypedArrayHelper::TypedArrayConstructor(argv, constructorName,
119 DataViewType::INT8));
120 TestHelper::TearDownFrame(thread, prev);
121 OperationResult result0 = JSTypedArray::GetProperty(thread, int8Array, 0U);
122 OperationResult result1 = JSTypedArray::GetProperty(thread, int8Array, 1U);
123 OperationResult result2 = JSTypedArray::GetProperty(thread, int8Array, 2U);
124 EXPECT_EQ(result0.GetRawValue().GetTaggedValue().GetInt(), 127); // 127 : -129 to int8 127
125 EXPECT_EQ(result1.GetRawValue().GetTaggedValue().GetInt(), -128); // -128 : -128 to int8 -128
126 EXPECT_EQ(result2.GetRawValue().GetTaggedValue().GetInt(), -128); // -128 : 128 to int8 -128
127 }
128
HWTEST_F_L0(TypedArrayHelperTest,AllocateTypedArray_001)129 HWTEST_F_L0(TypedArrayHelperTest, AllocateTypedArray_001)
130 {
131 auto ecmaVm = thread->GetEcmaVM();
132 auto factory = ecmaVm->GetFactory();
133 JSHandle<TaggedArray> array(factory->NewTaggedArray(0));
134 EcmaRuntimeCallInfo* argv = CreateTypedArrayCallInfo(thread, array, DataViewType::UINT8);
135 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledUint8ArrayString();
136 auto prev = TestHelper::SetupFrame(thread, argv);
137 JSHandle<JSTaggedValue> newTarget = BuiltinsBase::GetNewTarget(argv);
138 JSHandle<JSObject> arrayObj =
139 TypedArrayHelper::AllocateTypedArray(thread, constructorName, newTarget, DataViewType::UINT8);
140 TestHelper::TearDownFrame(thread, prev);
141 JSTypedArray *jsTypedArray = JSTypedArray::Cast(*arrayObj);
142 EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::Number);
143 EXPECT_EQ(jsTypedArray->GetTypedArrayName(thread).GetRawData(), constructorName.GetTaggedValue().GetRawData());
144 EXPECT_EQ(jsTypedArray->GetByteLength(), 0U);
145 EXPECT_EQ(jsTypedArray->GetByteOffset(), 0U);
146 EXPECT_EQ(jsTypedArray->GetArrayLength(), 0U);
147 }
148
HWTEST_F_L0(TypedArrayHelperTest,AllocateTypedArray_002)149 HWTEST_F_L0(TypedArrayHelperTest, AllocateTypedArray_002)
150 {
151 auto ecmaVm = thread->GetEcmaVM();
152 auto factory = ecmaVm->GetFactory();
153 int32_t length = 256;
154 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
155 EcmaRuntimeCallInfo* argv = CreateTypedArrayCallInfo(thread, array, DataViewType::UINT8);
156 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledUint8ArrayString();
157 auto prev = TestHelper::SetupFrame(thread, argv);
158 JSHandle<JSTaggedValue> newTarget = BuiltinsBase::GetNewTarget(argv);
159 JSHandle<JSObject> arrayObj =
160 TypedArrayHelper::AllocateTypedArray(thread, constructorName, newTarget, length, DataViewType::UINT8);
161 TestHelper::TearDownFrame(thread, prev);
162 JSTypedArray *jsTypedArray = JSTypedArray::Cast(*arrayObj);
163 EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::Number);
164 EXPECT_EQ(jsTypedArray->GetTypedArrayName(thread).GetRawData(), constructorName.GetTaggedValue().GetRawData());
165 EXPECT_EQ(jsTypedArray->GetByteLength(), 256U);
166 EXPECT_EQ(jsTypedArray->GetByteOffset(), 0U);
167 EXPECT_EQ(jsTypedArray->GetArrayLength(), 256U);
168 }
169
HWTEST_F_L0(TypedArrayHelperTest,TypedArraySpeciesCreate)170 HWTEST_F_L0(TypedArrayHelperTest, TypedArraySpeciesCreate)
171 {
172 auto factory = thread->GetEcmaVM()->GetFactory();
173 uint32_t lenVal = 3;
174 JSHandle<TaggedArray> array(factory->NewTaggedArray(lenVal));
175 EcmaRuntimeCallInfo* argv = CreateTypedArrayCallInfo(thread, array, DataViewType::INT16);
176 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledInt16ArrayString();
177 auto prev = TestHelper::SetupFrame(thread, argv);
178 JSHandle<JSTaggedValue> int16Array(thread, TypedArrayHelper::TypedArrayConstructor(argv, constructorName,
179 DataViewType::INT16));
180 TestHelper::TearDownFrame(thread, prev);
181 JSHandle<JSTypedArray> arrayObj(int16Array);
182 uint32_t len = arrayObj->GetArrayLength();
183 EXPECT_EQ(len, 3U);
184
185 uint32_t newLenVal = 6;
186 JSTaggedType args[1] = {JSTaggedValue(newLenVal).GetRawData()};
187 JSHandle<JSObject> newArrObj = TypedArrayHelper::TypedArraySpeciesCreate(thread, arrayObj, 1, args); // 1 : one arg
188 uint32_t newLen = JSHandle<JSTypedArray>::Cast(newArrObj)->GetArrayLength();
189 EXPECT_EQ(newLen, 6U);
190 }
191
HWTEST_F_L0(TypedArrayHelperTest,TypedArrayCreate)192 HWTEST_F_L0(TypedArrayHelperTest, TypedArrayCreate)
193 {
194 auto vm = thread->GetEcmaVM();
195 auto env = vm->GetGlobalEnv();
196 JSHandle<JSTaggedValue> constructor = env->GetUint16ArrayFunction();
197 JSHandle<JSTaggedValue> constructorName = thread->GlobalConstants()->GetHandledUint16ArrayString();
198 EXPECT_TRUE(constructor->IsConstructor());
199
200 uint32_t lenVal = 256;
201 JSTaggedType args[1] = {JSTaggedValue(lenVal).GetRawData()};
202 JSHandle<JSObject> newArrObj = TypedArrayHelper::TypedArrayCreate(thread, constructor, 1, args); // 1 : one arg
203 uint32_t len = JSHandle<JSTypedArray>::Cast(newArrObj)->GetArrayLength();
204 JSHandle<JSTaggedValue> type(thread, JSHandle<JSTypedArray>::Cast(newArrObj)->GetTypedArrayName(thread));
205 EXPECT_EQ(len, 256U);
206 EXPECT_EQ(type.GetTaggedValue().GetRawData(), constructorName.GetTaggedValue().GetRawData());
207 }
208
HWTEST_F_L0(TypedArrayHelperTest,ValidateTypedArray)209 HWTEST_F_L0(TypedArrayHelperTest, ValidateTypedArray)
210 {
211 JSHandle<JSTaggedValue> uint32Array;
212 CreateArrayList(thread, uint32Array);
213 JSHandle<JSTaggedValue> buffer(thread, TypedArrayHelper::ValidateTypedArray(thread, uint32Array));
214 JSTaggedValue result = JSHandle<JSTypedArray>::Cast(uint32Array)->GetViewedArrayBufferOrByteArray(thread);
215 EXPECT_EQ(buffer.GetTaggedValue().GetRawData(), result.GetRawData());
216 }
217
HWTEST_F_L0(TypedArrayHelperTest,GetType_001)218 HWTEST_F_L0(TypedArrayHelperTest, GetType_001)
219 {
220 auto factory = thread->GetEcmaVM()->GetFactory();
221 JSHandle<TaggedArray> array(factory->NewTaggedArray(0));
222 EcmaRuntimeCallInfo* argv1 = CreateTypedArrayCallInfo(thread, array, DataViewType::INT8);
223 EcmaRuntimeCallInfo* argv2 = CreateTypedArrayCallInfo(thread, array, DataViewType::BIGUINT64);
224 EcmaRuntimeCallInfo* argv3 = CreateTypedArrayCallInfo(thread, array, DataViewType::UINT8_CLAMPED);
225 JSHandle<JSTaggedValue> constructorName1 = thread->GlobalConstants()->GetHandledInt8ArrayString();
226 JSHandle<JSTaggedValue> constructorName2 = thread->GlobalConstants()->GetHandledBigUint64ArrayString();
227 JSHandle<JSTaggedValue> constructorName3 = thread->GlobalConstants()->GetHandledUint8ClampedArrayString();
228 auto prev1 = TestHelper::SetupFrame(thread, argv1);
229 JSHandle<JSTaggedValue> int8ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv1, constructorName1,
230 DataViewType::INT8));
231 TestHelper::TearDownFrame(thread, prev1);
232 auto prev2 = TestHelper::SetupFrame(thread, argv2);
233 JSHandle<JSTaggedValue> bigUint64ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv2, constructorName2,
234 DataViewType::BIGUINT64));
235 TestHelper::TearDownFrame(thread, prev2);
236 auto prev3 = TestHelper::SetupFrame(thread, argv3);
237 JSHandle<JSTaggedValue> uint8ClampedArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv3,
238 constructorName3, DataViewType::UINT8_CLAMPED));
239 TestHelper::TearDownFrame(thread, prev3);
240 JSHandle<JSTypedArray> int8Array(int8ArrayVal);
241 JSHandle<JSTypedArray> bigUint64Array(bigUint64ArrayVal);
242 JSHandle<JSTypedArray> uint8ClampedArray(uint8ClampedArrayVal);
243 DataViewType type1 = TypedArrayHelper::GetType(int8Array);
244 DataViewType type2 = TypedArrayHelper::GetType(JSHandle<JSTypedArray>::Cast(bigUint64Array));
245 DataViewType type3 = TypedArrayHelper::GetType(JSHandle<JSTypedArray>::Cast(uint8ClampedArray));
246 EXPECT_EQ(type1, DataViewType::INT8);
247 EXPECT_EQ(type2, DataViewType::BIGUINT64);
248 EXPECT_EQ(type3, DataViewType::UINT8_CLAMPED);
249 }
250
HWTEST_F_L0(TypedArrayHelperTest,GetType_002)251 HWTEST_F_L0(TypedArrayHelperTest, GetType_002)
252 {
253 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_INT8_ARRAY), DataViewType::INT8);
254 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_UINT8_ARRAY), DataViewType::UINT8);
255 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_UINT8_CLAMPED_ARRAY), DataViewType::UINT8_CLAMPED);
256 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_INT16_ARRAY), DataViewType::INT16);
257 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_UINT16_ARRAY), DataViewType::UINT16);
258 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_INT32_ARRAY), DataViewType::INT32);
259 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_UINT32_ARRAY), DataViewType::UINT32);
260 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_FLOAT32_ARRAY), DataViewType::FLOAT32);
261 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_FLOAT64_ARRAY), DataViewType::FLOAT64);
262 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_BIGINT64_ARRAY), DataViewType::BIGINT64);
263 EXPECT_EQ(TypedArrayHelper::GetType(JSType::JS_OBJECT), DataViewType::BIGUINT64);
264 }
265
HWTEST_F_L0(TypedArrayHelperTest,GetElementSize_001)266 HWTEST_F_L0(TypedArrayHelperTest, GetElementSize_001)
267 {
268 auto factory = thread->GetEcmaVM()->GetFactory();
269 JSHandle<TaggedArray> array(factory->NewTaggedArray(0));
270 EcmaRuntimeCallInfo* argv1 = CreateTypedArrayCallInfo(thread, array, DataViewType::INT8);
271 EcmaRuntimeCallInfo* argv2 = CreateTypedArrayCallInfo(thread, array, DataViewType::INT16);
272 EcmaRuntimeCallInfo* argv3 = CreateTypedArrayCallInfo(thread, array, DataViewType::INT32);
273 EcmaRuntimeCallInfo* argv4 = CreateTypedArrayCallInfo(thread, array, DataViewType::BIGUINT64);
274 JSHandle<JSTaggedValue> constructorName1 = thread->GlobalConstants()->GetHandledInt8ArrayString();
275 JSHandle<JSTaggedValue> constructorName2 = thread->GlobalConstants()->GetHandledInt16ArrayString();
276 JSHandle<JSTaggedValue> constructorName3 = thread->GlobalConstants()->GetHandledInt32ArrayString();
277 JSHandle<JSTaggedValue> constructorName4 = thread->GlobalConstants()->GetHandledBigUint64ArrayString();
278 auto prev1 = TestHelper::SetupFrame(thread, argv1);
279 JSHandle<JSTaggedValue> int8ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv1, constructorName1,
280 DataViewType::INT8));
281 TestHelper::TearDownFrame(thread, prev1);
282 auto prev2 = TestHelper::SetupFrame(thread, argv2);
283 JSHandle<JSTaggedValue> int16ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv2, constructorName2,
284 DataViewType::INT16));
285 TestHelper::TearDownFrame(thread, prev2);
286 auto prev3 = TestHelper::SetupFrame(thread, argv3);
287 JSHandle<JSTaggedValue> int32ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv3, constructorName3,
288 DataViewType::INT32));
289 TestHelper::TearDownFrame(thread, prev3);
290 auto prev4 = TestHelper::SetupFrame(thread, argv4);
291 JSHandle<JSTaggedValue> bigUint64ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv3, constructorName4,
292 DataViewType::BIGUINT64));
293 TestHelper::TearDownFrame(thread, prev4);
294 JSHandle<JSTypedArray> int8Array(int8ArrayVal);
295 JSHandle<JSTypedArray> int16Array(int16ArrayVal);
296 JSHandle<JSTypedArray> int32Array(int32ArrayVal);
297 JSHandle<JSTypedArray> bigUint64Array(bigUint64ArrayVal);
298 uint32_t elementSize1 = TypedArrayHelper::GetElementSize(int8Array);
299 uint32_t elementSize2 = TypedArrayHelper::GetElementSize(JSHandle<JSTypedArray>::Cast(int16Array));
300 uint32_t elementSize3 = TypedArrayHelper::GetElementSize(JSHandle<JSTypedArray>::Cast(int32Array));
301 uint32_t elementSize4 = TypedArrayHelper::GetElementSize(JSHandle<JSTypedArray>::Cast(bigUint64Array));
302 EXPECT_EQ(elementSize1, 1U);
303 EXPECT_EQ(elementSize2, 2U);
304 EXPECT_EQ(elementSize3, 4U);
305 EXPECT_EQ(elementSize4, 8U);
306 }
307
HWTEST_F_L0(TypedArrayHelperTest,GetElementSize_002)308 HWTEST_F_L0(TypedArrayHelperTest, GetElementSize_002)
309 {
310 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_INT8_ARRAY), 1U);
311 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_UINT8_ARRAY), 1U);
312 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_UINT8_CLAMPED_ARRAY), 1U);
313 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_INT16_ARRAY), 2U);
314 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_UINT16_ARRAY), 2U);
315 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_INT32_ARRAY), 4U);
316 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_UINT32_ARRAY), 4U);
317 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_FLOAT32_ARRAY), 4U);
318 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_FLOAT64_ARRAY), 8U);
319 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_BIGINT64_ARRAY), 8U);
320 EXPECT_EQ(TypedArrayHelper::GetElementSize(JSType::JS_OBJECT), 8U);
321 }
322
HWTEST_F_L0(TypedArrayHelperTest,GetConstructor)323 HWTEST_F_L0(TypedArrayHelperTest, GetConstructor)
324 {
325 auto factory = thread->GetEcmaVM()->GetFactory();
326 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
327 JSHandle<TaggedArray> array(factory->NewTaggedArray(0));
328 EcmaRuntimeCallInfo* argv1 = CreateTypedArrayCallInfo(thread, array, DataViewType::INT8);
329 EcmaRuntimeCallInfo* argv2 = CreateTypedArrayCallInfo(thread, array, DataViewType::BIGUINT64);
330 EcmaRuntimeCallInfo* argv3 = CreateTypedArrayCallInfo(thread, array, DataViewType::UINT8_CLAMPED);
331 JSHandle<JSTaggedValue> constructorName1 = thread->GlobalConstants()->GetHandledInt8ArrayString();
332 JSHandle<JSTaggedValue> constructorName2 = thread->GlobalConstants()->GetHandledBigUint64ArrayString();
333 JSHandle<JSTaggedValue> constructorName3 = thread->GlobalConstants()->GetHandledUint8ClampedArrayString();
334 auto prev1 = TestHelper::SetupFrame(thread, argv1);
335 JSHandle<JSTaggedValue> int8ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv1, constructorName1,
336 DataViewType::INT8));
337 TestHelper::TearDownFrame(thread, prev1);
338 auto prev2 = TestHelper::SetupFrame(thread, argv2);
339 JSHandle<JSTaggedValue> bigUint64ArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv2, constructorName2,
340 DataViewType::BIGUINT64));
341 TestHelper::TearDownFrame(thread, prev2);
342 auto prev3 = TestHelper::SetupFrame(thread, argv3);
343 JSHandle<JSTaggedValue> uint8ClampedArrayVal(thread, TypedArrayHelper::TypedArrayConstructor(argv3,
344 constructorName3, DataViewType::UINT8_CLAMPED));
345 TestHelper::TearDownFrame(thread, prev3);
346 JSHandle<JSTaggedValue> constructor1 = TypedArrayHelper::GetConstructor(thread, int8ArrayVal);
347 JSHandle<JSTaggedValue> constructor2 = TypedArrayHelper::GetConstructor(thread, bigUint64ArrayVal);
348 JSHandle<JSTaggedValue> constructor3 = TypedArrayHelper::GetConstructor(thread, uint8ClampedArrayVal);
349 EXPECT_EQ(constructor1.GetTaggedValue(), env->GetInt8ArrayFunction().GetTaggedValue());
350 EXPECT_EQ(constructor2.GetTaggedValue(), env->GetBigUint64ArrayFunction().GetTaggedValue());
351 EXPECT_EQ(constructor3.GetTaggedValue(), env->GetUint8ClampedArrayFunction().GetTaggedValue());
352 }
353
HWTEST_F_L0(TypedArrayHelperTest,GetConstructorFromType)354 HWTEST_F_L0(TypedArrayHelperTest, GetConstructorFromType)
355 {
356 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
357 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::INT8).GetTaggedValue(),
358 env->GetInt8ArrayFunction().GetTaggedValue());
359 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::UINT8).GetTaggedValue(),
360 env->GetUint8ArrayFunction().GetTaggedValue());
361 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::UINT8_CLAMPED).GetTaggedValue(),
362 env->GetUint8ClampedArrayFunction().GetTaggedValue());
363 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::INT16).GetTaggedValue(),
364 env->GetInt16ArrayFunction().GetTaggedValue());
365 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::UINT16).GetTaggedValue(),
366 env->GetUint16ArrayFunction().GetTaggedValue());
367 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::INT32).GetTaggedValue(),
368 env->GetInt32ArrayFunction().GetTaggedValue());
369 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::UINT32).GetTaggedValue(),
370 env->GetUint32ArrayFunction().GetTaggedValue());
371 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::FLOAT32).GetTaggedValue(),
372 env->GetFloat32ArrayFunction().GetTaggedValue());
373 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::FLOAT64).GetTaggedValue(),
374 env->GetFloat64ArrayFunction().GetTaggedValue());
375 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::BIGINT64).GetTaggedValue(),
376 env->GetBigInt64ArrayFunction().GetTaggedValue());
377 EXPECT_EQ(TypedArrayHelper::GetConstructorFromType(thread, DataViewType::BIGUINT64).GetTaggedValue(),
378 env->GetBigUint64ArrayFunction().GetTaggedValue());
379 }
380
HWTEST_F_L0(TypedArrayHelperTest,GetSizeFromType)381 HWTEST_F_L0(TypedArrayHelperTest, GetSizeFromType)
382 {
383 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::INT8), 1U);
384 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::UINT8), 1U);
385 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::UINT8_CLAMPED), 1U);
386 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::INT16), 2U);
387 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::UINT16), 2U);
388 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::INT32), 4U);
389 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::UINT32), 4U);
390 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::FLOAT32), 4U);
391 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::FLOAT64), 8U);
392 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::BIGINT64), 8U);
393 EXPECT_EQ(TypedArrayHelper::GetSizeFromType(DataViewType::BIGUINT64), 8U);
394 }
395
HWTEST_F_L0(TypedArrayHelperTest,SortCompare)396 HWTEST_F_L0(TypedArrayHelperTest, SortCompare)
397 {
398 JSHandle<JSTaggedValue> uint32Array;
399 CreateArrayList(thread, uint32Array);
400 JSHandle<JSTaggedValue> buffer(thread, TypedArrayHelper::ValidateTypedArray(thread, uint32Array));
401 EXPECT_FALSE(builtins::BuiltinsArrayBuffer::IsDetachedBuffer(thread, buffer.GetTaggedValue()));
402
403 JSHandle<JSTaggedValue> callbackfnHandle(thread, JSTaggedValue::Undefined());
404 JSHandle<JSTaggedValue> nan(thread, JSTaggedValue(base::NAN_VALUE));
405 JSHandle<JSTaggedValue> eZero(thread, JSTaggedValue(-0.0));
406 JSHandle<JSTaggedValue> pZero(thread, JSTaggedValue(+0.0));
407 JSHandle<JSTaggedValue> larger(thread, JSTaggedValue(321));
408 JSHandle<JSTaggedValue> smaller(thread, JSTaggedValue(123));
409
410 // if first value and second value are both NaN, return +0.
411 int32_t result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, nan, nan);
412 EXPECT_EQ(result, +0);
413
414 // if first value is NaN, return 1.
415 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, nan, smaller);
416 EXPECT_EQ(result, 1);
417
418 // if second value is NaN, return -1.
419 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, smaller, nan);
420 EXPECT_EQ(result, -1);
421
422 // if first value is smaller than second value, return -1.
423 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, smaller, larger);
424 EXPECT_EQ(result, -1);
425
426 // if first value is larger than second value, return 1.
427 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, larger, smaller);
428 EXPECT_EQ(result, 1);
429
430 // "-0.0" sort compare with "+0.0", retrun -1
431 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, eZero, pZero);
432 EXPECT_EQ(result, -1);
433
434 // "+0.0" sort compare with "-0.0", retrun 1
435 result = TypedArrayHelper::SortCompare(thread, callbackfnHandle, buffer, pZero, eZero);
436 EXPECT_EQ(result, 1);
437 }
438
HWTEST_F_L0(TypedArrayHelperTest,FastCreateTypedArray)439 HWTEST_F_L0(TypedArrayHelperTest, FastCreateTypedArray) {
440 uint8_t first = static_cast<uint8_t>(DataViewType::BIGINT64);
441 uint8_t last = static_cast<uint8_t>(DataViewType::UINT8_CLAMPED);
442 for (uint8_t type = first; type <= last; ++type) {
443 DataViewType arrayType = static_cast<DataViewType>(type);
444 JSHandle<JSTaggedValue> constructorName = TypedArrayHelper::GetConstructorNameFromType(thread, arrayType);
445 JSHandle<JSObject> arrayObj =
446 TypedArrayHelper::FastCreateTypedArray(thread, constructorName, 0, arrayType);
447 JSTypedArray *jsTypedArray = JSTypedArray::Cast(*arrayObj);
448 if (arrayType == DataViewType::BIGINT64 ||
449 arrayType == DataViewType::BIGUINT64) {
450 EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::BigInt);
451 } else {
452 EXPECT_EQ(jsTypedArray->GetContentType(), ContentType::Number);
453 }
454 EXPECT_EQ(jsTypedArray->GetTypedArrayName(thread).GetRawData(), constructorName.GetTaggedValue().GetRawData());
455 EXPECT_EQ(jsTypedArray->GetByteLength(), 0U);
456 EXPECT_EQ(jsTypedArray->GetByteOffset(), 0U);
457 EXPECT_EQ(jsTypedArray->GetArrayLength(), 0U);
458 }
459 }
460 } // namespace panda::test
461