133eb0b6dSopenharmony_ci/*
233eb0b6dSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
333eb0b6dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
433eb0b6dSopenharmony_ci * you may not use this file except in compliance with the License.
533eb0b6dSopenharmony_ci * You may obtain a copy of the License at
633eb0b6dSopenharmony_ci *
733eb0b6dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
833eb0b6dSopenharmony_ci *
933eb0b6dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1033eb0b6dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1133eb0b6dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1233eb0b6dSopenharmony_ci * See the License for the specific language governing permissions and
1333eb0b6dSopenharmony_ci * limitations under the License.
1433eb0b6dSopenharmony_ci */
1533eb0b6dSopenharmony_ci
1633eb0b6dSopenharmony_ci#include "ecmascript/napi/include/jsnapi.h"
1733eb0b6dSopenharmony_ci#include "napi/native_node_api.h"
1833eb0b6dSopenharmony_ci#include "native_api_internal.h"
1933eb0b6dSopenharmony_ci#include "native_engine/impl/ark/ark_native_options.h"
2033eb0b6dSopenharmony_ci#include "native_engine/native_async_hook_context.h"
2133eb0b6dSopenharmony_ci#include "native_engine/native_engine.h"
2233eb0b6dSopenharmony_ci#include "native_engine/native_utils.h"
2333eb0b6dSopenharmony_ci#include "utils/log.h"
2433eb0b6dSopenharmony_ci
2533eb0b6dSopenharmony_ciusing panda::Local;
2633eb0b6dSopenharmony_ciusing panda::StringRef;
2733eb0b6dSopenharmony_ci
2833eb0b6dSopenharmony_cistatic constexpr int32_t MAX_THREAD_SAFE_COUNT = 128;
2933eb0b6dSopenharmony_ci
3033eb0b6dSopenharmony_ciNAPI_EXTERN void napi_module_register(napi_module* mod)
3133eb0b6dSopenharmony_ci{
3233eb0b6dSopenharmony_ci    if (mod == nullptr) {
3333eb0b6dSopenharmony_ci        HILOG_ERROR("mod is nullptr");
3433eb0b6dSopenharmony_ci        return;
3533eb0b6dSopenharmony_ci    }
3633eb0b6dSopenharmony_ci
3733eb0b6dSopenharmony_ci    NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
3833eb0b6dSopenharmony_ci    NativeModule module;
3933eb0b6dSopenharmony_ci
4033eb0b6dSopenharmony_ci    module.version = mod->nm_version;
4133eb0b6dSopenharmony_ci    module.fileName = mod->nm_filename;
4233eb0b6dSopenharmony_ci    module.name = mod->nm_modname;
4333eb0b6dSopenharmony_ci    module.flags = mod->nm_flags;
4433eb0b6dSopenharmony_ci    module.registerCallback = (RegisterCallback)mod->nm_register_func;
4533eb0b6dSopenharmony_ci
4633eb0b6dSopenharmony_ci    moduleManager->Register(&module);
4733eb0b6dSopenharmony_ci}
4833eb0b6dSopenharmony_ci
4933eb0b6dSopenharmony_ciNAPI_EXTERN void napi_module_with_js_register(napi_module_with_js* mod)
5033eb0b6dSopenharmony_ci{
5133eb0b6dSopenharmony_ci    if (mod == nullptr) {
5233eb0b6dSopenharmony_ci        HILOG_ERROR("mod is nullptr");
5333eb0b6dSopenharmony_ci        return;
5433eb0b6dSopenharmony_ci    }
5533eb0b6dSopenharmony_ci
5633eb0b6dSopenharmony_ci    NativeModuleManager* moduleManager = NativeModuleManager::GetInstance();
5733eb0b6dSopenharmony_ci    NativeModule module;
5833eb0b6dSopenharmony_ci
5933eb0b6dSopenharmony_ci    module.version = mod->nm_version;
6033eb0b6dSopenharmony_ci    module.fileName = mod->nm_filename;
6133eb0b6dSopenharmony_ci    module.name = mod->nm_modname;
6233eb0b6dSopenharmony_ci    module.registerCallback = (RegisterCallback)mod->nm_register_func;
6333eb0b6dSopenharmony_ci    module.getJSCode = (GetJSCodeCallback)mod->nm_get_js_code;
6433eb0b6dSopenharmony_ci    module.getABCCode = (GetJSCodeCallback)mod->nm_get_abc_code;
6533eb0b6dSopenharmony_ci
6633eb0b6dSopenharmony_ci    moduleManager->Register(&module);
6733eb0b6dSopenharmony_ci}
6833eb0b6dSopenharmony_ci
6933eb0b6dSopenharmony_ciNAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location,
7033eb0b6dSopenharmony_ci                                                 size_t location_len,
7133eb0b6dSopenharmony_ci                                                 const char* message,
7233eb0b6dSopenharmony_ci                                                 size_t message_len)
7333eb0b6dSopenharmony_ci{
7433eb0b6dSopenharmony_ci    (void)location_len;
7533eb0b6dSopenharmony_ci    (void)message_len;
7633eb0b6dSopenharmony_ci    HILOG_FATAL("FATAL ERROR: %{public}s %{public}s\n", location, message);
7733eb0b6dSopenharmony_ci}
7833eb0b6dSopenharmony_ci
7933eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_create_limit_runtime(napi_env env, napi_env* result_env)
8033eb0b6dSopenharmony_ci{
8133eb0b6dSopenharmony_ci    CHECK_ENV(env);
8233eb0b6dSopenharmony_ci    CHECK_ARG(env, result_env);
8333eb0b6dSopenharmony_ci
8433eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
8533eb0b6dSopenharmony_ci
8633eb0b6dSopenharmony_ci    auto result = engine->CreateRuntime(true);
8733eb0b6dSopenharmony_ci    *result_env = reinterpret_cast<napi_env>(result);
8833eb0b6dSopenharmony_ci
8933eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
9033eb0b6dSopenharmony_ci}
9133eb0b6dSopenharmony_ci
9233eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_fatal_exception(napi_env env, napi_value err)
9333eb0b6dSopenharmony_ci{
9433eb0b6dSopenharmony_ci    NAPI_PREAMBLE(env);
9533eb0b6dSopenharmony_ci    CHECK_ENV(env);
9633eb0b6dSopenharmony_ci    CHECK_ARG(env, err);
9733eb0b6dSopenharmony_ci
9833eb0b6dSopenharmony_ci    auto exceptionValue = LocalValueFromJsValue(err);
9933eb0b6dSopenharmony_ci    auto ecmaVm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
10033eb0b6dSopenharmony_ci    RETURN_STATUS_IF_FALSE(env, exceptionValue->IsError(ecmaVm), napi_invalid_arg);
10133eb0b6dSopenharmony_ci
10233eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
10333eb0b6dSopenharmony_ci    engine->TriggerFatalException(exceptionValue);
10433eb0b6dSopenharmony_ci    return napi_ok;
10533eb0b6dSopenharmony_ci}
10633eb0b6dSopenharmony_ci
10733eb0b6dSopenharmony_ci// Methods to manage simple async operations
10833eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_create_async_work(napi_env env,
10933eb0b6dSopenharmony_ci                                               napi_value async_resource,
11033eb0b6dSopenharmony_ci                                               napi_value async_resource_name,
11133eb0b6dSopenharmony_ci                                               napi_async_execute_callback execute,
11233eb0b6dSopenharmony_ci                                               napi_async_complete_callback complete,
11333eb0b6dSopenharmony_ci                                               void* data,
11433eb0b6dSopenharmony_ci                                               napi_async_work* result)
11533eb0b6dSopenharmony_ci{
11633eb0b6dSopenharmony_ci    CHECK_ENV(env);
11733eb0b6dSopenharmony_ci    CHECK_ARG(env, async_resource_name);
11833eb0b6dSopenharmony_ci    CHECK_ARG(env, execute);
11933eb0b6dSopenharmony_ci    CHECK_ARG(env, complete);
12033eb0b6dSopenharmony_ci    CHECK_ARG(env, result);
12133eb0b6dSopenharmony_ci
12233eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
12333eb0b6dSopenharmony_ci    auto ecmaVm = engine->GetEcmaVm();
12433eb0b6dSopenharmony_ci    auto asyncResource = LocalValueFromJsValue(async_resource);
12533eb0b6dSopenharmony_ci    auto asyncResourceName = LocalValueFromJsValue(async_resource_name);
12633eb0b6dSopenharmony_ci    auto asyncExecute = reinterpret_cast<NativeAsyncExecuteCallback>(execute);
12733eb0b6dSopenharmony_ci    auto asyncComplete = reinterpret_cast<NativeAsyncCompleteCallback>(complete);
12833eb0b6dSopenharmony_ci    (void)asyncResource;
12933eb0b6dSopenharmony_ci    (void)asyncResourceName;
13033eb0b6dSopenharmony_ci    char name[64] = {0}; // 64:NAME_BUFFER_SIZE
13133eb0b6dSopenharmony_ci    if (!asyncResourceName->IsNull()) {
13233eb0b6dSopenharmony_ci        panda::Local<panda::StringRef> nativeString(asyncResourceName);
13333eb0b6dSopenharmony_ci        uint32_t copied = nativeString->WriteUtf8(ecmaVm, name, 63, true) - 1;  // 63:NAME_BUFFER_SIZE
13433eb0b6dSopenharmony_ci        name[copied] = '\0';
13533eb0b6dSopenharmony_ci    }
13633eb0b6dSopenharmony_ci    auto asyncWork  = new NativeAsyncWork(engine, asyncExecute, asyncComplete, name, data);
13733eb0b6dSopenharmony_ci    *result = reinterpret_cast<napi_async_work>(asyncWork);
13833eb0b6dSopenharmony_ci    return napi_status::napi_ok;
13933eb0b6dSopenharmony_ci}
14033eb0b6dSopenharmony_ci
14133eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_delete_async_work(napi_env env, napi_async_work work)
14233eb0b6dSopenharmony_ci{
14333eb0b6dSopenharmony_ci    CHECK_ENV(env);
14433eb0b6dSopenharmony_ci    CHECK_ARG(env, work);
14533eb0b6dSopenharmony_ci
14633eb0b6dSopenharmony_ci    auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
14733eb0b6dSopenharmony_ci    delete asyncWork;
14833eb0b6dSopenharmony_ci    asyncWork = nullptr;
14933eb0b6dSopenharmony_ci
15033eb0b6dSopenharmony_ci    return napi_status::napi_ok;
15133eb0b6dSopenharmony_ci}
15233eb0b6dSopenharmony_ci
15333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_queue_async_work(napi_env env, napi_async_work work)
15433eb0b6dSopenharmony_ci{
15533eb0b6dSopenharmony_ci    CHECK_ENV(env);
15633eb0b6dSopenharmony_ci    CHECK_ARG(env, work);
15733eb0b6dSopenharmony_ci
15833eb0b6dSopenharmony_ci    auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
15933eb0b6dSopenharmony_ci
16033eb0b6dSopenharmony_ci    asyncWork->Queue();
16133eb0b6dSopenharmony_ci    return napi_status::napi_ok;
16233eb0b6dSopenharmony_ci}
16333eb0b6dSopenharmony_ci
16433eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_cancel_async_work(napi_env env, napi_async_work work)
16533eb0b6dSopenharmony_ci{
16633eb0b6dSopenharmony_ci    CHECK_ENV(env);
16733eb0b6dSopenharmony_ci    CHECK_ARG(env, work);
16833eb0b6dSopenharmony_ci
16933eb0b6dSopenharmony_ci    auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work);
17033eb0b6dSopenharmony_ci
17133eb0b6dSopenharmony_ci    asyncWork->Cancel();
17233eb0b6dSopenharmony_ci    return napi_status::napi_ok;
17333eb0b6dSopenharmony_ci}
17433eb0b6dSopenharmony_ci
17533eb0b6dSopenharmony_ci// Version management
17633eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_get_node_version(napi_env env, const napi_node_version** version)
17733eb0b6dSopenharmony_ci{
17833eb0b6dSopenharmony_ci    (void)version;
17933eb0b6dSopenharmony_ci    return napi_status::napi_ok;
18033eb0b6dSopenharmony_ci}
18133eb0b6dSopenharmony_ci
18233eb0b6dSopenharmony_ci// Return the current libuv event loop for a given environment
18333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, struct uv_loop_s** loop)
18433eb0b6dSopenharmony_ci{
18533eb0b6dSopenharmony_ci    CHECK_ENV(env);
18633eb0b6dSopenharmony_ci    CHECK_ARG(env, loop);
18733eb0b6dSopenharmony_ci
18833eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
18933eb0b6dSopenharmony_ci    if (!NativeEngine::IsAlive(engine)) {
19033eb0b6dSopenharmony_ci        HILOG_ERROR("napi_env has been destoryed!");
19133eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
19233eb0b6dSopenharmony_ci    }
19333eb0b6dSopenharmony_ci    *loop = engine->GetUVLoop();
19433eb0b6dSopenharmony_ci
19533eb0b6dSopenharmony_ci    return napi_status::napi_ok;
19633eb0b6dSopenharmony_ci}
19733eb0b6dSopenharmony_ci
19833eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg)
19933eb0b6dSopenharmony_ci{
20033eb0b6dSopenharmony_ci    CHECK_ENV(env);
20133eb0b6dSopenharmony_ci    CHECK_ARG(env, fun);
20233eb0b6dSopenharmony_ci    WEAK_CROSS_THREAD_CHECK(env);
20333eb0b6dSopenharmony_ci
20433eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
20533eb0b6dSopenharmony_ci    engine->AddCleanupHook(fun, arg);
20633eb0b6dSopenharmony_ci
20733eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
20833eb0b6dSopenharmony_ci}
20933eb0b6dSopenharmony_ci
21033eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg)
21133eb0b6dSopenharmony_ci{
21233eb0b6dSopenharmony_ci    CHECK_ENV(env);
21333eb0b6dSopenharmony_ci    CHECK_ARG(env, fun);
21433eb0b6dSopenharmony_ci    WEAK_CROSS_THREAD_CHECK(env);
21533eb0b6dSopenharmony_ci
21633eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
21733eb0b6dSopenharmony_ci    engine->RemoveCleanupHook(fun, arg);
21833eb0b6dSopenharmony_ci
21933eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
22033eb0b6dSopenharmony_ci}
22133eb0b6dSopenharmony_ci
22233eb0b6dSopenharmony_ciusing CleanupHook = void (*)(void* arg);
22333eb0b6dSopenharmony_ciusing AsyncCleanupHook = void (*)(void* arg, void (*)(void*), void*);
22433eb0b6dSopenharmony_ci
22533eb0b6dSopenharmony_cistruct AsyncCleanupHookInfo final {
22633eb0b6dSopenharmony_ci    napi_env env_;
22733eb0b6dSopenharmony_ci    AsyncCleanupHook fun_;
22833eb0b6dSopenharmony_ci    void* arg_;
22933eb0b6dSopenharmony_ci    bool started_ = false;
23033eb0b6dSopenharmony_ci    // Use a self-reference to make sure the storage is kept alive while the
23133eb0b6dSopenharmony_ci    // cleanup hook is registered but not yet finished.
23233eb0b6dSopenharmony_ci    std::shared_ptr<AsyncCleanupHookInfo> self_;
23333eb0b6dSopenharmony_ci};
23433eb0b6dSopenharmony_ci
23533eb0b6dSopenharmony_ci// Opaque type that is basically an alias for `shared_ptr<AsyncCleanupHookInfo>`
23633eb0b6dSopenharmony_ci// (but not publicly so for easier ABI/API changes). In particular,
23733eb0b6dSopenharmony_ci// std::shared_ptr does not generally maintain a consistent ABI even on a
23833eb0b6dSopenharmony_ci// specific platform.
23933eb0b6dSopenharmony_cistruct ACHHandle final {
24033eb0b6dSopenharmony_ci    std::shared_ptr<AsyncCleanupHookInfo> info_;
24133eb0b6dSopenharmony_ci};
24233eb0b6dSopenharmony_ci
24333eb0b6dSopenharmony_cistruct DeleteACHHandle {
24433eb0b6dSopenharmony_ci    void operator()(ACHHandle* handle) const
24533eb0b6dSopenharmony_ci    {
24633eb0b6dSopenharmony_ci        delete handle;
24733eb0b6dSopenharmony_ci    };
24833eb0b6dSopenharmony_ci};
24933eb0b6dSopenharmony_ciusing AsyncCleanupHookHandle = std::unique_ptr<ACHHandle, DeleteACHHandle>;
25033eb0b6dSopenharmony_ci
25133eb0b6dSopenharmony_cistatic void FinishAsyncCleanupHook(void* arg)
25233eb0b6dSopenharmony_ci{
25333eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, start.", __func__);
25433eb0b6dSopenharmony_ci    AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg);
25533eb0b6dSopenharmony_ci    std::shared_ptr<AsyncCleanupHookInfo> keep_alive = info->self_;
25633eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(info->env_);
25733eb0b6dSopenharmony_ci    engine->DecreaseWaitingRequestCounter();
25833eb0b6dSopenharmony_ci    info->self_.reset();
25933eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, end.", __func__);
26033eb0b6dSopenharmony_ci}
26133eb0b6dSopenharmony_ci
26233eb0b6dSopenharmony_cistatic void RunAsyncCleanupHook(void* arg)
26333eb0b6dSopenharmony_ci{
26433eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, start.", __func__);
26533eb0b6dSopenharmony_ci    AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg);
26633eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(info->env_);
26733eb0b6dSopenharmony_ci    engine->IncreaseWaitingRequestCounter();
26833eb0b6dSopenharmony_ci    info->started_ = true;
26933eb0b6dSopenharmony_ci    info->fun_(info->arg_, FinishAsyncCleanupHook, info);
27033eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, end.", __func__);
27133eb0b6dSopenharmony_ci}
27233eb0b6dSopenharmony_ci
27333eb0b6dSopenharmony_cistatic AsyncCleanupHookHandle AddEnvironmentCleanupHook(napi_env env, AsyncCleanupHook fun, void* arg)
27433eb0b6dSopenharmony_ci{
27533eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, start.", __func__);
27633eb0b6dSopenharmony_ci    auto info = std::make_shared<AsyncCleanupHookInfo>();
27733eb0b6dSopenharmony_ci    info->env_ = env;
27833eb0b6dSopenharmony_ci    info->fun_ = fun;
27933eb0b6dSopenharmony_ci    info->arg_ = arg;
28033eb0b6dSopenharmony_ci    info->self_ = info;
28133eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
28233eb0b6dSopenharmony_ci    engine->AddCleanupHook(RunAsyncCleanupHook, info.get());
28333eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, end.", __func__);
28433eb0b6dSopenharmony_ci    return AsyncCleanupHookHandle(new ACHHandle { info });
28533eb0b6dSopenharmony_ci}
28633eb0b6dSopenharmony_ci
28733eb0b6dSopenharmony_cistatic void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle handle)
28833eb0b6dSopenharmony_ci{
28933eb0b6dSopenharmony_ci    if (handle->info_->started_) {
29033eb0b6dSopenharmony_ci        return;
29133eb0b6dSopenharmony_ci    }
29233eb0b6dSopenharmony_ci    handle->info_->self_.reset();
29333eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(handle->info_->env_);
29433eb0b6dSopenharmony_ci    engine->RemoveCleanupHook(RunAsyncCleanupHook, handle->info_.get());
29533eb0b6dSopenharmony_ci}
29633eb0b6dSopenharmony_ci
29733eb0b6dSopenharmony_cistruct napi_async_cleanup_hook_handle__ {
29833eb0b6dSopenharmony_ci    napi_async_cleanup_hook_handle__(napi_env env, napi_async_cleanup_hook user_hook, void* user_data)
29933eb0b6dSopenharmony_ci        : env_(env), user_hook_(user_hook), user_data_(user_data)
30033eb0b6dSopenharmony_ci    {
30133eb0b6dSopenharmony_ci        handle_ = AddEnvironmentCleanupHook(env, Hook, this);
30233eb0b6dSopenharmony_ci    }
30333eb0b6dSopenharmony_ci
30433eb0b6dSopenharmony_ci    ~napi_async_cleanup_hook_handle__()
30533eb0b6dSopenharmony_ci    {
30633eb0b6dSopenharmony_ci        RemoveEnvironmentCleanupHook(std::move(handle_));
30733eb0b6dSopenharmony_ci        if (done_cb_ != nullptr) {
30833eb0b6dSopenharmony_ci            done_cb_(done_data_);
30933eb0b6dSopenharmony_ci        }
31033eb0b6dSopenharmony_ci    }
31133eb0b6dSopenharmony_ci
31233eb0b6dSopenharmony_ci    static void Hook(void* data, void (*done_cb)(void*), void* done_data)
31333eb0b6dSopenharmony_ci    {
31433eb0b6dSopenharmony_ci        auto handle = static_cast<napi_async_cleanup_hook_handle__*>(data);
31533eb0b6dSopenharmony_ci        handle->done_cb_ = done_cb;
31633eb0b6dSopenharmony_ci        handle->done_data_ = done_data;
31733eb0b6dSopenharmony_ci        handle->user_hook_(handle, handle->user_data_);
31833eb0b6dSopenharmony_ci    }
31933eb0b6dSopenharmony_ci
32033eb0b6dSopenharmony_ci    AsyncCleanupHookHandle handle_;
32133eb0b6dSopenharmony_ci    napi_env env_ = nullptr;
32233eb0b6dSopenharmony_ci    napi_async_cleanup_hook user_hook_ = nullptr;
32333eb0b6dSopenharmony_ci    void* user_data_ = nullptr;
32433eb0b6dSopenharmony_ci    void (*done_cb_)(void*) = nullptr;
32533eb0b6dSopenharmony_ci    void* done_data_ = nullptr;
32633eb0b6dSopenharmony_ci};
32733eb0b6dSopenharmony_ci
32833eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_add_async_cleanup_hook(
32933eb0b6dSopenharmony_ci    napi_env env, napi_async_cleanup_hook hook, void* arg, napi_async_cleanup_hook_handle* remove_handle)
33033eb0b6dSopenharmony_ci{
33133eb0b6dSopenharmony_ci    CHECK_ENV(env);
33233eb0b6dSopenharmony_ci    CHECK_ARG(env, hook);
33333eb0b6dSopenharmony_ci    CROSS_THREAD_CHECK(env);
33433eb0b6dSopenharmony_ci
33533eb0b6dSopenharmony_ci    napi_async_cleanup_hook_handle__* handle = new napi_async_cleanup_hook_handle__(env, hook, arg);
33633eb0b6dSopenharmony_ci
33733eb0b6dSopenharmony_ci    if (remove_handle != nullptr)
33833eb0b6dSopenharmony_ci        *remove_handle = handle;
33933eb0b6dSopenharmony_ci
34033eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
34133eb0b6dSopenharmony_ci}
34233eb0b6dSopenharmony_ci
34333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle)
34433eb0b6dSopenharmony_ci{
34533eb0b6dSopenharmony_ci    if (remove_handle == nullptr) {
34633eb0b6dSopenharmony_ci        return napi_invalid_arg;
34733eb0b6dSopenharmony_ci    }
34833eb0b6dSopenharmony_ci
34933eb0b6dSopenharmony_ci    delete remove_handle;
35033eb0b6dSopenharmony_ci    return napi_ok;
35133eb0b6dSopenharmony_ci}
35233eb0b6dSopenharmony_ci
35333eb0b6dSopenharmony_ci// Methods to manager threadsafe
35433eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_create_threadsafe_function(napi_env env, napi_value func, napi_value async_resource,
35533eb0b6dSopenharmony_ci    napi_value async_resource_name, size_t max_queue_size, size_t initial_thread_count, void* thread_finalize_data,
35633eb0b6dSopenharmony_ci    napi_finalize thread_finalize_cb, void* context, napi_threadsafe_function_call_js call_js_cb,
35733eb0b6dSopenharmony_ci    napi_threadsafe_function* result)
35833eb0b6dSopenharmony_ci{
35933eb0b6dSopenharmony_ci    CHECK_ENV(env);
36033eb0b6dSopenharmony_ci    CHECK_ARG(env, async_resource_name);
36133eb0b6dSopenharmony_ci    RETURN_STATUS_IF_FALSE(env, max_queue_size >= 0, napi_invalid_arg);
36233eb0b6dSopenharmony_ci    RETURN_STATUS_IF_FALSE(
36333eb0b6dSopenharmony_ci        env, initial_thread_count > 0 && initial_thread_count <= MAX_THREAD_SAFE_COUNT, napi_invalid_arg);
36433eb0b6dSopenharmony_ci    CHECK_ARG(env, result);
36533eb0b6dSopenharmony_ci    if (func == nullptr) {
36633eb0b6dSopenharmony_ci        CHECK_ARG(env, call_js_cb);
36733eb0b6dSopenharmony_ci    }
36833eb0b6dSopenharmony_ci
36933eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
37033eb0b6dSopenharmony_ci    auto finalizeCallback = reinterpret_cast<NativeFinalize>(thread_finalize_cb);
37133eb0b6dSopenharmony_ci    auto callJsCallback = reinterpret_cast<NativeThreadSafeFunctionCallJs>(call_js_cb);
37233eb0b6dSopenharmony_ci    auto safeAsyncWork = engine->CreateSafeAsyncWork(func, async_resource, async_resource_name, max_queue_size,
37333eb0b6dSopenharmony_ci        initial_thread_count, thread_finalize_data, finalizeCallback, context, callJsCallback);
37433eb0b6dSopenharmony_ci    CHECK_ENV(safeAsyncWork);
37533eb0b6dSopenharmony_ci
37633eb0b6dSopenharmony_ci    auto ret = safeAsyncWork->Init();
37733eb0b6dSopenharmony_ci    if (ret) {
37833eb0b6dSopenharmony_ci        *result = reinterpret_cast<napi_threadsafe_function>(safeAsyncWork);
37933eb0b6dSopenharmony_ci    } else {
38033eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
38133eb0b6dSopenharmony_ci    }
38233eb0b6dSopenharmony_ci
38333eb0b6dSopenharmony_ci    return napi_status::napi_ok;
38433eb0b6dSopenharmony_ci}
38533eb0b6dSopenharmony_ci
38633eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_call_threadsafe_function(
38733eb0b6dSopenharmony_ci    napi_threadsafe_function func, void* data, napi_threadsafe_function_call_mode is_blocking)
38833eb0b6dSopenharmony_ci{
38933eb0b6dSopenharmony_ci    CHECK_ENV(func);
39033eb0b6dSopenharmony_ci
39133eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
39233eb0b6dSopenharmony_ci    auto callMode = static_cast<NativeThreadSafeFunctionCallMode>(is_blocking);
39333eb0b6dSopenharmony_ci
39433eb0b6dSopenharmony_ci    napi_status status = napi_status::napi_ok;
39533eb0b6dSopenharmony_ci    auto code = safeAsyncWork->Send(data, callMode);
39633eb0b6dSopenharmony_ci    switch (code) {
39733eb0b6dSopenharmony_ci        case SafeAsyncCode::SAFE_ASYNC_OK:
39833eb0b6dSopenharmony_ci            status = napi_status::napi_ok;
39933eb0b6dSopenharmony_ci            break;
40033eb0b6dSopenharmony_ci        case SafeAsyncCode::SAFE_ASYNC_QUEUE_FULL:
40133eb0b6dSopenharmony_ci            status = napi_status::napi_queue_full;
40233eb0b6dSopenharmony_ci            break;
40333eb0b6dSopenharmony_ci        case SafeAsyncCode::SAFE_ASYNC_INVALID_ARGS:
40433eb0b6dSopenharmony_ci            status = napi_status::napi_invalid_arg;
40533eb0b6dSopenharmony_ci            break;
40633eb0b6dSopenharmony_ci        case SafeAsyncCode::SAFE_ASYNC_CLOSED:
40733eb0b6dSopenharmony_ci            status = napi_status::napi_closing;
40833eb0b6dSopenharmony_ci            break;
40933eb0b6dSopenharmony_ci        case SafeAsyncCode::SAFE_ASYNC_FAILED:
41033eb0b6dSopenharmony_ci            status = napi_status::napi_generic_failure;
41133eb0b6dSopenharmony_ci            break;
41233eb0b6dSopenharmony_ci        default:
41333eb0b6dSopenharmony_ci            HILOG_FATAL("this branch is unreachable, code is %{public}d", code);
41433eb0b6dSopenharmony_ci            break;
41533eb0b6dSopenharmony_ci    }
41633eb0b6dSopenharmony_ci
41733eb0b6dSopenharmony_ci    return status;
41833eb0b6dSopenharmony_ci}
41933eb0b6dSopenharmony_ci
42033eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_acquire_threadsafe_function(napi_threadsafe_function func)
42133eb0b6dSopenharmony_ci{
42233eb0b6dSopenharmony_ci    CHECK_ENV(func);
42333eb0b6dSopenharmony_ci
42433eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
42533eb0b6dSopenharmony_ci
42633eb0b6dSopenharmony_ci    auto ret = safeAsyncWork->Acquire();
42733eb0b6dSopenharmony_ci    if (ret != SafeAsyncCode::SAFE_ASYNC_OK) {
42833eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
42933eb0b6dSopenharmony_ci    }
43033eb0b6dSopenharmony_ci
43133eb0b6dSopenharmony_ci    return napi_status::napi_ok;
43233eb0b6dSopenharmony_ci}
43333eb0b6dSopenharmony_ci
43433eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_release_threadsafe_function(
43533eb0b6dSopenharmony_ci    napi_threadsafe_function func, napi_threadsafe_function_release_mode mode)
43633eb0b6dSopenharmony_ci{
43733eb0b6dSopenharmony_ci    CHECK_ENV(func);
43833eb0b6dSopenharmony_ci
43933eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
44033eb0b6dSopenharmony_ci    auto releaseMode = static_cast<NativeThreadSafeFunctionReleaseMode>(mode);
44133eb0b6dSopenharmony_ci
44233eb0b6dSopenharmony_ci    auto ret = safeAsyncWork->Release(releaseMode);
44333eb0b6dSopenharmony_ci    if (ret != SafeAsyncCode::SAFE_ASYNC_OK) {
44433eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
44533eb0b6dSopenharmony_ci    }
44633eb0b6dSopenharmony_ci
44733eb0b6dSopenharmony_ci    return napi_status::napi_ok;
44833eb0b6dSopenharmony_ci}
44933eb0b6dSopenharmony_ci
45033eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_get_threadsafe_function_context(napi_threadsafe_function func, void** result)
45133eb0b6dSopenharmony_ci{
45233eb0b6dSopenharmony_ci    CHECK_ENV(func);
45333eb0b6dSopenharmony_ci    CHECK_ENV(result);
45433eb0b6dSopenharmony_ci
45533eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
45633eb0b6dSopenharmony_ci    *result = safeAsyncWork->GetContext();
45733eb0b6dSopenharmony_ci
45833eb0b6dSopenharmony_ci    return napi_status::napi_ok;
45933eb0b6dSopenharmony_ci}
46033eb0b6dSopenharmony_ci
46133eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func)
46233eb0b6dSopenharmony_ci{
46333eb0b6dSopenharmony_ci    CHECK_ENV(env);
46433eb0b6dSopenharmony_ci    CHECK_ARG(env, func);
46533eb0b6dSopenharmony_ci
46633eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
46733eb0b6dSopenharmony_ci    auto ret = safeAsyncWork->Ref();
46833eb0b6dSopenharmony_ci    if (!ret) {
46933eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
47033eb0b6dSopenharmony_ci    }
47133eb0b6dSopenharmony_ci
47233eb0b6dSopenharmony_ci    return napi_status::napi_ok;
47333eb0b6dSopenharmony_ci}
47433eb0b6dSopenharmony_ci
47533eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func)
47633eb0b6dSopenharmony_ci{
47733eb0b6dSopenharmony_ci    CHECK_ENV(env);
47833eb0b6dSopenharmony_ci    CHECK_ARG(env, func);
47933eb0b6dSopenharmony_ci
48033eb0b6dSopenharmony_ci    auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func);
48133eb0b6dSopenharmony_ci    auto ret = safeAsyncWork->Unref();
48233eb0b6dSopenharmony_ci    if (!ret) {
48333eb0b6dSopenharmony_ci        return napi_status::napi_generic_failure;
48433eb0b6dSopenharmony_ci    }
48533eb0b6dSopenharmony_ci
48633eb0b6dSopenharmony_ci    return napi_status::napi_ok;
48733eb0b6dSopenharmony_ci}
48833eb0b6dSopenharmony_ci
48933eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_async_init(
49033eb0b6dSopenharmony_ci    napi_env env, napi_value async_resource, napi_value async_resource_name, napi_async_context* result)
49133eb0b6dSopenharmony_ci{
49233eb0b6dSopenharmony_ci    CHECK_ENV(env);
49333eb0b6dSopenharmony_ci    CHECK_ARG(env, async_resource_name);
49433eb0b6dSopenharmony_ci    CHECK_ARG(env, result);
49533eb0b6dSopenharmony_ci
49633eb0b6dSopenharmony_ci    auto ecmaVm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm();
49733eb0b6dSopenharmony_ci    panda::Local<panda::ObjectRef> resource;
49833eb0b6dSopenharmony_ci    bool isExternalResource;
49933eb0b6dSopenharmony_ci    if (async_resource != nullptr) {
50033eb0b6dSopenharmony_ci        auto nativeValue = LocalValueFromJsValue(async_resource);
50133eb0b6dSopenharmony_ci        resource = nativeValue->ToObject(ecmaVm);
50233eb0b6dSopenharmony_ci        isExternalResource = true;
50333eb0b6dSopenharmony_ci    } else {
50433eb0b6dSopenharmony_ci        resource = panda::ObjectRef::New(ecmaVm);
50533eb0b6dSopenharmony_ci        isExternalResource = false;
50633eb0b6dSopenharmony_ci    }
50733eb0b6dSopenharmony_ci
50833eb0b6dSopenharmony_ci    auto nativeValue = LocalValueFromJsValue(async_resource_name);
50933eb0b6dSopenharmony_ci    auto resourceName = nativeValue->ToString(ecmaVm);
51033eb0b6dSopenharmony_ci
51133eb0b6dSopenharmony_ci    auto asyncContext = new NativeAsyncHookContext(reinterpret_cast<NativeEngine*>(env),
51233eb0b6dSopenharmony_ci                                                   resource,
51333eb0b6dSopenharmony_ci                                                   resourceName,
51433eb0b6dSopenharmony_ci                                                   isExternalResource);
51533eb0b6dSopenharmony_ci
51633eb0b6dSopenharmony_ci    *result = reinterpret_cast<napi_async_context>(asyncContext);
51733eb0b6dSopenharmony_ci
51833eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
51933eb0b6dSopenharmony_ci}
52033eb0b6dSopenharmony_ci
52133eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_async_destroy(napi_env env, napi_async_context async_context)
52233eb0b6dSopenharmony_ci{
52333eb0b6dSopenharmony_ci    CHECK_ENV(env);
52433eb0b6dSopenharmony_ci    CHECK_ARG(env, async_context);
52533eb0b6dSopenharmony_ci
52633eb0b6dSopenharmony_ci    NativeAsyncHookContext* nativeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context);
52733eb0b6dSopenharmony_ci
52833eb0b6dSopenharmony_ci    delete nativeAsyncContext;
52933eb0b6dSopenharmony_ci
53033eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
53133eb0b6dSopenharmony_ci}
53233eb0b6dSopenharmony_ci
53333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_open_callback_scope(
53433eb0b6dSopenharmony_ci    napi_env env, napi_value, napi_async_context async_context_handle, napi_callback_scope* result)
53533eb0b6dSopenharmony_ci{
53633eb0b6dSopenharmony_ci    CHECK_ENV(env);
53733eb0b6dSopenharmony_ci    CHECK_ARG(env, result);
53833eb0b6dSopenharmony_ci
53933eb0b6dSopenharmony_ci    NativeAsyncHookContext* nodeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context_handle);
54033eb0b6dSopenharmony_ci
54133eb0b6dSopenharmony_ci    *result = reinterpret_cast<napi_callback_scope>(nodeAsyncContext->OpenCallbackScope());
54233eb0b6dSopenharmony_ci
54333eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
54433eb0b6dSopenharmony_ci}
54533eb0b6dSopenharmony_ci
54633eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_close_callback_scope(napi_env env, napi_callback_scope scope)
54733eb0b6dSopenharmony_ci{
54833eb0b6dSopenharmony_ci    CHECK_ENV(env);
54933eb0b6dSopenharmony_ci    CHECK_ARG(env, scope);
55033eb0b6dSopenharmony_ci
55133eb0b6dSopenharmony_ci    auto ret = NativeAsyncHookContext::CloseCallbackScope(reinterpret_cast<NativeEngine*>(env),
55233eb0b6dSopenharmony_ci                                                          reinterpret_cast<NativeCallbackScope*>(scope));
55333eb0b6dSopenharmony_ci    if (ret == CALLBACK_SCOPE_MISMATCH) {
55433eb0b6dSopenharmony_ci        return napi_callback_scope_mismatch;
55533eb0b6dSopenharmony_ci    } else if (ret != CALLBACK_SCOPE_OK) {
55633eb0b6dSopenharmony_ci        return napi_invalid_arg;
55733eb0b6dSopenharmony_ci    }
55833eb0b6dSopenharmony_ci
55933eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
56033eb0b6dSopenharmony_ci}
56133eb0b6dSopenharmony_ci
56233eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_set_instance_data(
56333eb0b6dSopenharmony_ci    napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint)
56433eb0b6dSopenharmony_ci{
56533eb0b6dSopenharmony_ci    CHECK_ENV(env);
56633eb0b6dSopenharmony_ci    CROSS_THREAD_CHECK(env);
56733eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
56833eb0b6dSopenharmony_ci    auto callback = reinterpret_cast<NativeFinalize>(finalize_cb);
56933eb0b6dSopenharmony_ci    engine->SetInstanceData(data, callback, finalize_hint);
57033eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
57133eb0b6dSopenharmony_ci}
57233eb0b6dSopenharmony_ci
57333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_get_instance_data(napi_env env, void** data)
57433eb0b6dSopenharmony_ci{
57533eb0b6dSopenharmony_ci    CHECK_ENV(env);
57633eb0b6dSopenharmony_ci    CHECK_ARG(env, data);
57733eb0b6dSopenharmony_ci    CROSS_THREAD_CHECK(env);
57833eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
57933eb0b6dSopenharmony_ci    engine->GetInstanceData(data);
58033eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
58133eb0b6dSopenharmony_ci}
58233eb0b6dSopenharmony_ci
58333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status node_api_get_module_file_name(napi_env env, const char** result)
58433eb0b6dSopenharmony_ci{
58533eb0b6dSopenharmony_ci    CHECK_ENV(env);
58633eb0b6dSopenharmony_ci    CHECK_ARG(env, result);
58733eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
58833eb0b6dSopenharmony_ci    *result = engine->GetModuleFileName();
58933eb0b6dSopenharmony_ci    HILOG_INFO("%{public}s, napi called fileName : %{public}s", __func__, *result);
59033eb0b6dSopenharmony_ci    return napi_clear_last_error(env);
59133eb0b6dSopenharmony_ci}
59233eb0b6dSopenharmony_ci
59333eb0b6dSopenharmony_ciNAPI_EXTERN napi_status napi_make_callback(napi_env env,
59433eb0b6dSopenharmony_ci                                           napi_async_context async_context,
59533eb0b6dSopenharmony_ci                                           napi_value recv,
59633eb0b6dSopenharmony_ci                                           napi_value func,
59733eb0b6dSopenharmony_ci                                           size_t argc,
59833eb0b6dSopenharmony_ci                                           const napi_value* argv,
59933eb0b6dSopenharmony_ci                                           napi_value* result)
60033eb0b6dSopenharmony_ci{
60133eb0b6dSopenharmony_ci    NAPI_PREAMBLE(env);
60233eb0b6dSopenharmony_ci    CHECK_ARG(env, func);
60333eb0b6dSopenharmony_ci    CHECK_ARG(env, recv);
60433eb0b6dSopenharmony_ci    if (argc > 0) {
60533eb0b6dSopenharmony_ci        CHECK_ARG(env, argv);
60633eb0b6dSopenharmony_ci    }
60733eb0b6dSopenharmony_ci    auto engine = reinterpret_cast<NativeEngine*>(env);
60833eb0b6dSopenharmony_ci    auto vm = engine->GetEcmaVm();
60933eb0b6dSopenharmony_ci    RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(recv)->IsObject(vm), napi_object_expected);
61033eb0b6dSopenharmony_ci    RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(func)->IsFunction(vm), napi_function_expected);
61133eb0b6dSopenharmony_ci    panda::JSValueRef* Obj = reinterpret_cast<panda::JSValueRef *>(recv);
61233eb0b6dSopenharmony_ci    panda::FunctionRef* funRef = reinterpret_cast<panda::FunctionRef *>(func);
61333eb0b6dSopenharmony_ci    panda::JSValueRef* callBackRst;
61433eb0b6dSopenharmony_ci    if (async_context == nullptr) {
61533eb0b6dSopenharmony_ci        callBackRst = MakeCallback(engine, funRef, Obj,
61633eb0b6dSopenharmony_ci                                   argc, reinterpret_cast<panda::JSValueRef* const*>(argv), nullptr);
61733eb0b6dSopenharmony_ci    } else {
61833eb0b6dSopenharmony_ci        NativeAsyncHookContext* nativeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context);
61933eb0b6dSopenharmony_ci        callBackRst = nativeAsyncContext->MakeCallback(funRef, Obj,
62033eb0b6dSopenharmony_ci                                                       reinterpret_cast<panda::JSValueRef* const*>(argv), argc);
62133eb0b6dSopenharmony_ci    }
62233eb0b6dSopenharmony_ci    if (tryCatch.HasCaught()) {
62333eb0b6dSopenharmony_ci        HILOG_ERROR("print exception info: ");
62433eb0b6dSopenharmony_ci        panda::JSNApi::PrintExceptionInfo(vm);
62533eb0b6dSopenharmony_ci        return napi_set_last_error(env, napi_pending_exception);
62633eb0b6dSopenharmony_ci    }
62733eb0b6dSopenharmony_ci    if (result) {
62833eb0b6dSopenharmony_ci        *result = reinterpret_cast<napi_value>(callBackRst);
62933eb0b6dSopenharmony_ci    }
63033eb0b6dSopenharmony_ci    return GET_RETURN_STATUS(env);
63133eb0b6dSopenharmony_ci}
632