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#ifndef ECMASCRIPT_MEM_ASSERT_SCOPE_H
17#define ECMASCRIPT_MEM_ASSERT_SCOPE_H
18
19#include <optional>
20
21#include "ecmascript/common.h"
22#include "libpandabase/utils/bit_field.h"
23
24namespace panda::ecmascript {
25
26#ifndef NDEBUG
27constexpr bool IS_ALLOW_CHECK = true;
28#else
29constexpr bool IS_ALLOW_CHECK = false;
30#endif
31
32enum class AssertType : uint8_t {
33    GARBAGE_COLLECTION_ASSERT = 0,
34    HEAP_ALLOC_ASSERT,
35    HANDLE_ALLOC_ASSERT,
36    DEREF_HANDLE_ASSERT,
37    LOCAL_TO_SHARE_WEAK_REF_ASSERT,
38    LAST_ASSERT_TYPE
39};
40
41template<AssertType type, bool isAllow, bool IsDebug = IS_ALLOW_CHECK>
42class PUBLIC_API AssertScopeT {
43public:
44    static bool IsAllowed();
45};
46
47template<AssertType type, bool isAllow>
48class PUBLIC_API AssertScopeT<type, isAllow, true> {
49public:
50    AssertScopeT();
51
52    ~AssertScopeT();
53
54    static bool IsAllowed();
55
56private:
57    std::optional<size_t> oldData_;
58};
59
60using DisallowGarbageCollection = AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, false, IS_ALLOW_CHECK>;
61using AllowGarbageCollection = AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, true, IS_ALLOW_CHECK>;
62using DisAllowHeapAlloc = AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
63using AllowHeapAlloc = AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
64using DisAllowHandleAllocation = AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
65using AllowHandleAllocation = AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
66using DisAllowDeRefHandle = AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, false, IS_ALLOW_CHECK>;
67using AllowDeRefHandle = AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, true, IS_ALLOW_CHECK>;
68using DisAllowLocalToShareWeakRefHandle = AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT,
69                                                       false, IS_ALLOW_CHECK>;
70using AllowLocalToShareWeakRefHandle = AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT,
71                                                    true, IS_ALLOW_CHECK>;
72#if (!defined NDEBUG) || (defined RUN_TEST)
73// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
74#define DISALLOW_GARBAGE_COLLECTION [[maybe_unused]] DisallowGarbageCollection noGc
75// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
76#define ALLOW_GARBAGE_COLLECTION [[maybe_unused]] AllowGarbageCollection allowGc
77// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
78#define DISALLOW_HEAP_ALLOC [[maybe_unused]] DisAllowHeapAlloc noHeapAlloc
79// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
80#define ALLOW_HEAP_ALLOC [[maybe_unused]] AllowHeapAlloc allowHeapAlloc
81// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
82#define DISALLOW_HANDLE_ALLOC [[maybe_unused]] DisAllowHandleAllocation disAllowHandleAlloc
83// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
84#define ALLOW_HANDLE_ALLOC [[maybe_unused]] AllowHandleAllocation allowHandleAlloc
85// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
86#define DISALLOW_DEREF_HANDLE [[maybe_unused]] DisAllowDeRefHandle disAllowDeRefHandle
87// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
88#define ALLOW_DEREF_HANDLE [[maybe_unused]] AllowDeRefHandle allowDeRefHandle
89// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
90#define DISALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE             \
91    [[maybe_unused]] DisAllowLocalToShareWeakRefHandle disAllowLocalToShareWeakRefHandle
92// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
93#define ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE                \
94    [[maybe_unused]] AllowLocalToShareWeakRefHandle allowLocalToShareRefHandle
95// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
96#define DISALLOW_HEAP_ACCESS \
97    DISALLOW_HEAP_ALLOC;     \
98    DISALLOW_HANDLE_ALLOC;   \
99    DISALLOW_DEREF_HANDLE;
100// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
101#define ALLOW_HEAP_ACCESS \
102    ALLOW_HEAP_ALLOC;     \
103    ALLOW_HANDLE_ALLOC;   \
104    ALLOW_DEREF_HANDLE;
105#else
106#define DISALLOW_GARBAGE_COLLECTION
107#define ALLOW_GARBAGE_COLLECTION
108#define DISALLOW_HEAP_ALLOC
109#define ALLOW_HEAP_ALLOC
110#define DISALLOW_HANDLE_ALLOC
111#define ALLOW_HANDLE_ALLOC
112#define DISALLOW_HEAP_ACCESS
113#define ALLOW_HEAP_ACCESS
114#define DISALLOW_DEREF_HANDLE
115#define ALLOW_DEREF_HANDLE
116#define DISALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE
117#define ALLOW_LOCAL_TO_SHARE_WEAK_REF_HANDLE
118#endif
119
120// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
121#define CHECK_NO_GC ASSERT_PRINT(AllowGarbageCollection::IsAllowed(), "disallow execute garbage collection.")
122// Some checks failed, need to check and fix
123#undef CHECK_NO_GC
124// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
125#define CHECK_NO_GC static_cast<void>(0)
126
127// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
128#define CHECK_NO_HEAP_ALLOC ASSERT_PRINT(AllowHeapAlloc::IsAllowed(), "disallow execute heap alloc.")
129
130// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
131#define CHECK_NO_HANDLE_ALLOC ASSERT_PRINT(AllowHandleAllocation::IsAllowed(), "disallow execute handle alloc.")
132
133// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
134#define CHECK_NO_DEREF_HANDLE ASSERT_PRINT(AllowDeRefHandle::IsAllowed(), "disallow execute deref handle.")
135
136// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
137#define CHECK_NO_LOCAL_TO_SHARE_WEAK_REF_HANDLE         \
138    ASSERT_PRINT(AllowLocalToShareWeakRefHandle::IsAllowed(), "disallow local to share weak ref handle.")
139}  // namespace panda::ecmascript
140
141#endif  // ECMASCRIPT_MEM_ASSERT_SCOPE_H
142