• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
48 class BuiltinsTypedArrayTest : public testing::Test {
49 public:
SetUpTestCase()50     static void SetUpTestCase()
51     {
52         GTEST_LOG_(INFO) << "SetUpTestCase";
53     }
54 
TearDownTestCase()55     static void TearDownTestCase()
56     {
57         GTEST_LOG_(INFO) << "TearDownCase";
58     }
59 
SetUp()60     void SetUp() override
61     {
62         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
63     }
64 
TearDown()65     void TearDown() override
66     {
67         TestHelper::DestroyEcmaVMWithScope(instance, scope);
68     }
69 
70 protected:
71     EcmaVM *instance {nullptr};
72     EcmaHandleScope *scope {nullptr};
73     JSThread *thread {nullptr};
74 
75     class TestClass : public base::BuiltinsBase {
76     public:
TestForEachFunc(EcmaRuntimeCallInfo * argv)77         static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
78         {
79             JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
80             if (key->IsUndefined()) {
81                 return JSTaggedValue::Undefined();
82             }
83             JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject());
84             uint32_t length = jsArray->GetArrayLength() + 1U;
85             jsArray->SetArrayLength(argv->GetThread(), length);
86             return JSTaggedValue::Undefined();
87         }
88 
TestEveryFunc(EcmaRuntimeCallInfo * argv)89         static JSTaggedValue TestEveryFunc(EcmaRuntimeCallInfo *argv)
90         {
91             uint32_t argc = argv->GetArgsNumber();
92             if (argc > 0) {
93                 [[maybe_unused]] int aaa = GetCallArg(argv, 0)->GetInt();
94                 //  10 : test case
95                 if (GetCallArg(argv, 0)->GetInt() > 10) {
96                     return GetTaggedBoolean(true);
97                 }
98             }
99             return GetTaggedBoolean(false);
100         }
101 
TestFilterFunc(EcmaRuntimeCallInfo * argv)102         static JSTaggedValue TestFilterFunc(EcmaRuntimeCallInfo *argv)
103         {
104             ASSERT(argv);
105             uint32_t argc = argv->GetArgsNumber();
106             if (argc > 0) {
107                 // 10 : test case
108                 if (GetCallArg(argv, 0)->GetInt() > 10) {
109                     return GetTaggedBoolean(true);
110                 }
111             }
112             return GetTaggedBoolean(false);
113         }
114 
TestMapFunc(EcmaRuntimeCallInfo * argv)115         static JSTaggedValue TestMapFunc(EcmaRuntimeCallInfo *argv)
116         {
117             int accumulator = GetCallArg(argv, 0)->GetInt();
118             accumulator = accumulator * 2; // 2 : mapped to 2 times the original value
119             return BuiltinsBase::GetTaggedInt(accumulator);
120         }
121 
TestFindFunc(EcmaRuntimeCallInfo * argv)122         static JSTaggedValue TestFindFunc(EcmaRuntimeCallInfo *argv)
123         {
124             uint32_t argc = argv->GetArgsNumber();
125             if (argc > 0) {
126                 // 10 : test case
127                 if (GetCallArg(argv, 0)->GetInt() > 10) {
128                     return GetTaggedBoolean(true);
129                 }
130             }
131             return GetTaggedBoolean(false);
132         }
133 
TestFindIndexFunc(EcmaRuntimeCallInfo * argv)134         static JSTaggedValue TestFindIndexFunc(EcmaRuntimeCallInfo *argv)
135         {
136             uint32_t argc = argv->GetArgsNumber();
137             if (argc > 0) {
138                 //  10 : test case
139                 if (GetCallArg(argv, 0)->GetInt() > 10) {
140                     return GetTaggedBoolean(true);
141                 }
142             }
143             return GetTaggedBoolean(false);
144         }
145 
TestReduceFunc(EcmaRuntimeCallInfo * argv)146         static JSTaggedValue TestReduceFunc(EcmaRuntimeCallInfo *argv)
147         {
148             int accumulator = GetCallArg(argv, 0)->GetInt();
149             accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
150             return BuiltinsBase::GetTaggedInt(accumulator);
151         }
152 
TestReduceRightFunc(EcmaRuntimeCallInfo * argv)153         static JSTaggedValue TestReduceRightFunc(EcmaRuntimeCallInfo *argv)
154         {
155             int accumulator = GetCallArg(argv, 0)->GetInt();
156             accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
157             return BuiltinsBase::GetTaggedInt(accumulator);
158         }
159 
TestSomeFunc(EcmaRuntimeCallInfo * argv)160         static JSTaggedValue TestSomeFunc(EcmaRuntimeCallInfo *argv)
161         {
162             uint32_t argc = argv->GetArgsNumber();
163             if (argc > 0) {
164                 //  10 : test case
165                 if (GetCallArg(argv, 0)->GetInt() > 10) {
166                     return GetTaggedBoolean(true);
167                 }
168             }
169             return GetTaggedBoolean(false);
170         }
171     };
172 };
173 
CreateBuiltinsTypeArrayJSObject(JSThread * thread,const CString keyCStr)174 JSTaggedValue CreateBuiltinsTypeArrayJSObject(JSThread *thread, const CString keyCStr)
175 {
176     auto ecmaVM = thread->GetEcmaVM();
177     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
178     JSHandle<JSTaggedValue> hclass = env->GetObjectFunction();
179     ObjectFactory *factory = ecmaVM->GetFactory();
180 
181     JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass), hclass));
182     JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
183     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
184     JSObject::SetProperty(thread, obj, key, value);
185     return obj.GetTaggedValue();
186 }
187 
CreateTypedArrayFromList(JSThread * thread,const JSHandle<TaggedArray> & array)188 JSTypedArray *CreateTypedArrayFromList(JSThread *thread, const JSHandle<TaggedArray> &array)
189 {
190     auto ecmaVM = thread->GetEcmaVM();
191     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
192 
193     JSHandle<JSTaggedValue> jsarray(JSArray::CreateArrayFromList(thread, array));
194     JSHandle<JSFunction> int8_array(env->GetInt8ArrayFunction());
195     JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
196     //  6 : test case
197     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*int8_array), 6);
198     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue(*int8_array));
199     ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
200     ecmaRuntimeCallInfo1->SetCallArg(0, jsarray.GetTaggedValue());
201 
202     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
203     JSTaggedValue result = TypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1);
204     TestHelper::TearDownFrame(thread, prev);
205 
206     EXPECT_TRUE(result.IsECMAObject());
207     JSTypedArray *int8arr = JSTypedArray::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
208     return int8arr;
209 }
210 
211 
HWTEST_F_L0(BuiltinsTypedArrayTest,Species)212 HWTEST_F_L0(BuiltinsTypedArrayTest, Species)
213 {
214     auto ecmaVM = thread->GetEcmaVM();
215     JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
216     JSHandle<JSFunction> array(env->GetArrayFunction());
217     JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
218 
219     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
220     ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
221     ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
222 
223     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
224     JSTaggedValue result = TypedArray::Species(ecmaRuntimeCallInfo1);
225     ASSERT_TRUE(result.IsECMAObject());
226 }
227 
HWTEST_F_L0(BuiltinsTypedArrayTest,Includes)228 HWTEST_F_L0(BuiltinsTypedArrayTest, Includes)
229 {
230     ASSERT_NE(thread, nullptr);
231     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
232     [[maybe_unused]] JSHandle<TaggedArray> array(factory->NewTaggedArray(3));
233     array->Set(thread, 0, JSTaggedValue(2));
234     array->Set(thread, 1, JSTaggedValue(3));
235     array->Set(thread, 2, JSTaggedValue(4));
236 
237     [[maybe_unused]] JSHandle<JSTaggedValue> obj =
238         JSHandle<JSTaggedValue>(thread, CreateTypedArrayFromList(thread, array));
239     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
240     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
241     ecmaRuntimeCallInfo1->SetThis(obj.GetTaggedValue());
242     ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
243 
244     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
245     [[maybe_unused]] JSTaggedValue result = TypedArray::Includes(ecmaRuntimeCallInfo1);
246     TestHelper::TearDownFrame(thread, prev);
247 
248     ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2)
249 
250     auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
251     ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
252     ecmaRuntimeCallInfo2->SetThis(obj.GetTaggedValue());
253     ecmaRuntimeCallInfo2->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(1)));
254 
255     prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
256     result = TypedArray::Includes(ecmaRuntimeCallInfo2);
257     TestHelper::TearDownFrame(thread, prev);
258 
259     ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(1)
260 
261     auto ecmaRuntimeCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
262     ecmaRuntimeCallInfo3->SetFunction(JSTaggedValue::Undefined());
263     ecmaRuntimeCallInfo3->SetThis(obj.GetTaggedValue());
264     ecmaRuntimeCallInfo3->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(3)));
265     ecmaRuntimeCallInfo3->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
266 
267     prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo3);
268     result = TypedArray::Includes(ecmaRuntimeCallInfo3);
269     TestHelper::TearDownFrame(thread, prev);
270 
271     ASSERT_TRUE(result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(3, 1)
272 
273     auto ecmaRuntimeCallInfo4 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
274     ecmaRuntimeCallInfo4->SetFunction(JSTaggedValue::Undefined());
275     ecmaRuntimeCallInfo4->SetThis(obj.GetTaggedValue());
276     ecmaRuntimeCallInfo4->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
277     ecmaRuntimeCallInfo4->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(5)));
278 
279     prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo4);
280     result = Array::Includes(ecmaRuntimeCallInfo4);
281     TestHelper::TearDownFrame(thread, prev);
282 
283     ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, 5)
284 
285     auto ecmaRuntimeCallInfo5 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
286     ecmaRuntimeCallInfo5->SetFunction(JSTaggedValue::Undefined());
287     ecmaRuntimeCallInfo5->SetThis(obj.GetTaggedValue());
288     ecmaRuntimeCallInfo5->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(2)));
289     ecmaRuntimeCallInfo5->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(-2)));
290 
291     prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo5);
292     result = Array::Includes(ecmaRuntimeCallInfo5);
293     TestHelper::TearDownFrame(thread, prev);
294 
295     ASSERT_TRUE(!result.JSTaggedValue::ToBoolean()); // new Int8Array[2,3,4].includes(2, -2)
296 }
297 }  // namespace panda::test
298