• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "ark_hybrid_native_reference.h"
17 
18 #include <cinttypes>
19 
20 #include "native_engine/native_api_internal.h"
21 #include "native_engine/native_utils.h"
22 
ArkXRefNativeReference(ArkNativeEngine * engine,napi_value value,const ArkNativeReferenceConfig & config)23 ArkXRefNativeReference::ArkXRefNativeReference(ArkNativeEngine* engine,
24                                                napi_value value,
25                                                const ArkNativeReferenceConfig &config)
26     : ArkNativeReference(engine, config)
27 {
28     value_.CreateXRefGloablReference(engine->GetEcmaVm(), LocalValueFromJsValue(value));
29     ArkNativeReferenceConstructor();
30 }
31 
~ArkXRefNativeReference()32 ArkXRefNativeReference::~ArkXRefNativeReference()
33 {
34     VALID_ENGINE_CHECK(engine_, engine_, engineId_);
35 
36     if (value_.IsEmpty()) {
37         return;
38     }
39     value_.FreeXRefGlobalHandleAddr();
40 }
41 
FreeXRefGlobalCallBack(void * ref)42 void ArkXRefNativeReference::FreeXRefGlobalCallBack(void* ref)
43 {
44     auto that = reinterpret_cast<ArkXRefNativeReference*>(ref);
45     that->value_.FreeXRefGlobalHandleAddr();
46 }
47 
Unref()48 uint32_t ArkXRefNativeReference::Unref()
49 {
50     if (refCount_ == 0) {
51         return refCount_;
52     }
53     --refCount_;
54     if (value_.IsEmpty()) {
55         return refCount_;
56     }
57     if (refCount_ == 0) {
58         value_.SetWeakCallback(reinterpret_cast<void*>(this), FreeXRefGlobalCallBack, NativeFinalizeCallBack);
59     }
60     return refCount_;
61 }
62 
ArkNativeReferenceConstructor()63 void ArkXRefNativeReference::ArkNativeReferenceConstructor()
64 {
65     if (napiCallback_ != nullptr) {
66         // Async callback will redirect to root engine, no monitoring needed.
67         if (!IsAsyncCall()) {
68             engine_->IncreaseCallbackbleRefCounter();
69             // Non-callback runtime owned napi_ref will free when env teardown.
70             if (ownership_ == ReferenceOwnerShip::RUNTIME && !engine_->IsMainEnvContext()) {
71                 engine_->IncreaseRuntimeOwnedRefCounter();
72             }
73         }
74     } else {
75         engine_->IncreaseNonCallbackRefCounter();
76     }
77 
78     if (refCount_ == 0) {
79         value_.SetWeakCallback(reinterpret_cast<void*>(this), FreeXRefGlobalCallBack, NativeFinalizeCallBack);
80     }
81 
82     if (ownership_ == ReferenceOwnerShip::RUNTIME) {
83         NativeReferenceManager* referenceManager = engine_->GetReferenceManager();
84         if (referenceManager != nullptr) {
85             referenceManager->CreateHandler(this);
86         }
87     }
88 
89     engineId_ = engine_->GetId();
90 }
91