133eb0b6dSopenharmony_ci/*
233eb0b6dSopenharmony_ci * Copyright (c) 2021-2022 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#ifndef FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H
1733eb0b6dSopenharmony_ci#define FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H
1833eb0b6dSopenharmony_ci
1933eb0b6dSopenharmony_ci#include <functional>
2033eb0b6dSopenharmony_ci#include <list>
2133eb0b6dSopenharmony_ci#include <string>
2233eb0b6dSopenharmony_ci#include <unordered_map>
2333eb0b6dSopenharmony_ci#include <unordered_set>
2433eb0b6dSopenharmony_ci#include <vector>
2533eb0b6dSopenharmony_ci#ifdef LINUX_PLATFORM
2633eb0b6dSopenharmony_ci#include<atomic>
2733eb0b6dSopenharmony_ci#endif
2833eb0b6dSopenharmony_ci
2933eb0b6dSopenharmony_ci#include "callback_scope_manager/native_callback_scope_manager.h"
3033eb0b6dSopenharmony_ci#include "ecmascript/napi/include/jsnapi.h"
3133eb0b6dSopenharmony_ci#include "module_manager/native_module_manager.h"
3233eb0b6dSopenharmony_ci#include "native_engine/native_async_work.h"
3333eb0b6dSopenharmony_ci#include "native_engine/native_deferred.h"
3433eb0b6dSopenharmony_ci#include "native_engine/native_reference.h"
3533eb0b6dSopenharmony_ci#include "native_engine/native_safe_async_work.h"
3633eb0b6dSopenharmony_ci#include "native_engine/native_value.h"
3733eb0b6dSopenharmony_ci#include "native_property.h"
3833eb0b6dSopenharmony_ci#include "reference_manager/native_reference_manager.h"
3933eb0b6dSopenharmony_ci#include "utils/macros.h"
4033eb0b6dSopenharmony_ci#include "libpandafile/data_protect.h"
4133eb0b6dSopenharmony_ci
4233eb0b6dSopenharmony_cinamespace panda::ecmascript {
4333eb0b6dSopenharmony_ci    class EcmaVM;
4433eb0b6dSopenharmony_ci}
4533eb0b6dSopenharmony_ci
4633eb0b6dSopenharmony_citypedef int32_t (*GetContainerScopeIdCallback)(void);
4733eb0b6dSopenharmony_citypedef void (*ContainerScopeCallback)(int32_t);
4833eb0b6dSopenharmony_citypedef struct uv_loop_s uv_loop_t;
4933eb0b6dSopenharmony_ci
5033eb0b6dSopenharmony_cistruct NativeErrorExtendedInfo {
5133eb0b6dSopenharmony_ci    const char* message = nullptr;
5233eb0b6dSopenharmony_ci    void* reserved = nullptr;
5333eb0b6dSopenharmony_ci    uint32_t engineErrorCode = 0;
5433eb0b6dSopenharmony_ci    int errorCode = 0;
5533eb0b6dSopenharmony_ci};
5633eb0b6dSopenharmony_ci
5733eb0b6dSopenharmony_cienum LoopMode {
5833eb0b6dSopenharmony_ci    LOOP_DEFAULT, LOOP_ONCE, LOOP_NOWAIT
5933eb0b6dSopenharmony_ci};
6033eb0b6dSopenharmony_ci
6133eb0b6dSopenharmony_cienum class DumpFormat {
6233eb0b6dSopenharmony_ci    JSON, BINARY, OTHER
6333eb0b6dSopenharmony_ci};
6433eb0b6dSopenharmony_ci
6533eb0b6dSopenharmony_cienum class WorkerVersion {
6633eb0b6dSopenharmony_ci    NONE, OLD, NEW
6733eb0b6dSopenharmony_ci};
6833eb0b6dSopenharmony_ci
6933eb0b6dSopenharmony_ciusing CleanupCallback = void (*)(void*);
7033eb0b6dSopenharmony_ciusing ThreadId = uint32_t;
7133eb0b6dSopenharmony_ci
7233eb0b6dSopenharmony_ciclass NapiOptions;
7333eb0b6dSopenharmony_ciusing PostTask = std::function<void(bool needSync)>;
7433eb0b6dSopenharmony_ciusing CleanEnv = std::function<void()>;
7533eb0b6dSopenharmony_ciusing InitWorkerFunc = std::function<void(NativeEngine* engine)>;
7633eb0b6dSopenharmony_ciusing GetAssetFunc = std::function<void(const std::string& uri, uint8_t **buff, size_t *buffSize,
7733eb0b6dSopenharmony_ci    std::vector<uint8_t>& content, std::string& ami, bool &useSecureMem, bool isRestricted)>;
7833eb0b6dSopenharmony_ciusing OffWorkerFunc = std::function<void(NativeEngine* engine)>;
7933eb0b6dSopenharmony_ciusing DebuggerPostTask = std::function<void(std::function<void()>&&)>;
8033eb0b6dSopenharmony_ciusing NapiUncaughtExceptionCallback = std::function<void(napi_value value)>;
8133eb0b6dSopenharmony_ciusing PermissionCheckCallback = std::function<bool()>;
8233eb0b6dSopenharmony_ciusing NapiConcurrentCallback = void (*)(napi_env env, napi_value result, bool success, void* data);
8333eb0b6dSopenharmony_ciusing SourceMapCallback = std::function<std::string(const std::string& rawStack)>;
8433eb0b6dSopenharmony_ciusing SourceMapTranslateCallback = std::function<bool(std::string& url, int& line, int& column)>;
8533eb0b6dSopenharmony_ciusing AppFreezeFilterCallback = std::function<bool(const int32_t pid)>;
8633eb0b6dSopenharmony_ciusing EcmaVM = panda::ecmascript::EcmaVM;
8733eb0b6dSopenharmony_ciusing JsFrameInfo = panda::ecmascript::JsFrameInfo;
8833eb0b6dSopenharmony_ci
8933eb0b6dSopenharmony_ciclass NAPI_EXPORT NativeEngine {
9033eb0b6dSopenharmony_cipublic:
9133eb0b6dSopenharmony_ci    explicit NativeEngine(void* jsEngine);
9233eb0b6dSopenharmony_ci    NativeEngine(void* jsEngine, EcmaVM* vm);
9333eb0b6dSopenharmony_ci    virtual ~NativeEngine();
9433eb0b6dSopenharmony_ci
9533eb0b6dSopenharmony_ci    virtual NativeModuleManager* GetModuleManager();
9633eb0b6dSopenharmony_ci    virtual NativeReferenceManager* GetReferenceManager();
9733eb0b6dSopenharmony_ci    virtual NativeCallbackScopeManager* GetCallbackScopeManager();
9833eb0b6dSopenharmony_ci    virtual uv_loop_t* GetUVLoop() const;
9933eb0b6dSopenharmony_ci    virtual pthread_t GetTid() const;
10033eb0b6dSopenharmony_ci    inline ThreadId GetSysTid() const
10133eb0b6dSopenharmony_ci    {
10233eb0b6dSopenharmony_ci        return sysTid_;
10333eb0b6dSopenharmony_ci    };
10433eb0b6dSopenharmony_ci    static ThreadId GetCurSysTid();
10533eb0b6dSopenharmony_ci    inline uint64_t GetId() const
10633eb0b6dSopenharmony_ci    {
10733eb0b6dSopenharmony_ci        return id_;
10833eb0b6dSopenharmony_ci    };
10933eb0b6dSopenharmony_ci
11033eb0b6dSopenharmony_ci    virtual bool ReinitUVLoop();
11133eb0b6dSopenharmony_ci
11233eb0b6dSopenharmony_ci    virtual void Loop(LoopMode mode, bool needSync = false);
11333eb0b6dSopenharmony_ci    virtual void SetPostTask(PostTask postTask);
11433eb0b6dSopenharmony_ci    virtual void TriggerPostTask();
11533eb0b6dSopenharmony_ci#if !defined(PREVIEW)
11633eb0b6dSopenharmony_ci    virtual void CheckUVLoop();
11733eb0b6dSopenharmony_ci    virtual void CancelCheckUVLoop();
11833eb0b6dSopenharmony_ci#endif
11933eb0b6dSopenharmony_ci    virtual void* GetJsEngine();
12033eb0b6dSopenharmony_ci
12133eb0b6dSopenharmony_ci    inline NAPI_EXPORT const EcmaVM* GetEcmaVm() const
12233eb0b6dSopenharmony_ci    {
12333eb0b6dSopenharmony_ci        return vm_;
12433eb0b6dSopenharmony_ci    }
12533eb0b6dSopenharmony_ci    virtual bool NapiNewTypedArray(const EcmaVM* vm, NativeTypedArrayType typedArrayType,
12633eb0b6dSopenharmony_ci                                   panda::Local<panda::ArrayBufferRef> arrayBuf, size_t byte_offset,
12733eb0b6dSopenharmony_ci                                   size_t length, napi_value* result) = 0;
12833eb0b6dSopenharmony_ci    virtual bool NapiNewSendableTypedArray(const EcmaVM* vm, NativeTypedArrayType typedArrayType,
12933eb0b6dSopenharmony_ci                                           panda::Local<panda::SendableArrayBufferRef> arrayBuf, size_t byte_offset,
13033eb0b6dSopenharmony_ci                                           size_t length, napi_value* result) = 0;
13133eb0b6dSopenharmony_ci    virtual NativeTypedArrayType GetTypedArrayType(panda::Local<panda::TypedArrayRef> typedArray) = 0;
13233eb0b6dSopenharmony_ci    virtual NativeTypedArrayType GetSendableTypedArrayType(panda::Local<panda::SendableTypedArrayRef> typedArray) = 0;
13333eb0b6dSopenharmony_ci    virtual void SetPromiseRejectCallback(NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef) = 0;
13433eb0b6dSopenharmony_ci
13533eb0b6dSopenharmony_ci    virtual bool InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback) = 0;
13633eb0b6dSopenharmony_ci    virtual bool InitTaskPoolThread(napi_env env, NapiConcurrentCallback callback) = 0;
13733eb0b6dSopenharmony_ci    virtual bool InitTaskPoolFunc(napi_env env, napi_value func, void* taskInfo) = 0;
13833eb0b6dSopenharmony_ci    virtual void ClearCurrentTaskInfo() = 0;
13933eb0b6dSopenharmony_ci    virtual bool HasPendingJob() const = 0;
14033eb0b6dSopenharmony_ci    virtual bool IsProfiling() const = 0;
14133eb0b6dSopenharmony_ci    virtual bool IsExecutingPendingJob() const = 0;
14233eb0b6dSopenharmony_ci    virtual void* GetCurrentTaskInfo() const = 0;
14333eb0b6dSopenharmony_ci    virtual void TerminateExecution() const = 0;
14433eb0b6dSopenharmony_ci    virtual void NotifyTaskBegin() const = 0;
14533eb0b6dSopenharmony_ci    virtual void NotifyTaskFinished() const = 0;
14633eb0b6dSopenharmony_ci
14733eb0b6dSopenharmony_ci    virtual napi_value CallFunction(napi_value thisVar,
14833eb0b6dSopenharmony_ci                                    napi_value function,
14933eb0b6dSopenharmony_ci                                    napi_value const *argv,
15033eb0b6dSopenharmony_ci                                    size_t argc) = 0;
15133eb0b6dSopenharmony_ci    virtual bool RunScriptPath(const char* path, bool checkPath = false) = 0;
15233eb0b6dSopenharmony_ci    virtual napi_value RunScriptBuffer(const char* path, std::vector<uint8_t>& buffer, bool isBundle) = 0;
15333eb0b6dSopenharmony_ci    virtual bool RunScriptBuffer(const std::string &path, uint8_t* buffer, size_t size, bool isBundle) = 0;
15433eb0b6dSopenharmony_ci    virtual napi_value RunBufferScript(std::vector<uint8_t>& buffer) = 0;
15533eb0b6dSopenharmony_ci    virtual napi_value RunActor(uint8_t* buffer, size_t bufferSize,
15633eb0b6dSopenharmony_ci        const char* descriptor, char* entryPoint = nullptr, bool checkPath = false) = 0;
15733eb0b6dSopenharmony_ci
15833eb0b6dSopenharmony_ci    virtual napi_value CreateInstance(napi_value constructor, napi_value const *argv, size_t argc) = 0;
15933eb0b6dSopenharmony_ci
16033eb0b6dSopenharmony_ci    virtual NativeReference* CreateReference(napi_value value, uint32_t initialRefcount,
16133eb0b6dSopenharmony_ci        bool flag = false, NapiNativeFinalize callback = nullptr, void* data = nullptr, void* hint = nullptr,
16233eb0b6dSopenharmony_ci        size_t nativeBindingSize = 0) = 0;
16333eb0b6dSopenharmony_ci
16433eb0b6dSopenharmony_ci    virtual NativeReference* CreateAsyncReference(napi_value value, uint32_t initialRefcount,
16533eb0b6dSopenharmony_ci        bool flag = false, NapiNativeFinalize callback = nullptr, void* data = nullptr, void* hint = nullptr) = 0;
16633eb0b6dSopenharmony_ci
16733eb0b6dSopenharmony_ci    virtual NativeAsyncWork* CreateAsyncWork(napi_value asyncResource,
16833eb0b6dSopenharmony_ci                                             napi_value asyncResourceName,
16933eb0b6dSopenharmony_ci                                             NativeAsyncExecuteCallback execute,
17033eb0b6dSopenharmony_ci                                             NativeAsyncCompleteCallback complete,
17133eb0b6dSopenharmony_ci                                             void* data);
17233eb0b6dSopenharmony_ci
17333eb0b6dSopenharmony_ci    virtual NativeAsyncWork* CreateAsyncWork(const std::string &asyncResourceName,
17433eb0b6dSopenharmony_ci                                             NativeAsyncExecuteCallback execute,
17533eb0b6dSopenharmony_ci                                             NativeAsyncCompleteCallback complete,
17633eb0b6dSopenharmony_ci                                             void* data);
17733eb0b6dSopenharmony_ci    virtual NativeSafeAsyncWork* CreateSafeAsyncWork(napi_value func, napi_value asyncResource,
17833eb0b6dSopenharmony_ci        napi_value asyncResourceName, size_t maxQueueSize, size_t threadCount, void* finalizeData,
17933eb0b6dSopenharmony_ci        NativeFinalize finalizeCallback, void* context, NativeThreadSafeFunctionCallJs callJsCallback);
18033eb0b6dSopenharmony_ci
18133eb0b6dSopenharmony_ci    virtual void* CreateRuntime(bool isLimitedWorker = false) = 0;
18233eb0b6dSopenharmony_ci    virtual napi_value CreatePromise(NativeDeferred** deferred) = 0;
18333eb0b6dSopenharmony_ci
18433eb0b6dSopenharmony_ci    virtual void SetJsDumpThresholds(size_t thresholds) = 0;
18533eb0b6dSopenharmony_ci    virtual void SetAppFreezeFilterCallback(AppFreezeFilterCallback callback) = 0;
18633eb0b6dSopenharmony_ci
18733eb0b6dSopenharmony_ci    virtual void StartCpuProfiler(const std::string& fileName = "") = 0;
18833eb0b6dSopenharmony_ci    virtual void StopCpuProfiler() = 0;
18933eb0b6dSopenharmony_ci
19033eb0b6dSopenharmony_ci    virtual void ResumeVM() = 0;
19133eb0b6dSopenharmony_ci    virtual bool SuspendVM() = 0;
19233eb0b6dSopenharmony_ci    virtual bool IsSuspended() = 0;
19333eb0b6dSopenharmony_ci    virtual bool CheckSafepoint() = 0;
19433eb0b6dSopenharmony_ci    virtual bool SuspendVMById(uint32_t tid) = 0;
19533eb0b6dSopenharmony_ci    virtual void ResumeVMById(uint32_t tid) = 0;
19633eb0b6dSopenharmony_ci
19733eb0b6dSopenharmony_ci    virtual void DumpHeapSnapshot(const std::string &path, bool isVmMode = true,
19833eb0b6dSopenharmony_ci        DumpFormat dumpFormat = DumpFormat::JSON, bool isPrivate = false, bool captureNumericValue = false) = 0;
19933eb0b6dSopenharmony_ci    virtual void DumpCpuProfile() = 0;
20033eb0b6dSopenharmony_ci    virtual void DumpHeapSnapshot(bool isVmMode = true, DumpFormat dumpFormat = DumpFormat::JSON,
20133eb0b6dSopenharmony_ci        bool isPrivate = false, bool isFullGC = true) = 0;
20233eb0b6dSopenharmony_ci    virtual bool BuildNativeAndJsStackTrace(std::string &stackTraceStr) = 0;
20333eb0b6dSopenharmony_ci    virtual bool BuildJsStackTrace(std::string &stackTraceStr) = 0;
20433eb0b6dSopenharmony_ci    virtual bool BuildJsStackInfoListWithCustomDepth(std::vector<JsFrameInfo>& jsFrames)
20533eb0b6dSopenharmony_ci        = 0;
20633eb0b6dSopenharmony_ci    virtual bool DeleteWorker(NativeEngine* workerEngine) = 0;
20733eb0b6dSopenharmony_ci    virtual bool StartHeapTracking(double timeInterval, bool isVmMode = true) = 0;
20833eb0b6dSopenharmony_ci    virtual bool StopHeapTracking(const std::string &filePath) = 0;
20933eb0b6dSopenharmony_ci
21033eb0b6dSopenharmony_ci    virtual void AllowCrossThreadExecution() const = 0;
21133eb0b6dSopenharmony_ci
21233eb0b6dSopenharmony_ci    NativeErrorExtendedInfo* GetLastError();
21333eb0b6dSopenharmony_ci    void SetLastError(int errorCode, uint32_t engineErrorCode = 0, void* engineReserved = nullptr);
21433eb0b6dSopenharmony_ci    inline void ClearLastError()
21533eb0b6dSopenharmony_ci    {
21633eb0b6dSopenharmony_ci        lastError_.errorCode = 0;
21733eb0b6dSopenharmony_ci        lastError_.engineErrorCode = 0;
21833eb0b6dSopenharmony_ci        lastError_.message = nullptr;
21933eb0b6dSopenharmony_ci        lastError_.reserved = nullptr;
22033eb0b6dSopenharmony_ci    }
22133eb0b6dSopenharmony_ci    void EncodeToUtf8(napi_value value, char* buffer, uint32_t* written, size_t bufferSize, int32_t* nchars);
22233eb0b6dSopenharmony_ci    void EncodeToChinese(napi_value value, std::string& buffer, const std::string& encoding);
22333eb0b6dSopenharmony_ci    NativeEngine(NativeEngine&) = delete;
22433eb0b6dSopenharmony_ci    virtual NativeEngine& operator=(NativeEngine&) = delete;
22533eb0b6dSopenharmony_ci
22633eb0b6dSopenharmony_ci    virtual napi_value ValueToNapiValue(JSValueWrapper& value) = 0;
22733eb0b6dSopenharmony_ci    virtual std::string GetSourceCodeInfo(napi_value value, ErrorPos pos) = 0;
22833eb0b6dSopenharmony_ci
22933eb0b6dSopenharmony_ci    virtual void TriggerFatalException(panda::Local<panda::JSValueRef> exceptionValue) = 0;
23033eb0b6dSopenharmony_ci    virtual bool AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue) = 0;
23133eb0b6dSopenharmony_ci
23233eb0b6dSopenharmony_ci    void MarkWorkerThread()
23333eb0b6dSopenharmony_ci    {
23433eb0b6dSopenharmony_ci        jsThreadType_.Update(static_cast<uintptr_t>(JSThreadType::WORKER_THREAD));
23533eb0b6dSopenharmony_ci    }
23633eb0b6dSopenharmony_ci    void MarkRestrictedWorkerThread()
23733eb0b6dSopenharmony_ci    {
23833eb0b6dSopenharmony_ci        jsThreadType_.Update(static_cast<uintptr_t>(JSThreadType::RESTRICTEDWORKER_THREAD));
23933eb0b6dSopenharmony_ci    }
24033eb0b6dSopenharmony_ci    void MarkTaskPoolThread()
24133eb0b6dSopenharmony_ci    {
24233eb0b6dSopenharmony_ci        jsThreadType_.Update(static_cast<uintptr_t>(JSThreadType::TASKPOOL_THREAD));
24333eb0b6dSopenharmony_ci    }
24433eb0b6dSopenharmony_ci    void MarkNativeThread()
24533eb0b6dSopenharmony_ci    {
24633eb0b6dSopenharmony_ci        jsThreadType_.Update(static_cast<uintptr_t>(JSThreadType::NATIVE_THREAD));
24733eb0b6dSopenharmony_ci    }
24833eb0b6dSopenharmony_ci    bool IsWorkerThread() const
24933eb0b6dSopenharmony_ci    {
25033eb0b6dSopenharmony_ci        return static_cast<JSThreadType>(jsThreadType_.GetOriginPointer()) == JSThreadType::WORKER_THREAD;
25133eb0b6dSopenharmony_ci    }
25233eb0b6dSopenharmony_ci    bool IsRestrictedWorkerThread() const
25333eb0b6dSopenharmony_ci    {
25433eb0b6dSopenharmony_ci        return static_cast<JSThreadType>(jsThreadType_.GetOriginPointer()) == JSThreadType::RESTRICTEDWORKER_THREAD;
25533eb0b6dSopenharmony_ci    }
25633eb0b6dSopenharmony_ci    bool IsTaskPoolThread() const
25733eb0b6dSopenharmony_ci    {
25833eb0b6dSopenharmony_ci        return static_cast<JSThreadType>(jsThreadType_.GetOriginPointer()) == JSThreadType::TASKPOOL_THREAD;
25933eb0b6dSopenharmony_ci    }
26033eb0b6dSopenharmony_ci    bool IsMainThread() const
26133eb0b6dSopenharmony_ci    {
26233eb0b6dSopenharmony_ci        return static_cast<JSThreadType>(jsThreadType_.GetOriginPointer()) == JSThreadType::MAIN_THREAD;
26333eb0b6dSopenharmony_ci    }
26433eb0b6dSopenharmony_ci    bool IsNativeThread() const
26533eb0b6dSopenharmony_ci    {
26633eb0b6dSopenharmony_ci        return static_cast<JSThreadType>(jsThreadType_.GetOriginPointer()) == JSThreadType::NATIVE_THREAD;
26733eb0b6dSopenharmony_ci    }
26833eb0b6dSopenharmony_ci
26933eb0b6dSopenharmony_ci    bool CheckAndSetWorkerVersion(WorkerVersion expected, WorkerVersion desired)
27033eb0b6dSopenharmony_ci    {
27133eb0b6dSopenharmony_ci        return workerVersion_.compare_exchange_strong(expected, desired);
27233eb0b6dSopenharmony_ci    }
27333eb0b6dSopenharmony_ci    bool IsTargetWorkerVersion(WorkerVersion target) const
27433eb0b6dSopenharmony_ci    {
27533eb0b6dSopenharmony_ci        return workerVersion_.load() == target;
27633eb0b6dSopenharmony_ci    }
27733eb0b6dSopenharmony_ci
27833eb0b6dSopenharmony_ci    void IncreaseSubEnvCounter()
27933eb0b6dSopenharmony_ci    {
28033eb0b6dSopenharmony_ci        subEnvCounter_++;
28133eb0b6dSopenharmony_ci    }
28233eb0b6dSopenharmony_ci    void DecreaseSubEnvCounter()
28333eb0b6dSopenharmony_ci    {
28433eb0b6dSopenharmony_ci        subEnvCounter_--;
28533eb0b6dSopenharmony_ci    }
28633eb0b6dSopenharmony_ci    bool HasSubEnv()
28733eb0b6dSopenharmony_ci    {
28833eb0b6dSopenharmony_ci        return subEnvCounter_.load() != 0;
28933eb0b6dSopenharmony_ci    }
29033eb0b6dSopenharmony_ci
29133eb0b6dSopenharmony_ci    void SetCleanEnv(CleanEnv cleanEnv)
29233eb0b6dSopenharmony_ci    {
29333eb0b6dSopenharmony_ci        cleanEnv_ = cleanEnv;
29433eb0b6dSopenharmony_ci    }
29533eb0b6dSopenharmony_ci
29633eb0b6dSopenharmony_ci    // register init worker func
29733eb0b6dSopenharmony_ci    virtual void SetInitWorkerFunc(InitWorkerFunc func);
29833eb0b6dSopenharmony_ci    InitWorkerFunc GetInitWorkerFunc() const;
29933eb0b6dSopenharmony_ci    virtual void SetGetAssetFunc(GetAssetFunc func);
30033eb0b6dSopenharmony_ci    GetAssetFunc GetGetAssetFunc() const;
30133eb0b6dSopenharmony_ci    virtual void SetOffWorkerFunc(OffWorkerFunc func);
30233eb0b6dSopenharmony_ci    OffWorkerFunc GetOffWorkerFunc() const;
30333eb0b6dSopenharmony_ci
30433eb0b6dSopenharmony_ci    // call init worker func
30533eb0b6dSopenharmony_ci    virtual bool CallInitWorkerFunc(NativeEngine* engine);
30633eb0b6dSopenharmony_ci    virtual bool CallGetAssetFunc(const std::string& uri, uint8_t **buff, size_t *buffSize,
30733eb0b6dSopenharmony_ci        std::vector<uint8_t>& content, std::string& ami, bool &useSecureMem, bool isRestricted);
30833eb0b6dSopenharmony_ci    virtual bool CallOffWorkerFunc(NativeEngine* engine);
30933eb0b6dSopenharmony_ci
31033eb0b6dSopenharmony_ci    // adapt worker to ace container
31133eb0b6dSopenharmony_ci    virtual void SetGetContainerScopeIdFunc(GetContainerScopeIdCallback func);
31233eb0b6dSopenharmony_ci    virtual void SetInitContainerScopeFunc(ContainerScopeCallback func);
31333eb0b6dSopenharmony_ci    virtual void SetFinishContainerScopeFunc(ContainerScopeCallback func);
31433eb0b6dSopenharmony_ci    virtual int32_t GetContainerScopeIdFunc();
31533eb0b6dSopenharmony_ci    virtual bool InitContainerScopeFunc(int32_t id);
31633eb0b6dSopenharmony_ci    virtual bool FinishContainerScopeFunc(int32_t id);
31733eb0b6dSopenharmony_ci
31833eb0b6dSopenharmony_ci#if !defined(PREVIEW)
31933eb0b6dSopenharmony_ci    virtual void SetDebuggerPostTaskFunc(DebuggerPostTask func);
32033eb0b6dSopenharmony_ci    virtual void CallDebuggerPostTaskFunc(std::function<void()>&& task);
32133eb0b6dSopenharmony_ci#endif
32233eb0b6dSopenharmony_ci
32333eb0b6dSopenharmony_ci    virtual void SetHostEngine(NativeEngine* engine);
32433eb0b6dSopenharmony_ci    virtual NativeEngine* GetHostEngine() const;
32533eb0b6dSopenharmony_ci    virtual void SetApiVersion(int32_t apiVersion);
32633eb0b6dSopenharmony_ci    virtual int32_t GetApiVersion();
32733eb0b6dSopenharmony_ci    virtual bool IsApplicationApiVersionAPI11Plus();
32833eb0b6dSopenharmony_ci
32933eb0b6dSopenharmony_ci    virtual napi_status AddCleanupHook(CleanupCallback fun, void* arg);
33033eb0b6dSopenharmony_ci    virtual napi_status RemoveCleanupHook(CleanupCallback fun, void* arg);
33133eb0b6dSopenharmony_ci
33233eb0b6dSopenharmony_ci    void CleanupHandles();
33333eb0b6dSopenharmony_ci    void IncreaseWaitingRequestCounter();
33433eb0b6dSopenharmony_ci    void DecreaseWaitingRequestCounter();
33533eb0b6dSopenharmony_ci    bool HasWaitingRequest();
33633eb0b6dSopenharmony_ci
33733eb0b6dSopenharmony_ci    void IncreaseListeningCounter();
33833eb0b6dSopenharmony_ci    void DecreaseListeningCounter();
33933eb0b6dSopenharmony_ci    bool HasListeningCounter();
34033eb0b6dSopenharmony_ci
34133eb0b6dSopenharmony_ci    inline static bool IsAlive(NativeEngine* env)
34233eb0b6dSopenharmony_ci    {
34333eb0b6dSopenharmony_ci        std::lock_guard<std::mutex> alivedEngLock(g_alivedEngineMutex_);
34433eb0b6dSopenharmony_ci        return g_alivedEngine_.find(env) != g_alivedEngine_.end();
34533eb0b6dSopenharmony_ci    }
34633eb0b6dSopenharmony_ci
34733eb0b6dSopenharmony_ci    virtual void RunCleanup();
34833eb0b6dSopenharmony_ci
34933eb0b6dSopenharmony_ci    bool IsStopping() const
35033eb0b6dSopenharmony_ci    {
35133eb0b6dSopenharmony_ci        return isStopping_.load();
35233eb0b6dSopenharmony_ci    }
35333eb0b6dSopenharmony_ci
35433eb0b6dSopenharmony_ci    void SetStopping(bool value)
35533eb0b6dSopenharmony_ci    {
35633eb0b6dSopenharmony_ci        isStopping_.store(value);
35733eb0b6dSopenharmony_ci    }
35833eb0b6dSopenharmony_ci
35933eb0b6dSopenharmony_ci    virtual void PrintStatisticResult() = 0;
36033eb0b6dSopenharmony_ci    virtual void StartRuntimeStat() = 0;
36133eb0b6dSopenharmony_ci    virtual void StopRuntimeStat() = 0;
36233eb0b6dSopenharmony_ci    virtual size_t GetArrayBufferSize() = 0;
36333eb0b6dSopenharmony_ci    virtual size_t GetHeapTotalSize() = 0;
36433eb0b6dSopenharmony_ci    virtual size_t GetHeapUsedSize() = 0;
36533eb0b6dSopenharmony_ci    virtual size_t GetHeapObjectSize() = 0;
36633eb0b6dSopenharmony_ci    virtual size_t GetHeapLimitSize() = 0;
36733eb0b6dSopenharmony_ci    virtual size_t GetProcessHeapLimitSize() = 0;
36833eb0b6dSopenharmony_ci    virtual size_t GetGCCount() = 0;
36933eb0b6dSopenharmony_ci    virtual size_t GetGCDuration() = 0;
37033eb0b6dSopenharmony_ci    virtual size_t GetAccumulatedAllocateSize() = 0;
37133eb0b6dSopenharmony_ci    virtual size_t GetAccumulatedFreeSize() = 0;
37233eb0b6dSopenharmony_ci    virtual size_t GetFullGCLongTimeCount() = 0;
37333eb0b6dSopenharmony_ci    virtual void NotifyApplicationState(bool inBackground) = 0;
37433eb0b6dSopenharmony_ci    virtual void NotifyIdleStatusControl(std::function<void(bool)> callback) = 0;
37533eb0b6dSopenharmony_ci    virtual void NotifyIdleTime(int idleMicroSec) = 0;
37633eb0b6dSopenharmony_ci    virtual void NotifyMemoryPressure(bool inHighMemoryPressure = false) = 0;
37733eb0b6dSopenharmony_ci    virtual void NotifyForceExpandState(int32_t value) = 0;
37833eb0b6dSopenharmony_ci    virtual void SetMockModuleList(const std::map<std::string, std::string> &list) = 0;
37933eb0b6dSopenharmony_ci    virtual int32_t GetObjectHash(napi_env env, napi_value src) = 0;
38033eb0b6dSopenharmony_ci
38133eb0b6dSopenharmony_ci    void RegisterWorkerFunction(const NativeEngine* engine);
38233eb0b6dSopenharmony_ci    virtual void RegisterNapiUncaughtExceptionHandler(NapiUncaughtExceptionCallback callback) = 0;
38333eb0b6dSopenharmony_ci    virtual void HandleUncaughtException() = 0;
38433eb0b6dSopenharmony_ci    virtual bool HasPendingException()
38533eb0b6dSopenharmony_ci    {
38633eb0b6dSopenharmony_ci        return false;
38733eb0b6dSopenharmony_ci    }
38833eb0b6dSopenharmony_ci    virtual void ThrowException(const char* msg);
38933eb0b6dSopenharmony_ci    virtual void RegisterPermissionCheck(PermissionCheckCallback callback) = 0;
39033eb0b6dSopenharmony_ci    virtual bool ExecutePermissionCheck() = 0;
39133eb0b6dSopenharmony_ci    virtual void RegisterTranslateBySourceMap(SourceMapCallback callback) = 0;
39233eb0b6dSopenharmony_ci    virtual std::string ExecuteTranslateBySourceMap(const std::string& rawStack) = 0;
39333eb0b6dSopenharmony_ci    virtual void RegisterSourceMapTranslateCallback(SourceMapTranslateCallback callback) = 0;
39433eb0b6dSopenharmony_ci    virtual void SetPromiseRejectCallBackRef(NativeReference*) = 0;
39533eb0b6dSopenharmony_ci    virtual void SetCheckCallbackRef(NativeReference*) = 0;
39633eb0b6dSopenharmony_ci    virtual NapiUncaughtExceptionCallback GetNapiUncaughtExceptionCallback() = 0;
39733eb0b6dSopenharmony_ci    virtual void* GetPromiseRejectCallback() = 0;
39833eb0b6dSopenharmony_ci    virtual void GetCurrentModuleInfo(std::string& moduleName, std::string& fileName, bool needRecordName) = 0;
39933eb0b6dSopenharmony_ci    virtual bool GetIsBundle() = 0;
40033eb0b6dSopenharmony_ci    virtual bool GetIsNormalizedOhmUrlPack() = 0;
40133eb0b6dSopenharmony_ci    virtual bool GetIsDebugModeEnabled() = 0;
40233eb0b6dSopenharmony_ci    virtual std::string GetBundleName() = 0;
40333eb0b6dSopenharmony_ci    virtual bool IsExecuteModuleInAbcFile(std::string bundleName, std::string moduleName, std::string ohmurl) = 0;
40433eb0b6dSopenharmony_ci    virtual int GetProcessStartRealTime() = 0;
40533eb0b6dSopenharmony_ci    // run script by path
40633eb0b6dSopenharmony_ci    napi_value RunScriptForAbc(const char* path, char* entryPoint = nullptr);
40733eb0b6dSopenharmony_ci    napi_value RunScript(const char* path, char* entryPoint = nullptr);
40833eb0b6dSopenharmony_ci    napi_value RunScriptInRestrictedThread(const char* path);
40933eb0b6dSopenharmony_ci    bool GetAbcBuffer(const char* path, uint8_t **buffer, size_t* bufferSize, std::vector<uint8_t>& content,
41033eb0b6dSopenharmony_ci        std::string& ami, bool isRestrictedWorker = false);
41133eb0b6dSopenharmony_ci
41233eb0b6dSopenharmony_ci    const char* GetModuleFileName();
41333eb0b6dSopenharmony_ci
41433eb0b6dSopenharmony_ci    void SetModuleName(std::string &moduleName);
41533eb0b6dSopenharmony_ci    void SetModuleFileName(std::string &moduleFileName);
41633eb0b6dSopenharmony_ci
41733eb0b6dSopenharmony_ci    void SetInstanceData(void* data, NativeFinalize finalize_cb, void* hint);
41833eb0b6dSopenharmony_ci    void GetInstanceData(void** data);
41933eb0b6dSopenharmony_ci
42033eb0b6dSopenharmony_ci    /**
42133eb0b6dSopenharmony_ci     * @brief Set the Extension Infos
42233eb0b6dSopenharmony_ci     *
42333eb0b6dSopenharmony_ci     * @param extensionInfos extension infos to set
42433eb0b6dSopenharmony_ci     */
42533eb0b6dSopenharmony_ci    void SetExtensionInfos(std::unordered_map<std::string, int32_t>&& extensionInfos);
42633eb0b6dSopenharmony_ci
42733eb0b6dSopenharmony_ci    /**
42833eb0b6dSopenharmony_ci     * @brief Get the Extension Infos
42933eb0b6dSopenharmony_ci     *
43033eb0b6dSopenharmony_ci     * @return extension infos
43133eb0b6dSopenharmony_ci     */
43233eb0b6dSopenharmony_ci    const std::unordered_map<std::string, int32_t>& GetExtensionInfos();
43333eb0b6dSopenharmony_ci
43433eb0b6dSopenharmony_ci    /**
43533eb0b6dSopenharmony_ci     * @brief Set the Module Blocklist
43633eb0b6dSopenharmony_ci     *
43733eb0b6dSopenharmony_ci     * @param blocklist the blocklist set to native engine
43833eb0b6dSopenharmony_ci     */
43933eb0b6dSopenharmony_ci    void SetModuleBlocklist(std::unordered_map<int32_t, std::unordered_set<std::string>>&& blocklist);
44033eb0b6dSopenharmony_ci
44133eb0b6dSopenharmony_ci    /**
44233eb0b6dSopenharmony_ci     * @brief Set the Module Load Checker
44333eb0b6dSopenharmony_ci     *
44433eb0b6dSopenharmony_ci     * @param moduleCheckerDelegate the module checker delegate will intercept the module loading
44533eb0b6dSopenharmony_ci     */
44633eb0b6dSopenharmony_ci    void SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate>& moduleCheckerDelegate);
44733eb0b6dSopenharmony_ci
44833eb0b6dSopenharmony_ci    virtual napi_value NapiLoadModule(const char* path, const char* module_info) = 0;
44933eb0b6dSopenharmony_ci    virtual napi_value NapiLoadModuleWithInfo(const char* path, const char* module_info) = 0;
45033eb0b6dSopenharmony_ci    virtual std::string GetPkgName(const std::string &moduleName) = 0;
45133eb0b6dSopenharmony_ci
45233eb0b6dSopenharmony_ci    double NewAsyncId()
45333eb0b6dSopenharmony_ci    {
45433eb0b6dSopenharmony_ci        return 0;
45533eb0b6dSopenharmony_ci    }
45633eb0b6dSopenharmony_ci
45733eb0b6dSopenharmony_ci    double GetDefaultTriggerAsyncId()
45833eb0b6dSopenharmony_ci    {
45933eb0b6dSopenharmony_ci        return 0;
46033eb0b6dSopenharmony_ci    }
46133eb0b6dSopenharmony_ci
46233eb0b6dSopenharmony_ci    /**
46333eb0b6dSopenharmony_ci     * @brief run the uv loop in the engine by the designated uv run mode
46433eb0b6dSopenharmony_ci     *
46533eb0b6dSopenharmony_ci     * @param mode the specified uv mode that utilized to tell uv which mode will be used to run the uv loop
46633eb0b6dSopenharmony_ci     */
46733eb0b6dSopenharmony_ci    napi_status RunEventLoop(napi_event_mode mode);
46833eb0b6dSopenharmony_ci
46933eb0b6dSopenharmony_ci    /**
47033eb0b6dSopenharmony_ci     * @brief stop the uv loop in the engine
47133eb0b6dSopenharmony_ci     */
47233eb0b6dSopenharmony_ci    napi_status StopEventLoop();
47333eb0b6dSopenharmony_ci
47433eb0b6dSopenharmony_ci    napi_status SendEvent(const std::function<void()> &cb, napi_event_priority priority = napi_eprio_high);
47533eb0b6dSopenharmony_ci
47633eb0b6dSopenharmony_ci    virtual bool IsCrossThreadCheckEnabled() const = 0;
47733eb0b6dSopenharmony_ci
47833eb0b6dSopenharmony_ci    bool IsInDestructor() const
47933eb0b6dSopenharmony_ci    {
48033eb0b6dSopenharmony_ci        return isInDestructor_;
48133eb0b6dSopenharmony_ci    }
48233eb0b6dSopenharmony_ci
48333eb0b6dSopenharmony_ci    static NativeEngine* GetMainThreadEngine()
48433eb0b6dSopenharmony_ci    {
48533eb0b6dSopenharmony_ci        std::lock_guard<std::mutex> lock(g_mainThreadEngineMutex_);
48633eb0b6dSopenharmony_ci        return g_mainThreadEngine_;
48733eb0b6dSopenharmony_ci    }
48833eb0b6dSopenharmony_ci
48933eb0b6dSopenharmony_ci    static void SetMainThreadEngine(NativeEngine* engine)
49033eb0b6dSopenharmony_ci    {
49133eb0b6dSopenharmony_ci        if (g_mainThreadEngine_ == nullptr) {
49233eb0b6dSopenharmony_ci            std::lock_guard<std::mutex> lock(g_mainThreadEngineMutex_);
49333eb0b6dSopenharmony_ci            if (g_mainThreadEngine_ == nullptr) {
49433eb0b6dSopenharmony_ci                g_mainThreadEngine_ = engine;
49533eb0b6dSopenharmony_ci            }
49633eb0b6dSopenharmony_ci        }
49733eb0b6dSopenharmony_ci    }
49833eb0b6dSopenharmony_ci
49933eb0b6dSopenharmony_ciprivate:
50033eb0b6dSopenharmony_ci    void InitUvField();
50133eb0b6dSopenharmony_ci    void CreateDefaultFunction(void);
50233eb0b6dSopenharmony_ci    void DestoryDefaultFunction(bool release);
50333eb0b6dSopenharmony_ci
50433eb0b6dSopenharmony_ci    virtual NapiOptions *GetNapiOptions() const = 0;
50533eb0b6dSopenharmony_ci
50633eb0b6dSopenharmony_ci    inline void SetUnalived()
50733eb0b6dSopenharmony_ci    {
50833eb0b6dSopenharmony_ci        std::lock_guard<std::mutex> alivedEngLock(g_alivedEngineMutex_);
50933eb0b6dSopenharmony_ci        g_alivedEngine_.erase(this);
51033eb0b6dSopenharmony_ci        return;
51133eb0b6dSopenharmony_ci    }
51233eb0b6dSopenharmony_ci
51333eb0b6dSopenharmony_ci    // should only call once in life cycle of ArkNativeEngine(NativeEngine)
51433eb0b6dSopenharmony_ci    inline void SetAlived();
51533eb0b6dSopenharmony_ci
51633eb0b6dSopenharmony_ciprotected:
51733eb0b6dSopenharmony_ci    void *jsEngine_ = nullptr;
51833eb0b6dSopenharmony_ci
51933eb0b6dSopenharmony_ci    void Init();
52033eb0b6dSopenharmony_ci    void Deinit();
52133eb0b6dSopenharmony_ci
52233eb0b6dSopenharmony_ci    NativeModuleManager* moduleManager_ = nullptr;
52333eb0b6dSopenharmony_ci    NativeReferenceManager* referenceManager_ = nullptr;
52433eb0b6dSopenharmony_ci    NativeCallbackScopeManager* callbackScopeManager_ = nullptr;
52533eb0b6dSopenharmony_ci
52633eb0b6dSopenharmony_ci    uv_loop_t* loop_ = nullptr;
52733eb0b6dSopenharmony_ci
52833eb0b6dSopenharmony_ci    NativeErrorExtendedInfo lastError_;
52933eb0b6dSopenharmony_ci
53033eb0b6dSopenharmony_ci    // register for worker
53133eb0b6dSopenharmony_ci    InitWorkerFunc initWorkerFunc_ {nullptr};
53233eb0b6dSopenharmony_ci    GetAssetFunc getAssetFunc_ {nullptr};
53333eb0b6dSopenharmony_ci    OffWorkerFunc offWorkerFunc_ {nullptr};
53433eb0b6dSopenharmony_ci#if !defined(PREVIEW)
53533eb0b6dSopenharmony_ci    DebuggerPostTask debuggerPostTaskFunc_ {nullptr};
53633eb0b6dSopenharmony_ci#endif
53733eb0b6dSopenharmony_ci    NativeEngine* hostEngine_ {nullptr};
53833eb0b6dSopenharmony_ci    bool isAppModule_ = false;
53933eb0b6dSopenharmony_ci    EcmaVM* vm_ {nullptr};
54033eb0b6dSopenharmony_ci
54133eb0b6dSopenharmony_cipublic:
54233eb0b6dSopenharmony_ci    uint64_t openHandleScopes_ = 0;
54333eb0b6dSopenharmony_ci    panda::Local<panda::ObjectRef> lastException_;
54433eb0b6dSopenharmony_ci
54533eb0b6dSopenharmony_ciprivate:
54633eb0b6dSopenharmony_ci    std::string moduleName_;
54733eb0b6dSopenharmony_ci    std::string moduleFileName_;
54833eb0b6dSopenharmony_ci    std::mutex instanceDataLock_;
54933eb0b6dSopenharmony_ci    NativeObjectInfo instanceDataInfo_;
55033eb0b6dSopenharmony_ci    void FinalizerInstanceData(void);
55133eb0b6dSopenharmony_ci    pthread_t tid_ { 0 };
55233eb0b6dSopenharmony_ci    ThreadId sysTid_ { 0 };
55333eb0b6dSopenharmony_ci    uint64_t id_ { 0 };
55433eb0b6dSopenharmony_ci    std::unordered_map<std::string, int32_t> extensionInfos_;
55533eb0b6dSopenharmony_ci    uv_sem_t uvSem_;
55633eb0b6dSopenharmony_ci    // Application's sdk version
55733eb0b6dSopenharmony_ci    int32_t apiVersion_ = 8;
55833eb0b6dSopenharmony_ci
55933eb0b6dSopenharmony_ci    // the old worker api use before api9, the new worker api start with api9
56033eb0b6dSopenharmony_ci    enum JSThreadType { MAIN_THREAD, WORKER_THREAD, TASKPOOL_THREAD, RESTRICTEDWORKER_THREAD, NATIVE_THREAD };
56133eb0b6dSopenharmony_ci    panda::panda_file::DataProtect jsThreadType_ {panda::panda_file::DataProtect(uintptr_t(JSThreadType::MAIN_THREAD))};
56233eb0b6dSopenharmony_ci    // current is hostengine, can create old worker, new worker, or no workers on hostengine
56333eb0b6dSopenharmony_ci    std::atomic<WorkerVersion> workerVersion_ { WorkerVersion::NONE };
56433eb0b6dSopenharmony_ci
56533eb0b6dSopenharmony_ci#if !defined(PREVIEW)
56633eb0b6dSopenharmony_ci    static void UVThreadRunner(void* nativeEngine);
56733eb0b6dSopenharmony_ci    void PostLoopTask();
56833eb0b6dSopenharmony_ci
56933eb0b6dSopenharmony_ci    bool checkUVLoop_ = false;
57033eb0b6dSopenharmony_ci    uv_thread_t uvThread_;
57133eb0b6dSopenharmony_ci#endif
57233eb0b6dSopenharmony_ci    mutable std::shared_mutex eventMutex_;
57333eb0b6dSopenharmony_ci    napi_threadsafe_function defaultFunc_ = nullptr;
57433eb0b6dSopenharmony_ci    PostTask postTask_ = nullptr;
57533eb0b6dSopenharmony_ci    CleanEnv cleanEnv_ = nullptr;
57633eb0b6dSopenharmony_ci    uv_async_t uvAsync_;
57733eb0b6dSopenharmony_ci    std::unordered_map<void*, std::pair<CleanupCallback, uint64_t>> cleanupHooks_;
57833eb0b6dSopenharmony_ci    uint64_t cleanupHookCounter_ = 0;
57933eb0b6dSopenharmony_ci    std::atomic_int requestWaiting_ { 0 };
58033eb0b6dSopenharmony_ci    std::atomic_int listeningCounter_ { 0 };
58133eb0b6dSopenharmony_ci    std::atomic_int subEnvCounter_ { 0 };
58233eb0b6dSopenharmony_ci    std::atomic_bool isStopping_ { false };
58333eb0b6dSopenharmony_ci
58433eb0b6dSopenharmony_ci    std::mutex loopRunningMutex_;
58533eb0b6dSopenharmony_ci    bool isLoopRunning_ = false;
58633eb0b6dSopenharmony_ci    bool isInDestructor_ {false};
58733eb0b6dSopenharmony_ci
58833eb0b6dSopenharmony_ci    // protect alived engine set and last engine id
58933eb0b6dSopenharmony_ci    static std::mutex g_alivedEngineMutex_;
59033eb0b6dSopenharmony_ci    static std::unordered_set<NativeEngine*> g_alivedEngine_;
59133eb0b6dSopenharmony_ci    static uint64_t g_lastEngineId_;
59233eb0b6dSopenharmony_ci    static std::mutex g_mainThreadEngineMutex_;
59333eb0b6dSopenharmony_ci    static NativeEngine* g_mainThreadEngine_;
59433eb0b6dSopenharmony_ci};
59533eb0b6dSopenharmony_ci
59633eb0b6dSopenharmony_ciclass TryCatch : public panda::TryCatch {
59733eb0b6dSopenharmony_cipublic:
59833eb0b6dSopenharmony_ci    explicit TryCatch(napi_env env)
59933eb0b6dSopenharmony_ci        : panda::TryCatch(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm()),
60033eb0b6dSopenharmony_ci          engine_(reinterpret_cast<NativeEngine*>(env)) {}
60133eb0b6dSopenharmony_ci
60233eb0b6dSopenharmony_ci    ~TryCatch()
60333eb0b6dSopenharmony_ci    {
60433eb0b6dSopenharmony_ci        if (HasCaught()) {
60533eb0b6dSopenharmony_ci            engine_->lastException_ = GetException();
60633eb0b6dSopenharmony_ci        }
60733eb0b6dSopenharmony_ci    }
60833eb0b6dSopenharmony_ciprivate:
60933eb0b6dSopenharmony_ci   NativeEngine* engine_ = nullptr;
61033eb0b6dSopenharmony_ci};
61133eb0b6dSopenharmony_ci#endif /* FOUNDATION_ACE_NAPI_NATIVE_ENGINE_NATIVE_ENGINE_H */
612