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(EtsCoroutine * coro)83 EtsFinalizableWeakRef *GetPrev(EtsCoroutine *coro) const 84 { 85 auto *prev = ObjectAccessor::GetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, prev_)); 86 return FromCoreType(prev); 87 } 88 GetNext(EtsCoroutine * coro)89 EtsFinalizableWeakRef *GetNext(EtsCoroutine *coro) const 90 { 91 auto *next = ObjectAccessor::GetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, next_)); 92 return FromCoreType(next); 93 } 94 SetPrev(EtsCoroutine * coro,EtsFinalizableWeakRef * weakRef)95 void SetPrev(EtsCoroutine *coro, EtsFinalizableWeakRef *weakRef) 96 { 97 auto *prev = weakRef != nullptr ? weakRef->GetCoreType() : nullptr; 98 ObjectAccessor::SetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, prev_), prev); 99 } 100 SetNext(EtsCoroutine * coro,EtsFinalizableWeakRef * weakRef)101 void SetNext(EtsCoroutine *coro, EtsFinalizableWeakRef *weakRef) 102 { 103 auto *next = weakRef != nullptr ? weakRef->GetCoreType() : nullptr; 104 ObjectAccessor::SetObject(coro, this, MEMBER_OFFSET(EtsFinalizableWeakRef, next_), next); 105 } 106 107 private: 108 // Such field has the same layout as referent in std.core.FinalizableWeakRef class 109 ObjectPointer<EtsFinalizableWeakRef> prev_; 110 ObjectPointer<EtsFinalizableWeakRef> next_; 111 EtsLong finalizerPtr_; 112 EtsLong finalizerArgPtr_; 113 114 friend class test::EtsFinalizableWeakRefTest; 115 }; 116 117 } // namespace ark::ets 118 119 #endif // PANDA_PLUGINS_ETS_RUNTIME_TYPES_ETS_FINALIZABLE_WEAK_REF_H 120