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 #ifndef PANDA_PLUGINS_ETS_RUNTIME_TYPES_ETS_FINALIZABLE_WEAK_REF_H 16 #define PANDA_PLUGINS_ETS_RUNTIME_TYPES_ETS_FINALIZABLE_WEAK_REF_H 17 18 #include "plugins/ets/runtime/types/ets_weak_reference.h" 19 #include "plugins/ets/runtime/types/ets_primitives.h" 20 #include "plugins/ets/runtime/ets_coroutine.h" 21 22 namespace ark::ets { 23 24 namespace test { 25 class EtsFinalizableWeakRefTest; 26 } // namespace test 27 28 /// @class EtsWeakReference represent std.core.FinalizableWeakRef class 29 class EtsFinalizableWeakRef : public EtsWeakReference { 30 public: 31 using FinalizerFunc = void (*)(void *); 32 using FinalizerArg = void *; 33 34 class Finalizer { 35 public: Finalizer(FinalizerFunc funcPtr,FinalizerArg argPtr)36 explicit Finalizer(FinalizerFunc funcPtr, FinalizerArg argPtr) : funcPtr_(funcPtr), argPtr_(argPtr) {} 37 Run()38 void Run() 39 { 40 ASSERT(!IsEmpty()); 41 funcPtr_(argPtr_); 42 } 43 IsEmpty()44 bool IsEmpty() const 45 { 46 return funcPtr_ == nullptr; 47 } 48 49 private: 50 FinalizerFunc funcPtr_; 51 FinalizerArg argPtr_; 52 }; 53 54 static EtsFinalizableWeakRef *Create(EtsCoroutine *etsCoroutine); 55 FromCoreType(ObjectHeader * finalizableWeakRef)56 static EtsFinalizableWeakRef *FromCoreType(ObjectHeader *finalizableWeakRef) 57 { 58 return reinterpret_cast<EtsFinalizableWeakRef *>(finalizableWeakRef); 59 } 60 FromCoreType(const ObjectHeader * finalizableWeakRef)61 static const EtsFinalizableWeakRef *FromCoreType(const ObjectHeader *finalizableWeakRef) 62 { 63 return reinterpret_cast<const EtsFinalizableWeakRef *>(finalizableWeakRef); 64 } 65 FromEtsObject(EtsObject * finalizableWeakRef)66 static EtsFinalizableWeakRef *FromEtsObject(EtsObject *finalizableWeakRef) 67 { 68 return reinterpret_cast<EtsFinalizableWeakRef *>(finalizableWeakRef); 69 } 70 SetFinalizer(FinalizerFunc funcPtr,FinalizerArg argPtr)71 void SetFinalizer(FinalizerFunc funcPtr, FinalizerArg argPtr) 72 { 73 finalizerPtr_ = reinterpret_cast<EtsLong>(funcPtr); 74 finalizerArgPtr_ = reinterpret_cast<EtsLong>(argPtr); 75 } 76 ReleaseFinalizer()77 Finalizer ReleaseFinalizer() 78 { 79 return Finalizer(reinterpret_cast<FinalizerFunc>(std::exchange(finalizerPtr_, 0)), 80 reinterpret_cast<FinalizerArg>(std::exchange(finalizerArgPtr_, 0))); 81 } 82 GetPrev()83 EtsFinalizableWeakRef *GetPrev() const 84 { 85 auto *prev = ObjectAccessor::GetObject(this, MEMBER_OFFSET(EtsFinalizableWeakRef, prev_)); 86 return FromCoreType(prev); 87 } 88 GetPrevOffset()89 static constexpr size_t GetPrevOffset() 90 { 91 return MEMBER_OFFSET(EtsFinalizableWeakRef, prev_); 92 } 93 GetNext()94 EtsFinalizableWeakRef *GetNext() const 95 { 96 auto *next = ObjectAccessor::GetObject(this, MEMBER_OFFSET(EtsFinalizableWeakRef, next_)); 97 return FromCoreType(next); 98 } 99 GetNextOffset()100 static constexpr size_t GetNextOffset() 101 { 102 return MEMBER_OFFSET(EtsFinalizableWeakRef, next_); 103 } 104 SetPrev(EtsCoroutine * coro,EtsFinalizableWeakRef * weakRef)105 void SetPrev(EtsCoroutine *coro, EtsFinalizableWeakRef *weakRef) 106 { 107 auto *prev = weakRef != nullptr ? weakRef->GetCoreType() : nullptr; 108 ObjectAccessor::SetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, prev_), prev); 109 } 110 SetNext(EtsCoroutine * coro,EtsFinalizableWeakRef * weakRef)111 void SetNext(EtsCoroutine *coro, EtsFinalizableWeakRef *weakRef) 112 { 113 auto *next = weakRef != nullptr ? weakRef->GetCoreType() : nullptr; 114 ObjectAccessor::SetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, next_), next); 115 } 116 117 private: 118 // Such field has the same layout as referent in std.core.FinalizableWeakRef class 119 ObjectPointer<EtsFinalizableWeakRef> prev_; 120 ObjectPointer<EtsFinalizableWeakRef> next_; 121 EtsLong finalizerPtr_; 122 EtsLong finalizerArgPtr_; 123 124 friend class test::EtsFinalizableWeakRefTest; 125 }; 126 127 } // namespace ark::ets 128 129 #endif // PANDA_PLUGINS_ETS_RUNTIME_TYPES_ETS_FINALIZABLE_WEAK_REF_H 130