/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ark_hybrid_native_reference.h" #include #include "native_engine/native_api_internal.h" #include "native_engine/native_utils.h" ArkXRefNativeReference::ArkXRefNativeReference(ArkNativeEngine* engine, napi_value value, const ArkNativeReferenceConfig &config) : ArkNativeReference(engine, config) { value_.CreateXRefGloablReference(engine->GetEcmaVm(), LocalValueFromJsValue(value)); ArkNativeReferenceConstructor(); } ArkXRefNativeReference::~ArkXRefNativeReference() { VALID_ENGINE_CHECK(engine_, engine_, engineId_); if (value_.IsEmpty()) { return; } value_.FreeXRefGlobalHandleAddr(); } void ArkXRefNativeReference::FreeXRefGlobalCallBack(void* ref) { auto that = reinterpret_cast(ref); that->value_.FreeXRefGlobalHandleAddr(); } uint32_t ArkXRefNativeReference::Unref() { if (refCount_ == 0) { return refCount_; } --refCount_; if (value_.IsEmpty()) { return refCount_; } if (refCount_ == 0) { value_.SetWeakCallback(reinterpret_cast(this), FreeXRefGlobalCallBack, NativeFinalizeCallBack); } return refCount_; } void ArkXRefNativeReference::ArkNativeReferenceConstructor() { if (napiCallback_ != nullptr) { // Async callback will redirect to root engine, no monitoring needed. if (!IsAsyncCall()) { engine_->IncreaseCallbackbleRefCounter(); // Non-callback runtime owned napi_ref will free when env teardown. if (ownership_ == ReferenceOwnerShip::RUNTIME && !engine_->IsMainEnvContext()) { engine_->IncreaseRuntimeOwnedRefCounter(); } } } else { engine_->IncreaseNonCallbackRefCounter(); } if (refCount_ == 0) { value_.SetWeakCallback(reinterpret_cast(this), FreeXRefGlobalCallBack, NativeFinalizeCallBack); } if (ownership_ == ReferenceOwnerShip::RUNTIME) { NativeReferenceManager* referenceManager = engine_->GetReferenceManager(); if (referenceManager != nullptr) { referenceManager->CreateHandler(this); } } engineId_ = engine_->GetId(); }