1 /** 2 * Copyright (c) 2023-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 #ifndef PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_TYPED_POINTER_H_ 17 #define PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_TYPED_POINTER_H_ 18 19 #include "libpandabase/macros.h" 20 21 namespace ark::ets::interop::js::ets_proxy { 22 23 template <typename U, typename R> 24 struct TypedPointer { TypedPointerTypedPointer25 TypedPointer() : TypedPointer(static_cast<U *>(nullptr)) {} 26 TypedPointerTypedPointer27 explicit TypedPointer(U *ptr) 28 { 29 static_assert(alignof(U) >= (1U << 1U)); 30 SetTagged(ptr, true); 31 ASSERT(!IsResolved()); 32 } TypedPointerTypedPointer33 explicit TypedPointer(R *ptr) 34 { 35 static_assert(alignof(R) >= (1U << 1U)); 36 SetTagged(ptr, false); 37 ASSERT(IsResolved()); 38 } 39 IsResolvedTypedPointer40 bool IsResolved() const 41 { 42 return !GetTag(); 43 } 44 GetUnresolvedTypedPointer45 U *GetUnresolved() const 46 { 47 ASSERT(!IsResolved()); 48 return reinterpret_cast<U *>(GetUPtr()); 49 } 50 GetResolvedTypedPointer51 R *GetResolved() const 52 { 53 ASSERT(IsResolved()); 54 return reinterpret_cast<R *>(ptr_); 55 } 56 57 template <typename T> SetTypedPointer58 void Set(T *ptr) 59 { 60 *this = TypedPointer(ptr); 61 } 62 63 DEFAULT_COPY_SEMANTIC(TypedPointer); 64 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(TypedPointer); 65 ~TypedPointer() = default; 66 67 private: 68 uintptr_t static constexpr MASK = ~static_cast<uintptr_t>(1); 69 GetTagTypedPointer70 bool GetTag() const 71 { 72 return static_cast<bool>(ptr_ & ~MASK); 73 } 74 GetUPtrTypedPointer75 uintptr_t GetUPtr() const 76 { 77 return ptr_ & MASK; 78 } 79 80 template <typename T> SetTaggedTypedPointer81 void SetTagged(T *ptr, bool tag) 82 { 83 ptr_ = reinterpret_cast<uintptr_t>(ptr); 84 ASSERT(!GetTag()); 85 ptr_ |= static_cast<uintptr_t>(tag); 86 } 87 88 uintptr_t ptr_ {}; 89 }; 90 91 } // namespace ark::ets::interop::js::ets_proxy 92 93 #endif // !PANDA_PLUGINS_ETS_RUNTIME_INTEROP_JS_TYPED_POINTER_H_ 94