• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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/ecma_string.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/shared_objects/js_shared_array.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/object_factory.h"
22 #include "ecmascript/tests/test_helper.h"
23 
24 using namespace panda;
25 
26 using namespace panda::ecmascript;
27 
28 namespace panda::test {
29 class JSSharedArrayTest : public BaseTestWithScope<false> {
30 };
31 
HWTEST_F_L0(JSSharedArrayTest,SetCapacityTest001)32 HWTEST_F_L0(JSSharedArrayTest, SetCapacityTest001)
33 {
34     JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
35     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(0))
36                                                  .GetTaggedValue()
37                                                  .GetTaggedObject());
38     EXPECT_TRUE(arr != nullptr);
39     JSHandle<JSTaggedValue> obj(thread, arr);
40     EXPECT_EQ(JSSharedArray::GetProperty(thread, obj, lengthKeyHandle, SCheckMode::SKIP).GetValue()->GetInt(), 0);
41 
42     auto ecmaVM = thread->GetEcmaVM();
43     ObjectFactory *factory = ecmaVM->GetFactory();
44     JSHandle<TaggedArray> values(factory->NewTaggedArray(5));
45     for (int i = 0; i < 5; i++)
46     {
47         values->Set(thread, i, JSTaggedValue(i + 1));
48     }
49     JSHandle<TaggedArray> result(JSSharedArray::SetCapacity(thread, values, 10U));
50     JSHandle<JSSharedArray> sharedArray(JSSharedArray::CreateArrayFromList(thread, result));
51     EXPECT_EQ(sharedArray->GetArrayLength(), 10U);
52 }
53 
HWTEST_F_L0(JSSharedArrayTest,SetCapacityTest002)54 HWTEST_F_L0(JSSharedArrayTest, SetCapacityTest002)
55 {
56     JSSharedArray *sharedArray = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(5))
57                                                          .GetTaggedValue()
58                                                          .GetTaggedObject());
59     EXPECT_TRUE(sharedArray != nullptr);
60     JSHandle<JSObject> obj(thread, sharedArray);
61     JSSharedArray::SetCapacity(thread, obj, 5U, 10U);
62     EXPECT_EQ(sharedArray->GetArrayLength(), 10U);
63 }
64 
HWTEST_F_L0(JSSharedArrayTest,SetCapacityTest003)65 HWTEST_F_L0(JSSharedArrayTest, SetCapacityTest003)
66 {
67     JSSharedArray *sharedArray = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(5))
68                                                          .GetTaggedValue()
69                                                          .GetTaggedObject());
70     EXPECT_TRUE(sharedArray != nullptr);
71     JSHandle<JSObject> obj(thread, sharedArray);
72     JSSharedArray::SetCapacity(thread, obj, 10U, 5U);
73     EXPECT_EQ(sharedArray->GetArrayLength(), 5U);
74 }
75 
HWTEST_F_L0(JSSharedArrayTest,PropertyKeyToArrayIndex)76 HWTEST_F_L0(JSSharedArrayTest, PropertyKeyToArrayIndex)
77 {
78     auto ecmaVM = thread->GetEcmaVM();
79     ObjectFactory *factory = ecmaVM->GetFactory();
80     JSHandle<TaggedArray> values(factory->NewTaggedArray(5));
81     for (int i = 0; i < 5; i++)
82     {
83         values->Set(thread, i, JSTaggedValue(i + 1));
84     }
85     JSHandle<JSTaggedValue> key(thread, JSTaggedValue(5));
86     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(-1));
87     uint32_t output = 5;
88     ASSERT_TRUE(JSSharedArray::PropertyKeyToArrayIndex(thread, key, &output));
89     ASSERT_FALSE(JSSharedArray::PropertyKeyToArrayIndex(thread, key1, &output));
90 }
91 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLength)92 HWTEST_F_L0(JSSharedArrayTest, ArraySetLength)
93 {
94     JSHandle<JSTaggedValue> lengthKeyHandle = thread->GlobalConstants()->GetHandledLengthString();
95     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(1))
96                                                  .GetTaggedValue()
97                                                  .GetTaggedObject());
98     EXPECT_TRUE(arr != nullptr);
99     JSHandle<JSObject> obj(thread, arr);
100     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), true, true, true);
101     ASSERT_FALSE(JSSharedArray::ArraySetLength(thread, obj, desc1));
102     EXPECT_EQ(JSSharedArray::GetProperty(thread, JSHandle<JSTaggedValue>(obj), lengthKeyHandle, SCheckMode::SKIP)
103                   .GetValue()
104                   ->GetInt(),
105               1);
106 
107     std::vector<int> vals{1, 2, 3, 4, 5};
108     std::vector<JSHandle<JSTaggedValue>> keys;
109     for (size_t i = 0; i < vals.size(); i++)
110     {
111         keys.push_back(JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(i))));
112         PropertyDescriptor desc0(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(vals[i])), true, true, true);
113         EXPECT_TRUE(desc0.IsWritable());
114         JSSharedArray::DefineOwnProperty(thread, obj, keys[i], desc0);
115     }
116     PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(6)), true, true, true);
117     EXPECT_TRUE(desc1.IsWritable());
118     ASSERT_FALSE(JSSharedArray::ArraySetLength(thread, obj, desc2));
119 }
120 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLengthTest001)121 HWTEST_F_L0(JSSharedArrayTest, ArraySetLengthTest001)
122 {
123     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(1))
124                                                  .GetTaggedValue()
125                                                  .GetTaggedObject());
126     EXPECT_TRUE(arr != nullptr);
127     JSHandle<JSObject> obj(thread, arr);
128     PropertyDescriptor desc(thread);
129     ASSERT_TRUE(JSSharedArray::ArraySetLength(thread, obj, desc));
130 }
131 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLengthTest002)132 HWTEST_F_L0(JSSharedArrayTest, ArraySetLengthTest002)
133 {
134     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(2))
135                                                  .GetTaggedValue()
136                                                  .GetTaggedObject());
137     EXPECT_TRUE(arr != nullptr);
138     JSHandle<JSObject> obj(thread, arr);
139     PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(6)));
140     ASSERT_TRUE(JSSharedArray::ArraySetLength(thread, obj, desc));
141 }
142 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLengthTest003)143 HWTEST_F_L0(JSSharedArrayTest, ArraySetLengthTest003)
144 {
145     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(1))
146                                                  .GetTaggedValue()
147                                                  .GetTaggedObject());
148     EXPECT_TRUE(arr != nullptr);
149     JSHandle<JSObject> obj(thread, arr);
150     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), false, true, false);
151 
152     ASSERT_FALSE(JSSharedArray::ArraySetLength(thread, obj, desc1));
153     PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), false, true, true);
154 
155     ASSERT_FALSE(JSSharedArray::ArraySetLength(thread, obj, desc2));
156 }
157 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLengthTest004)158 HWTEST_F_L0(JSSharedArrayTest, ArraySetLengthTest004)
159 {
160     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(2))
161                                                  .GetTaggedValue()
162                                                  .GetTaggedObject());
163     EXPECT_TRUE(arr != nullptr);
164     JSHandle<JSObject> obj(thread, arr);
165     PropertyDescriptor desc(thread);
166     JSSharedArray::DefineOwnProperty(thread, obj,
167         JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(0))), desc);
168     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, false, false);
169     ASSERT_TRUE(JSSharedArray::ArraySetLength(thread, obj, desc1));
170 }
171 
HWTEST_F_L0(JSSharedArrayTest,ArrayCreateTest001)172 HWTEST_F_L0(JSSharedArrayTest, ArrayCreateTest001)
173 {
174     double len = (double)std::numeric_limits<uint32_t>::max() + 1000;
175     JSHandle<JSTaggedValue> result = JSSharedArray::ArrayCreate(thread, JSTaggedNumber(len));
176     EXPECT_EQ(result->GetRawData(), JSTaggedValue::Exception().GetRawData());
177 }
178 
HWTEST_F_L0(JSSharedArrayTest,ArrayCreateTest002)179 HWTEST_F_L0(JSSharedArrayTest, ArrayCreateTest002)
180 {
181     JSHandle<JSTaggedValue> result = JSSharedArray::ArrayCreate( \
182         thread, JSTaggedNumber(10), ArrayMode::LITERAL);
183     JSSharedArray *arr = JSSharedArray::Cast(result.GetTaggedValue().GetTaggedObject());
184     EXPECT_EQ(arr->GetArrayLength(), 10);
185 }
186 
HWTEST_F_L0(JSSharedArrayTest,LengthSetterTest001)187 HWTEST_F_L0(JSSharedArrayTest, LengthSetterTest001)
188 {
189     JSHandle<JSObject> self;
190     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(static_cast<int32_t>(-64)));
191     bool result = JSSharedArray::LengthSetter(thread, self, value, true);
192     EXPECT_EQ(result, false);
193 }
194 
HWTEST_F_L0(JSSharedArrayTest,LengthSetterTest003)195 HWTEST_F_L0(JSSharedArrayTest, LengthSetterTest003)
196 {
197     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(15))
198                                                  .GetTaggedValue()
199                                                  .GetTaggedObject());
200     EXPECT_TRUE(arr != nullptr);
201     JSHandle<JSObject> self(thread, arr);
202     auto *hclass = self->GetJSHClass();
203     LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout(thread).GetTaggedObject());
204     PropertyAttributes attr(layoutInfo->GetAttr(thread, JSArray::LENGTH_INLINE_PROPERTY_INDEX));
205     attr.SetWritable(false);
206     layoutInfo->SetNormalAttr(thread, 0, attr);
207     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(10));
208     bool result = JSSharedArray::LengthSetter(thread, self, value, true);
209     EXPECT_EQ(result, false);
210 }
211 
HWTEST_F_L0(JSSharedArrayTest,ArraySpeciesCreateTest001)212 HWTEST_F_L0(JSSharedArrayTest, ArraySpeciesCreateTest001)
213 {
214     JSArray *arr = JSArray::ArrayCreate(thread, JSTaggedNumber(0)).GetObject<JSArray>();
215     EXPECT_TRUE(arr != nullptr);
216     JSHandle<JSObject> obj(thread, arr);
217     JSSharedArray::ArraySpeciesCreate(thread, obj, JSTaggedNumber(10));
218 }
219 
HWTEST_F_L0(JSSharedArrayTest,LengthSetterTest004)220 HWTEST_F_L0(JSSharedArrayTest, LengthSetterTest004)
221 {
222     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(15))
223                                                  .GetTaggedValue()
224                                                  .GetTaggedObject());
225     EXPECT_TRUE(arr != nullptr);
226     JSHandle<JSObject> self(thread, arr);
227     auto *hclass = self->GetJSHClass();
228     LayoutInfo *layoutInfo = LayoutInfo::Cast(hclass->GetLayout(thread).GetTaggedObject());
229     PropertyAttributes attr(layoutInfo->GetAttr(thread, JSArray::LENGTH_INLINE_PROPERTY_INDEX));
230     attr.SetWritable(false);
231     layoutInfo->SetNormalAttr(thread, 0, attr);
232     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(10));
233     bool result = JSSharedArray::LengthSetter(thread, self, value, false);
234     EXPECT_EQ(result, false);
235 }
236 
HWTEST_F_L0(JSSharedArrayTest,ArraySetLengthTest005)237 HWTEST_F_L0(JSSharedArrayTest, ArraySetLengthTest005)
238 {
239     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(2))
240                                                  .GetTaggedValue()
241                                                  .GetTaggedObject());
242     EXPECT_TRUE(arr != nullptr);
243     JSHandle<JSObject> obj(thread, arr);
244     PropertyDescriptor desc(thread);
245     JSSharedArray::DefineOwnProperty(thread, obj,
246         JSHandle<JSTaggedValue>(thread, JSTaggedValue(static_cast<int>(0))), desc);
247     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread,
248                         JSTaggedValue(std::numeric_limits<uint64_t>::max())), true, false, false);
249     ASSERT_FALSE(JSSharedArray::ArraySetLength(thread, obj, desc1));
250 }
251 
HWTEST_F_L0(JSSharedArrayTest,LengthSetterTest002)252 HWTEST_F_L0(JSSharedArrayTest, LengthSetterTest002)
253 {
254     JSSharedArray *arr = JSSharedArray::Cast(JSSharedArray::ArrayCreate(thread, JSTaggedNumber(0))
255                                                  .GetTaggedValue()
256                                                  .GetTaggedObject());
257     EXPECT_TRUE(arr != nullptr);
258     JSHandle<JSObject> self(thread, arr);
259     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(static_cast<int32_t>(0)));
260     bool result = JSSharedArray::LengthSetter(thread, self, value, false);
261     EXPECT_EQ(result, true);
262 }
263 
HWTEST_F_L0(JSSharedArrayTest,CheckAndCopyArray)264 HWTEST_F_L0(JSSharedArrayTest, CheckAndCopyArray)
265 {
266     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
267     JSHandle<JSSharedArray> jsArray = factory->NewJSSArray();
268     JSHandle<TaggedArray> prop(thread, jsArray->GetProperties(thread));
269     JSHClass* hclass = JSHandle<TaggedObject>(prop)->GetClass();
270     hclass->SetObjectType(JSType::COW_TAGGED_ARRAY);
271     ASSERT_EQ(hclass->GetObjectType(), JSType::COW_TAGGED_ARRAY);
272     JSSharedArray::CheckAndCopyArray(thread, jsArray);
273 }
274 } // namespace panda::test