1 /** 2 * Copyright (c) 2021-2025 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 #ifndef RUNTIME_MEM_OBJECT_VMHANDLE_H 16 #define RUNTIME_MEM_OBJECT_VMHANDLE_H 17 18 #include "libpandabase/macros.h" 19 #include "runtime/handle_base.h" 20 #include "runtime/include/managed_thread.h" 21 #include "runtime/handle_scope.h" 22 23 namespace ark { 24 25 using TaggedType = coretypes::TaggedType; 26 using TaggedValue = coretypes::TaggedValue; 27 28 template <typename T> 29 class LocalObjectHandle; 30 31 // VMHandle should be used in language-agnostic part of runtime 32 template <typename T> 33 class VMHandle : public HandleBase { 34 public: VMHandle()35 inline explicit VMHandle() : HandleBase(reinterpret_cast<uintptr_t>(nullptr)) {} 36 VMHandle(ManagedThread * thread,ObjectHeader * object)37 explicit VMHandle(ManagedThread *thread, ObjectHeader *object) 38 { 39 if (object != nullptr) { 40 ASSERT(thread != nullptr); 41 auto scope = thread->GetTopScope<ObjectHeader *>(); 42 ASSERT(scope != nullptr); 43 address_ = scope->NewHandle(object); 44 } else { 45 address_ = reinterpret_cast<uintptr_t>(nullptr); 46 } 47 } 48 49 template <typename P, typename = std::enable_if_t<std::is_convertible_v<P *, T *>>> VMHandle(const VMHandle<P> & other)50 inline explicit VMHandle(const VMHandle<P> &other) : HandleBase(other.GetAddress()) 51 { 52 } 53 54 template <typename P, typename = std::enable_if_t<std::is_convertible_v<P *, T *>>> 55 inline explicit VMHandle(const LocalObjectHandle<P> &other); 56 57 inline explicit VMHandle(mem::GlobalObjectStorage *globalStorage, mem::Reference *reference); 58 59 ~VMHandle() = default; 60 61 DEFAULT_COPY_SEMANTIC(VMHandle); 62 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(VMHandle); 63 GetPtr()64 T *GetPtr() const 65 { 66 if (address_ == reinterpret_cast<uintptr_t>(nullptr)) { 67 return nullptr; 68 } 69 return *(reinterpret_cast<T **>(GetAddress())); 70 } 71 72 explicit operator T *() 73 { 74 return GetPtr(); 75 } 76 77 T *operator->() 78 { 79 T *ptr = GetPtr(); 80 ASSERT(ptr != nullptr); 81 return ptr; 82 } 83 }; 84 85 template <typename T> 86 class VMMutableHandle : public VMHandle<T> { 87 public: VMMutableHandle(ManagedThread * thread,ObjectHeader * object)88 VMMutableHandle(ManagedThread *thread, ObjectHeader *object) 89 { 90 scope_ = thread->GetTopScope<ObjectHeader *>(); 91 ASSERT(scope_ != nullptr); 92 if (object != nullptr) { 93 this->address_ = scope_->NewHandle(object); 94 } else { 95 this->address_ = reinterpret_cast<uintptr_t>(nullptr); 96 } 97 } 98 ~VMMutableHandle() = default; 99 Update(ObjectHeader * object)100 void Update(ObjectHeader *object) 101 { 102 ASSERT(object != nullptr); 103 if (this->address_ == reinterpret_cast<uintptr_t>(nullptr)) { 104 this->address_ = scope_->NewHandle(object); 105 } else { 106 *reinterpret_cast<ObjectHeader **>(this->address_) = object; 107 } 108 } 109 110 NO_COPY_SEMANTIC(VMMutableHandle); 111 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(VMMutableHandle); 112 113 private: 114 HandleScope<ObjectHeader *> *scope_ {nullptr}; 115 }; 116 } // namespace ark 117 118 #endif // RUNTIME_MEM_OBJECT_VMHANDLE_H 119