1 /*
2 * Copyright (c) 2021 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/builtins/builtins_typedarray.h"
17
18 #include "ecmascript/base/typed_array_helper-inl.h"
19 #include "ecmascript/base/typed_array_helper.h"
20 #include "ecmascript/builtins/builtins_array.h"
21 #include "ecmascript/builtins/builtins_object.h"
22 #include "ecmascript/ecma_runtime_call_info.h"
23 #include "ecmascript/ecma_string.h"
24 #include "ecmascript/ecma_vm.h"
25 #include "ecmascript/global_env.h"
26 #include "ecmascript/js_array.h"
27 #include "ecmascript/js_array_iterator.h"
28 #include "ecmascript/js_handle.h"
29 #include "ecmascript/js_hclass.h"
30 #include "ecmascript/js_object-inl.h"
31 #include "ecmascript/js_tagged_value-inl.h"
32 #include "ecmascript/js_tagged_value.h"
33 #include "ecmascript/js_thread.h"
34 #include "ecmascript/js_typed_array.h"
35 #include "ecmascript/object_factory.h"
36 #include "ecmascript/object_operator.h"
37 #include "ecmascript/tests/test_helper.h"
38
39 using namespace panda::ecmascript;
40 using namespace panda::ecmascript::builtins;
41 using namespace panda::ecmascript::base;
42
43 namespace panda::test {
44 using Array = ecmascript::builtins::BuiltinsArray;
45 using TypedArray = ecmascript::builtins::BuiltinsTypedArray;
46 using TypedArrayHelper = ecmascript::base::TypedArrayHelper;
47 constexpr uint32_t ECMA_RUNTIME_CALL_INFO_4 = 4;
48 constexpr uint32_t ECMA_RUNTIME_CALL_INFO_6 = 6;
49
50 enum class TypeArrayIndex {
51 TYPED_ARRAY_INDEX_0,
52 TYPED_ARRAY_INDEX_1,
53 TYPED_ARRAY_INDEX_2,
54 TYPED_ARRAY_INDEX_3
55 };
56 constexpr uint32_t TYPED_ARRAY_LENGTH_3 = 3;
57 constexpr int32_t INT_VALUE_0 = 0;
58 constexpr int32_t INT_VALUE_2 = 2;
59 constexpr int32_t INT_VALUE_4 = 4;
60 constexpr int32_t INT_VALUE_9 = 9;
61
62 class BuiltinsTypedArrayTest : public testing::Test {
63 public:
SetUpTestCase()64 static void SetUpTestCase()
65 {
66 GTEST_LOG_(INFO) << "SetUpTestCase";
67 }
68
TearDownTestCase()69 static void TearDownTestCase()
70 {
71 GTEST_LOG_(INFO) << "TearDownCase";
72 }
73
SetUp()74 void SetUp() override
75 {
76 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
77 }
78
TearDown()79 void TearDown() override
80 {
81 TestHelper::DestroyEcmaVMWithScope(instance, scope);
82 }
83
84 protected:
85 EcmaVM *instance {nullptr};
86 EcmaHandleScope *scope {nullptr};
87 JSThread *thread {nullptr};
88
89 class TestClass : public base::BuiltinsBase {
90 public:
TestForEachFunc(EcmaRuntimeCallInfo * argv)91 static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
92 {
93 JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
94 if (key->IsUndefined()) {
95 return JSTaggedValue::Undefined();
96 }
97 JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject());
98 uint32_t length = jsArray->GetArrayLength() + 1U;
99 jsArray->SetArrayLength(argv->GetThread(), length);
100 return JSTaggedValue::Undefined();
101 }
102
TestEveryFunc(EcmaRuntimeCallInfo * argv)103 static JSTaggedValue TestEveryFunc(EcmaRuntimeCallInfo *argv)
104 {
105 uint32_t argc = argv->GetArgsNumber();
106 if (argc > 0) {
107 [[maybe_unused]] int aaa = GetCallArg(argv, 0)->GetInt();
108 // 10 : test case
109 if (GetCallArg(argv, 0)->GetInt() > 10) {
110 return GetTaggedBoolean(true);
111 }
112 }
113 return GetTaggedBoolean(false);
114 }
115
TestFilterFunc(EcmaRuntimeCallInfo * argv)116 static JSTaggedValue TestFilterFunc(EcmaRuntimeCallInfo *argv)
117 {
118 ASSERT(argv);
119 uint32_t argc = argv->GetArgsNumber();
120 if (argc > 0) {
121 // 10 : test case
122 if (GetCallArg(argv, 0)->GetInt() > 10) {
123 return GetTaggedBoolean(true);
124 }
125 }
126 return GetTaggedBoolean(false);
127 }
128
TestMapFunc(EcmaRuntimeCallInfo * argv)129 static JSTaggedValue TestMapFunc(EcmaRuntimeCallInfo *argv)
130 {
131 int accumulator = GetCallArg(argv, 0)->GetInt();
132 accumulator = accumulator * 2; // 2 : mapped to 2 times the original value
133 return BuiltinsBase::GetTaggedInt(accumulator);
134 }
135
TestFindFunc(EcmaRuntimeCallInfo * argv)136 static JSTaggedValue TestFindFunc(EcmaRuntimeCallInfo *argv)
137 {
138 uint32_t argc = argv->GetArgsNumber();
139 if (argc > 0) {
140 // 10 : test case
141 if (GetCallArg(argv, 0)->GetInt() > 10) {
142 return GetTaggedBoolean(true);
143 }
144 }
145 return GetTaggedBoolean(false);
146 }
147
TestFindIndexFunc(EcmaRuntimeCallInfo * argv)148 static JSTaggedValue TestFindIndexFunc(EcmaRuntimeCallInfo *argv)
149 {
150 uint32_t argc = argv->GetArgsNumber();
151 if (argc > 0) {
152 // 10 : test case
153 if (GetCallArg(argv, 0)->GetInt() > 10) {
154 return GetTaggedBoolean(true);
155 }
156 }
157 return GetTaggedBoolean(false);
158 }
159
TestToSortedFunc(EcmaRuntimeCallInfo * argv)160 static JSTaggedValue TestToSortedFunc(EcmaRuntimeCallInfo *argv)
161 {
162 uint32_t argc = argv->GetArgsNumber();
163 if (argc > 1) {
164 // x < y
165 if (GetCallArg(argv, 0)->GetInt() < GetCallArg(argv, 1)->GetInt()) {
166 return GetTaggedBoolean(true);
167 }
168 }
169 return GetTaggedBoolean(false);
170 }
171
TestFindLastFunc(EcmaRuntimeCallInfo * argv)172 static JSTaggedValue TestFindLastFunc(EcmaRuntimeCallInfo *argv)
173 {
174 uint32_t argc = argv->GetArgsNumber();
175 if (argc > 0) {
176 // 20 : test case
177 if (GetCallArg(argv, 0)->GetInt() > 20) {
178 return GetTaggedBoolean(true);
179 }
180 }
181 return GetTaggedBoolean(false);
182 }
183
TestFindLastIndexFunc(EcmaRuntimeCallInfo * argv)184 static JSTaggedValue TestFindLastIndexFunc(EcmaRuntimeCallInfo *argv)
185 {
186 uint32_t argc = argv->GetArgsNumber();
187 if (argc > 0) {
188 // 20 : test case
189 if (GetCallArg(argv, 0)->GetInt() > 20) {
190 return GetTaggedBoolean(true);
191 }
192 }
193 return GetTaggedBoolean(false);
194 }
195
TestReduceFunc(EcmaRuntimeCallInfo * argv)196 static JSTaggedValue TestReduceFunc(EcmaRuntimeCallInfo *argv)
197 {
198 int accumulator = GetCallArg(argv, 0)->GetInt();
199 accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
200 return BuiltinsBase::GetTaggedInt(accumulator);
201 }
202
TestReduceRightFunc(EcmaRuntimeCallInfo * argv)203 static JSTaggedValue TestReduceRightFunc(EcmaRuntimeCallInfo *argv)
204 {
205 int accumulator = GetCallArg(argv, 0)->GetInt();
206 accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
207 return BuiltinsBase::GetTaggedInt(accumulator);
208 }
209
TestSomeFunc(EcmaRuntimeCallInfo * argv)210 static JSTaggedValue TestSomeFunc(EcmaRuntimeCallInfo *argv)
211 {
212 uint32_t argc = argv->GetArgsNumber();
213 if (argc > 0) {
214 // 10 : test case
215 if (GetCallArg(argv, 0)->GetInt() > 10) {
216 return GetTaggedBoolean(true);
217 }
218 }
219 return GetTaggedBoolean(false);
220 }
221 };
222 };
223
CreateBuiltinsTypeArrayJSObject(JSThread * thread,const CString keyCStr)224 JSTaggedValue CreateBuiltinsTypeArrayJSObject(JSThread *thread, const CString keyCStr)
225 {
226 auto ecmaVM = thread->GetEcmaVM();
227 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
228 JSHandle<JSTaggedValue> hclass = env->GetObjectFunction();
229 ObjectFactory *factory = ecmaVM->GetFactory();
230
231 JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
232 JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
233 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
234 JSObject::SetProperty(thread, obj, key, value);
235 return obj.GetTaggedValue();
236 }
237
CreateTypedArrayFromList(JSThread * thread,const JSHandle<TaggedArray> & array)238 JSTypedArray *CreateTypedArrayFromList(JSThread *thread, const JSHandle<TaggedArray> &array)
239 {
240 auto ecmaVM = thread->GetEcmaVM();
241 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
242
243 JSHandle<JSTaggedValue> jsarray(JSArray::CreateArrayFromList(thread, array));
244 JSHandle<JSFunction> int8_array(env->GetInt8ArrayFunction());
245 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
246 // 6 : test case
247 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*int8_array), 6);
248 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue(*int8_array));
249 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
250 ecmaRuntimeCallInfo1->SetCallArg(0, jsarray.GetTaggedValue());
251
252 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
253 JSTaggedValue result = TypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1);
254 TestHelper::TearDownFrame(thread, prev);
255
256 EXPECT_TRUE(result.IsECMAObject());
257 JSTypedArray *int8arr = JSTypedArray::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
258 return int8arr;
259 }
260
261
HWTEST_F_L0(BuiltinsTypedArrayTest,Species)262 HWTEST_F_L0(BuiltinsTypedArrayTest, Species)
263 {
264 auto ecmaVM = thread->GetEcmaVM();
265 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
266 JSHandle<JSFunction> array(env->GetArrayFunction());
267 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
268
269 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
270 ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
271 ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
272
273 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
274 JSTaggedValue result = TypedArray::Species(ecmaRuntimeCallInfo1);
275 ASSERT_TRUE(result.IsECMAObject());
276 }
277
HWTEST_F_L0(BuiltinsTypedArrayTest,Includes)278 HWTEST_F_L0(BuiltinsTypedArrayTest, Includes)
279 {
280 ASSERT_NE(thread, nullptr);
281 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
282 [[maybe_unused]] JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
283 array->Set(thread, 0, JSTaggedValue(2));
284 array->Set(thread, 1, JSTaggedValue(3));
285 array->Set(thread, 2, JSTaggedValue(4));
286
287 [[maybe_unused]] JSHandle<JSTaggedValue> obj =
288 JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
289 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
290 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
291 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
292 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
293
294 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
295 [[maybe_unused]] JSTaggedValue result = TypedArray::Includes(ecmaRuntimeCallInfo1);
296 TestHelper::TearDownFrame(thread, prev);
297
298 ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2)
299
300 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
301 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
302 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
303 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
304
305 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
306 result = TypedArray::Includes(ecmaRuntimeCallInfo2);
307 TestHelper::TearDownFrame(thread, prev);
308
309 ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(1)
310
311 auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
312 ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
313 ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue());
314 ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(3)));
315 ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
316
317 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
318 result = TypedArray::Includes(ecmaRuntimeCallInfo3);
319 TestHelper::TearDownFrame(thread, prev);
320
321 ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(3, 1)
322
323 auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
324 ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined());
325 ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue());
326 ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
327 ecmaRuntimeCallInfo4->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
328
329 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
330 result = Array::Includes(ecmaRuntimeCallInfo4);
331 TestHelper::TearDownFrame(thread, prev);
332
333 ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, 5)
334
335 auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
336 ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined());
337 ecmaRuntimeCallInfo5->SetThis(obj.GetTaggedValue());
338 ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
339 ecmaRuntimeCallInfo5->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(-2)));
340
341 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
342 result = Array::Includes(ecmaRuntimeCallInfo5);
343 TestHelper::TearDownFrame(thread, prev);
344
345 ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, -2)
346 }
347
HWTEST_F_L0(BuiltinsTypedArrayTest,At)348 HWTEST_F_L0(BuiltinsTypedArrayTest, At)
349 {
350 ASSERT_NE(thread, nullptr);
351 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
352 [[maybe_unused]] JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
353 array->Set(thread, 0, JSTaggedValue(2));
354 array->Set(thread, 1, JSTaggedValue(3));
355 array->Set(thread, 2, JSTaggedValue(4));
356
357 [[maybe_unused]] JSHandle<JSTaggedValue> obj =
358 JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
359 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
360 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
361 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
362 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
363
364 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
365 [[maybe_unused]] JSTaggedValue result = TypedArray::At(ecmaRuntimeCallInfo1);
366 TestHelper::TearDownFrame(thread, prev);
367
368 ASSERT_EQ(result, JSTaggedValue(4));
369
370 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
371 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
372 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
373 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-2)));
374
375 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
376 result = TypedArray::At(ecmaRuntimeCallInfo2);
377 TestHelper::TearDownFrame(thread, prev);
378
379 ASSERT_EQ(result, JSTaggedValue(3));
380
381 auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
382 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
383 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
384 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-4)));
385
386 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
387 result = TypedArray::At(ecmaRuntimeCallInfo3);
388 TestHelper::TearDownFrame(thread, prev);
389
390 ASSERT_TRUE(result.IsUndefined());
391
392 auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
393 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
394 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
395 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(3)));
396
397 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
398 result = TypedArray::At(ecmaRuntimeCallInfo4);
399 TestHelper::TearDownFrame(thread, prev);
400
401 ASSERT_TRUE(result.IsUndefined());
402 }
403
HWTEST_F_L0(BuiltinsTypedArrayTest,ToReversed)404 HWTEST_F_L0(BuiltinsTypedArrayTest, ToReversed)
405 {
406 ASSERT_NE(thread, nullptr);
407 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
408 [[maybe_unused]] JSHandle<TaggedArray> array(factory->NewTaggedArray(TYPED_ARRAY_LENGTH_3));
409 array->Set(thread, static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_0), JSTaggedValue(INT_VALUE_0));
410 array->Set(thread, static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_1), JSTaggedValue(INT_VALUE_4));
411 array->Set(thread, static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_2), JSTaggedValue(INT_VALUE_9));
412
413 [[maybe_unused]] JSHandle<JSTaggedValue> obj =
414 JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
415 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(),
416 ECMA_RUNTIME_CALL_INFO_4);
417 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
418 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
419
420 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
421 [[maybe_unused]] JSTaggedValue result = TypedArray::ToReversed(ecmaRuntimeCallInfo1);
422 TestHelper::TearDownFrame(thread, prev);
423
424 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread,
425 JSTaggedValue::Undefined(),
426 ECMA_RUNTIME_CALL_INFO_6);
427 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
428 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
429 ecmaRuntimeCallInfo2->SetCallArg(static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_0),
430 JSTaggedValue(INT_VALUE_0));
431 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
432 JSTaggedValue value = TypedArray::At(ecmaRuntimeCallInfo2);
433 TestHelper::TearDownFrame(thread, prev);
434 ASSERT_EQ(value, JSTaggedValue(INT_VALUE_0));
435
436 auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread,
437 JSTaggedValue::Undefined(),
438 ECMA_RUNTIME_CALL_INFO_6);
439 ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
440 ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue());
441 ecmaRuntimeCallInfo3->SetCallArg(static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_0),
442 JSTaggedValue(INT_VALUE_2));
443 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
444 value = TypedArray::At(ecmaRuntimeCallInfo3);
445 TestHelper::TearDownFrame(thread, prev);
446 ASSERT_EQ(value, JSTaggedValue(INT_VALUE_9));
447
448 auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread,
449 JSTaggedValue::Undefined(),
450 ECMA_RUNTIME_CALL_INFO_6);
451 ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined());
452 ecmaRuntimeCallInfo4->SetThis(result);
453 ecmaRuntimeCallInfo4->SetCallArg(static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_0),
454 JSTaggedValue(INT_VALUE_0));
455 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
456 value = TypedArray::At(ecmaRuntimeCallInfo4);
457 TestHelper::TearDownFrame(thread, prev);
458 ASSERT_EQ(value, JSTaggedValue(INT_VALUE_9));
459 auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread,
460 JSTaggedValue::Undefined(),
461 ECMA_RUNTIME_CALL_INFO_6);
462 ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined());
463 ecmaRuntimeCallInfo5->SetThis(result);
464 ecmaRuntimeCallInfo5->SetCallArg(static_cast<uint32_t>(TypeArrayIndex::TYPED_ARRAY_INDEX_0),
465 JSTaggedValue(INT_VALUE_2));
466 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
467 value = TypedArray::At(ecmaRuntimeCallInfo5);
468 TestHelper::TearDownFrame(thread, prev);
469 ASSERT_EQ(value, JSTaggedValue(INT_VALUE_0));
470 }
471
HWTEST_F_L0(BuiltinsTypedArrayTest,ToSorted)472 HWTEST_F_L0(BuiltinsTypedArrayTest, ToSorted)
473 {
474 ASSERT_NE(thread, nullptr);
475 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
476 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
477 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
478 // array [10, 8, 30]
479 array->Set(thread, 0, JSTaggedValue(10));
480 array->Set(thread, 1, JSTaggedValue(8));
481 array->Set(thread, 2, JSTaggedValue(30));
482
483 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
484 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestToSortedFunc));
485 auto ecmaRuntimeCallInfo1 =
486 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg
487 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
488 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
489 ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
490
491 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
492 JSTaggedValue result1 = TypedArray::ToSorted(ecmaRuntimeCallInfo1);
493 TestHelper::TearDownFrame(thread, prev1);
494
495 EXPECT_TRUE(result1.IsTypedArray());
496 JSHandle<JSTaggedValue> resultArr1 = JSHandle<JSTaggedValue>(thread, result1);
497 // [30, 10, 8]
498 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 0).GetValue()->GetInt(), 30);
499 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 1).GetValue()->GetInt(), 10);
500 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 2).GetValue()->GetInt(), 8);
501
502 auto ecmaRuntimeCallInfo2 =
503 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means 0 call arg
504 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
505 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
506
507 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
508 JSTaggedValue result2 = TypedArray::ToSorted(ecmaRuntimeCallInfo2);
509 TestHelper::TearDownFrame(thread, prev2);
510
511 EXPECT_TRUE(result2.IsTypedArray());
512 JSHandle<JSTaggedValue> resultArr2 = JSHandle<JSTaggedValue>(thread, result2);
513 // [8, 10 ,30]
514 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 0).GetValue()->GetInt(), 8);
515 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 1).GetValue()->GetInt(), 10);
516 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 2).GetValue()->GetInt(), 30);
517 }
518
HWTEST_F_L0(BuiltinsTypedArrayTest,With)519 HWTEST_F_L0(BuiltinsTypedArrayTest, With)
520 {
521 ASSERT_NE(thread, nullptr);
522 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
523 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
524 // array [1, 2, 3]
525 array->Set(thread, 0, JSTaggedValue(1));
526 array->Set(thread, 1, JSTaggedValue(2));
527 array->Set(thread, 2, JSTaggedValue(3));
528
529 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
530 auto ecmaRuntimeCallInfo1 =
531 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means 2 call args
532 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
533 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
534 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(-1)));
535 ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(30))); // with(-1, 30)
536
537 [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
538 JSTaggedValue result1 = TypedArray::With(ecmaRuntimeCallInfo1);
539 TestHelper::TearDownFrame(thread, prev1);
540
541 EXPECT_TRUE(result1.IsTypedArray());
542 JSHandle<JSTaggedValue> resultArr1 = JSHandle<JSTaggedValue>(thread, result1);
543 // [1, 2, 30]
544 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 0).GetValue()->GetInt(), 1);
545 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 1).GetValue()->GetInt(), 2);
546 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr1, 2).GetValue()->GetInt(), 30);
547
548 auto ecmaRuntimeCallInfo2 =
549 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8); // 8 means 2 call args
550 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
551 ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
552 ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
553 ecmaRuntimeCallInfo2->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(-100))); // with(1, -100)
554
555 [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
556 JSTaggedValue result2 = TypedArray::With(ecmaRuntimeCallInfo2);
557 TestHelper::TearDownFrame(thread, prev2);
558
559 EXPECT_TRUE(result2.IsTypedArray());
560 JSHandle<JSTaggedValue> resultArr2 = JSHandle<JSTaggedValue>(thread, result2);
561 // [1, -100, 3]
562 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 0).GetValue()->GetInt(), 1);
563 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 1).GetValue()->GetInt(), -100);
564 EXPECT_EQ(JSTypedArray::GetProperty(thread, resultArr2, 2).GetValue()->GetInt(), 3);
565 }
566
HWTEST_F_L0(BuiltinsTypedArrayTest,FindLast)567 HWTEST_F_L0(BuiltinsTypedArrayTest, FindLast)
568 {
569 ASSERT_NE(thread, nullptr);
570 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
571 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
572 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
573 // array [50, 40, 2]
574 array->Set(thread, 0, JSTaggedValue(50));
575 array->Set(thread, 1, JSTaggedValue(40));
576 array->Set(thread, 2, JSTaggedValue(2));
577
578 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
579 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindLastFunc));
580 auto ecmaRuntimeCallInfo1 =
581 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg
582 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
583 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
584 ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
585
586 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
587 JSTaggedValue result = TypedArray::FindLast(ecmaRuntimeCallInfo1);
588 TestHelper::TearDownFrame(thread, prev);
589
590 EXPECT_EQ(result.GetRawData(), JSTaggedValue(40).GetRawData());
591 }
592
HWTEST_F_L0(BuiltinsTypedArrayTest,FindLastIndex)593 HWTEST_F_L0(BuiltinsTypedArrayTest, FindLastIndex)
594 {
595 ASSERT_NE(thread, nullptr);
596 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
597 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
598 JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
599 // array [50, 40, 30]
600 array->Set(thread, 0, JSTaggedValue(50));
601 array->Set(thread, 1, JSTaggedValue(40));
602 array->Set(thread, 2, JSTaggedValue(30));
603
604 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
605 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestClass::TestFindLastFunc));
606 auto ecmaRuntimeCallInfo1 =
607 TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg
608 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
609 ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
610 ecmaRuntimeCallInfo1->SetCallArg(0, func.GetTaggedValue());
611
612 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
613 JSTaggedValue result = TypedArray::FindLastIndex(ecmaRuntimeCallInfo1);
614 TestHelper::TearDownFrame(thread, prev);
615
616 EXPECT_EQ(result.GetRawData(), JSTaggedValue(static_cast<double>(2)).GetRawData());
617 }
618 } // namespace panda::test
619