• 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/base/builtins_base.h"
17 #include "ecmascript/builtins/builtins_weak_map.h"
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/ecma_string.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_hclass.h"
25 #include "ecmascript/js_map_iterator.h"
26 #include "ecmascript/js_object-inl.h"
27 #include "ecmascript/js_tagged_value.h"
28 #include "ecmascript/js_thread.h"
29 #include "ecmascript/js_weak_container.h"
30 #include "ecmascript/object_factory.h"
31 #include "ecmascript/tagged_array-inl.h"
32 #include "ecmascript/tests/test_helper.h"
33 #include "utils/bit_utils.h"
34 
35 using namespace panda::ecmascript;
36 using namespace panda::ecmascript::builtins;
37 
38 namespace panda::test {
39 using BuiltinsWeakMap = ecmascript::builtins::BuiltinsWeakMap;
40 using JSWeakMap = ecmascript::JSWeakMap;
41 
42 class BuiltinsWeakMapTest : public testing::Test {
43 public:
SetUpTestCase()44     static void SetUpTestCase()
45     {
46         GTEST_LOG_(INFO) << "SetUpTestCase";
47     }
48 
TearDownTestCase()49     static void TearDownTestCase()
50     {
51         GTEST_LOG_(INFO) << "TearDownCase";
52     }
53 
SetUp()54     void SetUp() override
55     {
56         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
57     }
58 
TearDown()59     void TearDown() override
60     {
61         TestHelper::DestroyEcmaVMWithScope(instance, scope);
62     }
63 
64     PandaVM *instance {nullptr};
65     EcmaHandleScope *scope {nullptr};
66     JSThread *thread {nullptr};
67 };
68 
JSObjectTestCreate(JSThread * thread)69 static JSObject *JSObjectTestCreate(JSThread *thread)
70 {
71     EcmaVM *ecmaVM = thread->GetEcmaVM();
72     ObjectFactory *factory = ecmaVM->GetFactory();
73     [[maybe_unused]] EcmaHandleScope scope(thread);
74     JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
75     JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
76     return *factory->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
77 }
78 
CreateBuiltinsWeakMap(JSThread * thread)79 JSWeakMap *CreateBuiltinsWeakMap(JSThread *thread)
80 {
81     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
82     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakMapFunction());
83     // 4 : test case
84     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, newTarget.GetTaggedValue(), 4);
85     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
86     ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
87 
88     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
89     JSTaggedValue result = BuiltinsWeakMap::WeakMapConstructor(ecmaRuntimeCallInfo.get());
90 
91     EXPECT_TRUE(result.IsECMAObject());
92     return JSWeakMap::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData()));
93 }
94 
95 // new Map("abrupt").toString()
HWTEST_F_L0(BuiltinsWeakMapTest,CreateAndGetSize)96 HWTEST_F_L0(BuiltinsWeakMapTest, CreateAndGetSize)
97 {
98     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
99     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
100     JSHandle<JSFunction> newTarget(env->GetBuiltinsWeakMapFunction());
101     JSHandle<JSWeakMap> map(thread, CreateBuiltinsWeakMap(thread));
102 
103     JSHandle<TaggedArray> array(factory->NewTaggedArray(1));
104     JSHandle<TaggedArray> internal_array(factory->NewTaggedArray(2));
105     JSTaggedValue value(JSObjectTestCreate(thread));
106     internal_array->Set(thread, 0, value);
107     internal_array->Set(thread, 1, JSTaggedValue(0));
108     auto result = JSArray::CreateArrayFromList(thread, internal_array);
109     array->Set(thread, 0, result);
110 
111     JSHandle<JSArray> values = JSArray::CreateArrayFromList(thread, array);
112 
113     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
114     ecmaRuntimeCallInfo->SetFunction(newTarget.GetTaggedValue());
115     ecmaRuntimeCallInfo->SetThis(map.GetTaggedValue());
116     ecmaRuntimeCallInfo->SetCallArg(0, values.GetTaggedValue());
117     ecmaRuntimeCallInfo->SetNewTarget(newTarget.GetTaggedValue());
118 
119     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
120 
121     JSTaggedValue result1 = BuiltinsWeakMap::WeakMapConstructor(ecmaRuntimeCallInfo.get());
122     JSHandle<JSWeakMap> weakMap(thread, JSWeakMap::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
123     EXPECT_EQ(weakMap->GetSize(), 1);
124 }
125 
HWTEST_F_L0(BuiltinsWeakMapTest,SetAndHas)126 HWTEST_F_L0(BuiltinsWeakMapTest, SetAndHas)
127 {
128     // create jsWeakMap
129     JSHandle<JSWeakMap> weakMap(thread, CreateBuiltinsWeakMap(thread));
130     JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
131 
132     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
133     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
134     ecmaRuntimeCallInfo->SetThis(weakMap.GetTaggedValue());
135     ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
136     ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
137 
138     {
139         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
140         JSTaggedValue result1 = BuiltinsWeakMap::Has(ecmaRuntimeCallInfo.get());
141 
142         EXPECT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
143     }
144 
145     // test Set()
146     JSTaggedValue result2 = BuiltinsWeakMap::Set(ecmaRuntimeCallInfo.get());
147     EXPECT_TRUE(result2.IsECMAObject());
148     JSWeakMap *jsWeakMap = JSWeakMap::Cast(reinterpret_cast<TaggedObject *>(result2.GetRawData()));
149     EXPECT_EQ(jsWeakMap->GetSize(), 1);
150 
151     // test Has()
152     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
153     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
154     ecmaRuntimeCallInfo1->SetCallArg(0, key.GetTaggedValue());
155     ecmaRuntimeCallInfo1->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(1)));
156     ecmaRuntimeCallInfo1->SetThis(JSTaggedValue(jsWeakMap));
157     {
158         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
159         JSTaggedValue result3 = BuiltinsWeakMap::Has(ecmaRuntimeCallInfo1.get());
160 
161         EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
162     }
163 }
164 
HWTEST_F_L0(BuiltinsWeakMapTest,DeleteAndRemove)165 HWTEST_F_L0(BuiltinsWeakMapTest, DeleteAndRemove)
166 {
167     // create jsWeakMap
168     JSHandle<JSWeakMap> weakMap(thread, CreateBuiltinsWeakMap(thread));
169 
170     // add 40 keys
171     JSTaggedValue lastKey(JSTaggedValue::Undefined());
172     for (int i = 0; i < 40; i++) {
173         JSHandle<JSTaggedValue> key(thread, JSObjectTestCreate(thread));
174         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
175         ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
176         ecmaRuntimeCallInfo->SetThis(weakMap.GetTaggedValue());
177         ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
178         ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(i)));
179 
180         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo.get());
181         JSTaggedValue result1 = BuiltinsWeakMap::Set(ecmaRuntimeCallInfo.get());
182 
183         EXPECT_TRUE(result1.IsECMAObject());
184         JSWeakMap *jsWeakMap = JSWeakMap::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData()));
185         EXPECT_EQ(jsWeakMap->GetSize(), i + 1);
186         lastKey = key.GetTaggedValue();
187     }
188 
189     // whether jsWeakMap has delete lastKey
190 
191     auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
192     ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
193     ecmaRuntimeCallInfo1->SetThis(weakMap.GetTaggedValue());
194     ecmaRuntimeCallInfo1->SetCallArg(0, lastKey);
195 
196     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1.get());
197     JSTaggedValue result2 = BuiltinsWeakMap::Has(ecmaRuntimeCallInfo1.get());
198 
199     EXPECT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
200 
201     // delete
202     JSTaggedValue result3 = BuiltinsWeakMap::Delete(ecmaRuntimeCallInfo1.get());
203 
204     EXPECT_EQ(result3.GetRawData(), JSTaggedValue::True().GetRawData());
205 
206     // check deleteKey is deleted
207     JSTaggedValue result4 = BuiltinsWeakMap::Has(ecmaRuntimeCallInfo1.get());
208 
209     EXPECT_EQ(result4.GetRawData(), JSTaggedValue::False().GetRawData());
210 }
211 }  // namespace panda::test
212