• 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(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