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