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/ecma_vm.h"
17 #include "ecmascript/global_env.h"
18 #include "ecmascript/js_handle.h"
19 #include "ecmascript/object_factory.h"
20 #include "ecmascript/tagged_array-inl.h"
21 #include "ecmascript/tests/ecma_test_common.h"
22 
23 using namespace panda::ecmascript;
24 
25 namespace panda::test {
26 class WeakRefOldGCTest : public BaseTestWithScope<false> {
27 };
28 
JSObjectTestCreate(JSThread *thread)29 static JSObject *JSObjectTestCreate(JSThread *thread)
30 {
31     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
32     EcmaVM *ecmaVM = thread->GetEcmaVM();
33     auto globalEnv = ecmaVM->GetGlobalEnv();
34     JSFunction *jsFunc = globalEnv->GetObjectFunction().GetObject<JSFunction>();
35     JSHandle<JSTaggedValue> jsFunc1(thread, jsFunc);
36     JSHandle<JSObject> newObj =
37         ecmaVM->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc1), jsFunc1);
38     return *newObj;
39 }
40 
ArrayTestCreate(JSThread *thread)41 static TaggedArray *ArrayTestCreate(JSThread *thread)
42 {
43     [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
44     // 2 : test case
45     JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2);
46     return *array;
47 }
48 
HWTEST_F_L0(WeakRefOldGCTest, ArrayNonMovable)49 HWTEST_F_L0(WeakRefOldGCTest, ArrayNonMovable)
50 {
51     auto vm = thread->GetEcmaVM();
52     auto array = vm->GetFactory()->NewTaggedArray(2, JSTaggedValue::Undefined(), true);
53     JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
54     array->Set(thread, 0, newObj1.GetTaggedValue());
55 
56     JSObject *newObj2 = JSObjectTestCreate(thread);
57     JSTaggedValue value(newObj2);
58     value.CreateWeakRef();
59     array->Set(thread, 1, value);
60     EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
61     EXPECT_EQ(value, array->Get(1));
62     vm->CollectGarbage(TriggerGCType::OLD_GC);
63     EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
64     EXPECT_EQ(JSTaggedValue::Undefined(), array->Get(1));
65 }
66 
HWTEST_F_L0(WeakRefOldGCTest, ArrayUndefined)67 HWTEST_F_L0(WeakRefOldGCTest, ArrayUndefined)
68 {
69     EcmaTestCommon::ArrayUndefinedGcCommon(thread, TriggerGCType::OLD_GC);
70 }
71 
HWTEST_F_L0(WeakRefOldGCTest, ArrayKeep)72 HWTEST_F_L0(WeakRefOldGCTest, ArrayKeep)
73 {
74     EcmaTestCommon::ArrayKeepGcCommon(thread, TriggerGCType::OLD_GC);
75 }
76 
HWTEST_F_L0(WeakRefOldGCTest, ObjectUndefined)77 HWTEST_F_L0(WeakRefOldGCTest, ObjectUndefined)
78 {
79     JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
80     JSTaggedValue array(ArrayTestCreate(thread));
81     array.CreateWeakRef();
82     newObj1->SetElements(thread, array);
83     EXPECT_EQ(newObj1->GetElements(), array);
84     thread->GetEcmaVM()->CollectGarbage(TriggerGCType::OLD_GC);
85     EXPECT_EQ(newObj1->GetElements(), JSTaggedValue::Undefined());
86 }
87 
HWTEST_F_L0(WeakRefOldGCTest, ObjectKeep)88 HWTEST_F_L0(WeakRefOldGCTest, ObjectKeep)
89 {
90     JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
91     JSHandle<TaggedArray> array(thread, ArrayTestCreate(thread));
92     JSTaggedValue value = array.GetTaggedValue();
93     value.CreateWeakRef();
94     newObj1->SetElements(thread, value);
95     EXPECT_EQ(newObj1->GetElements(), value);
96     thread->GetEcmaVM()->CollectGarbage(TriggerGCType::OLD_GC);
97     value = array.GetTaggedValue();
98     value.CreateWeakRef();
99     EXPECT_EQ(newObj1->GetElements(), value);
100 }
101 }  // namespace panda::test
102