• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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