• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include <cinttypes>
17 
18 #include "ark_native_reference.h"
19 
20 #include "native_engine/native_api_internal.h"
21 #include "native_engine/native_utils.h"
22 
ArkNativeReference(ArkNativeEngine * engine,napi_value value,uint32_t initialRefcount,bool deleteSelf,NapiNativeFinalize napiCallback,void * data,void * hint,bool isAsyncCall,size_t nativeBindingSize)23 ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine,
24                                        napi_value value,
25                                        uint32_t initialRefcount,
26                                        bool deleteSelf,
27                                        NapiNativeFinalize napiCallback,
28                                        void* data,
29                                        void* hint,
30                                        bool isAsyncCall,
31                                        size_t nativeBindingSize)
32     : engine_(engine),
33       value_(engine->GetEcmaVm(), LocalValueFromJsValue(value)),
34       refCount_(initialRefcount),
35       deleteSelf_(deleteSelf),
36       isAsyncCall_(isAsyncCall),
37       napiCallback_(napiCallback),
38       data_(data),
39       hint_(hint),
40       nativeBindingSize_(nativeBindingSize)
41 {
42     ArkNativeReferenceConstructor(initialRefcount, deleteSelf);
43 }
44 
ArkNativeReference(ArkNativeEngine * engine,Local<JSValueRef> value,uint32_t initialRefcount,bool deleteSelf,NapiNativeFinalize napiCallback,void * data,void * hint,bool isAsyncCall,size_t nativeBindingSize)45 ArkNativeReference::ArkNativeReference(ArkNativeEngine* engine,
46                                        Local<JSValueRef> value,
47                                        uint32_t initialRefcount,
48                                        bool deleteSelf,
49                                        NapiNativeFinalize napiCallback,
50                                        void* data,
51                                        void* hint,
52                                        bool isAsyncCall,
53                                        size_t nativeBindingSize)
54     : engine_(engine),
55       value_(engine->GetEcmaVm(), value),
56       refCount_(initialRefcount),
57       deleteSelf_(deleteSelf),
58       isAsyncCall_(isAsyncCall),
59       napiCallback_(napiCallback),
60       data_(data),
61       hint_(hint),
62       nativeBindingSize_(nativeBindingSize)
63 {
64     ArkNativeReferenceConstructor(initialRefcount, deleteSelf);
65 }
66 
~ArkNativeReference()67 ArkNativeReference::~ArkNativeReference()
68 {
69     VALID_ENGINE_CHECK(engine_, engine_, engineId_);
70 
71     if (deleteSelf_ && engine_->GetReferenceManager()) {
72         engine_->GetReferenceManager()->ReleaseHandler(this);
73         prev_ = nullptr;
74         next_ = nullptr;
75     }
76     if (value_.IsEmpty()) {
77         return;
78     }
79     hasDelete_ = true;
80     value_.FreeGlobalHandleAddr();
81     FinalizeCallback(FinalizerState::DESTRUCTION);
82 }
83 
Ref()84 uint32_t ArkNativeReference::Ref()
85 {
86     ++refCount_;
87     if (refCount_ == 1) {
88         value_.ClearWeak();
89     }
90     return refCount_;
91 }
92 
Unref()93 uint32_t ArkNativeReference::Unref()
94 {
95     if (refCount_ == 0) {
96         return refCount_;
97     }
98     --refCount_;
99     if (value_.IsEmpty()) {
100         return refCount_;
101     }
102     if (refCount_ == 0) {
103         value_.SetWeakCallback(reinterpret_cast<void*>(this), FreeGlobalCallBack, NativeFinalizeCallBack);
104     }
105     return refCount_;
106 }
107 
Get(NativeEngine * engine)108 napi_value ArkNativeReference::Get(NativeEngine* engine)
109 {
110     if (value_.IsEmpty()) {
111         return nullptr;
112     }
113     VALID_ENGINE_CHECK(engine, engine_, engineId_);
114     Local<JSValueRef> value = value_.ToLocal(engine->GetEcmaVm());
115     return JsValueFromLocalValue(value);
116 }
117 
Get()118 napi_value ArkNativeReference::Get()
119 {
120     return Get(engine_);
121 }
122 
operator napi_value()123 ArkNativeReference::operator napi_value()
124 {
125     return Get(engine_);
126 }
127 
GetData()128 void* ArkNativeReference::GetData()
129 {
130     return data_;
131 }
132 
FinalizeCallback(FinalizerState state)133 void ArkNativeReference::FinalizeCallback(FinalizerState state)
134 {
135     if (napiCallback_ != nullptr && !engine_->IsInDestructor()) {
136         if (state == FinalizerState::COLLECTION) {
137             if (isAsyncCall_) {
138                 std::pair<void*, void*> pair = std::make_pair(data_, hint_);
139                 RefAsyncFinalizer asyncFinalizer = std::make_pair(napiCallback_, pair);
140                 engine_->GetPendingAsyncFinalizers().emplace_back(asyncFinalizer);
141             } else {
142                 std::tuple<NativeEngine*, void*, void*> tuple = std::make_tuple(engine_, data_, hint_);
143                 RefFinalizer finalizer = std::make_pair(napiCallback_, tuple);
144                 engine_->GetArkFinalizersPack().AddFinalizer(finalizer, nativeBindingSize_);
145             }
146         } else {
147             napiCallback_(reinterpret_cast<napi_env>(engine_), data_, hint_);
148         }
149     }
150     napiCallback_ = nullptr;
151     data_ = nullptr;
152     hint_ = nullptr;
153     finalRun_ = true;
154 
155     if (deleteSelf_ && !hasDelete_) {
156         delete this;
157     }
158 }
159 
FreeGlobalCallBack(void * ref)160 void ArkNativeReference::FreeGlobalCallBack(void* ref)
161 {
162     auto that = reinterpret_cast<ArkNativeReference*>(ref);
163     that->value_.FreeGlobalHandleAddr();
164 }
165 
NativeFinalizeCallBack(void * ref)166 void ArkNativeReference::NativeFinalizeCallBack(void* ref)
167 {
168     auto that = reinterpret_cast<ArkNativeReference*>(ref);
169     that->FinalizeCallback(FinalizerState::COLLECTION);
170 }
171 
SetDeleteSelf()172 void ArkNativeReference::SetDeleteSelf()
173 {
174     deleteSelf_ = true;
175 }
176 
GetDeleteSelf() const177 bool ArkNativeReference::GetDeleteSelf() const
178 {
179     return deleteSelf_;
180 }
181 
GetRefCount()182 uint32_t ArkNativeReference::GetRefCount()
183 {
184     return refCount_;
185 }
186 
GetFinalRun()187 bool ArkNativeReference::GetFinalRun()
188 {
189     return finalRun_;
190 }
191 
GetNapiValue()192 napi_value ArkNativeReference::GetNapiValue()
193 {
194     return Get();
195 }
196 
ResetFinalizer()197 void ArkNativeReference::ResetFinalizer()
198 {
199     napiCallback_ = nullptr;
200     data_ = nullptr;
201     hint_ = nullptr;
202 }