* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/mem/assert_scope.h"
namespace panda::ecmascript {
using AssertGarbageCollectBit = panda::BitField<bool, 0, 1>;
using AssertHeapAllocBit = AssertGarbageCollectBit::NextFlag;
using AssertHandleAllocBit = AssertHeapAllocBit::NextFlag;
using AssertDeRefHandleBit = AssertHandleAllocBit::NextFlag;
using AssertLocalToShareWeakRefBit = AssertDeRefHandleBit::NextFlag;
constexpr size_t INITIAL_ASSERT_DATA = AssertGarbageCollectBit::Mask() |
AssertHeapAllocBit::Mask() |
AssertHandleAllocBit::Mask() |
AssertDeRefHandleBit::Mask();
thread_local size_t currentAssertData = INITIAL_ASSERT_DATA;
void ForceResetAssertData()
{
currentAssertData = INITIAL_ASSERT_DATA;
}
template<AssertType type, bool isAllow, bool IsDebug>
bool AssertScopeT<type, isAllow, IsDebug>::IsAllowed()
{
return true;
};
template<AssertType type, bool isAllow>
AssertScopeT<type, isAllow, true>::AssertScopeT() : oldData_(currentAssertData)
{
switch (type) {
case AssertType::GARBAGE_COLLECTION_ASSERT:
currentAssertData = AssertGarbageCollectBit::Update(oldData_.value(), isAllow);
break;
case AssertType::HEAP_ALLOC_ASSERT:
currentAssertData = AssertHeapAllocBit::Update(oldData_.value(), isAllow);
break;
case AssertType::HANDLE_ALLOC_ASSERT:
currentAssertData = AssertHandleAllocBit::Update(oldData_.value(), isAllow);
break;
case AssertType::DEREF_HANDLE_ASSERT:
currentAssertData = AssertDeRefHandleBit::Update(oldData_.value(), isAllow);
break;
case AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT:
currentAssertData = AssertLocalToShareWeakRefBit::Update(oldData_.value(), isAllow);
break;
default:
break;
}
}
template<AssertType type, bool isAllow>
AssertScopeT<type, isAllow, true>::~AssertScopeT()
{
if (!oldData_.has_value()) {
return;
}
currentAssertData = oldData_.value();
oldData_.reset();
}
template<AssertType type, bool isAllow>
bool AssertScopeT<type, isAllow, true>::IsAllowed()
{
switch (type) {
case AssertType::GARBAGE_COLLECTION_ASSERT:
return AssertGarbageCollectBit::Decode(currentAssertData);
case AssertType::HEAP_ALLOC_ASSERT:
return AssertHeapAllocBit::Decode(currentAssertData);
case AssertType::HANDLE_ALLOC_ASSERT:
return AssertHandleAllocBit::Decode(currentAssertData);
case AssertType::DEREF_HANDLE_ASSERT:
return AssertDeRefHandleBit::Decode(currentAssertData);
case AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT:
return AssertLocalToShareWeakRefBit::Decode(currentAssertData);
default:
return true;
}
}
template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, false, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::GARBAGE_COLLECTION_ASSERT, true, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::HEAP_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, false, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::HANDLE_ALLOC_ASSERT, true, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, false, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::DEREF_HANDLE_ASSERT, true, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, false, IS_ALLOW_CHECK>;
template class PUBLIC_API AssertScopeT<AssertType::LOCAL_TO_SHARE_WEAK_REF_ASSERT, true, IS_ALLOW_CHECK>;
}