• 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_ref.h"
17 
18 #include "ecmascript/base/builtins_base.h"
19 #include "ecmascript/ecma_vm.h"
20 #include "ecmascript/ecma_runtime_call_info.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/jobs/micro_job_queue.h"
23 #include "ecmascript/js_weak_ref.h"
24 #include "ecmascript/js_array.h"
25 #include "ecmascript/js_handle.h"
26 #include "ecmascript/js_hclass.h"
27 #include "ecmascript/js_object-inl.h"
28 #include "ecmascript/js_tagged_value.h"
29 #include "ecmascript/js_thread.h"
30 #include "ecmascript/object_factory.h"
31 #include "ecmascript/tests/test_helper.h"
32 #include "ecmascript/tagged_array-inl.h"
33 
34 
35 using namespace panda::ecmascript;
36 using namespace panda::ecmascript::builtins;
37 using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
38 
39 namespace panda::test {
40 using BuiltinsWeakRef = ecmascript::builtins::BuiltinsWeakRef;
41 
42 class BuiltinsWeakRefTest : 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     EcmaVM *instance {nullptr};
65     EcmaHandleScope *scope {nullptr};
66     JSThread *thread {nullptr};
67 };
68 
CreateWeakRefConstructor(JSThread * thread,JSTaggedValue target)69 JSTaggedValue CreateWeakRefConstructor(JSThread *thread, JSTaggedValue target)
70 {
71     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
72     JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
73     JSHandle<JSFunction> weakRef(env->GetBuiltinsWeakRefFunction());
74 
75     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*weakRef), 6);
76     ecmaRuntimeCallInfo->SetFunction(weakRef.GetTaggedValue());
77     ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
78     ecmaRuntimeCallInfo->SetCallArg(0, target);
79 
80     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
81     JSTaggedValue result = BuiltinsWeakRef::WeakRefConstructor(ecmaRuntimeCallInfo);
82     TestHelper::TearDownFrame(thread, prev);
83     return result;
84 }
85 
86 // new WeakRef(target)
HWTEST_F_L0(BuiltinsWeakRefTest,WeakRefConstructor)87 HWTEST_F_L0(BuiltinsWeakRefTest, WeakRefConstructor)
88 {
89     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
90     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
91     JSHandle<JSTaggedValue> objectFunc(env->GetObjectFunction());
92 
93     JSHandle<JSObject> target(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
94 
95     JSHandle<JSFunction> weakRef(env->GetBuiltinsWeakRefFunction());
96     JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
97 
98     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, weakRef.GetTaggedValue(), 6);
99     ecmaRuntimeCallInfo->SetFunction(weakRef.GetTaggedValue());
100     ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
101     ecmaRuntimeCallInfo->SetCallArg(0, target.GetTaggedValue());
102 
103     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
104     JSTaggedValue result = BuiltinsWeakRef::WeakRefConstructor(ecmaRuntimeCallInfo);
105 
106     ASSERT_TRUE(result.IsECMAObject());
107 }
108 
109 // weakRef.Deref()
HWTEST_F_L0(BuiltinsWeakRefTest,Deref1)110 HWTEST_F_L0(BuiltinsWeakRefTest, Deref1)
111 {
112     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
113     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
114     JSHandle<JSTaggedValue> objectFunc(env->GetObjectFunction());
115 
116     JSHandle<JSObject> target(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
117     JSTaggedValue result = CreateWeakRefConstructor(thread, target.GetTaggedValue());
118     JSHandle<JSWeakRef> jsWeakRef(thread, JSWeakRef::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData())));
119     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
120     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
121     ecmaRuntimeCallInfo->SetThis(jsWeakRef.GetTaggedValue());
122 
123     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
124     TestHelper::TearDownFrame(thread, prev);
125     JSTaggedValue result1 = BuiltinsWeakRef::Deref(ecmaRuntimeCallInfo);
126     ASSERT_EQ(result1, target.GetTaggedValue());
127 }
128 
129 // weakRef.Deref()
HWTEST_F_L0(BuiltinsWeakRefTest,Deref2)130 HWTEST_F_L0(BuiltinsWeakRefTest, Deref2)
131 {
132     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
133     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
134     JSHandle<JSTaggedValue> objectFunc(env->GetObjectFunction());
135     JSHandle<JSTaggedValue> formatStyle = thread->GlobalConstants()->GetHandledStyleString();
136     JSHandle<JSTaggedValue> styleKey(factory->NewFromASCII("currency"));
137     JSHandle<JSTaggedValue> styleValue(factory->NewFromASCII("EUR"));
138     JSHandle<JSObject> target(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc));
139     JSObject::SetProperty(thread, target, formatStyle, styleKey);
140     JSObject::SetProperty(thread, target, styleKey, styleValue);
141 
142     JSTaggedValue result = CreateWeakRefConstructor(thread, target.GetTaggedValue());
143     JSHandle<JSWeakRef> jsWeakRef(thread, JSWeakRef::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData())));
144     auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
145     ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
146     ecmaRuntimeCallInfo->SetThis(jsWeakRef.GetTaggedValue());
147 
148     [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
149     TestHelper::TearDownFrame(thread, prev);
150     JSTaggedValue result1 = BuiltinsWeakRef::Deref(ecmaRuntimeCallInfo);
151     ASSERT_EQ(result1, target.GetTaggedValue());
152 
153     JSObject::SetProperty(thread, target, styleKey, styleValue);
154     ASSERT_EQ(result1, target.GetTaggedValue());
155 }
156 
157 // weakRef.Deref()
HWTEST_F_L0(BuiltinsWeakRefTest,Deref3)158 HWTEST_F_L0(BuiltinsWeakRefTest, Deref3)
159 {
160     EcmaVM *vm = thread->GetEcmaVM();
161     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
162     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
163     JSHandle<JSTaggedValue> objectFunc(env->GetObjectFunction());
164 
165     JSTaggedValue target =
166 	    factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc).GetTaggedValue();
167     JSTaggedValue result = CreateWeakRefConstructor(thread, target);
168     JSHandle<JSWeakRef> jsWeakRef(thread, JSWeakRef::Cast(reinterpret_cast<TaggedObject *>(result.GetRawData())));
169     JSTaggedValue result2 = JSTaggedValue::Undefined();
170 
171     {
172         [[maybe_unused]] EcmaHandleScope handleScope(thread);
173         auto obj =
174 	        factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objectFunc), objectFunc);
175         target = obj.GetTaggedValue();
176         auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
177         ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
178         ecmaRuntimeCallInfo1->SetThis(jsWeakRef.GetTaggedValue());
179 
180         [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
181         result2 = BuiltinsWeakRef::Deref(ecmaRuntimeCallInfo1);
182         TestHelper::TearDownFrame(thread, prev1);
183     }
184     vm->CollectGarbage(TriggerGCType::FULL_GC);
185     if (!thread->HasPendingException()) {
186         job::MicroJobQueue::ExecutePendingJob(thread, vm->GetJSThread()->GetCurrentEcmaContext()->GetMicroJobQueue());
187     }
188     vm->SetEnableForceGC(true);
189     ASSERT_TRUE(!result2.IsUndefined());
190 }
191 
192 // symbol target
HWTEST_F_L0(BuiltinsWeakRefTest,SymbolTarget)193 HWTEST_F_L0(BuiltinsWeakRefTest, SymbolTarget)
194 {
195     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
196     JSHandle<JSSymbol> symbolTarget = thread->GetEcmaVM()->GetFactory()->NewJSSymbol();
197     JSHandle<JSTaggedValue> target(symbolTarget);
198 
199     JSHandle<JSFunction> weakRef(env->GetBuiltinsWeakRefFunction());
200 
201     auto ecmaRuntimeCallInfo1 =
202         TestHelper::CreateEcmaRuntimeCallInfo(thread, weakRef.GetTaggedValue(), 6); // 6 means 1 call arg
203     ecmaRuntimeCallInfo1->SetFunction(weakRef.GetTaggedValue());
204     ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
205     ecmaRuntimeCallInfo1->SetCallArg(0, target.GetTaggedValue());
206 
207     // constructor
208     [[maybe_unused]] auto prev1 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
209     JSTaggedValue result1 = BuiltinsWeakRef::WeakRefConstructor(ecmaRuntimeCallInfo1);
210     TestHelper::TearDownFrame(thread, prev1);
211     ASSERT_TRUE(result1.IsECMAObject());
212 
213     JSHandle<JSWeakRef> jsWeakRef(thread, JSWeakRef::Cast(reinterpret_cast<TaggedObject *>(result1.GetRawData())));
214     auto ecmaRuntimeCallInfo2 =
215         TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4); // 4 means 0 call arg
216     ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
217     ecmaRuntimeCallInfo2->SetThis(jsWeakRef.GetTaggedValue());
218 
219     // weakRef.Deref()
220     [[maybe_unused]] auto prev2 = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
221     JSTaggedValue result2 = BuiltinsWeakRef::Deref(ecmaRuntimeCallInfo2);
222     TestHelper::TearDownFrame(thread, prev2);
223     ASSERT_EQ(result2, target.GetTaggedValue());
224 }
225 }  // namespace panda::test
226