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
18namespace panda::ecmascript {
19
20using AssertGarbageCollectBit = panda::BitField<bool, 0, 1>;            // default enable
21using AssertHeapAllocBit = AssertGarbageCollectBit::NextFlag;           // default enable
22using AssertHandleAllocBit = AssertHeapAllocBit::NextFlag;              // default enable
23using AssertDeRefHandleBit = AssertHandleAllocBit::NextFlag;            // default enable
24using AssertLocalToShareWeakRefBit = AssertDeRefHandleBit::NextFlag;    // default disable
25
26constexpr size_t INITIAL_ASSERT_DATA = AssertGarbageCollectBit::Mask() |
27                                       AssertHeapAllocBit::Mask() |
28                                       AssertHandleAllocBit::Mask() |
29                                       AssertDeRefHandleBit::Mask();
30
31thread_local size_t currentAssertData = INITIAL_ASSERT_DATA;
32
33template<AssertType type, bool isAllow, bool IsDebug>
34bool AssertScopeT<type, isAllow, IsDebug>::IsAllowed()
35{
36    return true;
37};
38
39template<AssertType type, bool isAllow>
40AssertScopeT<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
63template<AssertType type, bool isAllow>
64AssertScopeT<type, isAllow, true>::~AssertScopeT()
65{
66    if (!oldData_.has_value()) {
67        return;
68    }
69    currentAssertData = oldData_.value();
70    oldData_.reset();
71}
72
73template<AssertType type, bool isAllow>
74bool 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
92template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, false, IS_ALLOW_CHECK>;
93template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, true, IS_ALLOW_CHECK>;
94template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
95template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
96template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
97template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
98template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, false, IS_ALLOW_CHECK>;
99template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, true, IS_ALLOW_CHECK>;
100template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, false, IS_ALLOW_CHECK>;
101template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, true, IS_ALLOW_CHECK>;
102
103}  // namespace panda::ecmascript