1  /*
2  * Copyright (c) 2024 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/mem/assert_scope.h"
17 
18 namespace panda::ecmascript {
19 
20 using AssertGarbageCollectBit = panda::BitField<bool, 0, 1>;            // default enable
21 using AssertHeapAllocBit = AssertGarbageCollectBit::NextFlag;           // default enable
22 using AssertHandleAllocBit = AssertHeapAllocBit::NextFlag;              // default enable
23 using AssertDeRefHandleBit = AssertHandleAllocBit::NextFlag;            // default enable
24 using AssertLocalToShareWeakRefBit = AssertDeRefHandleBit::NextFlag;    // default disable
25 
26 constexpr size_t INITIAL_ASSERT_DATA = AssertGarbageCollectBit::Mask() |
27                                        AssertHeapAllocBit::Mask() |
28                                        AssertHandleAllocBit::Mask() |
29                                        AssertDeRefHandleBit::Mask();
30 
31 thread_local size_t currentAssertData = INITIAL_ASSERT_DATA;
32 
33 template<AssertType type, bool isAllow, bool IsDebug>
IsAllowed()34 bool AssertScopeT<type, isAllow, IsDebug>::IsAllowed()
35 {
36     return true;
37 };
38 
39 template<AssertType type, bool isAllow>
AssertScopeT()40 AssertScopeT<type, isAllow, true>::AssertScopeT() : oldData_(currentAssertData)
41 {
42     switch (type) {
43         case AssertType::GARBAGE_COLLECTION_ASSERT:
44             currentAssertData = AssertGarbageCollectBit::Update(oldData_.value(), isAllow);
45             break;
46         case AssertType::HEAP_ALLOC_ASSERT:
47             currentAssertData = AssertHeapAllocBit::Update(oldData_.value(), isAllow);
48             break;
49         case AssertType::HANDLE_ALLOC_ASSERT:
50             currentAssertData = AssertHandleAllocBit::Update(oldData_.value(), isAllow);
51             break;
52         case AssertType::DEREF_HANDLE_ASSERT:
53             currentAssertData = AssertDeRefHandleBit::Update(oldData_.value(), isAllow);
54             break;
55         case AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT:
56             currentAssertData = AssertLocalToShareWeakRefBit::Update(oldData_.value(), isAllow);
57             break;
58         default:
59             break;
60     }
61 }
62 
63 template<AssertType type, bool isAllow>
~AssertScopeT()64 AssertScopeT<type, isAllow, true>::~AssertScopeT()
65 {
66     if (!oldData_.has_value()) {
67         return;
68     }
69     currentAssertData = oldData_.value();
70     oldData_.reset();
71 }
72 
73 template<AssertType type, bool isAllow>
IsAllowed()74 bool AssertScopeT<type, isAllow, true>::IsAllowed()
75 {
76     switch (type) {
77         case AssertType::GARBAGE_COLLECTION_ASSERT:
78             return AssertGarbageCollectBit::Decode(currentAssertData);
79         case AssertType::HEAP_ALLOC_ASSERT:
80             return AssertHeapAllocBit::Decode(currentAssertData);
81         case AssertType::HANDLE_ALLOC_ASSERT:
82             return AssertHandleAllocBit::Decode(currentAssertData);
83         case AssertType::DEREF_HANDLE_ASSERT:
84             return AssertDeRefHandleBit::Decode(currentAssertData);
85         case AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT:
86             return AssertLocalToShareWeakRefBit::Decode(currentAssertData);
87         default:
88             return true;
89     }
90 }
91 
92 template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, false, IS_ALLOW_CHECK>;
93 template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, true, IS_ALLOW_CHECK>;
94 template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
95 template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
96 template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
97 template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
98 template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, false, IS_ALLOW_CHECK>;
99 template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, true, IS_ALLOW_CHECK>;
100 template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, false, IS_ALLOW_CHECK>;
101 template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, true, IS_ALLOW_CHECK>;
102 
103 }  // namespace panda::ecmascript