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/base/typed_array_helper-inl.h"
17 #include "ecmascript/base/typed_array_helper.h"
18
19 #include "ecmascript/builtins/builtins_array.h"
20 #include "ecmascript/builtins/builtins_object.h"
21 #include "ecmascript/builtins/builtins_typedarray.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
38 #include "ecmascript/tests/test_helper.h"
39 #include "utils/bit_utils.h"
40
41 using namespace panda::ecmascript;
42 using namespace panda::ecmascript::builtins;
43 using namespace panda::ecmascript::base;
44
45 namespace panda::test {
46 using Array = ecmascript::builtins::BuiltinsArray;
47 using TypedArray = ecmascript::builtins::BuiltinsTypedArray;
48 using TypedArrayHelper = ecmascript::base::TypedArrayHelper;
49
50 class BuiltinsTypedArrayTest : public testing::Test {
51 public:
SetUpTestCase()52 static void SetUpTestCase()
53 {
54 GTEST_LOG_(INFO) << "SetUpTestCase";
55 }
56
TearDownTestCase()57 static void TearDownTestCase()
58 {
59 GTEST_LOG_(INFO) << "TearDownCase";
60 }
61
SetUp()62 void SetUp() override
63 {
64 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
65 }
66
TearDown()67 void TearDown() override
68 {
69 TestHelper::DestroyEcmaVMWithScope(instance, scope);
70 }
71
72 protected:
73 PandaVM *instance {nullptr};
74 EcmaHandleScope *scope {nullptr};
75 JSThread *thread {nullptr};
76
77 class TestClass : public base::BuiltinsBase {
78 public:
TestForEachFunc(EcmaRuntimeCallInfo * argv)79 static JSTaggedValue TestForEachFunc(EcmaRuntimeCallInfo *argv)
80 {
81 JSHandle<JSTaggedValue> key = GetCallArg(argv, 0);
82 if (key->IsUndefined()) {
83 return JSTaggedValue::Undefined();
84 }
85 JSArray *jsArray = JSArray::Cast(GetThis(argv)->GetTaggedObject());
86 int length = jsArray->GetArrayLength() + 1;
87 jsArray->SetArrayLength(argv->GetThread(), length);
88 return JSTaggedValue::Undefined();
89 }
90
TestEveryFunc(EcmaRuntimeCallInfo * argv)91 static JSTaggedValue TestEveryFunc(EcmaRuntimeCallInfo *argv)
92 {
93 uint32_t argc = argv->GetArgsNumber();
94 if (argc > 0) {
95 [[maybe_unused]] int aaa = GetCallArg(argv, 0)->GetInt();
96 // 10 : test case
97 if (GetCallArg(argv, 0)->GetInt() > 10) {
98 return GetTaggedBoolean(true);
99 }
100 }
101 return GetTaggedBoolean(false);
102 }
103
TestFilterFunc(EcmaRuntimeCallInfo * argv)104 static JSTaggedValue TestFilterFunc(EcmaRuntimeCallInfo *argv)
105 {
106 ASSERT(argv);
107 uint32_t argc = argv->GetArgsNumber();
108 if (argc > 0) {
109 // 10 : test case
110 if (GetCallArg(argv, 0)->GetInt() > 10) {
111 return GetTaggedBoolean(true);
112 }
113 }
114 return GetTaggedBoolean(false);
115 }
116
TestMapFunc(EcmaRuntimeCallInfo * argv)117 static JSTaggedValue TestMapFunc(EcmaRuntimeCallInfo *argv)
118 {
119 int accumulator = GetCallArg(argv, 0)->GetInt();
120 accumulator = accumulator * 2; // 2 : mapped to 2 times the original value
121 return BuiltinsBase::GetTaggedInt(accumulator);
122 }
123
TestFindFunc(EcmaRuntimeCallInfo * argv)124 static JSTaggedValue TestFindFunc(EcmaRuntimeCallInfo *argv)
125 {
126 uint32_t argc = argv->GetArgsNumber();
127 if (argc > 0) {
128 // 10 : test case
129 if (GetCallArg(argv, 0)->GetInt() > 10) {
130 return GetTaggedBoolean(true);
131 }
132 }
133 return GetTaggedBoolean(false);
134 }
135
TestFindIndexFunc(EcmaRuntimeCallInfo * argv)136 static JSTaggedValue TestFindIndexFunc(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
TestReduceFunc(EcmaRuntimeCallInfo * argv)148 static JSTaggedValue TestReduceFunc(EcmaRuntimeCallInfo *argv)
149 {
150 int accumulator = GetCallArg(argv, 0)->GetInt();
151 accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
152 return BuiltinsBase::GetTaggedInt(accumulator);
153 }
154
TestReduceRightFunc(EcmaRuntimeCallInfo * argv)155 static JSTaggedValue TestReduceRightFunc(EcmaRuntimeCallInfo *argv)
156 {
157 int accumulator = GetCallArg(argv, 0)->GetInt();
158 accumulator = accumulator + GetCallArg(argv, 1)->GetInt();
159 return BuiltinsBase::GetTaggedInt(accumulator);
160 }
161
TestSomeFunc(EcmaRuntimeCallInfo * argv)162 static JSTaggedValue TestSomeFunc(EcmaRuntimeCallInfo *argv)
163 {
164 uint32_t argc = argv->GetArgsNumber();
165 if (argc > 0) {
166 // 10 : test case
167 if (GetCallArg(argv, 0)->GetInt() > 10) {
168 return GetTaggedBoolean(true);
169 }
170 }
171 return GetTaggedBoolean(false);
172 }
173 };
174 };
175
CreateBuiltinsJSObject(JSThread * thread,const CString keyCStr)176 JSTaggedValue CreateBuiltinsJSObject(JSThread *thread, const CString keyCStr)
177 {
178 auto ecmaVM = thread->GetEcmaVM();
179 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
180 JSHandle<JSTaggedValue> dynclass = env->GetObjectFunction();
181 ObjectFactory *factory = ecmaVM->GetFactory();
182
183 JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(dynclass), dynclass));
184 JSHandle<JSTaggedValue> key(factory->NewFromCanBeCompressString(&keyCStr[0]));
185 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
186 JSObject::SetProperty(thread, obj, key, value);
187 return obj.GetTaggedValue();
188 }
189
CreateTypedArrayFromList(JSThread * thread,const JSHandle<TaggedArray> & array)190 JSTypedArray *CreateTypedArrayFromList(JSThread *thread, const JSHandle<TaggedArray> &array)
191 {
192 auto ecmaVM = thread->GetEcmaVM();
193 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
194
195 JSHandle<JSTaggedValue> jsarray(JSArray::CreateArrayFromList(thread, array));
196 JSHandle<JSFunction> int8_array(env->GetInt8ArrayFunction());
197 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
198 // 6 : test case
199 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
200 ecmaRuntimeCallInfo1->SetNewTarget(JSTaggedValue(*int8_array));
201 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(*globalObject));
202 ecmaRuntimeCallInfo1->SetCallArg(0, jsarray.GetTaggedValue());
203
204 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
205 JSTaggedValue result = TypedArray::Int8ArrayConstructor(ecmaRuntimeCallInfo1.get());
206
207 EXPECT_TRUE(result.IsECMAObject());
208 JSTypedArray *int8arr = JSTypedArray::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
209 return int8arr;
210 }
211
212
HWTEST_F_L0(BuiltinsTypedArrayTest,Species)213 HWTEST_F_L0(BuiltinsTypedArrayTest, Species)
214 {
215 auto ecmaVM = thread->GetEcmaVM();
216 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
217 JSHandle<JSFunction> array(env->GetArrayFunction());
218 JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
219
220 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
221 ecmaRuntimeCallInfo1->SetFunction(array.GetTaggedValue());
222 ecmaRuntimeCallInfo1->SetThis(globalObject.GetTaggedValue());
223
224 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
225 JSTaggedValue result = TypedArray::Species(ecmaRuntimeCallInfo1.get());
226 ASSERT_TRUE(result.IsECMAObject());
227 }
228 } // namespace panda::test