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/test_helper.h"
22
23 using namespace panda::ecmascript;
24
25 namespace panda::test {
26 class WeakRefSemiGCTest : public testing::Test {
27 public:
SetUpTestCase()28 static void SetUpTestCase()
29 {
30 GTEST_LOG_(INFO) << "SetUpTestCase";
31 }
32
TearDownTestCase()33 static void TearDownTestCase()
34 {
35 GTEST_LOG_(INFO) << "TearDownCase";
36 }
37
SetUp()38 void SetUp() override
39 {
40 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
41 }
42
TearDown()43 void TearDown() override
44 {
45 TestHelper::DestroyEcmaVMWithScope(instance, scope);
46 }
47
48 EcmaVM *instance {nullptr};
49 EcmaHandleScope *scope {nullptr};
50 JSThread *thread {nullptr};
51 };
52
JSObjectTestCreate(JSThread * thread)53 static JSObject *JSObjectTestCreate(JSThread *thread)
54 {
55 [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
56 EcmaVM *ecmaVM = thread->GetEcmaVM();
57 auto globalEnv = ecmaVM->GetGlobalEnv();
58 JSHandle<JSTaggedValue> jsFunc = globalEnv->GetObjectFunction();
59 JSHandle<JSObject> newObj =
60 ecmaVM->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc), jsFunc);
61 return *newObj;
62 }
63
ArrayTestCreate(JSThread * thread)64 static TaggedArray *ArrayTestCreate(JSThread *thread)
65 {
66 [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
67 // 2 : test case
68 JSHandle<TaggedArray> array = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(2);
69 return *array;
70 }
71
HWTEST_F_L0(WeakRefSemiGCTest,ArrayUndefined)72 HWTEST_F_L0(WeakRefSemiGCTest, ArrayUndefined)
73 {
74 EcmaVM *ecmaVM = thread->GetEcmaVM();
75 JSHandle<TaggedArray> array = ecmaVM->GetFactory()->NewTaggedArray(2);
76 EXPECT_TRUE(*array != nullptr);
77 JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
78 array->Set(thread, 0, newObj1.GetTaggedValue());
79
80 JSObject *newObj2 = JSObjectTestCreate(thread);
81 JSTaggedValue value(newObj2);
82 value.CreateWeakRef();
83 array->Set(thread, 1, value);
84 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
85 EXPECT_EQ(value, array->Get(1));
86 ecmaVM->CollectGarbage(TriggerGCType::YOUNG_GC);
87 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
88 EXPECT_EQ(JSTaggedValue::Undefined(), array->Get(1));
89 }
90
HWTEST_F_L0(WeakRefSemiGCTest,ArrayKeep)91 HWTEST_F_L0(WeakRefSemiGCTest, ArrayKeep)
92 {
93 EcmaVM *ecmaVM = thread->GetEcmaVM();
94 JSHandle<TaggedArray> array = ecmaVM->GetFactory()->NewTaggedArray(2);
95 EXPECT_TRUE(*array != nullptr);
96 JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
97 array->Set(thread, 0, newObj1.GetTaggedValue());
98
99 JSHandle<JSObject> newObj2(thread, JSObjectTestCreate(thread));
100 JSTaggedValue value(newObj2.GetTaggedValue());
101 value.CreateWeakRef();
102 array->Set(thread, 1, value);
103 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
104 EXPECT_EQ(value, array->Get(1));
105 ecmaVM->CollectGarbage(TriggerGCType::YOUNG_GC);
106 EXPECT_EQ(newObj1.GetTaggedValue(), array->Get(0));
107 EXPECT_EQ(true, array->Get(1).IsWeak());
108 value = newObj2.GetTaggedValue();
109 value.CreateWeakRef();
110 EXPECT_EQ(value, array->Get(1));
111 }
112
HWTEST_F_L0(WeakRefSemiGCTest,ObjectUndefined)113 HWTEST_F_L0(WeakRefSemiGCTest, ObjectUndefined)
114 {
115 JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
116 JSTaggedValue array(ArrayTestCreate(thread));
117 array.CreateWeakRef();
118 newObj1->SetElements(thread, array);
119 EXPECT_EQ(newObj1->GetElements(), array);
120 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::YOUNG_GC);
121 EXPECT_EQ(newObj1->GetElements(), JSTaggedValue::Undefined());
122 }
123
HWTEST_F_L0(WeakRefSemiGCTest,ObjectKeep)124 HWTEST_F_L0(WeakRefSemiGCTest, ObjectKeep)
125 {
126 JSHandle<JSObject> newObj1(thread, JSObjectTestCreate(thread));
127 JSHandle<TaggedArray> array(thread, ArrayTestCreate(thread));
128 JSTaggedValue value = array.GetTaggedValue();
129 value.CreateWeakRef();
130 newObj1->SetElements(thread, value);
131 EXPECT_EQ(newObj1->GetElements(), value);
132 thread->GetEcmaVM()->CollectGarbage(TriggerGCType::YOUNG_GC);
133 value = array.GetTaggedValue();
134 value.CreateWeakRef();
135 EXPECT_EQ(newObj1->GetElements(), value);
136 }
137 } // namespace panda::test
138