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