• 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_weak_set.h"
17 
18 #include "ecmascript/ecma_string.h"
19 #include "ecmascript/ecma_vm.h"
20 #include "ecmascript/global_env.h"
21 #include "ecmascript/js_array.h"
22 #include "ecmascript/js_handle.h"
23 #include "ecmascript/js_hclass.h"
24 #include "ecmascript/js_object-inl.h"
25 #include "ecmascript/js_set_iterator.h"
26 #include "ecmascript/js_tagged_value.h"
27 #include "ecmascript/js_thread.h"
28 #include "ecmascript/js_weak_container.h"
29 #include "ecmascript/object_factory.h"
30 #include "ecmascript/tests/test_helper.h"
31 
32 using namespace panda::ecmascript;
33 using namespace panda::ecmascript::builtins;
34 
35 namespace panda::test {
36 using BuiltinsWeakSet = ecmascript::builtins::BuiltinsWeakSet;
37 using JSWeakSet = ecmascript::JSWeakSet;
38 
39 class BuiltinsWeakSetTest : public testing::Test {
40 public:
SetUpTestCase()41     static void SetUpTestCase()
42     {
43         GTEST_LOG_(INFO) << "SetUpTestCase";
44     }
45 
TearDownTestCase()46     static void TearDownTestCase()
47     {
48         GTEST_LOG_(INFO) << "TearDownCase";
49     }
50 
SetUp()51     void SetUp() override
52     {
53         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
54     }
55 
TearDown()56     void TearDown() override
57     {
58         TestHelper::DestroyEcmaVMWithScope(instance, scope);
59     }
60 
61     EcmaVM *instance {nullptr};
62     EcmaHandleScope *scope {nullptr};
63     JSThread *thread {nullptr};
64 };
65 
JSObjectTestCreate(JSThread * thread)66 static JSObject *JSObjectTestCreate(JSThread *thread)
67 {
68     [[maybe_unused]] EcmaHandleScope scope(thread);
69     EcmaVM *ecmaVM = thread->GetEcmaVM();
70     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
71     JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
72     JSHandle<JSObject> newObj =
73         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
74     return *newObj;
75 }
76 
CreateBuiltinsWeakSet(JSThread * thread)77 JSWeakSet *CreateBuiltinsWeakSet(JSThread *thread)
78 {
79     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
80     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakSetFunction());
81 
82     // 4 : test case
83     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*newTarget), 4);
84     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
85     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
86     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
87     JSTaggedValue result = BuiltinsWeakSet::WeakSetConstructor(ecmaRuntimeCallInfo);
88     TestHelper::TearDownFrame(thread, prev);
89 
90     EXPECT_TRUE(result.IsECMAObject());
91     JSWeakSet *jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
92     return jsWeakSet;
93 }
94 
HWTEST_F_L0(BuiltinsWeakSetTest,CreateAndGetSize)95 HWTEST_F_L0(BuiltinsWeakSetTest, CreateAndGetSize)
96 {
97     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
98     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
99     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakSetFunction());
100     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
101 
102     JSHandle<TaggedArray> array(factory->NewTaggedArray(5));
103     for (int i = 0; i < 5; i++) {
104         JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
105         array->Set(thread, i, key.GetTaggedValue());
106     }
107 
108     JSHandle<JSArray> values = JSArray::CreateArrayFromList(thread, array);
109     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
110     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
111     ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
112     ecmaRuntimeCallInfo->SetCallArg(0, values.GetTaggedValue());
113     ecmaRuntimeCallInfo->SetNewTarget(newTarget.GetTaggedValue());
114 
115     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
116 
117     JSTaggedValue result1 = BuiltinsWeakSet::WeakSetConstructor(ecmaRuntimeCallInfo);
118     TestHelper::TearDownFrame(thread, prev);
119     JSHandle<JSWeakSet> weakSetResult(thread,
120                                         JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
121     EXPECT_EQ(weakSetResult->GetSize(), 5);
122 }
123 
HWTEST_F_L0(BuiltinsWeakSetTest,AddAndHas)124 HWTEST_F_L0(BuiltinsWeakSetTest, AddAndHas)
125 {
126     // create jsWeakSet
127     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
128     JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
129     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
130     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
131     ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
132     ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
133 
134     JSWeakSet *jsWeakSet;
135     {
136         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
137         JSTaggedValue result1 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo);
138         TestHelper::TearDownFrame(thread, prev);
139 
140         EXPECT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
141 
142         // test Add()
143         JSTaggedValue result2 = BuiltinsWeakSet::Add(ecmaRuntimeCallInfo);
144         EXPECT_TRUE(result2.IsECMAObject());
145         jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result2.GetRawData()));
146         EXPECT_EQ(jsWeakSet->GetSize(), 1);
147     }
148 
149     // test Has()
150     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
151     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
152     ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(jsWeakSet));
153     ecmaRuntimeCallInfo1->SetCallArg(0, key.GetTaggedValue());
154     {
155         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
156         JSTaggedValue result3 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1);
157         TestHelper::TearDownFrame(thread, prev);
158 
159         EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
160     }
161 }
162 
HWTEST_F_L0(BuiltinsWeakSetTest,DeleteAndRemove)163 HWTEST_F_L0(BuiltinsWeakSetTest, DeleteAndRemove)
164 {
165     // create jsSet
166     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
167 
168     // add 40 keys
169     JSTaggedValue lastKey(JSTaggedValue::Undefined());
170     for (int i = 0; i < 40; i++) {
171         JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
172 
173         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
174         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
175         ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
176         ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
177 
178         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
179         JSTaggedValue result1 = BuiltinsWeakSet::Add(ecmaRuntimeCallInfo);
180         TestHelper::TearDownFrame(thread, prev);
181 
182         EXPECT_TRUE(result1.IsECMAObject());
183         JSWeakSet *jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData()));
184         EXPECT_EQ(jsWeakSet->GetSize(), static_cast<int>(i) + 1);
185         lastKey = key.GetTaggedValue();
186     }
187     // whether jsWeakSet has delete lastKey
188 
189     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
190     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
191     ecmaRuntimeCallInfo1->SetThis(weakSet.GetTaggedValue());
192     ecmaRuntimeCallInfo1->SetCallArg(0, lastKey);
193 
194     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
195     JSTaggedValue result2 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1);
196     TestHelper::TearDownFrame(thread, prev);
197 
198     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
199 
200     // delete
201     JSTaggedValue result3 = BuiltinsWeakSet::Delete(ecmaRuntimeCallInfo1);
202 
203     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
204 
205     // check deleteKey is deleted
206     JSTaggedValue result4 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1);
207 
208     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData());
209 }
210 
HWTEST_F_L0(BuiltinsWeakSetTest,SymbolKey)211 HWTEST_F_L0(BuiltinsWeakSetTest, SymbolKey)
212 {
213     // create jsSet
214     JSHandle<JSWeakSet> weakSet(thread, CreateBuiltinsWeakSet(thread));
215 
216     // add 2 keys
217     JSTaggedValue lastKey(JSTaggedValue::Undefined());
218     for (int i = 0; i < 2; i++) {
219         JSHandle<JSSymbol> symbolKey = thread->GetEcmaVM()->GetFactory()->NewJSSymbol();
220         JSHandle<JSTaggedValue> key(symbolKey);
221 
222         auto ecmaRuntimeCallInfo =
223             TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg
224         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
225         ecmaRuntimeCallInfo->SetThis(weakSet.GetTaggedValue());
226         ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
227 
228         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
229         // add
230         JSTaggedValue result1 = BuiltinsWeakSet::Add(ecmaRuntimeCallInfo);
231         TestHelper::TearDownFrame(thread, prev);
232 
233         EXPECT_TRUE(result1.IsECMAObject());
234         JSWeakSet *jsWeakSet = JSWeakSet::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData()));
235         EXPECT_EQ(jsWeakSet->GetSize(), static_cast<int>(i) + 1);
236         lastKey = key.GetTaggedValue();
237     }
238     // whether jsWeakSet has delete lastKey
239 
240     auto ecmaRuntimeCallInfo1 =
241         TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6); // 6 means 1 call arg
242     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
243     ecmaRuntimeCallInfo1->SetThis(weakSet.GetTaggedValue());
244     ecmaRuntimeCallInfo1->SetCallArg(0, lastKey);
245 
246     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
247     // has
248     JSTaggedValue result2 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1);
249     TestHelper::TearDownFrame(thread, prev);
250     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
251 
252     // delete
253     JSTaggedValue result3 = BuiltinsWeakSet::Delete(ecmaRuntimeCallInfo1);
254     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
255 
256     // check deleteKey is deleted
257     JSTaggedValue result4 = BuiltinsWeakSet::Has(ecmaRuntimeCallInfo1);
258     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData());
259 }
260 }  // namespace panda::test
261