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#include "ark_native_engine.h" 1733eb0b6dSopenharmony_ci 1833eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 1933eb0b6dSopenharmony_ci#include <sys/prctl.h> 2033eb0b6dSopenharmony_ci#endif 2133eb0b6dSopenharmony_ci 2233eb0b6dSopenharmony_ci#include <sstream> 2333eb0b6dSopenharmony_ci#include "ark_native_deferred.h" 2433eb0b6dSopenharmony_ci#if !defined(is_arkui_x) && defined(OHOS_PLATFORM) 2533eb0b6dSopenharmony_ci#include "unwinder.h" 2633eb0b6dSopenharmony_ci#endif 2733eb0b6dSopenharmony_ci#include "ark_native_reference.h" 2833eb0b6dSopenharmony_ci#include "native_engine/native_property.h" 2933eb0b6dSopenharmony_ci#include "native_engine/native_utils.h" 3033eb0b6dSopenharmony_ci#include "native_sendable.h" 3133eb0b6dSopenharmony_ci#include "securec.h" 3233eb0b6dSopenharmony_ci#include "utils/file.h" 3333eb0b6dSopenharmony_ci#include "utils/log.h" 3433eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) 3533eb0b6dSopenharmony_ci#include "parameters.h" 3633eb0b6dSopenharmony_ci#include <uv.h> 3733eb0b6dSopenharmony_ci#endif 3833eb0b6dSopenharmony_ci#ifdef ENABLE_CONTAINER_SCOPE 3933eb0b6dSopenharmony_ci#include "core/common/container_scope.h" 4033eb0b6dSopenharmony_ci#endif 4133eb0b6dSopenharmony_ci#if defined(ENABLE_EVENT_HANDLER) 4233eb0b6dSopenharmony_ci#include "event_handler.h" 4333eb0b6dSopenharmony_ci#endif 4433eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 4533eb0b6dSopenharmony_ci#include "hitrace/trace.h" 4633eb0b6dSopenharmony_ci#include "hitrace_meter.h" 4733eb0b6dSopenharmony_ci#include "parameter.h" 4833eb0b6dSopenharmony_ci#include "musl_preinit_common.h" 4933eb0b6dSopenharmony_ci#include "memory_trace.h" 5033eb0b6dSopenharmony_ci 5133eb0b6dSopenharmony_ci// LCOV_EXCL_START 5233eb0b6dSopenharmony_cistruct alignas(8) HookJsConfig { // 8 is 8 bit 5333eb0b6dSopenharmony_ci int32_t jsStackReport = 0; 5433eb0b6dSopenharmony_ci uint8_t maxJsStackDepth = 0; 5533eb0b6dSopenharmony_ci bool jsFpUnwind = false; 5633eb0b6dSopenharmony_ci char filterNapiName[64] = { "" }; 5733eb0b6dSopenharmony_ci}; 5833eb0b6dSopenharmony_ci 5933eb0b6dSopenharmony_ciclass BlockHookScope { 6033eb0b6dSopenharmony_cipublic: 6133eb0b6dSopenharmony_ci BlockHookScope() 6233eb0b6dSopenharmony_ci { 6333eb0b6dSopenharmony_ci previousState_ = __set_hook_flag(false); 6433eb0b6dSopenharmony_ci } 6533eb0b6dSopenharmony_ci ~BlockHookScope() 6633eb0b6dSopenharmony_ci { 6733eb0b6dSopenharmony_ci __set_hook_flag(previousState_); 6833eb0b6dSopenharmony_ci } 6933eb0b6dSopenharmony_ciprivate: 7033eb0b6dSopenharmony_ci bool previousState_ {true}; 7133eb0b6dSopenharmony_ci}; 7233eb0b6dSopenharmony_ci 7333eb0b6dSopenharmony_cistatic HookJsConfig* g_hookJsConfig = nullptr; 7433eb0b6dSopenharmony_cistatic std::once_flag g_hookOnceFlag; 7533eb0b6dSopenharmony_cistatic std::string JS_CALL_STACK_DEPTH_SEP = ","; // ',' is js call stack depth separator 7633eb0b6dSopenharmony_cistatic std::string JS_SYMBOL_FILEPATH_SEP = "|"; // '|' is js symbol and filepath separator 7733eb0b6dSopenharmony_cistatic constexpr uint64_t BUF_SIZE = 128; 7833eb0b6dSopenharmony_ci#endif 7933eb0b6dSopenharmony_ci 8033eb0b6dSopenharmony_ciusing panda::JsiRuntimeCallInfo; 8133eb0b6dSopenharmony_ciusing panda::BooleanRef; 8233eb0b6dSopenharmony_ciusing panda::ObjectRef; 8333eb0b6dSopenharmony_ciusing panda::StringRef; 8433eb0b6dSopenharmony_ciusing panda::Global; 8533eb0b6dSopenharmony_ciusing panda::JSNApi; 8633eb0b6dSopenharmony_ciusing panda::FunctionRef; 8733eb0b6dSopenharmony_ciusing panda::PrimitiveRef; 8833eb0b6dSopenharmony_ciusing panda::ArrayBufferRef; 8933eb0b6dSopenharmony_ciusing panda::TypedArrayRef; 9033eb0b6dSopenharmony_ciusing panda::PromiseCapabilityRef; 9133eb0b6dSopenharmony_ciusing panda::PropertyAttribute; 9233eb0b6dSopenharmony_ciusing panda::NativePointerRef; 9333eb0b6dSopenharmony_ciusing panda::SymbolRef; 9433eb0b6dSopenharmony_ciusing panda::IntegerRef; 9533eb0b6dSopenharmony_ciusing panda::DateRef; 9633eb0b6dSopenharmony_ciusing panda::BigIntRef; 9733eb0b6dSopenharmony_cistatic constexpr auto PANDA_MAIN_FUNCTION = "_GLOBAL::func_main_0"; 9833eb0b6dSopenharmony_cistatic constexpr auto PANDA_MODULE_NAME = "_GLOBAL_MODULE_NAME"; 9933eb0b6dSopenharmony_cistatic constexpr auto PANDA_MODULE_NAME_LEN = 32; 10033eb0b6dSopenharmony_cistatic std::unordered_set<std::string> NATIVE_MODULE = {"system.app", "ohos.app", "system.router", 10133eb0b6dSopenharmony_ci "system.curves", "ohos.curves", "system.matrix4", "ohos.matrix4"}; 10233eb0b6dSopenharmony_cistatic constexpr auto NATIVE_MODULE_PREFIX = "@native:"; 10333eb0b6dSopenharmony_cistatic constexpr auto OHOS_MODULE_PREFIX = "@ohos:"; 10433eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 10533eb0b6dSopenharmony_ciconstexpr auto NAPI_PROFILER_PARAM_SIZE = 10; 10633eb0b6dSopenharmony_cistd::atomic<uint64_t> g_chainId = 0; 10733eb0b6dSopenharmony_ciconstexpr int NAPI_CALL_STACK = 2; // just for napi call stack 10833eb0b6dSopenharmony_ci#endif 10933eb0b6dSopenharmony_ci 11033eb0b6dSopenharmony_cistd::string ArkNativeEngine::tempModuleName_ {""}; 11133eb0b6dSopenharmony_cibool ArkNativeEngine::napiProfilerEnabled {false}; 11233eb0b6dSopenharmony_cibool ArkNativeEngine::napiProfilerParamReaded {false}; 11333eb0b6dSopenharmony_ciPermissionCheckCallback ArkNativeEngine::permissionCheckCallback_ {nullptr}; 11433eb0b6dSopenharmony_ci 11533eb0b6dSopenharmony_ci// This interface is using by ace_engine 11633eb0b6dSopenharmony_cinapi_value LocalValueToLocalNapiValue(panda::Local<panda::JSValueRef> local) 11733eb0b6dSopenharmony_ci{ 11833eb0b6dSopenharmony_ci return JsValueFromLocalValue(local); 11933eb0b6dSopenharmony_ci} 12033eb0b6dSopenharmony_ci 12133eb0b6dSopenharmony_ci// This interface is using by ace_engine 12233eb0b6dSopenharmony_cipanda::Local<panda::JSValueRef> NapiValueToLocalValue(napi_value v) 12333eb0b6dSopenharmony_ci{ 12433eb0b6dSopenharmony_ci return LocalValueFromJsValue(v); 12533eb0b6dSopenharmony_ci} 12633eb0b6dSopenharmony_ci 12733eb0b6dSopenharmony_ci#ifdef ENABLE_CONTAINER_SCOPE 12833eb0b6dSopenharmony_civoid FunctionSetContainerId(const EcmaVM *vm, panda::Local<panda::JSValueRef> &value) 12933eb0b6dSopenharmony_ci{ 13033eb0b6dSopenharmony_ci if (!value->IsFunction(vm)) { 13133eb0b6dSopenharmony_ci return; 13233eb0b6dSopenharmony_ci } 13333eb0b6dSopenharmony_ci panda::Local<panda::FunctionRef> funcValue(value); 13433eb0b6dSopenharmony_ci if (funcValue->IsNative(vm)) { 13533eb0b6dSopenharmony_ci return; 13633eb0b6dSopenharmony_ci } 13733eb0b6dSopenharmony_ci 13833eb0b6dSopenharmony_ci auto extraInfo = funcValue->GetData(vm); 13933eb0b6dSopenharmony_ci if (extraInfo != nullptr) { 14033eb0b6dSopenharmony_ci return; 14133eb0b6dSopenharmony_ci } 14233eb0b6dSopenharmony_ci 14333eb0b6dSopenharmony_ci NapiFunctionInfo *funcInfo = NapiFunctionInfo::CreateNewInstance(); 14433eb0b6dSopenharmony_ci if (funcInfo == nullptr) { 14533eb0b6dSopenharmony_ci HILOG_ERROR("funcInfo is nullptr"); 14633eb0b6dSopenharmony_ci return; 14733eb0b6dSopenharmony_ci } 14833eb0b6dSopenharmony_ci funcInfo->scopeId = OHOS::Ace::ContainerScope::CurrentId(); 14933eb0b6dSopenharmony_ci funcValue->SetData(vm, reinterpret_cast<void*>(funcInfo), 15033eb0b6dSopenharmony_ci [](void* env, void *externalPointer, void *data) { 15133eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 15233eb0b6dSopenharmony_ci if (info != nullptr) { 15333eb0b6dSopenharmony_ci delete info; 15433eb0b6dSopenharmony_ci info = nullptr; 15533eb0b6dSopenharmony_ci } 15633eb0b6dSopenharmony_ci }, true); 15733eb0b6dSopenharmony_ci} 15833eb0b6dSopenharmony_ci#endif 15933eb0b6dSopenharmony_ci 16033eb0b6dSopenharmony_cipanda::Local<panda::JSValueRef> NapiDefineClass(napi_env env, const char* name, NapiNativeCallback callback, 16133eb0b6dSopenharmony_ci void* data, const NapiPropertyDescriptor* properties, size_t length) 16233eb0b6dSopenharmony_ci{ 16333eb0b6dSopenharmony_ci auto vm = const_cast<EcmaVM*>(reinterpret_cast<NativeEngine*>(env)->GetEcmaVm()); 16433eb0b6dSopenharmony_ci std::string className(name); 16533eb0b6dSopenharmony_ci if (ArkNativeEngine::napiProfilerEnabled) { 16633eb0b6dSopenharmony_ci className = ArkNativeEngine::tempModuleName_ + "." + name; 16733eb0b6dSopenharmony_ci } 16833eb0b6dSopenharmony_ci 16933eb0b6dSopenharmony_ci NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance(); 17033eb0b6dSopenharmony_ci if (funcInfo == nullptr) { 17133eb0b6dSopenharmony_ci HILOG_ERROR("funcInfo is nullptr"); 17233eb0b6dSopenharmony_ci return panda::JSValueRef::Undefined(vm); 17333eb0b6dSopenharmony_ci } 17433eb0b6dSopenharmony_ci funcInfo->callback = callback; 17533eb0b6dSopenharmony_ci funcInfo->data = data; 17633eb0b6dSopenharmony_ci#ifdef ENABLE_CONTAINER_SCOPE 17733eb0b6dSopenharmony_ci funcInfo->scopeId = OHOS::Ace::ContainerScope::CurrentId(); 17833eb0b6dSopenharmony_ci#endif 17933eb0b6dSopenharmony_ci 18033eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = panda::FunctionRef::NewConcurrentClassFunction(vm, ArkNativeFunctionCallBack, 18133eb0b6dSopenharmony_ci [](void* env, void* externalPointer, void* data) { 18233eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 18333eb0b6dSopenharmony_ci if (info != nullptr) { 18433eb0b6dSopenharmony_ci delete info; 18533eb0b6dSopenharmony_ci } 18633eb0b6dSopenharmony_ci }, 18733eb0b6dSopenharmony_ci reinterpret_cast<void*>(funcInfo), true); 18833eb0b6dSopenharmony_ci 18933eb0b6dSopenharmony_ci Local<panda::StringRef> fnName = panda::StringRef::NewFromUtf8(vm, className.c_str()); 19033eb0b6dSopenharmony_ci fn->SetName(vm, fnName); 19133eb0b6dSopenharmony_ci 19233eb0b6dSopenharmony_ci if (length == 0) { 19333eb0b6dSopenharmony_ci return fn; 19433eb0b6dSopenharmony_ci } 19533eb0b6dSopenharmony_ci Local<panda::ObjectRef> classPrototype = fn->GetFunctionPrototype(vm); 19633eb0b6dSopenharmony_ci Local<panda::ObjectRef> fnObj = fn->ToObject(vm); 19733eb0b6dSopenharmony_ci for (size_t i = 0; i < length; i++) { 19833eb0b6dSopenharmony_ci if (properties[i].attributes & NATIVE_STATIC) { 19933eb0b6dSopenharmony_ci NapiDefineProperty(env, fnObj, properties[i]); 20033eb0b6dSopenharmony_ci } else { 20133eb0b6dSopenharmony_ci if (classPrototype->IsUndefined()) { 20233eb0b6dSopenharmony_ci HILOG_ERROR("ArkNativeEngineImpl::Class's prototype is null"); 20333eb0b6dSopenharmony_ci continue; 20433eb0b6dSopenharmony_ci } 20533eb0b6dSopenharmony_ci reinterpret_cast<ArkNativeEngine*>(env)->SetModuleName(classPrototype, className); 20633eb0b6dSopenharmony_ci NapiDefineProperty(env, classPrototype, properties[i]); 20733eb0b6dSopenharmony_ci } 20833eb0b6dSopenharmony_ci } 20933eb0b6dSopenharmony_ci 21033eb0b6dSopenharmony_ci return fn; 21133eb0b6dSopenharmony_ci} 21233eb0b6dSopenharmony_ci 21333eb0b6dSopenharmony_ciLocal<panda::JSValueRef> NapiNativeCreateSendableFunction(napi_env env, 21433eb0b6dSopenharmony_ci const char* name, 21533eb0b6dSopenharmony_ci NapiNativeCallback cb, 21633eb0b6dSopenharmony_ci void* value) 21733eb0b6dSopenharmony_ci{ 21833eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 21933eb0b6dSopenharmony_ci auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm()); 22033eb0b6dSopenharmony_ci NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance(); 22133eb0b6dSopenharmony_ci if (funcInfo == nullptr) { 22233eb0b6dSopenharmony_ci HILOG_ERROR("funcInfo is nullptr"); 22333eb0b6dSopenharmony_ci return JSValueRef::Undefined(vm); 22433eb0b6dSopenharmony_ci } 22533eb0b6dSopenharmony_ci funcInfo->callback = cb; 22633eb0b6dSopenharmony_ci funcInfo->data = value; 22733eb0b6dSopenharmony_ci 22833eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = panda::FunctionRef::NewSendable( 22933eb0b6dSopenharmony_ci vm, ArkNativeFunctionCallBack, 23033eb0b6dSopenharmony_ci [](void* env, void* externalPointer, void* data) { 23133eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 23233eb0b6dSopenharmony_ci if (info != nullptr) { 23333eb0b6dSopenharmony_ci delete info; 23433eb0b6dSopenharmony_ci } 23533eb0b6dSopenharmony_ci }, 23633eb0b6dSopenharmony_ci reinterpret_cast<void*>(funcInfo), true); 23733eb0b6dSopenharmony_ci return fn; 23833eb0b6dSopenharmony_ci} 23933eb0b6dSopenharmony_ci 24033eb0b6dSopenharmony_cipanda::Local<panda::JSValueRef> NapiDefineSendableClass(napi_env env, 24133eb0b6dSopenharmony_ci const char* name, 24233eb0b6dSopenharmony_ci NapiNativeCallback callback, 24333eb0b6dSopenharmony_ci void* data, 24433eb0b6dSopenharmony_ci const NapiPropertyDescriptor* properties, 24533eb0b6dSopenharmony_ci size_t propertiesLength, 24633eb0b6dSopenharmony_ci napi_value parent) 24733eb0b6dSopenharmony_ci{ 24833eb0b6dSopenharmony_ci const EcmaVM* vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm(); 24933eb0b6dSopenharmony_ci NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance(); 25033eb0b6dSopenharmony_ci if (funcInfo == nullptr) { 25133eb0b6dSopenharmony_ci HILOG_FATAL("funcInfo is nullptr"); 25233eb0b6dSopenharmony_ci return JSValueRef::Undefined(vm); 25333eb0b6dSopenharmony_ci } 25433eb0b6dSopenharmony_ci funcInfo->callback = callback; 25533eb0b6dSopenharmony_ci funcInfo->data = data; 25633eb0b6dSopenharmony_ci 25733eb0b6dSopenharmony_ci std::string className(name); 25833eb0b6dSopenharmony_ci if (ArkNativeEngine::napiProfilerEnabled) { 25933eb0b6dSopenharmony_ci className = ArkNativeEngine::tempModuleName_ + "." + name; 26033eb0b6dSopenharmony_ci } 26133eb0b6dSopenharmony_ci 26233eb0b6dSopenharmony_ci Local<panda::StringRef> fnName = panda::StringRef::NewFromUtf8(vm, className.c_str()); 26333eb0b6dSopenharmony_ci Local<JSValueRef> localParent = JSValueRef::Null(vm); 26433eb0b6dSopenharmony_ci if (parent != nullptr) { 26533eb0b6dSopenharmony_ci localParent = LocalValueFromJsValue(parent); 26633eb0b6dSopenharmony_ci } 26733eb0b6dSopenharmony_ci 26833eb0b6dSopenharmony_ci auto infos = NativeSendable::CreateSendablePropertiesInfos(env, properties, propertiesLength); 26933eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = panda::FunctionRef::NewSendableClassFunction( 27033eb0b6dSopenharmony_ci vm, ArkNativeFunctionCallBack, 27133eb0b6dSopenharmony_ci [](void* env, void* externalPointer, void* data) { 27233eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 27333eb0b6dSopenharmony_ci if (info != nullptr) { 27433eb0b6dSopenharmony_ci delete info; 27533eb0b6dSopenharmony_ci } 27633eb0b6dSopenharmony_ci }, 27733eb0b6dSopenharmony_ci reinterpret_cast<void*>(funcInfo), fnName, infos, localParent, true); 27833eb0b6dSopenharmony_ci 27933eb0b6dSopenharmony_ci return fn; 28033eb0b6dSopenharmony_ci} 28133eb0b6dSopenharmony_ci 28233eb0b6dSopenharmony_cistruct MoudleNameLocker { 28333eb0b6dSopenharmony_ci explicit MoudleNameLocker(std::string moduleName) 28433eb0b6dSopenharmony_ci { 28533eb0b6dSopenharmony_ci ArkNativeEngine::tempModuleName_ = moduleName; 28633eb0b6dSopenharmony_ci } 28733eb0b6dSopenharmony_ci ~MoudleNameLocker() 28833eb0b6dSopenharmony_ci { 28933eb0b6dSopenharmony_ci ArkNativeEngine::tempModuleName_ = ""; 29033eb0b6dSopenharmony_ci } 29133eb0b6dSopenharmony_ci}; 29233eb0b6dSopenharmony_ci 29333eb0b6dSopenharmony_civoid* ArkNativeEngine::GetNativePtrCallBack(void* data) 29433eb0b6dSopenharmony_ci{ 29533eb0b6dSopenharmony_ci if (data == nullptr) { 29633eb0b6dSopenharmony_ci HILOG_ERROR("data is nullptr"); 29733eb0b6dSopenharmony_ci return nullptr; 29833eb0b6dSopenharmony_ci } 29933eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 30033eb0b6dSopenharmony_ci auto cb = reinterpret_cast<void*>(info->callback); 30133eb0b6dSopenharmony_ci return cb; 30233eb0b6dSopenharmony_ci} 30333eb0b6dSopenharmony_ci 30433eb0b6dSopenharmony_cibool ArkNativeEngine::CheckArkApiAllowList( 30533eb0b6dSopenharmony_ci NativeModule* module, panda::ecmascript::ApiCheckContext context, panda::Local<panda::ObjectRef>& exportCopy) 30633eb0b6dSopenharmony_ci{ 30733eb0b6dSopenharmony_ci std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker = module->apiAllowListChecker; 30833eb0b6dSopenharmony_ci if (apiAllowListChecker != nullptr) { 30933eb0b6dSopenharmony_ci const std::string apiPath = context.moduleName->ToString(context.ecmaVm); 31033eb0b6dSopenharmony_ci if ((*apiAllowListChecker)(apiPath)) { 31133eb0b6dSopenharmony_ci CopyPropertyApiFilter(apiAllowListChecker, context.ecmaVm, context.exportObj, exportCopy, apiPath); 31233eb0b6dSopenharmony_ci } 31333eb0b6dSopenharmony_ci return true; 31433eb0b6dSopenharmony_ci } 31533eb0b6dSopenharmony_ci return false; 31633eb0b6dSopenharmony_ci} 31733eb0b6dSopenharmony_ci 31833eb0b6dSopenharmony_civoid ArkNativeEngine::CopyPropertyApiFilter(const std::unique_ptr<ApiAllowListChecker>& apiAllowListChecker, 31933eb0b6dSopenharmony_ci const EcmaVM* ecmaVm, const panda::Local<panda::ObjectRef> exportObj, panda::Local<panda::ObjectRef>& exportCopy, 32033eb0b6dSopenharmony_ci const std::string& apiPath) 32133eb0b6dSopenharmony_ci{ 32233eb0b6dSopenharmony_ci panda::Local<panda::ArrayRef> namesArrayRef = exportObj->GetAllPropertyNames(ecmaVm, NATIVE_DEFAULT); 32333eb0b6dSopenharmony_ci for (uint32_t i = 0; i < namesArrayRef->Length(ecmaVm); ++i) { 32433eb0b6dSopenharmony_ci const panda::Local<panda::JSValueRef> nameValue = panda::ArrayRef::GetValueAt(ecmaVm, namesArrayRef, i); 32533eb0b6dSopenharmony_ci const panda::Local<panda::JSValueRef> value = exportObj->Get(ecmaVm, nameValue); 32633eb0b6dSopenharmony_ci const std::string curPath = apiPath + "." + nameValue->ToString(ecmaVm)->ToString(ecmaVm); 32733eb0b6dSopenharmony_ci if ((*apiAllowListChecker)(curPath)) { 32833eb0b6dSopenharmony_ci const std::string valueType = value->Typeof(ecmaVm)->ToString(ecmaVm); 32933eb0b6dSopenharmony_ci if (valueType == "object") { 33033eb0b6dSopenharmony_ci panda::Local<panda::ObjectRef> subObject = ObjectRef::New(ecmaVm); 33133eb0b6dSopenharmony_ci CopyPropertyApiFilter(apiAllowListChecker, ecmaVm, value, subObject, curPath); 33233eb0b6dSopenharmony_ci exportCopy->Set(ecmaVm, nameValue, subObject); 33333eb0b6dSopenharmony_ci HILOG_DEBUG("Set the package '%{public}s' to the allow list", curPath.c_str()); 33433eb0b6dSopenharmony_ci } else if (valueType == "function") { 33533eb0b6dSopenharmony_ci exportCopy->Set(ecmaVm, nameValue, value); 33633eb0b6dSopenharmony_ci HILOG_DEBUG("Set the function '%{public}s' to the allow list", curPath.c_str()); 33733eb0b6dSopenharmony_ci } else { 33833eb0b6dSopenharmony_ci exportCopy->Set(ecmaVm, nameValue, value); 33933eb0b6dSopenharmony_ci HILOG_DEBUG("Set the element type is '%{public}s::%{public}s' to the allow list", valueType.c_str(), 34033eb0b6dSopenharmony_ci curPath.c_str()); 34133eb0b6dSopenharmony_ci } 34233eb0b6dSopenharmony_ci } 34333eb0b6dSopenharmony_ci } 34433eb0b6dSopenharmony_ci} 34533eb0b6dSopenharmony_ci 34633eb0b6dSopenharmony_ciArkNativeEngine::ArkNativeEngine(EcmaVM* vm, void* jsEngine, bool isLimitedWorker) : NativeEngine(jsEngine, vm), 34733eb0b6dSopenharmony_ci topScope_(vm), 34833eb0b6dSopenharmony_ci isLimitedWorker_(isLimitedWorker) 34933eb0b6dSopenharmony_ci{ 35033eb0b6dSopenharmony_ci HILOG_DEBUG("ArkNativeEngine::ArkNativeEngine"); 35133eb0b6dSopenharmony_ci panda::JSNApi::SetEnv(vm, this); 35233eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 35333eb0b6dSopenharmony_ci if (!ArkNativeEngine::napiProfilerParamReaded) { 35433eb0b6dSopenharmony_ci char napiProfilerParam[NAPI_PROFILER_PARAM_SIZE] = {0}; 35533eb0b6dSopenharmony_ci int ret = GetParameter("persist.hiviewdfx.napiprofiler.enabled", "false", 35633eb0b6dSopenharmony_ci napiProfilerParam, sizeof(napiProfilerParam)); 35733eb0b6dSopenharmony_ci if (ret > 0 && strcmp(napiProfilerParam, "true") == 0) { 35833eb0b6dSopenharmony_ci ArkNativeEngine::napiProfilerEnabled = true; 35933eb0b6dSopenharmony_ci } 36033eb0b6dSopenharmony_ci ArkNativeEngine::napiProfilerParamReaded = true; 36133eb0b6dSopenharmony_ci } 36233eb0b6dSopenharmony_ci#endif 36333eb0b6dSopenharmony_ci LocalScope scope(vm_); 36433eb0b6dSopenharmony_ci Local<StringRef> requireInternalName = StringRef::NewFromUtf8(vm, "requireInternal"); 36533eb0b6dSopenharmony_ci void* requireData = static_cast<void*>(this); 36633eb0b6dSopenharmony_ci 36733eb0b6dSopenharmony_ci options_ = new NapiOptions(); 36833eb0b6dSopenharmony_ci crossThreadCheck_ = JSNApi::IsMultiThreadCheckEnabled(vm); 36933eb0b6dSopenharmony_ci#if defined(OHOS_PLATFORM) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) 37033eb0b6dSopenharmony_ci int napiProperties = OHOS::system::GetIntParameter<int>("persist.ark.napi.properties", -1); 37133eb0b6dSopenharmony_ci if (options_ != nullptr) { 37233eb0b6dSopenharmony_ci options_->SetProperties(napiProperties); 37333eb0b6dSopenharmony_ci } 37433eb0b6dSopenharmony_ci#endif 37533eb0b6dSopenharmony_ci Local<FunctionRef> requireNapi = 37633eb0b6dSopenharmony_ci FunctionRef::New( 37733eb0b6dSopenharmony_ci vm, 37833eb0b6dSopenharmony_ci [](JsiRuntimeCallInfo *info) -> Local<JSValueRef> { 37933eb0b6dSopenharmony_ci EcmaVM *ecmaVm = info->GetVM(); 38033eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(ecmaVm); 38133eb0b6dSopenharmony_ci NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 38233eb0b6dSopenharmony_ci ArkNativeEngine* arkNativeEngine = static_cast<ArkNativeEngine*>(info->GetData()); 38333eb0b6dSopenharmony_ci Local<StringRef> moduleName(info->GetCallArgRef(0)); 38433eb0b6dSopenharmony_ci NativeModule* module = nullptr; 38533eb0b6dSopenharmony_ci bool isAppModule = false; 38633eb0b6dSopenharmony_ci std::string errInfo = ""; 38733eb0b6dSopenharmony_ci Local<JSValueRef> exports(JSValueRef::Undefined(ecmaVm)); 38833eb0b6dSopenharmony_ci#ifdef IOS_PLATFORM 38933eb0b6dSopenharmony_ci if (arkNativeEngine->isLimitedWorker_) { 39033eb0b6dSopenharmony_ci if (!moduleManager->CheckModuleRestricted(moduleName->ToString(ecmaVm).c_str())) { 39133eb0b6dSopenharmony_ci HILOG_ERROR("module %{public}s does not found in whitelist", 39233eb0b6dSopenharmony_ci moduleName->ToString(ecmaVm).c_str()); 39333eb0b6dSopenharmony_ci return scope.Escape(exports); 39433eb0b6dSopenharmony_ci } 39533eb0b6dSopenharmony_ci } 39633eb0b6dSopenharmony_ci module = moduleManager->LoadNativeModule( 39733eb0b6dSopenharmony_ci moduleName->ToString(ecmaVm).c_str(), nullptr, false, errInfo, false, ""); 39833eb0b6dSopenharmony_ci#else 39933eb0b6dSopenharmony_ci const uint32_t lengthMax = 2; 40033eb0b6dSopenharmony_ci if (info->GetArgsNumber() >= lengthMax) { 40133eb0b6dSopenharmony_ci Local<BooleanRef> ret(info->GetCallArgRef(1)); 40233eb0b6dSopenharmony_ci isAppModule = ret->Value(); 40333eb0b6dSopenharmony_ci } 40433eb0b6dSopenharmony_ci arkNativeEngine->isAppModule_ = isAppModule; 40533eb0b6dSopenharmony_ci if (arkNativeEngine->isLimitedWorker_ && !isAppModule) { 40633eb0b6dSopenharmony_ci if (!moduleManager->CheckModuleRestricted(moduleName->ToString(ecmaVm).c_str())) { 40733eb0b6dSopenharmony_ci HILOG_ERROR("module %{public}s does not found in whitelist", 40833eb0b6dSopenharmony_ci moduleName->ToString(ecmaVm).c_str()); 40933eb0b6dSopenharmony_ci return scope.Escape(exports); 41033eb0b6dSopenharmony_ci } 41133eb0b6dSopenharmony_ci } 41233eb0b6dSopenharmony_ci 41333eb0b6dSopenharmony_ci if (info->GetArgsNumber() == 3) { // 3:Determine if the number of parameters is equal to 3 41433eb0b6dSopenharmony_ci Local<StringRef> path(info->GetCallArgRef(2)); // 2:Take the second parameter 41533eb0b6dSopenharmony_ci module = moduleManager->LoadNativeModule(moduleName->ToString(ecmaVm).c_str(), 41633eb0b6dSopenharmony_ci path->ToString(ecmaVm).c_str(), isAppModule, errInfo, false, ""); 41733eb0b6dSopenharmony_ci } else if (info->GetArgsNumber() == 4) { // 4:Determine if the number of parameters is equal to 4 41833eb0b6dSopenharmony_ci Local<StringRef> path(info->GetCallArgRef(2)); // 2:Take the second parameter 41933eb0b6dSopenharmony_ci Local<StringRef> relativePath(info->GetCallArgRef(3)); // 3:Take the second parameter 42033eb0b6dSopenharmony_ci module = moduleManager->LoadNativeModule(moduleName->ToString(ecmaVm).c_str(), nullptr, isAppModule, 42133eb0b6dSopenharmony_ci errInfo, false, relativePath->ToString(ecmaVm).c_str()); 42233eb0b6dSopenharmony_ci } else { 42333eb0b6dSopenharmony_ci module = 42433eb0b6dSopenharmony_ci moduleManager->LoadNativeModule(moduleName->ToString(ecmaVm).c_str(), 42533eb0b6dSopenharmony_ci nullptr, isAppModule, errInfo, false, ""); 42633eb0b6dSopenharmony_ci } 42733eb0b6dSopenharmony_ci#endif 42833eb0b6dSopenharmony_ci if (module != nullptr) { 42933eb0b6dSopenharmony_ci auto it = arkNativeEngine->loadedModules_.find(module); 43033eb0b6dSopenharmony_ci if (it != arkNativeEngine->loadedModules_.end()) { 43133eb0b6dSopenharmony_ci return scope.Escape(it->second.ToLocal(ecmaVm)); 43233eb0b6dSopenharmony_ci } 43333eb0b6dSopenharmony_ci std::string strModuleName = moduleName->ToString(ecmaVm); 43433eb0b6dSopenharmony_ci moduleManager->SetNativeEngine(strModuleName, arkNativeEngine); 43533eb0b6dSopenharmony_ci MoudleNameLocker nameLocker(strModuleName); 43633eb0b6dSopenharmony_ci 43733eb0b6dSopenharmony_ci if (module->jsCode == nullptr && module->getABCCode != nullptr) { 43833eb0b6dSopenharmony_ci module->getABCCode(&module->jsCode, &module->jsCodeLen); 43933eb0b6dSopenharmony_ci } 44033eb0b6dSopenharmony_ci if (module->jsABCCode != nullptr || module->jsCode != nullptr) { 44133eb0b6dSopenharmony_ci char fileName[NAPI_PATH_MAX] = { 0 }; 44233eb0b6dSopenharmony_ci const char* name = module->name; 44333eb0b6dSopenharmony_ci if (sprintf_s(fileName, sizeof(fileName), "lib%s.z.so/%s.js", name, name) == -1) { 44433eb0b6dSopenharmony_ci HILOG_ERROR("sprintf_s file name failed"); 44533eb0b6dSopenharmony_ci return scope.Escape(exports); 44633eb0b6dSopenharmony_ci } 44733eb0b6dSopenharmony_ci HILOG_DEBUG("load js code from %{public}s", fileName); 44833eb0b6dSopenharmony_ci const void *buffer = nullptr; 44933eb0b6dSopenharmony_ci if (module->jsABCCode) { 45033eb0b6dSopenharmony_ci buffer = static_cast<const void *>(module->jsABCCode); 45133eb0b6dSopenharmony_ci } else { 45233eb0b6dSopenharmony_ci buffer = static_cast<const void *>(module->jsCode); 45333eb0b6dSopenharmony_ci } 45433eb0b6dSopenharmony_ci auto exportObject = arkNativeEngine->LoadArkModule(buffer, module->jsCodeLen, fileName); 45533eb0b6dSopenharmony_ci if (exportObject->IsUndefined()) { 45633eb0b6dSopenharmony_ci HILOG_ERROR("load module failed"); 45733eb0b6dSopenharmony_ci return scope.Escape(exports); 45833eb0b6dSopenharmony_ci } else { 45933eb0b6dSopenharmony_ci exports = exportObject; 46033eb0b6dSopenharmony_ci arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports); 46133eb0b6dSopenharmony_ci } 46233eb0b6dSopenharmony_ci } else if (module->registerCallback != nullptr) { 46333eb0b6dSopenharmony_ci Local<ObjectRef> exportObj = ObjectRef::New(ecmaVm); 46433eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 46533eb0b6dSopenharmony_ci StartTrace(HITRACE_TAG_ACE, "NAPI module init, name = " + std::string(module->name)); 46633eb0b6dSopenharmony_ci#endif 46733eb0b6dSopenharmony_ci arkNativeEngine->SetModuleName(exportObj, module->name); 46833eb0b6dSopenharmony_ci module->registerCallback(reinterpret_cast<napi_env>(arkNativeEngine), 46933eb0b6dSopenharmony_ci JsValueFromLocalValue(exportObj)); 47033eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 47133eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 47233eb0b6dSopenharmony_ci#endif 47333eb0b6dSopenharmony_ci panda::Local<panda::ObjectRef> exportCopy = panda::ObjectRef::New(ecmaVm); 47433eb0b6dSopenharmony_ci panda::ecmascript::ApiCheckContext context{moduleManager, ecmaVm, moduleName, exportObj, scope}; 47533eb0b6dSopenharmony_ci if (CheckArkApiAllowList(module, context, exportCopy)) { 47633eb0b6dSopenharmony_ci return scope.Escape(exportCopy); 47733eb0b6dSopenharmony_ci } 47833eb0b6dSopenharmony_ci exports = exportObj; 47933eb0b6dSopenharmony_ci arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports); 48033eb0b6dSopenharmony_ci } else { 48133eb0b6dSopenharmony_ci HILOG_ERROR("init module failed"); 48233eb0b6dSopenharmony_ci return scope.Escape(exports); 48333eb0b6dSopenharmony_ci } 48433eb0b6dSopenharmony_ci } 48533eb0b6dSopenharmony_ci if (module == nullptr) { 48633eb0b6dSopenharmony_ci HILOG_INFO("%{public}s", errInfo.c_str()); 48733eb0b6dSopenharmony_ci exports = panda::ObjectRef::CreateNativeModuleFailureInfo(ecmaVm, errInfo); 48833eb0b6dSopenharmony_ci } 48933eb0b6dSopenharmony_ci return scope.Escape(exports); 49033eb0b6dSopenharmony_ci }, 49133eb0b6dSopenharmony_ci nullptr, 49233eb0b6dSopenharmony_ci requireData); 49333eb0b6dSopenharmony_ci 49433eb0b6dSopenharmony_ci Local<FunctionRef> requireInternal = 49533eb0b6dSopenharmony_ci FunctionRef::New( 49633eb0b6dSopenharmony_ci vm, 49733eb0b6dSopenharmony_ci [](JsiRuntimeCallInfo *info) -> Local<JSValueRef> { 49833eb0b6dSopenharmony_ci EcmaVM *ecmaVm = info->GetVM(); 49933eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(ecmaVm); 50033eb0b6dSopenharmony_ci NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 50133eb0b6dSopenharmony_ci ArkNativeEngine* arkNativeEngine = static_cast<ArkNativeEngine*>(info->GetData()); 50233eb0b6dSopenharmony_ci Local<StringRef> moduleName(info->GetCallArgRef(0)); 50333eb0b6dSopenharmony_ci std::string errInfo = ""; 50433eb0b6dSopenharmony_ci Local<JSValueRef> exports(JSValueRef::Undefined(ecmaVm)); 50533eb0b6dSopenharmony_ci if (arkNativeEngine->isLimitedWorker_) { 50633eb0b6dSopenharmony_ci if (!moduleManager->CheckModuleRestricted(moduleName->ToString(ecmaVm).c_str())) { 50733eb0b6dSopenharmony_ci HILOG_ERROR("module %{public}s does not found in whitelist", 50833eb0b6dSopenharmony_ci moduleName->ToString(ecmaVm).c_str()); 50933eb0b6dSopenharmony_ci return scope.Escape(exports); 51033eb0b6dSopenharmony_ci } 51133eb0b6dSopenharmony_ci } 51233eb0b6dSopenharmony_ci NativeModule* module = moduleManager->LoadNativeModule(moduleName->ToString(ecmaVm).c_str(), 51333eb0b6dSopenharmony_ci nullptr, false, errInfo, false, ""); 51433eb0b6dSopenharmony_ci MoudleNameLocker nameLocker(moduleName->ToString(ecmaVm)); 51533eb0b6dSopenharmony_ci if (module != nullptr && arkNativeEngine) { 51633eb0b6dSopenharmony_ci auto it = arkNativeEngine->loadedModules_.find(module); 51733eb0b6dSopenharmony_ci if (it != arkNativeEngine->loadedModules_.end()) { 51833eb0b6dSopenharmony_ci return scope.Escape(it->second.ToLocal(ecmaVm)); 51933eb0b6dSopenharmony_ci } 52033eb0b6dSopenharmony_ci std::string strModuleName = moduleName->ToString(ecmaVm); 52133eb0b6dSopenharmony_ci moduleManager->SetNativeEngine(strModuleName, arkNativeEngine); 52233eb0b6dSopenharmony_ci Local<ObjectRef> exportObj = ObjectRef::New(ecmaVm); 52333eb0b6dSopenharmony_ci if (exportObj->IsObject(ecmaVm)) { 52433eb0b6dSopenharmony_ci arkNativeEngine->SetModuleName(exportObj, module->name); 52533eb0b6dSopenharmony_ci module->registerCallback(reinterpret_cast<napi_env>(arkNativeEngine), 52633eb0b6dSopenharmony_ci JsValueFromLocalValue(exportObj)); 52733eb0b6dSopenharmony_ci exports = exportObj; 52833eb0b6dSopenharmony_ci arkNativeEngine->loadedModules_[module] = Global<JSValueRef>(ecmaVm, exports); 52933eb0b6dSopenharmony_ci } else { 53033eb0b6dSopenharmony_ci HILOG_ERROR("exportObject is nullptr"); 53133eb0b6dSopenharmony_ci return scope.Escape(exports); 53233eb0b6dSopenharmony_ci } 53333eb0b6dSopenharmony_ci } 53433eb0b6dSopenharmony_ci return scope.Escape(exports); 53533eb0b6dSopenharmony_ci }, 53633eb0b6dSopenharmony_ci nullptr, 53733eb0b6dSopenharmony_ci requireData); 53833eb0b6dSopenharmony_ci 53933eb0b6dSopenharmony_ci Local<ObjectRef> global = panda::JSNApi::GetGlobalObject(vm); 54033eb0b6dSopenharmony_ci#if !defined(PREVIEW) 54133eb0b6dSopenharmony_ci Local<StringRef> requireName = StringRef::NewFromUtf8(vm, "requireNapi"); 54233eb0b6dSopenharmony_ci global->Set(vm, requireName, requireNapi); 54333eb0b6dSopenharmony_ci#else 54433eb0b6dSopenharmony_ci Local<StringRef> requireNapiPreview = StringRef::NewFromUtf8(vm, "requireNapiPreview"); 54533eb0b6dSopenharmony_ci global->Set(vm, requireNapiPreview, requireNapi); 54633eb0b6dSopenharmony_ci#endif 54733eb0b6dSopenharmony_ci global->Set(vm, requireInternalName, requireInternal); 54833eb0b6dSopenharmony_ci JSNApi::SetNativePtrGetter(vm, reinterpret_cast<void*>(ArkNativeEngine::GetNativePtrCallBack)); 54933eb0b6dSopenharmony_ci // need to call init of base class. 55033eb0b6dSopenharmony_ci NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 55133eb0b6dSopenharmony_ci std::function<bool(const std::string&)> func = [moduleManager](const std::string& moduleKey) -> bool { 55233eb0b6dSopenharmony_ci return moduleManager->UnloadNativeModule(moduleKey); 55333eb0b6dSopenharmony_ci }; 55433eb0b6dSopenharmony_ci JSNApi::SetUnloadNativeModuleCallback(vm, func); 55533eb0b6dSopenharmony_ci Init(); 55633eb0b6dSopenharmony_ci panda::JSNApi::SetLoop(vm, loop_); 55733eb0b6dSopenharmony_ci panda::JSNApi::SetWeakFinalizeTaskCallback(vm, [this] () -> void { 55833eb0b6dSopenharmony_ci this->PostFinalizeTasks(); 55933eb0b6dSopenharmony_ci }); 56033eb0b6dSopenharmony_ci JSNApi::SetAsyncCleanTaskCallback(vm, [this] (AsyncNativeCallbacksPack *callbacksPack) { 56133eb0b6dSopenharmony_ci this->PostAsyncTask(callbacksPack); 56233eb0b6dSopenharmony_ci }); 56333eb0b6dSopenharmony_ci#if defined(ENABLE_EVENT_HANDLER) 56433eb0b6dSopenharmony_ci if (JSNApi::IsJSMainThreadOfEcmaVM(vm)) { 56533eb0b6dSopenharmony_ci arkIdleMonitor_ = new ArkIdleMonitor(vm); 56633eb0b6dSopenharmony_ci JSNApi::SetTriggerGCTaskCallback(vm, [this](TriggerGCData& data) { 56733eb0b6dSopenharmony_ci this->PostTriggerGCTask(data); 56833eb0b6dSopenharmony_ci }); 56933eb0b6dSopenharmony_ci arkIdleMonitor_->SetStartTimerCallback(); 57033eb0b6dSopenharmony_ci PostLooperTriggerIdleGCTask(); 57133eb0b6dSopenharmony_ci } 57233eb0b6dSopenharmony_ci#endif 57333eb0b6dSopenharmony_ci} 57433eb0b6dSopenharmony_ci 57533eb0b6dSopenharmony_ciArkNativeEngine::~ArkNativeEngine() 57633eb0b6dSopenharmony_ci{ 57733eb0b6dSopenharmony_ci HILOG_DEBUG("ArkNativeEngine::~ArkNativeEngine"); 57833eb0b6dSopenharmony_ci Deinit(); 57933eb0b6dSopenharmony_ci // Free cached objects 58033eb0b6dSopenharmony_ci for (auto&& [module, exportObj] : loadedModules_) { 58133eb0b6dSopenharmony_ci exportObj.FreeGlobalHandleAddr(); 58233eb0b6dSopenharmony_ci } 58333eb0b6dSopenharmony_ci // Free callbackRef 58433eb0b6dSopenharmony_ci if (promiseRejectCallbackRef_ != nullptr) { 58533eb0b6dSopenharmony_ci delete promiseRejectCallbackRef_; 58633eb0b6dSopenharmony_ci } 58733eb0b6dSopenharmony_ci if (checkCallbackRef_ != nullptr) { 58833eb0b6dSopenharmony_ci delete checkCallbackRef_; 58933eb0b6dSopenharmony_ci } 59033eb0b6dSopenharmony_ci if (options_ != nullptr) { 59133eb0b6dSopenharmony_ci delete options_; 59233eb0b6dSopenharmony_ci options_ = nullptr; 59333eb0b6dSopenharmony_ci } 59433eb0b6dSopenharmony_ci 59533eb0b6dSopenharmony_ci if (arkIdleMonitor_ != nullptr) { 59633eb0b6dSopenharmony_ci delete arkIdleMonitor_; 59733eb0b6dSopenharmony_ci arkIdleMonitor_ = nullptr; 59833eb0b6dSopenharmony_ci } 59933eb0b6dSopenharmony_ci} 60033eb0b6dSopenharmony_ci 60133eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 60233eb0b6dSopenharmony_cistatic inline bool CheckHookConfig(const std::string &nameRef) 60333eb0b6dSopenharmony_ci{ 60433eb0b6dSopenharmony_ci if (g_hookJsConfig == nullptr || g_hookJsConfig->jsStackReport <= 0 || 60533eb0b6dSopenharmony_ci g_hookJsConfig->maxJsStackDepth == 0 || !g_hookJsConfig->jsFpUnwind) { 60633eb0b6dSopenharmony_ci return false; 60733eb0b6dSopenharmony_ci } else if (g_hookJsConfig->filterNapiName[0] != '\0' && 60833eb0b6dSopenharmony_ci nameRef.find(g_hookJsConfig->filterNapiName) != std::string::npos) { 60933eb0b6dSopenharmony_ci return false; 61033eb0b6dSopenharmony_ci } 61133eb0b6dSopenharmony_ci return true; 61233eb0b6dSopenharmony_ci} 61333eb0b6dSopenharmony_ci#endif 61433eb0b6dSopenharmony_ci 61533eb0b6dSopenharmony_cistatic inline uint64_t StartNapiProfilerTrace(panda::JsiRuntimeCallInfo* runtimeInfo, void* cb) 61633eb0b6dSopenharmony_ci{ 61733eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 61833eb0b6dSopenharmony_ci if (ArkNativeEngine::napiProfilerEnabled) { 61933eb0b6dSopenharmony_ci EcmaVM *vm = runtimeInfo->GetVM(); 62033eb0b6dSopenharmony_ci LocalScope scope(vm); 62133eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = runtimeInfo->GetFunctionRef(); 62233eb0b6dSopenharmony_ci Local<panda::StringRef> nameRef = fn->GetName(vm); 62333eb0b6dSopenharmony_ci char threadName[BUF_SIZE]; 62433eb0b6dSopenharmony_ci prctl(PR_GET_NAME, threadName); 62533eb0b6dSopenharmony_ci StartTraceArgs(HITRACE_TAG_ACE, "Napi called:%s, tname:%s", nameRef->ToString(vm).c_str(), threadName); 62633eb0b6dSopenharmony_ci } 62733eb0b6dSopenharmony_ci bool hookFlag = __get_hook_flag() && __get_global_hook_flag(); 62833eb0b6dSopenharmony_ci if (!hookFlag) { 62933eb0b6dSopenharmony_ci return 0; 63033eb0b6dSopenharmony_ci } 63133eb0b6dSopenharmony_ci EcmaVM* vm = runtimeInfo->GetVM(); 63233eb0b6dSopenharmony_ci LocalScope scope(vm); 63333eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = runtimeInfo->GetFunctionRef(); 63433eb0b6dSopenharmony_ci Local<panda::StringRef> nameRef = fn->GetName(vm); 63533eb0b6dSopenharmony_ci if (g_hookJsConfig == nullptr) { 63633eb0b6dSopenharmony_ci std::call_once(g_hookOnceFlag, []() { g_hookJsConfig = (HookJsConfig*)__get_hook_config(); }); 63733eb0b6dSopenharmony_ci } 63833eb0b6dSopenharmony_ci // add memtrace function 63933eb0b6dSopenharmony_ci if (g_hookJsConfig != nullptr && g_hookJsConfig->jsStackReport == NAPI_CALL_STACK && !g_hookJsConfig->jsFpUnwind) { 64033eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::ClearId(); 64133eb0b6dSopenharmony_ci std::unique_ptr<OHOS::HiviewDFX::HiTraceId> arkCallBackTraceId = std::make_unique<OHOS::HiviewDFX::HiTraceId>( 64233eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::Begin("New ArkCallBackTrace", 0)); 64333eb0b6dSopenharmony_ci char buffer[256] = {0}; // 256 : buffer size of tag name 64433eb0b6dSopenharmony_ci if (sprintf_s(buffer, sizeof(buffer), "napi:0x%x:%s", arkCallBackTraceId->GetChainId(), 64533eb0b6dSopenharmony_ci nameRef->ToString(vm).c_str()) == -1) { 64633eb0b6dSopenharmony_ci return 0; 64733eb0b6dSopenharmony_ci } 64833eb0b6dSopenharmony_ci uint64_t addr = reinterpret_cast<uint64_t>(cb); 64933eb0b6dSopenharmony_ci ++g_chainId; 65033eb0b6dSopenharmony_ci (void)memtrace(reinterpret_cast<void*>(addr + g_chainId), 8, buffer, true); // 8: the size of addr 65133eb0b6dSopenharmony_ci return 0; 65233eb0b6dSopenharmony_ci } 65333eb0b6dSopenharmony_ci if (!CheckHookConfig(nameRef->ToString(vm))) { 65433eb0b6dSopenharmony_ci return 0; 65533eb0b6dSopenharmony_ci } 65633eb0b6dSopenharmony_ci BlockHookScope blockHook; // block hook 65733eb0b6dSopenharmony_ci std::string rawStack; 65833eb0b6dSopenharmony_ci std::vector<JsFrameInfo> jsFrames; 65933eb0b6dSopenharmony_ci uint64_t nestChainId = 0; 66033eb0b6dSopenharmony_ci jsFrames.reserve(g_hookJsConfig->maxJsStackDepth); 66133eb0b6dSopenharmony_ci auto env = reinterpret_cast<napi_env>(JSNApi::GetEnv(vm)); 66233eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 66333eb0b6dSopenharmony_ci engine->BuildJsStackInfoListWithCustomDepth(jsFrames); 66433eb0b6dSopenharmony_ci std::stringstream ssRawStack; 66533eb0b6dSopenharmony_ci for (size_t i = 0; i < jsFrames.size() && i < g_hookJsConfig->maxJsStackDepth; i++) { 66633eb0b6dSopenharmony_ci ssRawStack << jsFrames[i].functionName << JS_SYMBOL_FILEPATH_SEP << jsFrames[i].fileName << ":" << 66733eb0b6dSopenharmony_ci jsFrames[i].pos; 66833eb0b6dSopenharmony_ci if (i < jsFrames.size() - 1) { 66933eb0b6dSopenharmony_ci ssRawStack << JS_CALL_STACK_DEPTH_SEP; 67033eb0b6dSopenharmony_ci } 67133eb0b6dSopenharmony_ci } 67233eb0b6dSopenharmony_ci rawStack = ssRawStack.str(); 67333eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::Begin("ArkNativeFunctionCallBack", 0); 67433eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceId hitraceId = OHOS::HiviewDFX::HiTraceChain::GetId(); 67533eb0b6dSopenharmony_ci // resolve nested calls to napi and ts 67633eb0b6dSopenharmony_ci if (hitraceId.IsValid()) { 67733eb0b6dSopenharmony_ci nestChainId = hitraceId.GetChainId(); 67833eb0b6dSopenharmony_ci } 67933eb0b6dSopenharmony_ci uint64_t chainId = ++g_chainId; 68033eb0b6dSopenharmony_ci hitraceId.SetChainId(chainId); 68133eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::SetId(hitraceId); 68233eb0b6dSopenharmony_ci __send_hook_misc_data(chainId, rawStack.c_str(), rawStack.size() + 1, 1); 68333eb0b6dSopenharmony_ci return nestChainId; 68433eb0b6dSopenharmony_ci 68533eb0b6dSopenharmony_ci#endif 68633eb0b6dSopenharmony_ci return 0; 68733eb0b6dSopenharmony_ci} 68833eb0b6dSopenharmony_ci 68933eb0b6dSopenharmony_cistatic inline void FinishNapiProfilerTrace(uint64_t value) 69033eb0b6dSopenharmony_ci{ 69133eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 69233eb0b6dSopenharmony_ci if (ArkNativeEngine::napiProfilerEnabled) { 69333eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 69433eb0b6dSopenharmony_ci } 69533eb0b6dSopenharmony_ci bool hookFlag = __get_hook_flag() && __get_global_hook_flag(); 69633eb0b6dSopenharmony_ci if (!hookFlag) { 69733eb0b6dSopenharmony_ci return; 69833eb0b6dSopenharmony_ci } 69933eb0b6dSopenharmony_ci BlockHookScope blockHook; // block hook 70033eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceId hitraceId = OHOS::HiviewDFX::HiTraceChain::GetId(); 70133eb0b6dSopenharmony_ci if (hitraceId.IsValid()) { 70233eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::End(hitraceId); 70333eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::ClearId(); 70433eb0b6dSopenharmony_ci } 70533eb0b6dSopenharmony_ci // resolve nested calls to napi and ts 70633eb0b6dSopenharmony_ci if (value) { 70733eb0b6dSopenharmony_ci hitraceId.SetChainId(value); 70833eb0b6dSopenharmony_ci OHOS::HiviewDFX::HiTraceChain::SetId(hitraceId); 70933eb0b6dSopenharmony_ci } 71033eb0b6dSopenharmony_ci 71133eb0b6dSopenharmony_ci#endif 71233eb0b6dSopenharmony_ci} 71333eb0b6dSopenharmony_ci 71433eb0b6dSopenharmony_citemplate <bool changeState> 71533eb0b6dSopenharmony_cipanda::JSValueRef ArkNativeFunctionCallBack(JsiRuntimeCallInfo *runtimeInfo) 71633eb0b6dSopenharmony_ci{ 71733eb0b6dSopenharmony_ci EcmaVM *vm = runtimeInfo->GetVM(); 71833eb0b6dSopenharmony_ci panda::LocalScope scope(vm); 71933eb0b6dSopenharmony_ci bool getStackBeforeCallNapiSuccess = false; 72033eb0b6dSopenharmony_ci JSNApi::GetStackBeforeCallNapiSuccess(vm, getStackBeforeCallNapiSuccess); 72133eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(runtimeInfo->GetData()); 72233eb0b6dSopenharmony_ci auto env = reinterpret_cast<napi_env>(JSNApi::GetEnv(vm)); 72333eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 72433eb0b6dSopenharmony_ci auto cb = info->callback; 72533eb0b6dSopenharmony_ci if (engine == nullptr) { 72633eb0b6dSopenharmony_ci HILOG_ERROR("native engine is null"); 72733eb0b6dSopenharmony_ci return **JSValueRef::Undefined(vm); 72833eb0b6dSopenharmony_ci } 72933eb0b6dSopenharmony_ci 73033eb0b6dSopenharmony_ci uint64_t nestChainId = StartNapiProfilerTrace(runtimeInfo, reinterpret_cast<void *>(cb)); 73133eb0b6dSopenharmony_ci 73233eb0b6dSopenharmony_ci if (JSNApi::IsMixedDebugEnabled(vm)) { 73333eb0b6dSopenharmony_ci JSNApi::NotifyNativeCalling(vm, reinterpret_cast<void *>(cb)); 73433eb0b6dSopenharmony_ci } 73533eb0b6dSopenharmony_ci 73633eb0b6dSopenharmony_ci napi_value result = nullptr; 73733eb0b6dSopenharmony_ci if (cb != nullptr) { 73833eb0b6dSopenharmony_ci if constexpr (changeState) { 73933eb0b6dSopenharmony_ci panda::JsiNativeScope nativeScope(vm); 74033eb0b6dSopenharmony_ci result = cb(env, runtimeInfo); 74133eb0b6dSopenharmony_ci } else { 74233eb0b6dSopenharmony_ci result = cb(env, runtimeInfo); 74333eb0b6dSopenharmony_ci } 74433eb0b6dSopenharmony_ci } 74533eb0b6dSopenharmony_ci 74633eb0b6dSopenharmony_ci if (JSNApi::IsMixedDebugEnabled(vm)) { 74733eb0b6dSopenharmony_ci JSNApi::NotifyNativeReturn(vm, reinterpret_cast<void *>(cb)); 74833eb0b6dSopenharmony_ci } 74933eb0b6dSopenharmony_ci 75033eb0b6dSopenharmony_ci Local<panda::JSValueRef> localRet = panda::JSValueRef::Undefined(vm); 75133eb0b6dSopenharmony_ci if (result != nullptr) { 75233eb0b6dSopenharmony_ci localRet = LocalValueFromJsValue(result); 75333eb0b6dSopenharmony_ci } 75433eb0b6dSopenharmony_ci 75533eb0b6dSopenharmony_ci FinishNapiProfilerTrace(nestChainId); 75633eb0b6dSopenharmony_ci // Fixme: Rethrow error to engine while clear lastException_ 75733eb0b6dSopenharmony_ci if (!engine->lastException_.IsEmpty()) { 75833eb0b6dSopenharmony_ci engine->lastException_.Empty(); 75933eb0b6dSopenharmony_ci } 76033eb0b6dSopenharmony_ci 76133eb0b6dSopenharmony_ci if (localRet.IsEmpty()) { 76233eb0b6dSopenharmony_ci return **JSValueRef::Undefined(vm); 76333eb0b6dSopenharmony_ci } 76433eb0b6dSopenharmony_ci if (getStackBeforeCallNapiSuccess) { 76533eb0b6dSopenharmony_ci JSNApi::GetStackAfterCallNapi(vm); 76633eb0b6dSopenharmony_ci } 76733eb0b6dSopenharmony_ci return **localRet; 76833eb0b6dSopenharmony_ci} 76933eb0b6dSopenharmony_ci 77033eb0b6dSopenharmony_cistatic Local<panda::JSValueRef> NapiNativeCreateFunction(napi_env env, const char* name, 77133eb0b6dSopenharmony_ci NapiNativeCallback cb, void* value) 77233eb0b6dSopenharmony_ci{ 77333eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 77433eb0b6dSopenharmony_ci auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm()); 77533eb0b6dSopenharmony_ci NapiFunctionInfo* funcInfo = NapiFunctionInfo::CreateNewInstance(); 77633eb0b6dSopenharmony_ci if (funcInfo == nullptr) { 77733eb0b6dSopenharmony_ci HILOG_ERROR("funcInfo is nullptr"); 77833eb0b6dSopenharmony_ci return JSValueRef::Undefined(vm); 77933eb0b6dSopenharmony_ci } 78033eb0b6dSopenharmony_ci funcInfo->callback = cb; 78133eb0b6dSopenharmony_ci funcInfo->data = value; 78233eb0b6dSopenharmony_ci#ifdef ENABLE_CONTAINER_SCOPE 78333eb0b6dSopenharmony_ci funcInfo->scopeId = OHOS::Ace::ContainerScope::CurrentId(); 78433eb0b6dSopenharmony_ci#endif 78533eb0b6dSopenharmony_ci 78633eb0b6dSopenharmony_ci Local<panda::FunctionRef> fn = panda::FunctionRef::NewConcurrent( 78733eb0b6dSopenharmony_ci vm, ArkNativeFunctionCallBack, 78833eb0b6dSopenharmony_ci [](void* env, void* externalPointer, void* data) { 78933eb0b6dSopenharmony_ci auto info = reinterpret_cast<NapiFunctionInfo*>(data); 79033eb0b6dSopenharmony_ci if (info != nullptr) { 79133eb0b6dSopenharmony_ci delete info; 79233eb0b6dSopenharmony_ci } 79333eb0b6dSopenharmony_ci }, 79433eb0b6dSopenharmony_ci reinterpret_cast<void*>(funcInfo), true 79533eb0b6dSopenharmony_ci ); 79633eb0b6dSopenharmony_ci Local<panda::StringRef> fnName = panda::StringRef::NewFromUtf8(vm, name); 79733eb0b6dSopenharmony_ci fn->SetName(vm, fnName); 79833eb0b6dSopenharmony_ci return fn; 79933eb0b6dSopenharmony_ci} 80033eb0b6dSopenharmony_ci 80133eb0b6dSopenharmony_cistatic Local<JSValueRef> GetProperty(EcmaVM* vm, Local<panda::ObjectRef> &obj, const char* name) 80233eb0b6dSopenharmony_ci{ 80333eb0b6dSopenharmony_ci Local<StringRef> key = StringRef::NewFromUtf8(vm, name); 80433eb0b6dSopenharmony_ci Local<JSValueRef> val = obj->Get(vm, key); 80533eb0b6dSopenharmony_ci return val; 80633eb0b6dSopenharmony_ci} 80733eb0b6dSopenharmony_ci 80833eb0b6dSopenharmony_civoid GetCString(EcmaVM* vm, Local<StringRef> str, char* buffer, size_t size, size_t* length) 80933eb0b6dSopenharmony_ci{ 81033eb0b6dSopenharmony_ci if (length == nullptr) { 81133eb0b6dSopenharmony_ci return; 81233eb0b6dSopenharmony_ci } 81333eb0b6dSopenharmony_ci if (buffer == nullptr) { 81433eb0b6dSopenharmony_ci *length = str->Utf8Length(vm, true) - 1; 81533eb0b6dSopenharmony_ci } else if (size != 0) { 81633eb0b6dSopenharmony_ci uint32_t copied = str->WriteUtf8(vm, buffer, size - 1, true) - 1; 81733eb0b6dSopenharmony_ci buffer[copied] = '\0'; 81833eb0b6dSopenharmony_ci *length = copied; 81933eb0b6dSopenharmony_ci } else { 82033eb0b6dSopenharmony_ci *length = 0; 82133eb0b6dSopenharmony_ci } 82233eb0b6dSopenharmony_ci} 82333eb0b6dSopenharmony_ci 82433eb0b6dSopenharmony_cistd::string NapiGetModuleName(napi_env env, Local<panda::ObjectRef> &obj) 82533eb0b6dSopenharmony_ci{ 82633eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 82733eb0b6dSopenharmony_ci auto vm = const_cast<EcmaVM*>(engine->GetEcmaVm()); 82833eb0b6dSopenharmony_ci std::string moduleName(""); 82933eb0b6dSopenharmony_ci auto nativeModuleName = GetProperty(vm, obj, PANDA_MODULE_NAME); 83033eb0b6dSopenharmony_ci if (nativeModuleName->IsString(vm)) { 83133eb0b6dSopenharmony_ci char arrayName[PANDA_MODULE_NAME_LEN] = {0}; 83233eb0b6dSopenharmony_ci size_t len = 0; 83333eb0b6dSopenharmony_ci GetCString(vm, nativeModuleName, arrayName, PANDA_MODULE_NAME_LEN, &len); 83433eb0b6dSopenharmony_ci moduleName += arrayName; 83533eb0b6dSopenharmony_ci moduleName += "."; 83633eb0b6dSopenharmony_ci } 83733eb0b6dSopenharmony_ci return moduleName; 83833eb0b6dSopenharmony_ci} 83933eb0b6dSopenharmony_ci 84033eb0b6dSopenharmony_civoid NapiDefinePropertyInner(napi_env env, 84133eb0b6dSopenharmony_ci Local<panda::ObjectRef> &obj, 84233eb0b6dSopenharmony_ci NapiPropertyDescriptor &propertyDescriptor, 84333eb0b6dSopenharmony_ci Local<panda::JSValueRef> &propertyName, 84433eb0b6dSopenharmony_ci bool &result) 84533eb0b6dSopenharmony_ci{ 84633eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 84733eb0b6dSopenharmony_ci auto vm = engine->GetEcmaVm(); 84833eb0b6dSopenharmony_ci bool writable = (propertyDescriptor.attributes & NATIVE_WRITABLE) != 0; 84933eb0b6dSopenharmony_ci bool enumable = (propertyDescriptor.attributes & NATIVE_ENUMERABLE) != 0; 85033eb0b6dSopenharmony_ci bool configable = (propertyDescriptor.attributes & NATIVE_CONFIGURABLE) != 0; 85133eb0b6dSopenharmony_ci std::string fullName(""); 85233eb0b6dSopenharmony_ci if (propertyDescriptor.getter != nullptr || propertyDescriptor.setter != nullptr) { 85333eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 85433eb0b6dSopenharmony_ci fullName += NapiGetModuleName(env, obj); 85533eb0b6dSopenharmony_ci#endif 85633eb0b6dSopenharmony_ci Local<panda::JSValueRef> localGetter = panda::JSValueRef::Undefined(vm); 85733eb0b6dSopenharmony_ci Local<panda::JSValueRef> localSetter = panda::JSValueRef::Undefined(vm); 85833eb0b6dSopenharmony_ci 85933eb0b6dSopenharmony_ci if (propertyDescriptor.getter != nullptr) { 86033eb0b6dSopenharmony_ci fullName += "getter"; 86133eb0b6dSopenharmony_ci localGetter = NapiNativeCreateFunction(env, fullName.c_str(), 86233eb0b6dSopenharmony_ci propertyDescriptor.getter, propertyDescriptor.data); 86333eb0b6dSopenharmony_ci } 86433eb0b6dSopenharmony_ci if (propertyDescriptor.setter != nullptr) { 86533eb0b6dSopenharmony_ci fullName += "setter"; 86633eb0b6dSopenharmony_ci localSetter = NapiNativeCreateFunction(env, fullName.c_str(), 86733eb0b6dSopenharmony_ci propertyDescriptor.setter, propertyDescriptor.data); 86833eb0b6dSopenharmony_ci } 86933eb0b6dSopenharmony_ci 87033eb0b6dSopenharmony_ci PropertyAttribute attr(panda::JSValueRef::Undefined(vm), false, enumable, configable); 87133eb0b6dSopenharmony_ci result = obj->SetAccessorProperty(vm, propertyName, localGetter, localSetter, attr); 87233eb0b6dSopenharmony_ci } else if (propertyDescriptor.method != nullptr) { 87333eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 87433eb0b6dSopenharmony_ci fullName += NapiGetModuleName(env, obj); 87533eb0b6dSopenharmony_ci#endif 87633eb0b6dSopenharmony_ci if (propertyDescriptor.utf8name != nullptr) { 87733eb0b6dSopenharmony_ci fullName += propertyDescriptor.utf8name; 87833eb0b6dSopenharmony_ci } else { 87933eb0b6dSopenharmony_ci fullName += propertyName->IsString(vm) 88033eb0b6dSopenharmony_ci ? Local<panda::StringRef>(propertyName)->ToString(vm) 88133eb0b6dSopenharmony_ci : Local<panda::SymbolRef>(propertyName)->GetDescription(vm)->ToString(vm); 88233eb0b6dSopenharmony_ci } 88333eb0b6dSopenharmony_ci Local<panda::JSValueRef> cbObj = NapiNativeCreateFunction(env, fullName.c_str(), 88433eb0b6dSopenharmony_ci propertyDescriptor.method, propertyDescriptor.data); 88533eb0b6dSopenharmony_ci PropertyAttribute attr(cbObj, writable, enumable, configable); 88633eb0b6dSopenharmony_ci result = obj->DefineProperty(vm, propertyName, attr); 88733eb0b6dSopenharmony_ci } else { 88833eb0b6dSopenharmony_ci Local<panda::JSValueRef> val = LocalValueFromJsValue(propertyDescriptor.value); 88933eb0b6dSopenharmony_ci 89033eb0b6dSopenharmony_ci PropertyAttribute attr(val, writable, enumable, configable); 89133eb0b6dSopenharmony_ci result = obj->DefineProperty(vm, propertyName, attr); 89233eb0b6dSopenharmony_ci } 89333eb0b6dSopenharmony_ci} 89433eb0b6dSopenharmony_ci 89533eb0b6dSopenharmony_cibool NapiDefineProperty(napi_env env, Local<panda::ObjectRef> &obj, NapiPropertyDescriptor propertyDescriptor) 89633eb0b6dSopenharmony_ci{ 89733eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 89833eb0b6dSopenharmony_ci auto vm = engine->GetEcmaVm(); 89933eb0b6dSopenharmony_ci bool result = false; 90033eb0b6dSopenharmony_ci Local<panda::JSValueRef> propertyName; 90133eb0b6dSopenharmony_ci if (propertyDescriptor.utf8name != nullptr) { 90233eb0b6dSopenharmony_ci propertyName = panda::StringRef::NewFromUtf8(vm, propertyDescriptor.utf8name); 90333eb0b6dSopenharmony_ci } else { 90433eb0b6dSopenharmony_ci propertyName = LocalValueFromJsValue(propertyDescriptor.name); 90533eb0b6dSopenharmony_ci } 90633eb0b6dSopenharmony_ci if (obj->IsJSShared(vm)) { 90733eb0b6dSopenharmony_ci NativeSendable::NapiDefineSendabledProperty(env, obj, propertyDescriptor, propertyName, result); 90833eb0b6dSopenharmony_ci } else { 90933eb0b6dSopenharmony_ci NapiDefinePropertyInner(env, obj, propertyDescriptor, propertyName, result); 91033eb0b6dSopenharmony_ci } 91133eb0b6dSopenharmony_ci Local<panda::ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm); 91233eb0b6dSopenharmony_ci if (!excep.IsNull()) { 91333eb0b6dSopenharmony_ci HILOG_DEBUG("ArkNativeObject::DefineProperty occur Exception"); 91433eb0b6dSopenharmony_ci panda::JSNApi::GetAndClearUncaughtException(vm); 91533eb0b6dSopenharmony_ci } 91633eb0b6dSopenharmony_ci return result; 91733eb0b6dSopenharmony_ci} 91833eb0b6dSopenharmony_ci 91933eb0b6dSopenharmony_cipanda::Local<panda::ObjectRef> NapiCreateObjectWithProperties(napi_env env, size_t propertyCount, 92033eb0b6dSopenharmony_ci const napi_property_descriptor *properties, 92133eb0b6dSopenharmony_ci Local<panda::JSValueRef> *keys, 92233eb0b6dSopenharmony_ci PropertyAttribute *attrs) 92333eb0b6dSopenharmony_ci{ 92433eb0b6dSopenharmony_ci auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm(); 92533eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm); 92633eb0b6dSopenharmony_ci for (size_t i = 0; i < propertyCount; ++i) { 92733eb0b6dSopenharmony_ci const napi_property_descriptor &property = properties[i]; 92833eb0b6dSopenharmony_ci 92933eb0b6dSopenharmony_ci const char* utf8name = property.utf8name; 93033eb0b6dSopenharmony_ci uint32_t attributes = property.attributes; 93133eb0b6dSopenharmony_ci bool writable = (attributes & NATIVE_WRITABLE) != 0; 93233eb0b6dSopenharmony_ci bool enumable = (attributes & NATIVE_ENUMERABLE) != 0; 93333eb0b6dSopenharmony_ci bool configable = (attributes & NATIVE_CONFIGURABLE) != 0; 93433eb0b6dSopenharmony_ci NapiNativeCallback method = reinterpret_cast<NapiNativeCallback>(property.method); 93533eb0b6dSopenharmony_ci NapiNativeCallback getter = reinterpret_cast<NapiNativeCallback>(property.getter); 93633eb0b6dSopenharmony_ci NapiNativeCallback setter = reinterpret_cast<NapiNativeCallback>(property.setter); 93733eb0b6dSopenharmony_ci napi_value value = property.value; 93833eb0b6dSopenharmony_ci void *data = property.data; 93933eb0b6dSopenharmony_ci 94033eb0b6dSopenharmony_ci Local<panda::JSValueRef> val = panda::JSValueRef::Undefined(vm); 94133eb0b6dSopenharmony_ci 94233eb0b6dSopenharmony_ci std::string fullName(""); 94333eb0b6dSopenharmony_ci if (getter != nullptr || setter != nullptr) { 94433eb0b6dSopenharmony_ci Local<panda::JSValueRef> localGetter = panda::JSValueRef::Undefined(vm); 94533eb0b6dSopenharmony_ci Local<panda::JSValueRef> localSetter = panda::JSValueRef::Undefined(vm); 94633eb0b6dSopenharmony_ci 94733eb0b6dSopenharmony_ci if (getter != nullptr) { 94833eb0b6dSopenharmony_ci fullName += "getter"; 94933eb0b6dSopenharmony_ci localGetter = NapiNativeCreateFunction(env, fullName.c_str(), getter, data); 95033eb0b6dSopenharmony_ci } 95133eb0b6dSopenharmony_ci if (setter != nullptr) { 95233eb0b6dSopenharmony_ci fullName += "setter"; 95333eb0b6dSopenharmony_ci localSetter = NapiNativeCreateFunction(env, fullName.c_str(), setter, data); 95433eb0b6dSopenharmony_ci } 95533eb0b6dSopenharmony_ci 95633eb0b6dSopenharmony_ci val = panda::ObjectRef::CreateAccessorData(vm, localGetter, localSetter); 95733eb0b6dSopenharmony_ci writable = false; 95833eb0b6dSopenharmony_ci } else if (method != nullptr) { 95933eb0b6dSopenharmony_ci fullName += utf8name; 96033eb0b6dSopenharmony_ci val = NapiNativeCreateFunction(env, fullName.c_str(), method, data); 96133eb0b6dSopenharmony_ci } else { 96233eb0b6dSopenharmony_ci val = LocalValueFromJsValue(value); 96333eb0b6dSopenharmony_ci } 96433eb0b6dSopenharmony_ci new (reinterpret_cast<void *>(&attrs[i])) PropertyAttribute(val, writable, enumable, configable); 96533eb0b6dSopenharmony_ci keys[i] = panda::StringRef::NewFromUtf8(vm, utf8name); 96633eb0b6dSopenharmony_ci } 96733eb0b6dSopenharmony_ci Local<panda::ObjectRef> object = panda::ObjectRef::NewWithProperties(vm, propertyCount, keys, attrs); 96833eb0b6dSopenharmony_ci return scope.Escape(object); 96933eb0b6dSopenharmony_ci} 97033eb0b6dSopenharmony_ci 97133eb0b6dSopenharmony_cipanda::Local<panda::ObjectRef> NapiCreateSObjectWithProperties(napi_env env, 97233eb0b6dSopenharmony_ci size_t propertyCount, 97333eb0b6dSopenharmony_ci const NapiPropertyDescriptor* properties) 97433eb0b6dSopenharmony_ci{ 97533eb0b6dSopenharmony_ci auto vm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm(); 97633eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm); 97733eb0b6dSopenharmony_ci FunctionRef::SendablePropertiesInfo info; 97833eb0b6dSopenharmony_ci for (size_t i = 0; i < propertyCount; ++i) { 97933eb0b6dSopenharmony_ci NativeSendable::InitSendablePropertiesInfo(env, info, properties[i]); 98033eb0b6dSopenharmony_ci } 98133eb0b6dSopenharmony_ci Local<panda::ObjectRef> object = panda::ObjectRef::NewSWithProperties(vm, info); 98233eb0b6dSopenharmony_ci return scope.Escape(object); 98333eb0b6dSopenharmony_ci} 98433eb0b6dSopenharmony_ci 98533eb0b6dSopenharmony_cipanda::Local<panda::ObjectRef> ArkNativeEngine::GetModuleFromName( 98633eb0b6dSopenharmony_ci const std::string& moduleName, bool isAppModule, const std::string& id, const std::string& param, 98733eb0b6dSopenharmony_ci const std::string& instanceName, void** instance) 98833eb0b6dSopenharmony_ci{ 98933eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 99033eb0b6dSopenharmony_ci Local<ObjectRef> exports(JSValueRef::Undefined(vm_)); 99133eb0b6dSopenharmony_ci NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 99233eb0b6dSopenharmony_ci std::string errInfo = ""; 99333eb0b6dSopenharmony_ci NativeModule* module = moduleManager->LoadNativeModule(moduleName.c_str(), nullptr, isAppModule, errInfo); 99433eb0b6dSopenharmony_ci if (module != nullptr) { 99533eb0b6dSopenharmony_ci Local<StringRef> idStr = StringRef::NewFromUtf8(vm_, id.c_str(), id.size()); 99633eb0b6dSopenharmony_ci napi_value idValue = JsValueFromLocalValue(idStr); 99733eb0b6dSopenharmony_ci Local<StringRef> paramStr = StringRef::NewFromUtf8(vm_, param.c_str(), param.size()); 99833eb0b6dSopenharmony_ci napi_value paramValue = JsValueFromLocalValue(paramStr); 99933eb0b6dSopenharmony_ci Local<ObjectRef> exportObj = ObjectRef::New(vm_); 100033eb0b6dSopenharmony_ci NapiPropertyDescriptor idProperty, paramProperty; 100133eb0b6dSopenharmony_ci idProperty.utf8name = "id"; 100233eb0b6dSopenharmony_ci idProperty.value = idValue; 100333eb0b6dSopenharmony_ci paramProperty.utf8name = "param"; 100433eb0b6dSopenharmony_ci paramProperty.value = paramValue; 100533eb0b6dSopenharmony_ci SetModuleName(exportObj, module->name); 100633eb0b6dSopenharmony_ci NapiDefineProperty(reinterpret_cast<napi_env>(this), exportObj, idProperty); 100733eb0b6dSopenharmony_ci NapiDefineProperty(reinterpret_cast<napi_env>(this), exportObj, paramProperty); 100833eb0b6dSopenharmony_ci MoudleNameLocker nameLocker(module->name); 100933eb0b6dSopenharmony_ci module->registerCallback(reinterpret_cast<napi_env>(this), JsValueFromLocalValue(exportObj)); 101033eb0b6dSopenharmony_ci napi_value nExport = JsValueFromLocalValue(exportObj); 101133eb0b6dSopenharmony_ci napi_value exportInstance = nullptr; 101233eb0b6dSopenharmony_ci napi_status status = napi_get_named_property( 101333eb0b6dSopenharmony_ci reinterpret_cast<napi_env>(this), nExport, instanceName.c_str(), &exportInstance); 101433eb0b6dSopenharmony_ci if (status != napi_ok) { 101533eb0b6dSopenharmony_ci HILOG_ERROR("GetModuleFromName napi_get_named_property status != napi_ok"); 101633eb0b6dSopenharmony_ci } 101733eb0b6dSopenharmony_ci 101833eb0b6dSopenharmony_ci status = napi_unwrap(reinterpret_cast<napi_env>(this), exportInstance, reinterpret_cast<void**>(instance)); 101933eb0b6dSopenharmony_ci if (status != napi_ok) { 102033eb0b6dSopenharmony_ci HILOG_ERROR("GetModuleFromName napi_unwrap status != napi_ok"); 102133eb0b6dSopenharmony_ci } 102233eb0b6dSopenharmony_ci exports = exportObj; 102333eb0b6dSopenharmony_ci } 102433eb0b6dSopenharmony_ci return scope.Escape(exports); 102533eb0b6dSopenharmony_ci} 102633eb0b6dSopenharmony_ci 102733eb0b6dSopenharmony_cinapi_value ArkNativeEngine::CreatePromise(NativeDeferred** deferred) 102833eb0b6dSopenharmony_ci{ 102933eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 103033eb0b6dSopenharmony_ci Local<PromiseCapabilityRef> capability = PromiseCapabilityRef::New(vm_); 103133eb0b6dSopenharmony_ci if (capability->IsUndefined()) { 103233eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(JSValueRef::Undefined(vm_))); 103333eb0b6dSopenharmony_ci } 103433eb0b6dSopenharmony_ci *deferred = new ArkNativeDeferred(this, capability); 103533eb0b6dSopenharmony_ci Local<JSValueRef> promiseValue = capability->GetPromise(vm_); 103633eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(promiseValue)); 103733eb0b6dSopenharmony_ci} 103833eb0b6dSopenharmony_ci 103933eb0b6dSopenharmony_cipanda::Local<panda::ObjectRef> ArkNativeEngine::LoadModuleByName(const std::string& moduleName, bool isAppModule, 104033eb0b6dSopenharmony_ci const std::string& param, const std::string& instanceName, void* instance, const std::string& path) 104133eb0b6dSopenharmony_ci{ 104233eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 104333eb0b6dSopenharmony_ci Local<ObjectRef> exports(JSValueRef::Undefined(vm_)); 104433eb0b6dSopenharmony_ci NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 104533eb0b6dSopenharmony_ci std::string errInfo = ""; 104633eb0b6dSopenharmony_ci NativeModule* module = moduleManager->LoadNativeModule(moduleName.c_str(), 104733eb0b6dSopenharmony_ci path.empty() ? nullptr : path.c_str(), isAppModule, errInfo); 104833eb0b6dSopenharmony_ci if (module != nullptr) { 104933eb0b6dSopenharmony_ci Local<ObjectRef> exportObj = ObjectRef::New(vm_); 105033eb0b6dSopenharmony_ci NapiPropertyDescriptor paramProperty, instanceProperty; 105133eb0b6dSopenharmony_ci Local<StringRef> paramStr = StringRef::NewFromUtf8(vm_, param.c_str(), param.size()); 105233eb0b6dSopenharmony_ci napi_value paramValue = JsValueFromLocalValue(paramStr); 105333eb0b6dSopenharmony_ci paramProperty.utf8name = "param"; 105433eb0b6dSopenharmony_ci paramProperty.value = paramValue; 105533eb0b6dSopenharmony_ci Local<ObjectRef> instanceValue = ObjectRef::New(vm_); 105633eb0b6dSopenharmony_ci Local<StringRef> key = StringRef::GetNapiWrapperString(vm_); 105733eb0b6dSopenharmony_ci if (instance == nullptr && instanceValue->Has(vm_, key)) { 105833eb0b6dSopenharmony_ci Local<ObjectRef> wrapper = instanceValue->Get(vm_, key); 105933eb0b6dSopenharmony_ci auto ref = reinterpret_cast<NativeReference*>(wrapper->GetNativePointerField(vm_, 0)); 106033eb0b6dSopenharmony_ci wrapper->SetNativePointerField(vm_, 0, nullptr, nullptr, nullptr, 0); 106133eb0b6dSopenharmony_ci instanceValue->Delete(vm_, key); 106233eb0b6dSopenharmony_ci delete ref; 106333eb0b6dSopenharmony_ci } else { 106433eb0b6dSopenharmony_ci Local<ObjectRef> object = ObjectRef::New(vm_); 106533eb0b6dSopenharmony_ci NativeReference* ref = nullptr; 106633eb0b6dSopenharmony_ci Local<JSValueRef> value(instanceValue); 106733eb0b6dSopenharmony_ci ref = new ArkNativeReference(this, value, 0, true, nullptr, instance, nullptr); 106833eb0b6dSopenharmony_ci 106933eb0b6dSopenharmony_ci object->SetNativePointerFieldCount(vm_, 1); 107033eb0b6dSopenharmony_ci object->SetNativePointerField(vm_, 0, ref, nullptr, nullptr, 0); 107133eb0b6dSopenharmony_ci PropertyAttribute attr(object, true, false, true); 107233eb0b6dSopenharmony_ci instanceValue->DefineProperty(vm_, key, attr); 107333eb0b6dSopenharmony_ci } 107433eb0b6dSopenharmony_ci instanceProperty.utf8name = instanceName.c_str(); 107533eb0b6dSopenharmony_ci instanceProperty.value = JsValueFromLocalValue(instanceValue); 107633eb0b6dSopenharmony_ci SetModuleName(exportObj, module->name); 107733eb0b6dSopenharmony_ci NapiDefineProperty(reinterpret_cast<napi_env>(this), exportObj, paramProperty); 107833eb0b6dSopenharmony_ci NapiDefineProperty(reinterpret_cast<napi_env>(this), exportObj, instanceProperty); 107933eb0b6dSopenharmony_ci 108033eb0b6dSopenharmony_ci MoudleNameLocker nameLocker(module->name); 108133eb0b6dSopenharmony_ci module->registerCallback(reinterpret_cast<napi_env>(this), JsValueFromLocalValue(exportObj)); 108233eb0b6dSopenharmony_ci exports = exportObj; 108333eb0b6dSopenharmony_ci } 108433eb0b6dSopenharmony_ci return scope.Escape(exports); 108533eb0b6dSopenharmony_ci} 108633eb0b6dSopenharmony_ci 108733eb0b6dSopenharmony_civoid ArkNativeEngine::Loop(LoopMode mode, bool needSync) 108833eb0b6dSopenharmony_ci{ 108933eb0b6dSopenharmony_ci LocalScope scope(vm_); 109033eb0b6dSopenharmony_ci NativeEngine::Loop(mode, needSync); 109133eb0b6dSopenharmony_ci panda::JSNApi::ExecutePendingJob(vm_); 109233eb0b6dSopenharmony_ci} 109333eb0b6dSopenharmony_ci 109433eb0b6dSopenharmony_civoid ArkNativeEngine::SetModuleName(Local<ObjectRef> &nativeObj, std::string moduleName) 109533eb0b6dSopenharmony_ci{ 109633eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 109733eb0b6dSopenharmony_ci if (ArkNativeEngine::napiProfilerEnabled) { 109833eb0b6dSopenharmony_ci Local<StringRef> moduleNameStr = StringRef::NewFromUtf8(vm_, moduleName.c_str(), moduleName.size()); 109933eb0b6dSopenharmony_ci Local<StringRef> key = StringRef::NewFromUtf8(vm_, PANDA_MODULE_NAME); 110033eb0b6dSopenharmony_ci nativeObj->Set(vm_, key, moduleNameStr); 110133eb0b6dSopenharmony_ci } 110233eb0b6dSopenharmony_ci#endif 110333eb0b6dSopenharmony_ci} 110433eb0b6dSopenharmony_ci 110533eb0b6dSopenharmony_cistatic void ConcurrentCallbackFunc(Local<JSValueRef> result, bool success, void *taskInfo, void *data) 110633eb0b6dSopenharmony_ci{ 110733eb0b6dSopenharmony_ci if (data == nullptr) { 110833eb0b6dSopenharmony_ci return; 110933eb0b6dSopenharmony_ci } 111033eb0b6dSopenharmony_ci auto engine = static_cast<ArkNativeEngine *>(data); 111133eb0b6dSopenharmony_ci auto concurrentCallbackFunc = engine->GetConcurrentCallbackFunc(); 111233eb0b6dSopenharmony_ci if (concurrentCallbackFunc == nullptr) { 111333eb0b6dSopenharmony_ci return; 111433eb0b6dSopenharmony_ci } 111533eb0b6dSopenharmony_ci napi_env env = reinterpret_cast<napi_env>(engine); 111633eb0b6dSopenharmony_ci concurrentCallbackFunc(env, ArkNativeEngine::ArkValueToNapiValue(env, result), success, taskInfo); 111733eb0b6dSopenharmony_ci} 111833eb0b6dSopenharmony_ci 111933eb0b6dSopenharmony_cibool ArkNativeEngine::InitTaskPoolThread(NativeEngine* engine, NapiConcurrentCallback callback) 112033eb0b6dSopenharmony_ci{ 112133eb0b6dSopenharmony_ci concurrentCallbackFunc_ = callback; 112233eb0b6dSopenharmony_ci return JSNApi::InitForConcurrentThread(vm_, ConcurrentCallbackFunc, static_cast<void *>(this)); 112333eb0b6dSopenharmony_ci} 112433eb0b6dSopenharmony_ci 112533eb0b6dSopenharmony_cibool ArkNativeEngine::InitTaskPoolThread(napi_env env, NapiConcurrentCallback callback) 112633eb0b6dSopenharmony_ci{ 112733eb0b6dSopenharmony_ci concurrentCallbackFunc_ = callback; 112833eb0b6dSopenharmony_ci return JSNApi::InitForConcurrentThread(vm_, ConcurrentCallbackFunc, static_cast<void *>(this)); 112933eb0b6dSopenharmony_ci} 113033eb0b6dSopenharmony_ci 113133eb0b6dSopenharmony_cibool ArkNativeEngine::InitTaskPoolFunc(napi_env env, napi_value func, void* taskInfo) 113233eb0b6dSopenharmony_ci{ 113333eb0b6dSopenharmony_ci LocalScope scope(vm_); 113433eb0b6dSopenharmony_ci Local<JSValueRef> function = LocalValueFromJsValue(func); 113533eb0b6dSopenharmony_ci return JSNApi::InitForConcurrentFunction(vm_, function, taskInfo); 113633eb0b6dSopenharmony_ci} 113733eb0b6dSopenharmony_ci 113833eb0b6dSopenharmony_cibool ArkNativeEngine::HasPendingJob() const 113933eb0b6dSopenharmony_ci{ 114033eb0b6dSopenharmony_ci return JSNApi::HasPendingJob(vm_); 114133eb0b6dSopenharmony_ci} 114233eb0b6dSopenharmony_ci 114333eb0b6dSopenharmony_cibool ArkNativeEngine::IsProfiling() const 114433eb0b6dSopenharmony_ci{ 114533eb0b6dSopenharmony_ci return JSNApi::IsProfiling(vm_); 114633eb0b6dSopenharmony_ci} 114733eb0b6dSopenharmony_ci 114833eb0b6dSopenharmony_cibool ArkNativeEngine::IsExecutingPendingJob() const 114933eb0b6dSopenharmony_ci{ 115033eb0b6dSopenharmony_ci return panda::JSNApi::IsExecutingPendingJob(vm_); 115133eb0b6dSopenharmony_ci} 115233eb0b6dSopenharmony_ci 115333eb0b6dSopenharmony_civoid* ArkNativeEngine::GetCurrentTaskInfo() const 115433eb0b6dSopenharmony_ci{ 115533eb0b6dSopenharmony_ci return JSNApi::GetCurrentTaskInfo(vm_); 115633eb0b6dSopenharmony_ci} 115733eb0b6dSopenharmony_ci 115833eb0b6dSopenharmony_civoid ArkNativeEngine::ClearCurrentTaskInfo() 115933eb0b6dSopenharmony_ci{ 116033eb0b6dSopenharmony_ci JSNApi::ClearCurrentTaskInfo(vm_); 116133eb0b6dSopenharmony_ci} 116233eb0b6dSopenharmony_ci 116333eb0b6dSopenharmony_civoid ArkNativeEngine::TerminateExecution() const 116433eb0b6dSopenharmony_ci{ 116533eb0b6dSopenharmony_ci DFXJSNApi::TerminateExecution(vm_); 116633eb0b6dSopenharmony_ci} 116733eb0b6dSopenharmony_ci 116833eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyTaskBegin() const 116933eb0b6dSopenharmony_ci{ 117033eb0b6dSopenharmony_ci JSNApi::NotifyTaskBegin(vm_); 117133eb0b6dSopenharmony_ci} 117233eb0b6dSopenharmony_ci 117333eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyTaskFinished() const 117433eb0b6dSopenharmony_ci{ 117533eb0b6dSopenharmony_ci JSNApi::NotifyTaskFinished(vm_); 117633eb0b6dSopenharmony_ci} 117733eb0b6dSopenharmony_ci 117833eb0b6dSopenharmony_cinapi_value ArkNativeEngine::CallFunction( 117933eb0b6dSopenharmony_ci napi_value thisVar, napi_value function, napi_value const* argv, size_t argc) 118033eb0b6dSopenharmony_ci{ 118133eb0b6dSopenharmony_ci if (function == nullptr) { 118233eb0b6dSopenharmony_ci return nullptr; 118333eb0b6dSopenharmony_ci } 118433eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 118533eb0b6dSopenharmony_ci Local<JSValueRef> thisObj = JSValueRef::Undefined(vm_); 118633eb0b6dSopenharmony_ci if (thisVar != nullptr) { 118733eb0b6dSopenharmony_ci thisObj = LocalValueFromJsValue(thisVar); 118833eb0b6dSopenharmony_ci } 118933eb0b6dSopenharmony_ci Local<FunctionRef> funcObj = LocalValueFromJsValue(function); 119033eb0b6dSopenharmony_ci std::vector<Local<JSValueRef>> args; 119133eb0b6dSopenharmony_ci args.reserve(argc); 119233eb0b6dSopenharmony_ci for (size_t i = 0; i < argc; i++) { 119333eb0b6dSopenharmony_ci if (argv[i] != nullptr) { 119433eb0b6dSopenharmony_ci args.emplace_back(LocalValueFromJsValue(argv[i])); 119533eb0b6dSopenharmony_ci } else { 119633eb0b6dSopenharmony_ci args.emplace_back(JSValueRef::Undefined(vm_)); 119733eb0b6dSopenharmony_ci } 119833eb0b6dSopenharmony_ci } 119933eb0b6dSopenharmony_ci 120033eb0b6dSopenharmony_ci Local<JSValueRef> value = funcObj->Call(vm_, thisObj, args.data(), argc); 120133eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 120233eb0b6dSopenharmony_ci HILOG_ERROR("pending exception when js function called"); 120333eb0b6dSopenharmony_ci HILOG_ERROR("print exception info: "); 120433eb0b6dSopenharmony_ci panda::JSNApi::PrintExceptionInfo(vm_); 120533eb0b6dSopenharmony_ci return nullptr; 120633eb0b6dSopenharmony_ci } 120733eb0b6dSopenharmony_ci 120833eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(value)); 120933eb0b6dSopenharmony_ci} 121033eb0b6dSopenharmony_ci 121133eb0b6dSopenharmony_cibool ArkNativeEngine::NapiNewTypedArray(const EcmaVM* vm, NativeTypedArrayType typedArrayType, 121233eb0b6dSopenharmony_ci Local<panda::ArrayBufferRef> arrayBuf, 121333eb0b6dSopenharmony_ci size_t byte_offset, size_t length, napi_value* result) 121433eb0b6dSopenharmony_ci{ 121533eb0b6dSopenharmony_ci Local<panda::TypedArrayRef> typedArray; 121633eb0b6dSopenharmony_ci switch (typedArrayType) { 121733eb0b6dSopenharmony_ci case NATIVE_INT8_ARRAY: 121833eb0b6dSopenharmony_ci typedArray = panda::Int8ArrayRef::New(vm, arrayBuf, byte_offset, length); 121933eb0b6dSopenharmony_ci break; 122033eb0b6dSopenharmony_ci case NATIVE_UINT8_ARRAY: 122133eb0b6dSopenharmony_ci typedArray = panda::Uint8ArrayRef::New(vm, arrayBuf, byte_offset, length); 122233eb0b6dSopenharmony_ci break; 122333eb0b6dSopenharmony_ci case NATIVE_UINT8_CLAMPED_ARRAY: 122433eb0b6dSopenharmony_ci typedArray = panda::Uint8ClampedArrayRef::New(vm, arrayBuf, byte_offset, length); 122533eb0b6dSopenharmony_ci break; 122633eb0b6dSopenharmony_ci case NATIVE_INT16_ARRAY: 122733eb0b6dSopenharmony_ci typedArray = panda::Int16ArrayRef::New(vm, arrayBuf, byte_offset, length); 122833eb0b6dSopenharmony_ci break; 122933eb0b6dSopenharmony_ci case NATIVE_UINT16_ARRAY: 123033eb0b6dSopenharmony_ci typedArray = panda::Uint16ArrayRef::New(vm, arrayBuf, byte_offset, length); 123133eb0b6dSopenharmony_ci break; 123233eb0b6dSopenharmony_ci case NATIVE_INT32_ARRAY: 123333eb0b6dSopenharmony_ci typedArray = panda::Int32ArrayRef::New(vm, arrayBuf, byte_offset, length); 123433eb0b6dSopenharmony_ci break; 123533eb0b6dSopenharmony_ci case NATIVE_UINT32_ARRAY: 123633eb0b6dSopenharmony_ci typedArray = panda::Uint32ArrayRef::New(vm, arrayBuf, byte_offset, length); 123733eb0b6dSopenharmony_ci break; 123833eb0b6dSopenharmony_ci case NATIVE_FLOAT32_ARRAY: 123933eb0b6dSopenharmony_ci typedArray = panda::Float32ArrayRef::New(vm, arrayBuf, byte_offset, length); 124033eb0b6dSopenharmony_ci break; 124133eb0b6dSopenharmony_ci case NATIVE_FLOAT64_ARRAY: 124233eb0b6dSopenharmony_ci typedArray = panda::Float64ArrayRef::New(vm, arrayBuf, byte_offset, length); 124333eb0b6dSopenharmony_ci break; 124433eb0b6dSopenharmony_ci case NATIVE_BIGINT64_ARRAY: 124533eb0b6dSopenharmony_ci typedArray = panda::BigInt64ArrayRef::New(vm, arrayBuf, byte_offset, length); 124633eb0b6dSopenharmony_ci break; 124733eb0b6dSopenharmony_ci case NATIVE_BIGUINT64_ARRAY: 124833eb0b6dSopenharmony_ci typedArray = panda::BigUint64ArrayRef::New(vm, arrayBuf, byte_offset, length); 124933eb0b6dSopenharmony_ci break; 125033eb0b6dSopenharmony_ci default: 125133eb0b6dSopenharmony_ci *result = nullptr; 125233eb0b6dSopenharmony_ci return false; 125333eb0b6dSopenharmony_ci } 125433eb0b6dSopenharmony_ci *result = JsValueFromLocalValue(typedArray); 125533eb0b6dSopenharmony_ci return true; 125633eb0b6dSopenharmony_ci} 125733eb0b6dSopenharmony_ci 125833eb0b6dSopenharmony_cibool ArkNativeEngine::NapiNewSendableTypedArray(const EcmaVM* vm, NativeTypedArrayType typedArrayType, 125933eb0b6dSopenharmony_ci Local<panda::SendableArrayBufferRef> arrayBuf, 126033eb0b6dSopenharmony_ci size_t byte_offset, size_t length, napi_value* result) 126133eb0b6dSopenharmony_ci{ 126233eb0b6dSopenharmony_ci Local<panda::SendableTypedArrayRef> typedArray; 126333eb0b6dSopenharmony_ci switch (typedArrayType) { 126433eb0b6dSopenharmony_ci case NATIVE_INT8_ARRAY: 126533eb0b6dSopenharmony_ci typedArray = panda::SharedInt8ArrayRef::New(vm, arrayBuf, byte_offset, length); 126633eb0b6dSopenharmony_ci break; 126733eb0b6dSopenharmony_ci case NATIVE_UINT8_ARRAY: 126833eb0b6dSopenharmony_ci typedArray = panda::SharedUint8ArrayRef::New(vm, arrayBuf, byte_offset, length); 126933eb0b6dSopenharmony_ci break; 127033eb0b6dSopenharmony_ci case NATIVE_INT16_ARRAY: 127133eb0b6dSopenharmony_ci typedArray = panda::SharedInt16ArrayRef::New(vm, arrayBuf, byte_offset, length); 127233eb0b6dSopenharmony_ci break; 127333eb0b6dSopenharmony_ci case NATIVE_UINT16_ARRAY: 127433eb0b6dSopenharmony_ci typedArray = panda::SharedUint16ArrayRef::New(vm, arrayBuf, byte_offset, length); 127533eb0b6dSopenharmony_ci break; 127633eb0b6dSopenharmony_ci case NATIVE_INT32_ARRAY: 127733eb0b6dSopenharmony_ci typedArray = panda::SharedInt32ArrayRef::New(vm, arrayBuf, byte_offset, length); 127833eb0b6dSopenharmony_ci break; 127933eb0b6dSopenharmony_ci case NATIVE_UINT32_ARRAY: 128033eb0b6dSopenharmony_ci typedArray = panda::SharedUint32ArrayRef::New(vm, arrayBuf, byte_offset, length); 128133eb0b6dSopenharmony_ci break; 128233eb0b6dSopenharmony_ci case NATIVE_FLOAT32_ARRAY: 128333eb0b6dSopenharmony_ci typedArray = panda::SharedFloat32ArrayRef::New(vm, arrayBuf, byte_offset, length); 128433eb0b6dSopenharmony_ci break; 128533eb0b6dSopenharmony_ci case NATIVE_UINT8_CLAMPED_ARRAY: 128633eb0b6dSopenharmony_ci typedArray = panda::SharedUint8ClampedArrayRef::New(vm, arrayBuf, byte_offset, length); 128733eb0b6dSopenharmony_ci break; 128833eb0b6dSopenharmony_ci default: 128933eb0b6dSopenharmony_ci *result = nullptr; 129033eb0b6dSopenharmony_ci return false; 129133eb0b6dSopenharmony_ci } 129233eb0b6dSopenharmony_ci *result = JsValueFromLocalValue(typedArray); 129333eb0b6dSopenharmony_ci return true; 129433eb0b6dSopenharmony_ci} 129533eb0b6dSopenharmony_ci 129633eb0b6dSopenharmony_ciNativeTypedArrayType ArkNativeEngine::GetTypedArrayType(panda::Local<panda::TypedArrayRef> typedArray) 129733eb0b6dSopenharmony_ci{ 129833eb0b6dSopenharmony_ci NativeTypedArrayType thisType = NATIVE_INT8_ARRAY; 129933eb0b6dSopenharmony_ci if (typedArray->IsInt32Array(vm_)) { 130033eb0b6dSopenharmony_ci thisType = NATIVE_INT32_ARRAY; 130133eb0b6dSopenharmony_ci } else if (typedArray->IsInt8Array(vm_)) { 130233eb0b6dSopenharmony_ci thisType = NATIVE_INT8_ARRAY; 130333eb0b6dSopenharmony_ci } else if (typedArray->IsUint8Array(vm_)) { 130433eb0b6dSopenharmony_ci thisType = NATIVE_UINT8_ARRAY; 130533eb0b6dSopenharmony_ci } else if (typedArray->IsUint8ClampedArray(vm_)) { 130633eb0b6dSopenharmony_ci thisType = NATIVE_UINT8_CLAMPED_ARRAY; 130733eb0b6dSopenharmony_ci } else if (typedArray->IsInt16Array(vm_)) { 130833eb0b6dSopenharmony_ci thisType = NATIVE_INT16_ARRAY; 130933eb0b6dSopenharmony_ci } else if (typedArray->IsUint16Array(vm_)) { 131033eb0b6dSopenharmony_ci thisType = NATIVE_UINT16_ARRAY; 131133eb0b6dSopenharmony_ci } else if (typedArray->IsUint32Array(vm_)) { 131233eb0b6dSopenharmony_ci thisType = NATIVE_UINT32_ARRAY; 131333eb0b6dSopenharmony_ci } else if (typedArray->IsFloat32Array(vm_)) { 131433eb0b6dSopenharmony_ci thisType = NATIVE_FLOAT32_ARRAY; 131533eb0b6dSopenharmony_ci } else if (typedArray->IsFloat64Array(vm_)) { 131633eb0b6dSopenharmony_ci thisType = NATIVE_FLOAT64_ARRAY; 131733eb0b6dSopenharmony_ci } else if (typedArray->IsBigInt64Array(vm_)) { 131833eb0b6dSopenharmony_ci thisType = NATIVE_BIGINT64_ARRAY; 131933eb0b6dSopenharmony_ci } else if (typedArray->IsBigUint64Array(vm_)) { 132033eb0b6dSopenharmony_ci thisType = NATIVE_BIGUINT64_ARRAY; 132133eb0b6dSopenharmony_ci } 132233eb0b6dSopenharmony_ci 132333eb0b6dSopenharmony_ci return thisType; 132433eb0b6dSopenharmony_ci} 132533eb0b6dSopenharmony_ci 132633eb0b6dSopenharmony_ciNativeTypedArrayType ArkNativeEngine::GetSendableTypedArrayType(panda::Local<panda::SendableTypedArrayRef> typedArray) 132733eb0b6dSopenharmony_ci{ 132833eb0b6dSopenharmony_ci NativeTypedArrayType thisType = NATIVE_INT8_ARRAY; 132933eb0b6dSopenharmony_ci if (typedArray->IsJSSharedInt8Array(vm_)) { 133033eb0b6dSopenharmony_ci thisType = NATIVE_INT8_ARRAY; 133133eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedUint8Array(vm_)) { 133233eb0b6dSopenharmony_ci thisType = NATIVE_UINT8_ARRAY; 133333eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedInt16Array(vm_)) { 133433eb0b6dSopenharmony_ci thisType = NATIVE_INT16_ARRAY; 133533eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedUint16Array(vm_)) { 133633eb0b6dSopenharmony_ci thisType = NATIVE_UINT16_ARRAY; 133733eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedInt32Array(vm_)) { 133833eb0b6dSopenharmony_ci thisType = NATIVE_INT32_ARRAY; 133933eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedUint32Array(vm_)) { 134033eb0b6dSopenharmony_ci thisType = NATIVE_UINT32_ARRAY; 134133eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedFloat32Array(vm_)) { 134233eb0b6dSopenharmony_ci thisType = NATIVE_FLOAT32_ARRAY; 134333eb0b6dSopenharmony_ci } else if (typedArray->IsJSSharedUint8ClampedArray(vm_)) { 134433eb0b6dSopenharmony_ci thisType = NATIVE_UINT8_CLAMPED_ARRAY; 134533eb0b6dSopenharmony_ci } 134633eb0b6dSopenharmony_ci 134733eb0b6dSopenharmony_ci return thisType; 134833eb0b6dSopenharmony_ci} 134933eb0b6dSopenharmony_ci 135033eb0b6dSopenharmony_ci/* 135133eb0b6dSopenharmony_ci * Before: input: 1. @ohos.hilog 135233eb0b6dSopenharmony_ci 2. @system.app (NATIVE_MODULE contains this name) 135333eb0b6dSopenharmony_ci * After: return: 1.@ohos:hilog 135433eb0b6dSopenharmony_ci * 2.@native:system.app 135533eb0b6dSopenharmony_ci */ 135633eb0b6dSopenharmony_cistd::string ArkNativeEngine::GetOhmurl(std::string path) 135733eb0b6dSopenharmony_ci{ 135833eb0b6dSopenharmony_ci const std::regex reg("@(ohos|system)\\.(\\S+)"); 135933eb0b6dSopenharmony_ci path.erase(0, path.find_first_not_of(" ")); 136033eb0b6dSopenharmony_ci path.erase(path.find_last_not_of(" ") + 1); 136133eb0b6dSopenharmony_ci bool ret = std::regex_match(path, reg); 136233eb0b6dSopenharmony_ci if (!ret) { 136333eb0b6dSopenharmony_ci HILOG_ERROR("ArkNativeEngine:The module name doesn't comply with the naming rules"); 136433eb0b6dSopenharmony_ci return ""; 136533eb0b6dSopenharmony_ci } 136633eb0b6dSopenharmony_ci std::string systemModule = path.substr(1); 136733eb0b6dSopenharmony_ci if (NATIVE_MODULE.count(systemModule)) { 136833eb0b6dSopenharmony_ci return NATIVE_MODULE_PREFIX + systemModule; 136933eb0b6dSopenharmony_ci } else { 137033eb0b6dSopenharmony_ci int pos = static_cast<int>(path.find('.')); 137133eb0b6dSopenharmony_ci std::string systemKey = path.substr(pos + 1, systemModule.size()); 137233eb0b6dSopenharmony_ci return OHOS_MODULE_PREFIX + systemKey; 137333eb0b6dSopenharmony_ci } 137433eb0b6dSopenharmony_ci} 137533eb0b6dSopenharmony_ci 137633eb0b6dSopenharmony_ciLocal<JSValueRef> ArkNativeEngine::NapiLoadNativeModule(std::string path) 137733eb0b6dSopenharmony_ci{ 137833eb0b6dSopenharmony_ci std::string key = GetOhmurl(path); 137933eb0b6dSopenharmony_ci if (key.size() == 0) { 138033eb0b6dSopenharmony_ci return JSValueRef::Undefined(vm_); 138133eb0b6dSopenharmony_ci } 138233eb0b6dSopenharmony_ci return panda::JSNApi::ExecuteNativeModule(vm_, key); 138333eb0b6dSopenharmony_ci} 138433eb0b6dSopenharmony_ci 138533eb0b6dSopenharmony_ciModuleTypes ArkNativeEngine::CheckLoadType(const std::string &path) 138633eb0b6dSopenharmony_ci{ 138733eb0b6dSopenharmony_ci if (path[0] == '@') { 138833eb0b6dSopenharmony_ci return ModuleTypes::NATIVE_MODULE; 138933eb0b6dSopenharmony_ci } else if (path.find("ets/") == 0) { // ets/xxx/xxx 139033eb0b6dSopenharmony_ci return ModuleTypes::MODULE_INNER_FILE; 139133eb0b6dSopenharmony_ci } 139233eb0b6dSopenharmony_ci return ModuleTypes::UNKNOWN; 139333eb0b6dSopenharmony_ci} 139433eb0b6dSopenharmony_ci 139533eb0b6dSopenharmony_cinapi_value ArkNativeEngine::NapiLoadModule(const char* path, const char* module_info) 139633eb0b6dSopenharmony_ci{ 139733eb0b6dSopenharmony_ci if (path == nullptr) { 139833eb0b6dSopenharmony_ci HILOG_ERROR("ArkNativeEngine:The module name is empty"); 139933eb0b6dSopenharmony_ci return nullptr; 140033eb0b6dSopenharmony_ci } 140133eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 140233eb0b6dSopenharmony_ci Local<JSValueRef> undefObj = JSValueRef::Undefined(vm_); 140333eb0b6dSopenharmony_ci Local<ObjectRef> exportObj(undefObj); 140433eb0b6dSopenharmony_ci std::string inputPath(path); 140533eb0b6dSopenharmony_ci std::string modulePath; 140633eb0b6dSopenharmony_ci if (module_info != nullptr) { 140733eb0b6dSopenharmony_ci modulePath = module_info; 140833eb0b6dSopenharmony_ci } 140933eb0b6dSopenharmony_ci switch (CheckLoadType(inputPath)) { 141033eb0b6dSopenharmony_ci case ModuleTypes::NATIVE_MODULE: { 141133eb0b6dSopenharmony_ci exportObj = NapiLoadNativeModule(inputPath); 141233eb0b6dSopenharmony_ci break; 141333eb0b6dSopenharmony_ci } 141433eb0b6dSopenharmony_ci case ModuleTypes::MODULE_INNER_FILE: { 141533eb0b6dSopenharmony_ci exportObj = panda::JSNApi::GetModuleNameSpaceFromFile(vm_, inputPath, modulePath); 141633eb0b6dSopenharmony_ci break; 141733eb0b6dSopenharmony_ci } 141833eb0b6dSopenharmony_ci default: { 141933eb0b6dSopenharmony_ci std::string msg = "ArkNativeEngine:NapiLoadModule input path:" + inputPath + " is invalid."; 142033eb0b6dSopenharmony_ci ThrowException(msg.c_str()); 142133eb0b6dSopenharmony_ci } 142233eb0b6dSopenharmony_ci } 142333eb0b6dSopenharmony_ci if (!exportObj->IsObject(vm_)) { 142433eb0b6dSopenharmony_ci ThrowException("ArkNativeEngine:NapiLoadModule failed."); 142533eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(undefObj)); 142633eb0b6dSopenharmony_ci } 142733eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(exportObj)); 142833eb0b6dSopenharmony_ci} 142933eb0b6dSopenharmony_ci 143033eb0b6dSopenharmony_cinapi_value ArkNativeEngine::NapiLoadModuleWithInfo(const char* path, const char* module_info) 143133eb0b6dSopenharmony_ci{ 143233eb0b6dSopenharmony_ci if (path == nullptr) { 143333eb0b6dSopenharmony_ci HILOG_ERROR("ArkNativeEngine:The module name is empty"); 143433eb0b6dSopenharmony_ci return nullptr; 143533eb0b6dSopenharmony_ci } 143633eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 143733eb0b6dSopenharmony_ci Local<JSValueRef> undefObj = JSValueRef::Undefined(vm_); 143833eb0b6dSopenharmony_ci Local<ObjectRef> exportObj(undefObj); 143933eb0b6dSopenharmony_ci std::string inputPath(path); 144033eb0b6dSopenharmony_ci std::string modulePath; 144133eb0b6dSopenharmony_ci if (module_info != nullptr) { 144233eb0b6dSopenharmony_ci modulePath = module_info; 144333eb0b6dSopenharmony_ci exportObj = panda::JSNApi::GetModuleNameSpaceWithModuleInfo(vm_, inputPath, modulePath); 144433eb0b6dSopenharmony_ci } else { 144533eb0b6dSopenharmony_ci exportObj = NapiLoadNativeModule(inputPath); 144633eb0b6dSopenharmony_ci } 144733eb0b6dSopenharmony_ci 144833eb0b6dSopenharmony_ci if (!exportObj->IsObject(vm_)) { 144933eb0b6dSopenharmony_ci ThrowException("ArkNativeEngine:NapiLoadModuleWithInfo failed."); 145033eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(undefObj)); 145133eb0b6dSopenharmony_ci } 145233eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(exportObj)); 145333eb0b6dSopenharmony_ci} 145433eb0b6dSopenharmony_ci 145533eb0b6dSopenharmony_cibool ArkNativeEngine::SuspendVMById(uint32_t tid) 145633eb0b6dSopenharmony_ci{ 145733eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 145833eb0b6dSopenharmony_ci return DFXJSNApi::SuspendVMById(vm_, tid); 145933eb0b6dSopenharmony_ci#else 146033eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 146133eb0b6dSopenharmony_ci return false; 146233eb0b6dSopenharmony_ci#endif 146333eb0b6dSopenharmony_ci} 146433eb0b6dSopenharmony_ci 146533eb0b6dSopenharmony_civoid ArkNativeEngine::ResumeVMById(uint32_t tid) 146633eb0b6dSopenharmony_ci{ 146733eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 146833eb0b6dSopenharmony_ci DFXJSNApi::ResumeVMById(vm_, tid); 146933eb0b6dSopenharmony_ci#else 147033eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 147133eb0b6dSopenharmony_ci return; 147233eb0b6dSopenharmony_ci#endif 147333eb0b6dSopenharmony_ci} 147433eb0b6dSopenharmony_ci 147533eb0b6dSopenharmony_civoid ArkNativeEngine::SetPackagePath(const std::string appLibPathKey, const std::vector<std::string>& packagePath) 147633eb0b6dSopenharmony_ci{ 147733eb0b6dSopenharmony_ci auto moduleManager = NativeModuleManager::GetInstance(); 147833eb0b6dSopenharmony_ci if (moduleManager && !packagePath.empty()) { 147933eb0b6dSopenharmony_ci moduleManager->SetAppLibPath(appLibPathKey, packagePath); 148033eb0b6dSopenharmony_ci } 148133eb0b6dSopenharmony_ci} 148233eb0b6dSopenharmony_ci 148333eb0b6dSopenharmony_cinapi_value ArkNativeEngine::CreateInstance(napi_value constructor, napi_value const *argv, size_t argc) 148433eb0b6dSopenharmony_ci{ 148533eb0b6dSopenharmony_ci if (constructor == nullptr) { 148633eb0b6dSopenharmony_ci return nullptr; 148733eb0b6dSopenharmony_ci } 148833eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 148933eb0b6dSopenharmony_ci Local<FunctionRef> value = LocalValueFromJsValue(constructor); 149033eb0b6dSopenharmony_ci std::vector<Local<JSValueRef>> args; 149133eb0b6dSopenharmony_ci args.reserve(argc); 149233eb0b6dSopenharmony_ci for (size_t i = 0; i < argc; i++) { 149333eb0b6dSopenharmony_ci if (argv[i] != nullptr) { 149433eb0b6dSopenharmony_ci args.emplace_back(LocalValueFromJsValue(argv[i])); 149533eb0b6dSopenharmony_ci } else { 149633eb0b6dSopenharmony_ci args.emplace_back(JSValueRef::Undefined(vm_)); 149733eb0b6dSopenharmony_ci } 149833eb0b6dSopenharmony_ci } 149933eb0b6dSopenharmony_ci Local<JSValueRef> instance = value->Constructor(vm_, args.data(), argc); 150033eb0b6dSopenharmony_ci Local<ObjectRef> excep = panda::JSNApi::GetUncaughtException(vm_); 150133eb0b6dSopenharmony_ci if (!excep.IsNull()) { 150233eb0b6dSopenharmony_ci HILOG_ERROR("ArkNativeEngineImpl::CreateInstance occur Exception"); 150333eb0b6dSopenharmony_ci return nullptr; 150433eb0b6dSopenharmony_ci } 150533eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(instance)); 150633eb0b6dSopenharmony_ci} 150733eb0b6dSopenharmony_ci 150833eb0b6dSopenharmony_ciNativeReference* ArkNativeEngine::CreateReference(napi_value value, uint32_t initialRefcount, 150933eb0b6dSopenharmony_ci bool flag, NapiNativeFinalize callback, void* data, void* hint, size_t nativeBindingSize) 151033eb0b6dSopenharmony_ci{ 151133eb0b6dSopenharmony_ci return new ArkNativeReference(this, value, initialRefcount, flag, callback, data, hint, false, nativeBindingSize); 151233eb0b6dSopenharmony_ci} 151333eb0b6dSopenharmony_ci 151433eb0b6dSopenharmony_ciNativeReference* ArkNativeEngine::CreateAsyncReference(napi_value value, uint32_t initialRefcount, 151533eb0b6dSopenharmony_ci bool flag, NapiNativeFinalize callback, void* data, void* hint) 151633eb0b6dSopenharmony_ci{ 151733eb0b6dSopenharmony_ci return new ArkNativeReference(this, value, initialRefcount, flag, callback, data, hint, true); 151833eb0b6dSopenharmony_ci} 151933eb0b6dSopenharmony_ci 152033eb0b6dSopenharmony_ci__attribute__((optnone)) void ArkNativeEngine::RunCallbacks(TriggerGCData *triggerGCData) 152133eb0b6dSopenharmony_ci{ 152233eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 152333eb0b6dSopenharmony_ci StartTrace(HITRACE_TAG_ACE, "RunTriggerGCTaskCallback"); 152433eb0b6dSopenharmony_ci#endif 152533eb0b6dSopenharmony_ci std::pair<void *, uint8_t> ¶m = *triggerGCData; 152633eb0b6dSopenharmony_ci JSNApi::TriggerIdleGC(reinterpret_cast<panda::ecmascript::EcmaVM *>(param.first), 152733eb0b6dSopenharmony_ci static_cast<panda::JSNApi::TRIGGER_IDLE_GC_TYPE>(param.second)); 152833eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 152933eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 153033eb0b6dSopenharmony_ci#endif 153133eb0b6dSopenharmony_ci} 153233eb0b6dSopenharmony_ci 153333eb0b6dSopenharmony_ci__attribute__((optnone)) void ArkNativeEngine::RunCallbacks(ArkFinalizersPack *finalizersPack) 153433eb0b6dSopenharmony_ci{ 153533eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 153633eb0b6dSopenharmony_ci StartTrace(HITRACE_TAG_ACE, "RunFinalizeCallbacks:" + std::to_string(finalizersPack->GetNumFinalizers())); 153733eb0b6dSopenharmony_ci#endif 153833eb0b6dSopenharmony_ci finalizersPack->ProcessAll(); 153933eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 154033eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 154133eb0b6dSopenharmony_ci#endif 154233eb0b6dSopenharmony_ci} 154333eb0b6dSopenharmony_ci 154433eb0b6dSopenharmony_ci__attribute__((optnone)) void ArkNativeEngine::RunAsyncCallbacks(std::vector<RefFinalizer> *finalizers) 154533eb0b6dSopenharmony_ci{ 154633eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 154733eb0b6dSopenharmony_ci StartTrace(HITRACE_TAG_ACE, "RunFinalizeCallbacks:" + std::to_string(finalizers->size())); 154833eb0b6dSopenharmony_ci#endif 154933eb0b6dSopenharmony_ci for (auto iter : (*finalizers)) { 155033eb0b6dSopenharmony_ci NapiNativeFinalize callback = iter.first; 155133eb0b6dSopenharmony_ci std::tuple<NativeEngine*, void*, void*> ¶m = iter.second; 155233eb0b6dSopenharmony_ci callback(reinterpret_cast<napi_env>(std::get<0>(param)), 155333eb0b6dSopenharmony_ci std::get<1>(param), std::get<2>(param)); // 2 is the param. 155433eb0b6dSopenharmony_ci } 155533eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 155633eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 155733eb0b6dSopenharmony_ci#endif 155833eb0b6dSopenharmony_ci} 155933eb0b6dSopenharmony_ci 156033eb0b6dSopenharmony_civoid ArkNativeEngine::PostFinalizeTasks() 156133eb0b6dSopenharmony_ci{ 156233eb0b6dSopenharmony_ci if (IsInDestructor()) { 156333eb0b6dSopenharmony_ci return; 156433eb0b6dSopenharmony_ci } 156533eb0b6dSopenharmony_ci if (!pendingAsyncFinalizers_.empty()) { 156633eb0b6dSopenharmony_ci uv_work_t *asynWork = new uv_work_t; 156733eb0b6dSopenharmony_ci std::vector<RefFinalizer> *asyncFinalizers = new std::vector<RefFinalizer>(); 156833eb0b6dSopenharmony_ci asyncFinalizers->swap(pendingAsyncFinalizers_); 156933eb0b6dSopenharmony_ci asynWork->data = reinterpret_cast<void *>(asyncFinalizers); 157033eb0b6dSopenharmony_ci 157133eb0b6dSopenharmony_ci int ret = uv_queue_work_with_qos(GetUVLoop(), asynWork, [](uv_work_t *asynWork) { 157233eb0b6dSopenharmony_ci std::vector<RefFinalizer> *finalizers = reinterpret_cast<std::vector<RefFinalizer> *>(asynWork->data); 157333eb0b6dSopenharmony_ci RunAsyncCallbacks(finalizers); 157433eb0b6dSopenharmony_ci HILOG_DEBUG("uv_queue_work async running "); 157533eb0b6dSopenharmony_ci delete finalizers; 157633eb0b6dSopenharmony_ci }, [](uv_work_t *asynWork, int32_t) { 157733eb0b6dSopenharmony_ci delete asynWork; 157833eb0b6dSopenharmony_ci }, uv_qos_t(napi_qos_background)); 157933eb0b6dSopenharmony_ci if (ret != 0) { 158033eb0b6dSopenharmony_ci HILOG_ERROR("uv_queue_work fail ret '%{public}d'", ret); 158133eb0b6dSopenharmony_ci RunAsyncCallbacks(asyncFinalizers); 158233eb0b6dSopenharmony_ci delete asynWork; 158333eb0b6dSopenharmony_ci delete asyncFinalizers; 158433eb0b6dSopenharmony_ci } 158533eb0b6dSopenharmony_ci } 158633eb0b6dSopenharmony_ci if (arkFinalizersPack_.Empty()) { 158733eb0b6dSopenharmony_ci return; 158833eb0b6dSopenharmony_ci } 158933eb0b6dSopenharmony_ci ArkFinalizersPack *finalizersPack = new ArkFinalizersPack(); 159033eb0b6dSopenharmony_ci std::swap(arkFinalizersPack_, *finalizersPack); 159133eb0b6dSopenharmony_ci if (!IsMainThread()) { 159233eb0b6dSopenharmony_ci panda::JsiNativeScope nativeScope(vm_); 159333eb0b6dSopenharmony_ci RunCallbacks(finalizersPack); 159433eb0b6dSopenharmony_ci delete finalizersPack; 159533eb0b6dSopenharmony_ci return; 159633eb0b6dSopenharmony_ci } 159733eb0b6dSopenharmony_ci size_t bindingSize = finalizersPack->GetTotalNativeBindingSize(); 159833eb0b6dSopenharmony_ci if (pendingFinalizersPackNativeBindingSize_ > FINALIZERS_PACK_PENDING_NATIVE_BINDING_SIZE_THRESHOLD && 159933eb0b6dSopenharmony_ci bindingSize > 0) { 160033eb0b6dSopenharmony_ci HILOG_DEBUG("Pending Finalizers NativeBindingSize '%{public}zu' large than '%{public}zu', process sync.", 160133eb0b6dSopenharmony_ci pendingFinalizersPackNativeBindingSize_, FINALIZERS_PACK_PENDING_NATIVE_BINDING_SIZE_THRESHOLD); 160233eb0b6dSopenharmony_ci panda::JsiNativeScope nativeScope(vm_); 160333eb0b6dSopenharmony_ci RunCallbacks(finalizersPack); 160433eb0b6dSopenharmony_ci delete finalizersPack; 160533eb0b6dSopenharmony_ci return; 160633eb0b6dSopenharmony_ci } 160733eb0b6dSopenharmony_ci uv_work_t *syncWork = new uv_work_t; 160833eb0b6dSopenharmony_ci finalizersPack->RegisterFinishNotify([this] (size_t totalNativeBindingSize) { 160933eb0b6dSopenharmony_ci this->DecreasePendingFinalizersPackNativeBindingSize(totalNativeBindingSize); 161033eb0b6dSopenharmony_ci }); 161133eb0b6dSopenharmony_ci IncreasePendingFinalizersPackNativeBindingSize(bindingSize); 161233eb0b6dSopenharmony_ci 161333eb0b6dSopenharmony_ci syncWork->data = reinterpret_cast<void *>(finalizersPack); 161433eb0b6dSopenharmony_ci int ret = uv_queue_work_with_qos(GetUVLoop(), syncWork, [](uv_work_t *) {}, [](uv_work_t *syncWork, int32_t) { 161533eb0b6dSopenharmony_ci ArkFinalizersPack *finalizersPack = reinterpret_cast<ArkFinalizersPack*>(syncWork->data); 161633eb0b6dSopenharmony_ci RunCallbacks(finalizersPack); 161733eb0b6dSopenharmony_ci HILOG_DEBUG("uv_queue_work running"); 161833eb0b6dSopenharmony_ci delete syncWork; 161933eb0b6dSopenharmony_ci delete finalizersPack; 162033eb0b6dSopenharmony_ci }, uv_qos_t(napi_qos_background)); 162133eb0b6dSopenharmony_ci if (ret != 0) { 162233eb0b6dSopenharmony_ci HILOG_ERROR("uv_queue_work fail ret '%{public}d'", ret); 162333eb0b6dSopenharmony_ci panda::JsiNativeScope nativeScope(vm_); 162433eb0b6dSopenharmony_ci RunCallbacks(finalizersPack); 162533eb0b6dSopenharmony_ci delete syncWork; 162633eb0b6dSopenharmony_ci delete finalizersPack; 162733eb0b6dSopenharmony_ci } 162833eb0b6dSopenharmony_ci} 162933eb0b6dSopenharmony_ci 163033eb0b6dSopenharmony_ci__attribute__((optnone)) void ArkNativeEngine::RunCallbacks(AsyncNativeCallbacksPack *callbacksPack) 163133eb0b6dSopenharmony_ci{ 163233eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 163333eb0b6dSopenharmony_ci StartTrace(HITRACE_TAG_ACE, "RunNativeCallbacks:" + std::to_string(callbacksPack->GetNumCallBacks())); 163433eb0b6dSopenharmony_ci#endif 163533eb0b6dSopenharmony_ci callbacksPack->ProcessAll(); 163633eb0b6dSopenharmony_ci#ifdef ENABLE_HITRACE 163733eb0b6dSopenharmony_ci FinishTrace(HITRACE_TAG_ACE); 163833eb0b6dSopenharmony_ci#endif 163933eb0b6dSopenharmony_ci} 164033eb0b6dSopenharmony_ci 164133eb0b6dSopenharmony_civoid ArkNativeEngine::PostAsyncTask(AsyncNativeCallbacksPack *callBacksPack) 164233eb0b6dSopenharmony_ci{ 164333eb0b6dSopenharmony_ci if (IsInDestructor()) { 164433eb0b6dSopenharmony_ci delete callBacksPack; 164533eb0b6dSopenharmony_ci return; 164633eb0b6dSopenharmony_ci } 164733eb0b6dSopenharmony_ci uv_work_t *syncWork = new uv_work_t; 164833eb0b6dSopenharmony_ci syncWork->data = reinterpret_cast<void *>(callBacksPack); 164933eb0b6dSopenharmony_ci 165033eb0b6dSopenharmony_ci int ret = uv_queue_work_with_qos(GetUVLoop(), syncWork, [](uv_work_t *) {}, [](uv_work_t *syncWork, int32_t) { 165133eb0b6dSopenharmony_ci AsyncNativeCallbacksPack *finalizers = reinterpret_cast<AsyncNativeCallbacksPack*>(syncWork->data); 165233eb0b6dSopenharmony_ci RunCallbacks(finalizers); 165333eb0b6dSopenharmony_ci HILOG_DEBUG("uv_queue_work running"); 165433eb0b6dSopenharmony_ci delete syncWork; 165533eb0b6dSopenharmony_ci delete finalizers; 165633eb0b6dSopenharmony_ci }, uv_qos_t(napi_qos_background)); 165733eb0b6dSopenharmony_ci if (ret != 0) { 165833eb0b6dSopenharmony_ci HILOG_ERROR("uv_queue_work fail ret '%{public}d'", ret); 165933eb0b6dSopenharmony_ci panda::JsiNativeScope nativeScope(vm_); 166033eb0b6dSopenharmony_ci RunCallbacks(callBacksPack); 166133eb0b6dSopenharmony_ci delete callBacksPack; 166233eb0b6dSopenharmony_ci delete syncWork; 166333eb0b6dSopenharmony_ci } 166433eb0b6dSopenharmony_ci} 166533eb0b6dSopenharmony_ci 166633eb0b6dSopenharmony_civoid ArkNativeEngine::PostTriggerGCTask(TriggerGCData& data) 166733eb0b6dSopenharmony_ci{ 166833eb0b6dSopenharmony_ci TriggerGCData *triggerGCData = new TriggerGCData(data); 166933eb0b6dSopenharmony_ci uv_work_t *syncWork = new uv_work_t; 167033eb0b6dSopenharmony_ci syncWork->data = reinterpret_cast<void *>(triggerGCData); 167133eb0b6dSopenharmony_ci int ret = uv_queue_work_with_qos(GetUVLoop(), syncWork, [](uv_work_t *) {}, [](uv_work_t *syncWork, int32_t) { 167233eb0b6dSopenharmony_ci auto triggerGCData = reinterpret_cast<TriggerGCData *>(syncWork->data); 167333eb0b6dSopenharmony_ci RunCallbacks(triggerGCData); 167433eb0b6dSopenharmony_ci delete syncWork; 167533eb0b6dSopenharmony_ci delete triggerGCData; 167633eb0b6dSopenharmony_ci }, uv_qos_t(napi_qos_user_initiated)); 167733eb0b6dSopenharmony_ci if (ret != 0) { 167833eb0b6dSopenharmony_ci HILOG_ERROR("uv_queue_work fail ret '%{public}d'", ret); 167933eb0b6dSopenharmony_ci RunCallbacks(triggerGCData); 168033eb0b6dSopenharmony_ci delete syncWork; 168133eb0b6dSopenharmony_ci delete triggerGCData; 168233eb0b6dSopenharmony_ci } 168333eb0b6dSopenharmony_ci} 168433eb0b6dSopenharmony_ci 168533eb0b6dSopenharmony_ci#if defined(OHOS_PLATFORM) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) 168633eb0b6dSopenharmony_civoid ArkNativeEngine::SetAttribute(bool isLimitedWorker, panda::RuntimeOption &option) 168733eb0b6dSopenharmony_ci{ 168833eb0b6dSopenharmony_ci int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1); 168933eb0b6dSopenharmony_ci std::string bundleName = OHOS::system::GetParameter("persist.ark.arkbundlename", ""); 169033eb0b6dSopenharmony_ci std::string memConfigProperty = OHOS::system::GetParameter("persist.ark.mem_config_property", ""); 169133eb0b6dSopenharmony_ci size_t gcThreadNum = OHOS::system::GetUintParameter<size_t>("persist.ark.gcthreads", 7); 169233eb0b6dSopenharmony_ci size_t longPauseTime = OHOS::system::GetUintParameter<size_t>("persist.ark.longpausetime", 40); 169333eb0b6dSopenharmony_ci bool asmInterpreterEnabled = OHOS::system::GetBoolParameter("persist.ark.asminterpreter", true); 169433eb0b6dSopenharmony_ci std::string asmOpcodeDisableRange = OHOS::system::GetParameter("persist.ark.asmopcodedisablerange", ""); 169533eb0b6dSopenharmony_ci bool builtinsLazyEnabled = OHOS::system::GetBoolParameter("persist.ark.enablebuiltinslazy", true); 169633eb0b6dSopenharmony_ci option.SetEnableBuiltinsLazy(builtinsLazyEnabled); 169733eb0b6dSopenharmony_ci option.SetArkProperties(arkProperties); 169833eb0b6dSopenharmony_ci option.SetArkBundleName(bundleName); 169933eb0b6dSopenharmony_ci option.SetMemConfigProperty(memConfigProperty); 170033eb0b6dSopenharmony_ci option.SetGcThreadNum(gcThreadNum); 170133eb0b6dSopenharmony_ci option.SetLongPauseTime(longPauseTime); 170233eb0b6dSopenharmony_ci option.SetEnableAsmInterpreter(asmInterpreterEnabled); 170333eb0b6dSopenharmony_ci option.SetAsmOpcodeDisableRange(asmOpcodeDisableRange); 170433eb0b6dSopenharmony_ci option.SetIsWorker(); 170533eb0b6dSopenharmony_ci option.SetIsRestrictedWorker(isLimitedWorker); 170633eb0b6dSopenharmony_ci HILOG_DEBUG("ArkNativeEngineImpl::CreateRuntimeFunc ark properties = %{public}d, bundlename = %{public}s", 170733eb0b6dSopenharmony_ci arkProperties, bundleName.c_str()); 170833eb0b6dSopenharmony_ci} 170933eb0b6dSopenharmony_ci#endif 171033eb0b6dSopenharmony_ci 171133eb0b6dSopenharmony_ciNativeEngine* ArkNativeEngine::CreateRuntimeFunc(NativeEngine* engine, void* jsEngine, bool isLimitedWorker) 171233eb0b6dSopenharmony_ci{ 171333eb0b6dSopenharmony_ci panda::RuntimeOption option; 171433eb0b6dSopenharmony_ci#if defined(OHOS_PLATFORM) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) 171533eb0b6dSopenharmony_ci SetAttribute(isLimitedWorker, option); 171633eb0b6dSopenharmony_ci#endif 171733eb0b6dSopenharmony_ci option.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC); 171833eb0b6dSopenharmony_ci const int64_t poolSize = 0x1000000; 171933eb0b6dSopenharmony_ci option.SetGcPoolSize(poolSize); 172033eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 172133eb0b6dSopenharmony_ci option.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::INFO); 172233eb0b6dSopenharmony_ci#endif 172333eb0b6dSopenharmony_ci option.SetDebuggerLibraryPath(""); 172433eb0b6dSopenharmony_ci EcmaVM* vm = panda::JSNApi::CreateJSVM(option); 172533eb0b6dSopenharmony_ci if (vm == nullptr) { 172633eb0b6dSopenharmony_ci return nullptr; 172733eb0b6dSopenharmony_ci } 172833eb0b6dSopenharmony_ci // worker adaptation mergeabc 172933eb0b6dSopenharmony_ci const panda::ecmascript::EcmaVM* hostVM = reinterpret_cast<ArkNativeEngine*>(engine)->GetEcmaVm(); 173033eb0b6dSopenharmony_ci panda::JSNApi::SynchronizVMInfo(vm, hostVM); 173133eb0b6dSopenharmony_ci ArkNativeEngine* arkEngine = new ArkNativeEngine(vm, jsEngine, isLimitedWorker); 173233eb0b6dSopenharmony_ci // init callback 173333eb0b6dSopenharmony_ci arkEngine->RegisterWorkerFunction(engine); 173433eb0b6dSopenharmony_ci arkEngine->SetHostEngine(engine); 173533eb0b6dSopenharmony_ci // sync apiVersion 173633eb0b6dSopenharmony_ci arkEngine->SetApiVersion(engine->GetApiVersion()); 173733eb0b6dSopenharmony_ci 173833eb0b6dSopenharmony_ci auto cleanEnv = [vm]() { 173933eb0b6dSopenharmony_ci if (vm != nullptr) { 174033eb0b6dSopenharmony_ci HILOG_DEBUG("cleanEnv is called"); 174133eb0b6dSopenharmony_ci panda::JSNApi::DestroyJSVM(vm); 174233eb0b6dSopenharmony_ci } 174333eb0b6dSopenharmony_ci }; 174433eb0b6dSopenharmony_ci arkEngine->SetCleanEnv(cleanEnv); 174533eb0b6dSopenharmony_ci if (hostVM != nullptr) { 174633eb0b6dSopenharmony_ci panda::JSNApi::AddWorker(const_cast<EcmaVM*>(hostVM), vm); 174733eb0b6dSopenharmony_ci } 174833eb0b6dSopenharmony_ci return arkEngine; 174933eb0b6dSopenharmony_ci} 175033eb0b6dSopenharmony_ci 175133eb0b6dSopenharmony_civoid* ArkNativeEngine::CreateRuntime(bool isLimitedWorker) 175233eb0b6dSopenharmony_ci{ 175333eb0b6dSopenharmony_ci return ArkNativeEngine::CreateRuntimeFunc(this, jsEngine_, isLimitedWorker); 175433eb0b6dSopenharmony_ci} 175533eb0b6dSopenharmony_ci 175633eb0b6dSopenharmony_civoid ArkNativeEngine::SetJsDumpThresholds(size_t thresholds) 175733eb0b6dSopenharmony_ci{ 175833eb0b6dSopenharmony_ci DFXJSNApi::SetJsDumpThresholds(vm_, thresholds); 175933eb0b6dSopenharmony_ci} 176033eb0b6dSopenharmony_ci 176133eb0b6dSopenharmony_civoid ArkNativeEngine::SetAppFreezeFilterCallback(AppFreezeFilterCallback callback) 176233eb0b6dSopenharmony_ci{ 176333eb0b6dSopenharmony_ci DFXJSNApi::SetAppFreezeFilterCallback(vm_, callback); 176433eb0b6dSopenharmony_ci} 176533eb0b6dSopenharmony_ci 176633eb0b6dSopenharmony_civoid ArkNativeEngine::StartCpuProfiler(const std::string& fileName) 176733eb0b6dSopenharmony_ci{ 176833eb0b6dSopenharmony_ci JSNApi::SetNativePtrGetter(vm_, reinterpret_cast<void*>(ArkNativeEngine::GetNativePtrCallBack)); 176933eb0b6dSopenharmony_ci DFXJSNApi::StartCpuProfilerForFile(vm_, fileName); 177033eb0b6dSopenharmony_ci} 177133eb0b6dSopenharmony_ci 177233eb0b6dSopenharmony_civoid ArkNativeEngine::StopCpuProfiler() 177333eb0b6dSopenharmony_ci{ 177433eb0b6dSopenharmony_ci DFXJSNApi::StopCpuProfilerForFile(vm_); 177533eb0b6dSopenharmony_ci JSNApi::SetNativePtrGetter(vm_, nullptr); 177633eb0b6dSopenharmony_ci} 177733eb0b6dSopenharmony_ci 177833eb0b6dSopenharmony_civoid ArkNativeEngine::ResumeVM() 177933eb0b6dSopenharmony_ci{ 178033eb0b6dSopenharmony_ci DFXJSNApi::ResumeVM(vm_); 178133eb0b6dSopenharmony_ci} 178233eb0b6dSopenharmony_ci 178333eb0b6dSopenharmony_cibool ArkNativeEngine::SuspendVM() 178433eb0b6dSopenharmony_ci{ 178533eb0b6dSopenharmony_ci return DFXJSNApi::SuspendVM(vm_); 178633eb0b6dSopenharmony_ci} 178733eb0b6dSopenharmony_ci 178833eb0b6dSopenharmony_cibool ArkNativeEngine::IsSuspended() 178933eb0b6dSopenharmony_ci{ 179033eb0b6dSopenharmony_ci return DFXJSNApi::IsSuspended(vm_); 179133eb0b6dSopenharmony_ci} 179233eb0b6dSopenharmony_ci 179333eb0b6dSopenharmony_cibool ArkNativeEngine::CheckSafepoint() 179433eb0b6dSopenharmony_ci{ 179533eb0b6dSopenharmony_ci return DFXJSNApi::CheckSafepoint(vm_); 179633eb0b6dSopenharmony_ci} 179733eb0b6dSopenharmony_ci 179833eb0b6dSopenharmony_civoid ArkNativeEngine::GetCurrentModuleInfo(std::string& moduleName, std::string& fileName, bool needRecordName) 179933eb0b6dSopenharmony_ci{ 180033eb0b6dSopenharmony_ci LocalScope scope(vm_); 180133eb0b6dSopenharmony_ci std::pair<std::string, std::string> moduleInfo = panda::JSNApi::GetCurrentModuleInfo(vm_, needRecordName); 180233eb0b6dSopenharmony_ci moduleName = moduleInfo.first; // if needRecordName is true, then moduleName is recordName. 180333eb0b6dSopenharmony_ci fileName = moduleInfo.second; 180433eb0b6dSopenharmony_ci} 180533eb0b6dSopenharmony_ci 180633eb0b6dSopenharmony_cibool ArkNativeEngine::GetIsBundle() 180733eb0b6dSopenharmony_ci{ 180833eb0b6dSopenharmony_ci LocalScope scope(vm_); 180933eb0b6dSopenharmony_ci return panda::JSNApi::IsBundle(vm_); 181033eb0b6dSopenharmony_ci} 181133eb0b6dSopenharmony_ci 181233eb0b6dSopenharmony_cibool ArkNativeEngine::GetIsNormalizedOhmUrlPack() 181333eb0b6dSopenharmony_ci{ 181433eb0b6dSopenharmony_ci LocalScope scope(vm_); 181533eb0b6dSopenharmony_ci return panda::JSNApi::IsNormalizedOhmUrlPack(vm_); 181633eb0b6dSopenharmony_ci} 181733eb0b6dSopenharmony_ci 181833eb0b6dSopenharmony_cibool ArkNativeEngine::GetIsDebugModeEnabled() 181933eb0b6dSopenharmony_ci{ 182033eb0b6dSopenharmony_ci LocalScope scope(vm_); 182133eb0b6dSopenharmony_ci return panda::JSNApi::IsDebugModeEnabled(vm_); 182233eb0b6dSopenharmony_ci} 182333eb0b6dSopenharmony_ci 182433eb0b6dSopenharmony_cistd::string ArkNativeEngine::GetBundleName() 182533eb0b6dSopenharmony_ci{ 182633eb0b6dSopenharmony_ci LocalScope scope(vm_); 182733eb0b6dSopenharmony_ci return panda::JSNApi::GetBundleName(vm_); 182833eb0b6dSopenharmony_ci} 182933eb0b6dSopenharmony_ci 183033eb0b6dSopenharmony_cistd::string ArkNativeEngine::GetPkgName(const std::string &moduleName) 183133eb0b6dSopenharmony_ci{ 183233eb0b6dSopenharmony_ci LocalScope scope(vm_); 183333eb0b6dSopenharmony_ci return panda::JSNApi::GetPkgName(vm_, moduleName); 183433eb0b6dSopenharmony_ci} 183533eb0b6dSopenharmony_ci 183633eb0b6dSopenharmony_ciint ArkNativeEngine::GetProcessStartRealTime() 183733eb0b6dSopenharmony_ci{ 183833eb0b6dSopenharmony_ci LocalScope scope(vm_); 183933eb0b6dSopenharmony_ci return panda::JSNApi::GetStartRealTime(vm_); 184033eb0b6dSopenharmony_ci} 184133eb0b6dSopenharmony_ci 184233eb0b6dSopenharmony_cibool ArkNativeEngine::IsExecuteModuleInAbcFile(std::string bundleName, std::string moduleName, std::string ohmurl) 184333eb0b6dSopenharmony_ci{ 184433eb0b6dSopenharmony_ci LocalScope scope(vm_); 184533eb0b6dSopenharmony_ci return panda::JSNApi::IsExecuteModuleInAbcFile(vm_, bundleName, moduleName, ohmurl); 184633eb0b6dSopenharmony_ci} 184733eb0b6dSopenharmony_ci 184833eb0b6dSopenharmony_cinapi_value ArkNativeEngine::ValueToNapiValue(JSValueWrapper& value) 184933eb0b6dSopenharmony_ci{ 185033eb0b6dSopenharmony_ci Global<JSValueRef> arkValue = value; 185133eb0b6dSopenharmony_ci return JsValueFromLocalValue(arkValue.ToLocal(vm_)); 185233eb0b6dSopenharmony_ci} 185333eb0b6dSopenharmony_ci 185433eb0b6dSopenharmony_cinapi_value ArkNativeEngine::ArkValueToNapiValue(napi_env env, Local<JSValueRef> value) 185533eb0b6dSopenharmony_ci{ 185633eb0b6dSopenharmony_ci return JsValueFromLocalValue(value); 185733eb0b6dSopenharmony_ci} 185833eb0b6dSopenharmony_ci 185933eb0b6dSopenharmony_cistd::string ArkNativeEngine::GetSourceCodeInfo(napi_value value, ErrorPos pos) 186033eb0b6dSopenharmony_ci{ 186133eb0b6dSopenharmony_ci if (value == nullptr || pos.first == 0) { 186233eb0b6dSopenharmony_ci return ""; 186333eb0b6dSopenharmony_ci } 186433eb0b6dSopenharmony_ci 186533eb0b6dSopenharmony_ci LocalScope scope(vm_); 186633eb0b6dSopenharmony_ci Local<panda::FunctionRef> func = LocalValueFromJsValue(value); 186733eb0b6dSopenharmony_ci uint32_t line = pos.first; 186833eb0b6dSopenharmony_ci uint32_t column = pos.second; 186933eb0b6dSopenharmony_ci Local<panda::StringRef> sourceCode = func->GetSourceCode(vm_, line); 187033eb0b6dSopenharmony_ci std::string sourceCodeStr = sourceCode->ToString(vm_); 187133eb0b6dSopenharmony_ci if (sourceCodeStr.empty()) { 187233eb0b6dSopenharmony_ci return ""; 187333eb0b6dSopenharmony_ci } 187433eb0b6dSopenharmony_ci std::string sourceCodeInfo = "SourceCode:\n"; 187533eb0b6dSopenharmony_ci sourceCodeInfo.append(sourceCodeStr).append("\n"); 187633eb0b6dSopenharmony_ci for (uint32_t k = 1; k < column; k++) { 187733eb0b6dSopenharmony_ci sourceCodeInfo.push_back(' '); 187833eb0b6dSopenharmony_ci } 187933eb0b6dSopenharmony_ci sourceCodeInfo.append("^\n"); 188033eb0b6dSopenharmony_ci return sourceCodeInfo; 188133eb0b6dSopenharmony_ci} 188233eb0b6dSopenharmony_ci 188333eb0b6dSopenharmony_civoid ArkNativeEngine::TriggerFatalException(panda::Local<panda::JSValueRef> exceptionValue) 188433eb0b6dSopenharmony_ci{ 188533eb0b6dSopenharmony_ci panda::JSNApi::ThrowException(GetEcmaVm(), exceptionValue); 188633eb0b6dSopenharmony_ci HandleUncaughtException(); 188733eb0b6dSopenharmony_ci} 188833eb0b6dSopenharmony_ci 188933eb0b6dSopenharmony_cibool ArkNativeEngine::AdjustExternalMemory(int64_t ChangeInBytes, int64_t* AdjustedValue) 189033eb0b6dSopenharmony_ci{ 189133eb0b6dSopenharmony_ci return true; 189233eb0b6dSopenharmony_ci} 189333eb0b6dSopenharmony_ci 189433eb0b6dSopenharmony_civoid ArkNativeEngine::SetPromiseRejectCallback(NativeReference* rejectCallbackRef, NativeReference* checkCallbackRef) 189533eb0b6dSopenharmony_ci{ 189633eb0b6dSopenharmony_ci if (rejectCallbackRef == nullptr || checkCallbackRef == nullptr) { 189733eb0b6dSopenharmony_ci HILOG_ERROR("rejectCallbackRef or checkCallbackRef is nullptr"); 189833eb0b6dSopenharmony_ci return; 189933eb0b6dSopenharmony_ci } 190033eb0b6dSopenharmony_ci promiseRejectCallbackRef_ = rejectCallbackRef; 190133eb0b6dSopenharmony_ci checkCallbackRef_ = checkCallbackRef; 190233eb0b6dSopenharmony_ci JSNApi::SetHostPromiseRejectionTracker(vm_, reinterpret_cast<void*>(PromiseRejectCallback), 190333eb0b6dSopenharmony_ci reinterpret_cast<void*>(this)); 190433eb0b6dSopenharmony_ci} 190533eb0b6dSopenharmony_ci 190633eb0b6dSopenharmony_civoid ArkNativeEngine::PromiseRejectCallback(void* info) 190733eb0b6dSopenharmony_ci{ 190833eb0b6dSopenharmony_ci panda::PromiseRejectInfo* promiseRejectInfo = reinterpret_cast<panda::PromiseRejectInfo*>(info); 190933eb0b6dSopenharmony_ci ArkNativeEngine* env = reinterpret_cast<ArkNativeEngine*>(promiseRejectInfo->GetData()); 191033eb0b6dSopenharmony_ci 191133eb0b6dSopenharmony_ci if (env == nullptr) { 191233eb0b6dSopenharmony_ci HILOG_ERROR("engine is nullptr"); 191333eb0b6dSopenharmony_ci return; 191433eb0b6dSopenharmony_ci } 191533eb0b6dSopenharmony_ci 191633eb0b6dSopenharmony_ci if (env->promiseRejectCallbackRef_ == nullptr || env->checkCallbackRef_ == nullptr) { 191733eb0b6dSopenharmony_ci HILOG_ERROR("promiseRejectCallbackRef or checkCallbackRef is nullptr"); 191833eb0b6dSopenharmony_ci return; 191933eb0b6dSopenharmony_ci } 192033eb0b6dSopenharmony_ci panda::ecmascript::EcmaVM* vm = const_cast<EcmaVM*>(env->GetEcmaVm()); 192133eb0b6dSopenharmony_ci LocalScope scope(vm); 192233eb0b6dSopenharmony_ci Local<JSValueRef> promise = promiseRejectInfo->GetPromise(); 192333eb0b6dSopenharmony_ci Local<JSValueRef> reason = promiseRejectInfo->GetReason(); 192433eb0b6dSopenharmony_ci panda::PromiseRejectInfo::PROMISE_REJECTION_EVENT operation = promiseRejectInfo->GetOperation(); 192533eb0b6dSopenharmony_ci 192633eb0b6dSopenharmony_ci Local<JSValueRef> type(IntegerRef::New(vm, static_cast<int32_t>(operation))); 192733eb0b6dSopenharmony_ci 192833eb0b6dSopenharmony_ci Local<JSValueRef> args[] = {type, promise, reason}; 192933eb0b6dSopenharmony_ci 193033eb0b6dSopenharmony_ci napi_value promiseNapiRejectCallback = env->promiseRejectCallbackRef_->Get(env); 193133eb0b6dSopenharmony_ci Local<FunctionRef> promiseRejectCallback = LocalValueFromJsValue(promiseNapiRejectCallback); 193233eb0b6dSopenharmony_ci if (!promiseRejectCallback.IsEmpty()) { 193333eb0b6dSopenharmony_ci promiseRejectCallback->Call(vm, JSValueRef::Undefined(vm), args, 3); // 3 args size 193433eb0b6dSopenharmony_ci } 193533eb0b6dSopenharmony_ci 193633eb0b6dSopenharmony_ci if (operation == panda::PromiseRejectInfo::PROMISE_REJECTION_EVENT::REJECT) { 193733eb0b6dSopenharmony_ci Local<JSValueRef> checkCallback = LocalValueFromJsValue(env->checkCallbackRef_->Get(env)); 193833eb0b6dSopenharmony_ci if (!checkCallback.IsEmpty()) { 193933eb0b6dSopenharmony_ci JSNApi::SetHostEnqueueJob(vm, checkCallback, panda::QueueType::QUEUE_SCRIPT); 194033eb0b6dSopenharmony_ci } 194133eb0b6dSopenharmony_ci } 194233eb0b6dSopenharmony_ci} 194333eb0b6dSopenharmony_ci 194433eb0b6dSopenharmony_civoid ArkNativeEngine::DumpHeapSnapshot(const std::string& path, bool isVmMode, DumpFormat dumpFormat, 194533eb0b6dSopenharmony_ci bool isPrivate, bool captureNumericValue) 194633eb0b6dSopenharmony_ci{ 194733eb0b6dSopenharmony_ci panda::ecmascript::DumpSnapShotOption dumpOption; 194833eb0b6dSopenharmony_ci dumpOption.isVmMode = isVmMode; 194933eb0b6dSopenharmony_ci dumpOption.isSync = true; 195033eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::JSON) { 195133eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::JSON; 195233eb0b6dSopenharmony_ci dumpOption.isPrivate = isPrivate; 195333eb0b6dSopenharmony_ci dumpOption.captureNumericValue = captureNumericValue; 195433eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, path, dumpOption); 195533eb0b6dSopenharmony_ci } 195633eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::BINARY) { 195733eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::BINARY; 195833eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, path, dumpOption); 195933eb0b6dSopenharmony_ci } 196033eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::OTHER) { 196133eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::OTHER; 196233eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, path, dumpOption); // 2:enum is 2 196333eb0b6dSopenharmony_ci } 196433eb0b6dSopenharmony_ci} 196533eb0b6dSopenharmony_ci 196633eb0b6dSopenharmony_civoid ArkNativeEngine::DumpCpuProfile() 196733eb0b6dSopenharmony_ci{ 196833eb0b6dSopenharmony_ci DFXJSNApi::DumpCpuProfile(vm_); 196933eb0b6dSopenharmony_ci} 197033eb0b6dSopenharmony_ci 197133eb0b6dSopenharmony_civoid ArkNativeEngine::DumpHeapSnapshot(bool isVmMode, DumpFormat dumpFormat, bool isPrivate, bool isFullGC) 197233eb0b6dSopenharmony_ci{ 197333eb0b6dSopenharmony_ci panda::ecmascript::DumpSnapShotOption dumpOption; 197433eb0b6dSopenharmony_ci dumpOption.isVmMode = isVmMode; 197533eb0b6dSopenharmony_ci dumpOption.isPrivate = isPrivate; 197633eb0b6dSopenharmony_ci dumpOption.isFullGC = isFullGC; 197733eb0b6dSopenharmony_ci dumpOption.isSync = false; 197833eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::JSON) { 197933eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::JSON; 198033eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, dumpOption); 198133eb0b6dSopenharmony_ci } 198233eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::BINARY) { 198333eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::BINARY; 198433eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, dumpOption); 198533eb0b6dSopenharmony_ci } 198633eb0b6dSopenharmony_ci if (dumpFormat == DumpFormat::OTHER) { 198733eb0b6dSopenharmony_ci dumpOption.dumpFormat = panda::ecmascript::DumpFormat::OTHER; 198833eb0b6dSopenharmony_ci DFXJSNApi::DumpHeapSnapshot(vm_, dumpOption); 198933eb0b6dSopenharmony_ci } 199033eb0b6dSopenharmony_ci} 199133eb0b6dSopenharmony_ci 199233eb0b6dSopenharmony_cibool ArkNativeEngine::BuildNativeAndJsStackTrace(std::string& stackTraceStr) 199333eb0b6dSopenharmony_ci{ 199433eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 199533eb0b6dSopenharmony_ci return DFXJSNApi::BuildNativeAndJsStackTrace(vm_, stackTraceStr); 199633eb0b6dSopenharmony_ci#else 199733eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 199833eb0b6dSopenharmony_ci return false; 199933eb0b6dSopenharmony_ci#endif 200033eb0b6dSopenharmony_ci} 200133eb0b6dSopenharmony_ci 200233eb0b6dSopenharmony_cibool ArkNativeEngine::BuildJsStackTrace(std::string& stackTraceStr) 200333eb0b6dSopenharmony_ci{ 200433eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 200533eb0b6dSopenharmony_ci return DFXJSNApi::BuildJsStackTrace(vm_, stackTraceStr); 200633eb0b6dSopenharmony_ci#else 200733eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 200833eb0b6dSopenharmony_ci return false; 200933eb0b6dSopenharmony_ci#endif 201033eb0b6dSopenharmony_ci} 201133eb0b6dSopenharmony_ci 201233eb0b6dSopenharmony_cibool ArkNativeEngine::BuildJsStackInfoListWithCustomDepth(std::vector<JsFrameInfo>& jsFrames) 201333eb0b6dSopenharmony_ci{ 201433eb0b6dSopenharmony_ci#if !defined(PREVIEW) && !defined(IOS_PLATFORM) 201533eb0b6dSopenharmony_ci bool sign = DFXJSNApi::BuildJsStackInfoList(vm_, gettid(), jsFrames); 201633eb0b6dSopenharmony_ci return sign; 201733eb0b6dSopenharmony_ci#else 201833eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 201933eb0b6dSopenharmony_ci return false; 202033eb0b6dSopenharmony_ci#endif 202133eb0b6dSopenharmony_ci} 202233eb0b6dSopenharmony_ci 202333eb0b6dSopenharmony_cibool ArkNativeEngine::DeleteWorker(NativeEngine* workerEngine) 202433eb0b6dSopenharmony_ci{ 202533eb0b6dSopenharmony_ci if (workerEngine != nullptr) { 202633eb0b6dSopenharmony_ci#if !defined(PREVIEW) 202733eb0b6dSopenharmony_ci const panda::ecmascript::EcmaVM* workerVM = reinterpret_cast<ArkNativeEngine*>(workerEngine)->GetEcmaVm(); 202833eb0b6dSopenharmony_ci if (workerVM != nullptr) { 202933eb0b6dSopenharmony_ci return panda::JSNApi::DeleteWorker(vm_, const_cast<EcmaVM*>(workerVM)); 203033eb0b6dSopenharmony_ci } 203133eb0b6dSopenharmony_ci#else 203233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 203333eb0b6dSopenharmony_ci#endif 203433eb0b6dSopenharmony_ci return false; 203533eb0b6dSopenharmony_ci } 203633eb0b6dSopenharmony_ci return false; 203733eb0b6dSopenharmony_ci} 203833eb0b6dSopenharmony_ci 203933eb0b6dSopenharmony_cibool ArkNativeEngine::StartHeapTracking(double timeInterval, bool isVmMode) 204033eb0b6dSopenharmony_ci{ 204133eb0b6dSopenharmony_ci return DFXJSNApi::StartHeapTracking(vm_, timeInterval, isVmMode); 204233eb0b6dSopenharmony_ci} 204333eb0b6dSopenharmony_ci 204433eb0b6dSopenharmony_cibool ArkNativeEngine::StopHeapTracking(const std::string &filePath) 204533eb0b6dSopenharmony_ci{ 204633eb0b6dSopenharmony_ci return DFXJSNApi::StopHeapTracking(vm_, filePath); 204733eb0b6dSopenharmony_ci} 204833eb0b6dSopenharmony_ci 204933eb0b6dSopenharmony_ci#if !defined(PREVIEW) 205033eb0b6dSopenharmony_civoid ArkNativeEngine::PrintStatisticResult() 205133eb0b6dSopenharmony_ci{ 205233eb0b6dSopenharmony_ci DFXJSNApi::PrintStatisticResult(vm_); 205333eb0b6dSopenharmony_ci} 205433eb0b6dSopenharmony_ci 205533eb0b6dSopenharmony_civoid ArkNativeEngine::StartRuntimeStat() 205633eb0b6dSopenharmony_ci{ 205733eb0b6dSopenharmony_ci DFXJSNApi::StartRuntimeStat(vm_); 205833eb0b6dSopenharmony_ci} 205933eb0b6dSopenharmony_ci 206033eb0b6dSopenharmony_civoid ArkNativeEngine::StopRuntimeStat() 206133eb0b6dSopenharmony_ci{ 206233eb0b6dSopenharmony_ci DFXJSNApi::StopRuntimeStat(vm_); 206333eb0b6dSopenharmony_ci} 206433eb0b6dSopenharmony_ci 206533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetArrayBufferSize() 206633eb0b6dSopenharmony_ci{ 206733eb0b6dSopenharmony_ci return DFXJSNApi::GetArrayBufferSize(vm_); 206833eb0b6dSopenharmony_ci} 206933eb0b6dSopenharmony_ci 207033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapTotalSize() 207133eb0b6dSopenharmony_ci{ 207233eb0b6dSopenharmony_ci return DFXJSNApi::GetHeapTotalSize(vm_); 207333eb0b6dSopenharmony_ci} 207433eb0b6dSopenharmony_ci 207533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapUsedSize() 207633eb0b6dSopenharmony_ci{ 207733eb0b6dSopenharmony_ci return DFXJSNApi::GetHeapUsedSize(vm_); 207833eb0b6dSopenharmony_ci} 207933eb0b6dSopenharmony_ci 208033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapObjectSize() 208133eb0b6dSopenharmony_ci{ 208233eb0b6dSopenharmony_ci return DFXJSNApi::GetHeapObjectSize(vm_); 208333eb0b6dSopenharmony_ci} 208433eb0b6dSopenharmony_ci 208533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapLimitSize() 208633eb0b6dSopenharmony_ci{ 208733eb0b6dSopenharmony_ci return DFXJSNApi::GetHeapLimitSize(vm_); 208833eb0b6dSopenharmony_ci} 208933eb0b6dSopenharmony_ci 209033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetProcessHeapLimitSize() 209133eb0b6dSopenharmony_ci{ 209233eb0b6dSopenharmony_ci return DFXJSNApi::GetProcessHeapLimitSize(); 209333eb0b6dSopenharmony_ci} 209433eb0b6dSopenharmony_ci 209533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetGCCount() 209633eb0b6dSopenharmony_ci{ 209733eb0b6dSopenharmony_ci return DFXJSNApi::GetGCCount(vm_); 209833eb0b6dSopenharmony_ci} 209933eb0b6dSopenharmony_ci 210033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetGCDuration() 210133eb0b6dSopenharmony_ci{ 210233eb0b6dSopenharmony_ci return DFXJSNApi::GetGCDuration(vm_); 210333eb0b6dSopenharmony_ci} 210433eb0b6dSopenharmony_ci 210533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetAccumulatedAllocateSize() 210633eb0b6dSopenharmony_ci{ 210733eb0b6dSopenharmony_ci return DFXJSNApi::GetAccumulatedAllocateSize(vm_); 210833eb0b6dSopenharmony_ci} 210933eb0b6dSopenharmony_ci 211033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetAccumulatedFreeSize() 211133eb0b6dSopenharmony_ci{ 211233eb0b6dSopenharmony_ci return DFXJSNApi::GetAccumulatedFreeSize(vm_); 211333eb0b6dSopenharmony_ci} 211433eb0b6dSopenharmony_ci 211533eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetFullGCLongTimeCount() 211633eb0b6dSopenharmony_ci{ 211733eb0b6dSopenharmony_ci return DFXJSNApi::GetFullGCLongTimeCount(vm_); 211833eb0b6dSopenharmony_ci} 211933eb0b6dSopenharmony_ci 212033eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyApplicationState(bool inBackground) 212133eb0b6dSopenharmony_ci{ 212233eb0b6dSopenharmony_ci DFXJSNApi::NotifyApplicationState(vm_, inBackground); 212333eb0b6dSopenharmony_ci arkIdleMonitor_->NotifyChangeBackgroundState(inBackground); 212433eb0b6dSopenharmony_ci} 212533eb0b6dSopenharmony_ci 212633eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyIdleStatusControl(std::function<void(bool)> callback) 212733eb0b6dSopenharmony_ci{ 212833eb0b6dSopenharmony_ci DFXJSNApi::NotifyIdleStatusControl(vm_, callback); 212933eb0b6dSopenharmony_ci} 213033eb0b6dSopenharmony_ci 213133eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyIdleTime(int idleMicroSec) 213233eb0b6dSopenharmony_ci{ 213333eb0b6dSopenharmony_ci DFXJSNApi::NotifyIdleTime(vm_, idleMicroSec); 213433eb0b6dSopenharmony_ci} 213533eb0b6dSopenharmony_ci 213633eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyMemoryPressure(bool inHighMemoryPressure) 213733eb0b6dSopenharmony_ci{ 213833eb0b6dSopenharmony_ci DFXJSNApi::NotifyMemoryPressure(vm_, inHighMemoryPressure); 213933eb0b6dSopenharmony_ci} 214033eb0b6dSopenharmony_ci 214133eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyForceExpandState(int32_t value) 214233eb0b6dSopenharmony_ci{ 214333eb0b6dSopenharmony_ci switch (ForceExpandState(value)) { 214433eb0b6dSopenharmony_ci case ForceExpandState::FINISH_COLD_START: 214533eb0b6dSopenharmony_ci DFXJSNApi::NotifyFinishColdStart(vm_, true); 214633eb0b6dSopenharmony_ci break; 214733eb0b6dSopenharmony_ci case ForceExpandState::START_HIGH_SENSITIVE: 214833eb0b6dSopenharmony_ci DFXJSNApi::NotifyHighSensitive(vm_, true); 214933eb0b6dSopenharmony_ci break; 215033eb0b6dSopenharmony_ci case ForceExpandState::FINISH_HIGH_SENSITIVE: 215133eb0b6dSopenharmony_ci DFXJSNApi::NotifyHighSensitive(vm_, false); 215233eb0b6dSopenharmony_ci break; 215333eb0b6dSopenharmony_ci default: 215433eb0b6dSopenharmony_ci HILOG_ERROR("Invalid Force Expand State: %{public}d.", value); 215533eb0b6dSopenharmony_ci break; 215633eb0b6dSopenharmony_ci } 215733eb0b6dSopenharmony_ci} 215833eb0b6dSopenharmony_ci#else 215933eb0b6dSopenharmony_civoid ArkNativeEngine::PrintStatisticResult() 216033eb0b6dSopenharmony_ci{ 216133eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 216233eb0b6dSopenharmony_ci} 216333eb0b6dSopenharmony_ci 216433eb0b6dSopenharmony_civoid ArkNativeEngine::StartRuntimeStat() 216533eb0b6dSopenharmony_ci{ 216633eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 216733eb0b6dSopenharmony_ci} 216833eb0b6dSopenharmony_ci 216933eb0b6dSopenharmony_civoid ArkNativeEngine::StopRuntimeStat() 217033eb0b6dSopenharmony_ci{ 217133eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 217233eb0b6dSopenharmony_ci} 217333eb0b6dSopenharmony_ci 217433eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetArrayBufferSize() 217533eb0b6dSopenharmony_ci{ 217633eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 217733eb0b6dSopenharmony_ci return 0; 217833eb0b6dSopenharmony_ci} 217933eb0b6dSopenharmony_ci 218033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapTotalSize() 218133eb0b6dSopenharmony_ci{ 218233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 218333eb0b6dSopenharmony_ci return 0; 218433eb0b6dSopenharmony_ci} 218533eb0b6dSopenharmony_ci 218633eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapUsedSize() 218733eb0b6dSopenharmony_ci{ 218833eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 218933eb0b6dSopenharmony_ci return 0; 219033eb0b6dSopenharmony_ci} 219133eb0b6dSopenharmony_ci 219233eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapObjectSize() 219333eb0b6dSopenharmony_ci{ 219433eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 219533eb0b6dSopenharmony_ci return 0; 219633eb0b6dSopenharmony_ci} 219733eb0b6dSopenharmony_ci 219833eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetHeapLimitSize() 219933eb0b6dSopenharmony_ci{ 220033eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 220133eb0b6dSopenharmony_ci return 0; 220233eb0b6dSopenharmony_ci} 220333eb0b6dSopenharmony_ci 220433eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetProcessHeapLimitSize() 220533eb0b6dSopenharmony_ci{ 220633eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 220733eb0b6dSopenharmony_ci return 0; 220833eb0b6dSopenharmony_ci} 220933eb0b6dSopenharmony_ci 221033eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetGCCount() 221133eb0b6dSopenharmony_ci{ 221233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 221333eb0b6dSopenharmony_ci return 0; 221433eb0b6dSopenharmony_ci} 221533eb0b6dSopenharmony_ci 221633eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetGCDuration() 221733eb0b6dSopenharmony_ci{ 221833eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 221933eb0b6dSopenharmony_ci return 0; 222033eb0b6dSopenharmony_ci} 222133eb0b6dSopenharmony_ci 222233eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetAccumulatedAllocateSize() 222333eb0b6dSopenharmony_ci{ 222433eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 222533eb0b6dSopenharmony_ci return 0; 222633eb0b6dSopenharmony_ci} 222733eb0b6dSopenharmony_ci 222833eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetAccumulatedFreeSize() 222933eb0b6dSopenharmony_ci{ 223033eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 223133eb0b6dSopenharmony_ci return 0; 223233eb0b6dSopenharmony_ci} 223333eb0b6dSopenharmony_ci 223433eb0b6dSopenharmony_cisize_t ArkNativeEngine::GetFullGCLongTimeCount() 223533eb0b6dSopenharmony_ci{ 223633eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 223733eb0b6dSopenharmony_ci return 0; 223833eb0b6dSopenharmony_ci} 223933eb0b6dSopenharmony_ci 224033eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyApplicationState([[maybe_unused]] bool inBackground) 224133eb0b6dSopenharmony_ci{ 224233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 224333eb0b6dSopenharmony_ci} 224433eb0b6dSopenharmony_ci 224533eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyIdleStatusControl([[maybe_unused]] std::function<void(bool)> callback) 224633eb0b6dSopenharmony_ci{ 224733eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 224833eb0b6dSopenharmony_ci} 224933eb0b6dSopenharmony_ci 225033eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyIdleTime([[maybe_unused]] int idleMicroSec) 225133eb0b6dSopenharmony_ci{ 225233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 225333eb0b6dSopenharmony_ci} 225433eb0b6dSopenharmony_ci 225533eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyMemoryPressure([[maybe_unused]] bool inHighMemoryPressure) 225633eb0b6dSopenharmony_ci{ 225733eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 225833eb0b6dSopenharmony_ci} 225933eb0b6dSopenharmony_ci 226033eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyForceExpandState([[maybe_unused]] int32_t value) 226133eb0b6dSopenharmony_ci{ 226233eb0b6dSopenharmony_ci HILOG_WARN("ARK does not support dfx on windows"); 226333eb0b6dSopenharmony_ci} 226433eb0b6dSopenharmony_ci#endif 226533eb0b6dSopenharmony_ci 226633eb0b6dSopenharmony_civoid ArkNativeEngine::SetMockModuleList(const std::map<std::string, std::string> &list) 226733eb0b6dSopenharmony_ci{ 226833eb0b6dSopenharmony_ci JSNApi::SetMockModuleList(vm_, list); 226933eb0b6dSopenharmony_ci} 227033eb0b6dSopenharmony_ci 227133eb0b6dSopenharmony_civoid ArkNativeEngine::RegisterNapiUncaughtExceptionHandler(NapiUncaughtExceptionCallback callback) 227233eb0b6dSopenharmony_ci{ 227333eb0b6dSopenharmony_ci JSNApi::EnableUserUncaughtErrorHandler(vm_); 227433eb0b6dSopenharmony_ci napiUncaughtExceptionCallback_ = callback; 227533eb0b6dSopenharmony_ci} 227633eb0b6dSopenharmony_ci 227733eb0b6dSopenharmony_civoid ArkNativeEngine::HandleUncaughtException() 227833eb0b6dSopenharmony_ci{ 227933eb0b6dSopenharmony_ci if (napiUncaughtExceptionCallback_ == nullptr) { 228033eb0b6dSopenharmony_ci return; 228133eb0b6dSopenharmony_ci } 228233eb0b6dSopenharmony_ci LocalScope scope(vm_); 228333eb0b6dSopenharmony_ci lastException_.Empty(); 228433eb0b6dSopenharmony_ci Local<ObjectRef> exception = JSNApi::GetAndClearUncaughtException(vm_); 228533eb0b6dSopenharmony_ci if (!exception.IsEmpty() && !exception->IsHole()) { 228633eb0b6dSopenharmony_ci if (napiUncaughtExceptionCallback_ != nullptr) { 228733eb0b6dSopenharmony_ci napiUncaughtExceptionCallback_(ArkValueToNapiValue(reinterpret_cast<napi_env>(this), exception)); 228833eb0b6dSopenharmony_ci } 228933eb0b6dSopenharmony_ci } 229033eb0b6dSopenharmony_ci} 229133eb0b6dSopenharmony_ci 229233eb0b6dSopenharmony_cibool ArkNativeEngine::HasPendingException() 229333eb0b6dSopenharmony_ci{ 229433eb0b6dSopenharmony_ci return panda::JSNApi::HasPendingException(vm_); 229533eb0b6dSopenharmony_ci} 229633eb0b6dSopenharmony_ci 229733eb0b6dSopenharmony_civoid ArkNativeEngine::RegisterPermissionCheck(PermissionCheckCallback callback) 229833eb0b6dSopenharmony_ci{ 229933eb0b6dSopenharmony_ci if (permissionCheckCallback_ == nullptr) { 230033eb0b6dSopenharmony_ci permissionCheckCallback_ = callback; 230133eb0b6dSopenharmony_ci } 230233eb0b6dSopenharmony_ci} 230333eb0b6dSopenharmony_ci 230433eb0b6dSopenharmony_cibool ArkNativeEngine::ExecutePermissionCheck() 230533eb0b6dSopenharmony_ci{ 230633eb0b6dSopenharmony_ci if (permissionCheckCallback_ != nullptr) { 230733eb0b6dSopenharmony_ci return permissionCheckCallback_(); 230833eb0b6dSopenharmony_ci } else { 230933eb0b6dSopenharmony_ci HILOG_INFO("permissionCheckCallback_ is still nullptr when executing permission check!"); 231033eb0b6dSopenharmony_ci return true; 231133eb0b6dSopenharmony_ci } 231233eb0b6dSopenharmony_ci} 231333eb0b6dSopenharmony_ci 231433eb0b6dSopenharmony_civoid ArkNativeEngine::RegisterTranslateBySourceMap(SourceMapCallback callback) 231533eb0b6dSopenharmony_ci{ 231633eb0b6dSopenharmony_ci if (SourceMapCallback_ == nullptr) { 231733eb0b6dSopenharmony_ci SourceMapCallback_ = callback; 231833eb0b6dSopenharmony_ci } 231933eb0b6dSopenharmony_ci // regedit SourceMapCallback to ark_js_runtime 232033eb0b6dSopenharmony_ci panda::JSNApi::SetSourceMapCallback(vm_, callback); 232133eb0b6dSopenharmony_ci} 232233eb0b6dSopenharmony_ci 232333eb0b6dSopenharmony_civoid ArkNativeEngine::RegisterSourceMapTranslateCallback(SourceMapTranslateCallback callback) 232433eb0b6dSopenharmony_ci{ 232533eb0b6dSopenharmony_ci panda::JSNApi::SetSourceMapTranslateCallback(vm_, callback); 232633eb0b6dSopenharmony_ci} 232733eb0b6dSopenharmony_ci 232833eb0b6dSopenharmony_cistd::string ArkNativeEngine::ExecuteTranslateBySourceMap(const std::string& rawStack) 232933eb0b6dSopenharmony_ci{ 233033eb0b6dSopenharmony_ci if (SourceMapCallback_ != nullptr) { 233133eb0b6dSopenharmony_ci return SourceMapCallback_(rawStack); 233233eb0b6dSopenharmony_ci } else { 233333eb0b6dSopenharmony_ci HILOG_WARN("SourceMapCallback_ is nullptr."); 233433eb0b6dSopenharmony_ci return rawStack; 233533eb0b6dSopenharmony_ci } 233633eb0b6dSopenharmony_ci} 233733eb0b6dSopenharmony_ci 233833eb0b6dSopenharmony_cibool ArkNativeEngine::IsMixedDebugEnabled() 233933eb0b6dSopenharmony_ci{ 234033eb0b6dSopenharmony_ci return JSNApi::IsMixedDebugEnabled(vm_); 234133eb0b6dSopenharmony_ci} 234233eb0b6dSopenharmony_ci 234333eb0b6dSopenharmony_civoid ArkNativeEngine::NotifyNativeCalling(const void *nativeAddress) 234433eb0b6dSopenharmony_ci{ 234533eb0b6dSopenharmony_ci JSNApi::NotifyNativeCalling(vm_, nativeAddress); 234633eb0b6dSopenharmony_ci} 234733eb0b6dSopenharmony_ci 234833eb0b6dSopenharmony_civoid ArkNativeEngine::AllowCrossThreadExecution() const 234933eb0b6dSopenharmony_ci{ 235033eb0b6dSopenharmony_ci JSNApi::AllowCrossThreadExecution(vm_); 235133eb0b6dSopenharmony_ci} 235233eb0b6dSopenharmony_ci 235333eb0b6dSopenharmony_ci#if !defined(is_arkui_x) && defined(OHOS_PLATFORM) 235433eb0b6dSopenharmony_cistd::string DumpHybridStack(const EcmaVM* vm) 235533eb0b6dSopenharmony_ci{ 235633eb0b6dSopenharmony_ci constexpr size_t skipframes = 5; 235733eb0b6dSopenharmony_ci auto unwinder = std::make_shared<OHOS::HiviewDFX::Unwinder>(); 235833eb0b6dSopenharmony_ci std::vector<OHOS::HiviewDFX::DfxFrame> frames; 235933eb0b6dSopenharmony_ci unwinder->EnableMethodIdLocal(true); 236033eb0b6dSopenharmony_ci if (unwinder->UnwindLocal(false, false, DEFAULT_MAX_FRAME_NUM, skipframes)) { 236133eb0b6dSopenharmony_ci frames = unwinder->GetFrames(); 236233eb0b6dSopenharmony_ci } else { 236333eb0b6dSopenharmony_ci HILOG_ERROR("Failed to unwind local"); 236433eb0b6dSopenharmony_ci } 236533eb0b6dSopenharmony_ci 236633eb0b6dSopenharmony_ci for (auto &frame : frames) { 236733eb0b6dSopenharmony_ci if (frame.isJsFrame) { 236833eb0b6dSopenharmony_ci DFXJSNApi::TranslateJSStackInfo(vm, frame.mapName, frame.line, frame.column); 236933eb0b6dSopenharmony_ci } 237033eb0b6dSopenharmony_ci } 237133eb0b6dSopenharmony_ci 237233eb0b6dSopenharmony_ci return OHOS::HiviewDFX::Unwinder::GetFramesStr(frames); 237333eb0b6dSopenharmony_ci} 237433eb0b6dSopenharmony_ci#endif 237533eb0b6dSopenharmony_ci 237633eb0b6dSopenharmony_civoid ArkNativeEngine::PostLooperTriggerIdleGCTask() 237733eb0b6dSopenharmony_ci{ 237833eb0b6dSopenharmony_ci#if defined(ENABLE_EVENT_HANDLER) 237933eb0b6dSopenharmony_ci std::shared_ptr<OHOS::AppExecFwk::EventRunner> mainThreadRunner = 238033eb0b6dSopenharmony_ci OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); 238133eb0b6dSopenharmony_ci if (mainThreadRunner.get() == nullptr) { 238233eb0b6dSopenharmony_ci HILOG_FATAL("ArkNativeEngine:: the mainEventRunner is nullptr"); 238333eb0b6dSopenharmony_ci return; 238433eb0b6dSopenharmony_ci } 238533eb0b6dSopenharmony_ci auto callback = [this](OHOS::AppExecFwk::EventRunnerStage stage, 238633eb0b6dSopenharmony_ci const OHOS::AppExecFwk::StageInfo* info) -> int { 238733eb0b6dSopenharmony_ci switch (stage) { 238833eb0b6dSopenharmony_ci case OHOS::AppExecFwk::EventRunnerStage::STAGE_BEFORE_WAITING: 238933eb0b6dSopenharmony_ci arkIdleMonitor_->NotifyLooperIdleStart(info->timestamp, info->sleepTime); 239033eb0b6dSopenharmony_ci break; 239133eb0b6dSopenharmony_ci case OHOS::AppExecFwk::EventRunnerStage::STAGE_AFTER_WAITING: 239233eb0b6dSopenharmony_ci arkIdleMonitor_->NotifyLooperIdleEnd(info->timestamp); 239333eb0b6dSopenharmony_ci break; 239433eb0b6dSopenharmony_ci default: 239533eb0b6dSopenharmony_ci HILOG_ERROR("this branch is unreachable"); 239633eb0b6dSopenharmony_ci } 239733eb0b6dSopenharmony_ci return 0; 239833eb0b6dSopenharmony_ci }; 239933eb0b6dSopenharmony_ci uint32_t stage = (static_cast<uint32_t>(OHOS::AppExecFwk::EventRunnerStage::STAGE_BEFORE_WAITING) | 240033eb0b6dSopenharmony_ci static_cast<uint32_t>(OHOS::AppExecFwk::EventRunnerStage::STAGE_AFTER_WAITING)); 240133eb0b6dSopenharmony_ci mainThreadRunner->GetEventQueue()->AddObserver(OHOS::AppExecFwk::Observer::ARKTS_GC, stage, callback); 240233eb0b6dSopenharmony_ci#endif 240333eb0b6dSopenharmony_ci} 240433eb0b6dSopenharmony_ci 240533eb0b6dSopenharmony_ciint32_t ArkNativeEngine::GetObjectHash(napi_env env, napi_value src) 240633eb0b6dSopenharmony_ci{ 240733eb0b6dSopenharmony_ci auto engine = reinterpret_cast<NativeEngine*>(env); 240833eb0b6dSopenharmony_ci auto vm = engine->GetEcmaVm(); 240933eb0b6dSopenharmony_ci auto nativeValue = LocalValueFromJsValue(src); 241033eb0b6dSopenharmony_ci return DFXJSNApi::GetObjectHash(vm, nativeValue); 241133eb0b6dSopenharmony_ci} 241233eb0b6dSopenharmony_ci// LCOV_EXCL_STOP 241333eb0b6dSopenharmony_ci 241433eb0b6dSopenharmony_cibool ArkNativeEngine::RunScriptPath(const char* path, bool checkPath) 241533eb0b6dSopenharmony_ci{ 241633eb0b6dSopenharmony_ci if (checkPath && !IsValidPandaFile(path)) { 241733eb0b6dSopenharmony_ci HILOG_ERROR("file is not exist or format is invalid"); 241833eb0b6dSopenharmony_ci return false; 241933eb0b6dSopenharmony_ci } 242033eb0b6dSopenharmony_ci // LCOV_EXCL_START 242133eb0b6dSopenharmony_ci panda::JSExecutionScope executionScope(vm_); 242233eb0b6dSopenharmony_ci LocalScope scope(vm_); 242333eb0b6dSopenharmony_ci [[maybe_unused]] bool ret = panda::JSNApi::Execute(vm_, path, PANDA_MAIN_FUNCTION); 242433eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 242533eb0b6dSopenharmony_ci HandleUncaughtException(); 242633eb0b6dSopenharmony_ci return false; 242733eb0b6dSopenharmony_ci } 242833eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 242933eb0b6dSopenharmony_ci return true; 243033eb0b6dSopenharmony_ci} 243133eb0b6dSopenharmony_ci 243233eb0b6dSopenharmony_cibool ArkNativeEngine::IsValidPandaFile(const char* path) 243333eb0b6dSopenharmony_ci{ 243433eb0b6dSopenharmony_ci if (path == nullptr) { 243533eb0b6dSopenharmony_ci HILOG_ERROR("file path is nullptr"); 243633eb0b6dSopenharmony_ci return false; 243733eb0b6dSopenharmony_ci } 243833eb0b6dSopenharmony_ci 243933eb0b6dSopenharmony_ci char filePath[PATH_MAX + 1] = { 0 }; 244033eb0b6dSopenharmony_ci if (!RealPath(path, filePath, PATH_MAX + 1)) { 244133eb0b6dSopenharmony_ci HILOG_ERROR("failed to format path"); 244233eb0b6dSopenharmony_ci return false; 244333eb0b6dSopenharmony_ci } 244433eb0b6dSopenharmony_ci struct stat fileStat; 244533eb0b6dSopenharmony_ci int ret = stat(filePath, &fileStat); 244633eb0b6dSopenharmony_ci if (ret != 0) { 244733eb0b6dSopenharmony_ci HILOG_ERROR("script file \"%{public}s\" is not exist", filePath); 244833eb0b6dSopenharmony_ci return false; 244933eb0b6dSopenharmony_ci } 245033eb0b6dSopenharmony_ci 245133eb0b6dSopenharmony_ci if (!(fileStat.st_mode & S_IFREG)) { 245233eb0b6dSopenharmony_ci HILOG_ERROR("script path \"%{public}s\" is a directory", filePath); 245333eb0b6dSopenharmony_ci return false; 245433eb0b6dSopenharmony_ci } 245533eb0b6dSopenharmony_ci std::ifstream abcStream(filePath, std::ios::in | std::ios::binary); 245633eb0b6dSopenharmony_ci 245733eb0b6dSopenharmony_ci constexpr size_t fileHeaderLength = sizeof(uint64_t); 245833eb0b6dSopenharmony_ci uint8_t fileHeader[fileHeaderLength] = { 0 }; 245933eb0b6dSopenharmony_ci if (abcStream.is_open()) { 246033eb0b6dSopenharmony_ci size_t fileSize = fileStat.st_size; 246133eb0b6dSopenharmony_ci if (fileSize < fileHeaderLength) { 246233eb0b6dSopenharmony_ci HILOG_ERROR("faild to read file header, invalid format \"%{public}s\"", filePath); 246333eb0b6dSopenharmony_ci abcStream.close(); 246433eb0b6dSopenharmony_ci return false; 246533eb0b6dSopenharmony_ci } 246633eb0b6dSopenharmony_ci abcStream.read(reinterpret_cast<char*>(fileHeader), fileHeaderLength); 246733eb0b6dSopenharmony_ci abcStream.close(); 246833eb0b6dSopenharmony_ci return IsValidScriptBuffer(fileHeader, fileHeaderLength); 246933eb0b6dSopenharmony_ci } 247033eb0b6dSopenharmony_ci return false; 247133eb0b6dSopenharmony_ci} 247233eb0b6dSopenharmony_ci 247333eb0b6dSopenharmony_cibool ArkNativeEngine::IsValidScriptBuffer(uint8_t* scriptBuffer, size_t bufferSize) 247433eb0b6dSopenharmony_ci{ 247533eb0b6dSopenharmony_ci if (scriptBuffer == nullptr) { 247633eb0b6dSopenharmony_ci HILOG_ERROR("buffer is nullptr"); 247733eb0b6dSopenharmony_ci return false; 247833eb0b6dSopenharmony_ci } 247933eb0b6dSopenharmony_ci constexpr size_t headerLen = sizeof(uint64_t); 248033eb0b6dSopenharmony_ci if (bufferSize < headerLen) { 248133eb0b6dSopenharmony_ci HILOG_ERROR("invalid buffer"); 248233eb0b6dSopenharmony_ci return false; 248333eb0b6dSopenharmony_ci } 248433eb0b6dSopenharmony_ci constexpr char pandaFileHeader[headerLen] = "PANDA"; 248533eb0b6dSopenharmony_ci const uint64_t bytePandaHeader = *reinterpret_cast<const uint64_t*>(pandaFileHeader); 248633eb0b6dSopenharmony_ci char fileHeader[headerLen] = { 0 }; 248733eb0b6dSopenharmony_ci // Ensure destMax paramter is set correctly to avoid buffer overflows 248833eb0b6dSopenharmony_ci if (memcpy_s(fileHeader, sizeof(fileHeader), scriptBuffer, sizeof(fileHeader)) != 0) { 248933eb0b6dSopenharmony_ci HILOG_ERROR("faild to read file header of buffer"); 249033eb0b6dSopenharmony_ci return false; 249133eb0b6dSopenharmony_ci } 249233eb0b6dSopenharmony_ci 249333eb0b6dSopenharmony_ci uint64_t byteFileHeader = *reinterpret_cast<uint64_t*>(fileHeader); 249433eb0b6dSopenharmony_ci if (byteFileHeader != bytePandaHeader) { 249533eb0b6dSopenharmony_ci HILOG_ERROR("invalid format of file buffer"); 249633eb0b6dSopenharmony_ci return false; 249733eb0b6dSopenharmony_ci } 249833eb0b6dSopenharmony_ci return true; 249933eb0b6dSopenharmony_ci} 250033eb0b6dSopenharmony_ci 250133eb0b6dSopenharmony_ci// The security interface needs to be modified accordingly. 250233eb0b6dSopenharmony_cinapi_value ArkNativeEngine::RunScriptBuffer(const char* path, std::vector<uint8_t>& buffer, bool isBundle) 250333eb0b6dSopenharmony_ci{ 250433eb0b6dSopenharmony_ci if (!IsValidScriptBuffer(buffer.data(), buffer.size())) { 250533eb0b6dSopenharmony_ci HILOG_ERROR("invalid script buffer"); 250633eb0b6dSopenharmony_ci return nullptr; 250733eb0b6dSopenharmony_ci } 250833eb0b6dSopenharmony_ci 250933eb0b6dSopenharmony_ci // LCOV_EXCL_START 251033eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 251133eb0b6dSopenharmony_ci [[maybe_unused]] bool ret = false; 251233eb0b6dSopenharmony_ci if (isBundle) { 251333eb0b6dSopenharmony_ci ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION, path); 251433eb0b6dSopenharmony_ci } else { 251533eb0b6dSopenharmony_ci ret = panda::JSNApi::ExecuteModuleBuffer(vm_, buffer.data(), buffer.size(), path); 251633eb0b6dSopenharmony_ci } 251733eb0b6dSopenharmony_ci 251833eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 251933eb0b6dSopenharmony_ci HandleUncaughtException(); 252033eb0b6dSopenharmony_ci return nullptr; 252133eb0b6dSopenharmony_ci } 252233eb0b6dSopenharmony_ci Local<JSValueRef> undefObj = JSValueRef::Undefined(vm_); 252333eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 252433eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(undefObj)); 252533eb0b6dSopenharmony_ci} 252633eb0b6dSopenharmony_ci 252733eb0b6dSopenharmony_cibool ArkNativeEngine::RunScriptBuffer(const std::string& path, uint8_t* buffer, size_t size, bool isBundle) 252833eb0b6dSopenharmony_ci{ 252933eb0b6dSopenharmony_ci if (!IsValidScriptBuffer(buffer, size)) { 253033eb0b6dSopenharmony_ci HILOG_ERROR("invalid script buffer"); 253133eb0b6dSopenharmony_ci return false; 253233eb0b6dSopenharmony_ci } 253333eb0b6dSopenharmony_ci 253433eb0b6dSopenharmony_ci // LCOV_EXCL_START 253533eb0b6dSopenharmony_ci panda::JSExecutionScope executionScope(vm_); 253633eb0b6dSopenharmony_ci LocalScope scope(vm_); 253733eb0b6dSopenharmony_ci bool ret = false; 253833eb0b6dSopenharmony_ci if (isBundle) { 253933eb0b6dSopenharmony_ci ret = panda::JSNApi::ExecuteSecure(vm_, buffer, size, PANDA_MAIN_FUNCTION, path); 254033eb0b6dSopenharmony_ci } else { 254133eb0b6dSopenharmony_ci ret = panda::JSNApi::ExecuteModuleBufferSecure(vm_, buffer, size, path); 254233eb0b6dSopenharmony_ci } 254333eb0b6dSopenharmony_ci 254433eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 254533eb0b6dSopenharmony_ci HandleUncaughtException(); 254633eb0b6dSopenharmony_ci return false; 254733eb0b6dSopenharmony_ci } 254833eb0b6dSopenharmony_ci return ret; 254933eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 255033eb0b6dSopenharmony_ci} 255133eb0b6dSopenharmony_ci 255233eb0b6dSopenharmony_cinapi_value ArkNativeEngine::RunBufferScript(std::vector<uint8_t>& buffer) 255333eb0b6dSopenharmony_ci{ 255433eb0b6dSopenharmony_ci if (!IsValidScriptBuffer(buffer.data(), buffer.size())) { 255533eb0b6dSopenharmony_ci HILOG_ERROR("invalid script buffer"); 255633eb0b6dSopenharmony_ci return nullptr; 255733eb0b6dSopenharmony_ci } 255833eb0b6dSopenharmony_ci 255933eb0b6dSopenharmony_ci // LCOV_EXCL_START 256033eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 256133eb0b6dSopenharmony_ci [[maybe_unused]] bool ret = panda::JSNApi::Execute(vm_, buffer.data(), buffer.size(), PANDA_MAIN_FUNCTION); 256233eb0b6dSopenharmony_ci 256333eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 256433eb0b6dSopenharmony_ci HandleUncaughtException(); 256533eb0b6dSopenharmony_ci return nullptr; 256633eb0b6dSopenharmony_ci } 256733eb0b6dSopenharmony_ci Local<JSValueRef> undefObj = JSValueRef::Undefined(vm_); 256833eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(undefObj)); 256933eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 257033eb0b6dSopenharmony_ci} 257133eb0b6dSopenharmony_ci 257233eb0b6dSopenharmony_ci#define EXECUTE_BUFFER(functionName) \ 257333eb0b6dSopenharmony_ci if (panda::JSNApi::IsBundle(vm_)) { \ 257433eb0b6dSopenharmony_ci /* FA doesn't enable securemem */ \ 257533eb0b6dSopenharmony_ci ret = panda::JSNApi::Execute(vm_, buffer, bufferSize, PANDA_MAIN_FUNCTION, desc); \ 257633eb0b6dSopenharmony_ci } else if (bufferSize != 0) { \ 257733eb0b6dSopenharmony_ci if (entryPoint == nullptr) { \ 257833eb0b6dSopenharmony_ci HILOG_DEBUG("Input entryPoint is nullptr, please input entryPoint for merged ESModule"); \ 257933eb0b6dSopenharmony_ci /* this path for bundle and abc compiled by single module js */ \ 258033eb0b6dSopenharmony_ci ret = panda::JSNApi::functionName(vm_, buffer, bufferSize, PANDA_MAIN_FUNCTION, desc); \ 258133eb0b6dSopenharmony_ci } else { \ 258233eb0b6dSopenharmony_ci /* this path for mergeabc with specific entryPoint */ \ 258333eb0b6dSopenharmony_ci ret = panda::JSNApi::functionName(vm_, buffer, bufferSize, entryPoint, desc); \ 258433eb0b6dSopenharmony_ci } \ 258533eb0b6dSopenharmony_ci } else { \ 258633eb0b6dSopenharmony_ci /* this path for worker */ \ 258733eb0b6dSopenharmony_ci ret = panda::JSNApi::Execute(vm_, desc, PANDA_MAIN_FUNCTION); \ 258833eb0b6dSopenharmony_ci } 258933eb0b6dSopenharmony_ci 259033eb0b6dSopenharmony_cinapi_value ArkNativeEngine::RunActor(uint8_t* buffer, size_t bufferSize, 259133eb0b6dSopenharmony_ci const char* descriptor, char* entryPoint, bool checkPath) 259233eb0b6dSopenharmony_ci{ 259333eb0b6dSopenharmony_ci if (buffer == nullptr && descriptor == nullptr) { 259433eb0b6dSopenharmony_ci HILOG_ERROR("invalid param, both buffer and descriptor are nullptr"); 259533eb0b6dSopenharmony_ci return nullptr; 259633eb0b6dSopenharmony_ci } 259733eb0b6dSopenharmony_ci 259833eb0b6dSopenharmony_ci if ((buffer != nullptr && !IsValidScriptBuffer(buffer, bufferSize)) && 259933eb0b6dSopenharmony_ci (checkPath && descriptor != nullptr && !IsValidPandaFile(descriptor))) { 260033eb0b6dSopenharmony_ci HILOG_ERROR("invalid param"); 260133eb0b6dSopenharmony_ci return nullptr; 260233eb0b6dSopenharmony_ci } 260333eb0b6dSopenharmony_ci 260433eb0b6dSopenharmony_ci // LCOV_EXCL_START 260533eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 260633eb0b6dSopenharmony_ci std::string desc(descriptor); 260733eb0b6dSopenharmony_ci [[maybe_unused]] bool ret = false; 260833eb0b6dSopenharmony_ci // if apiVersion > API11, use secure path. 260933eb0b6dSopenharmony_ci if (IsApplicationApiVersionAPI11Plus()) { 261033eb0b6dSopenharmony_ci EXECUTE_BUFFER(ExecuteSecure); 261133eb0b6dSopenharmony_ci } else { 261233eb0b6dSopenharmony_ci EXECUTE_BUFFER(Execute); 261333eb0b6dSopenharmony_ci } 261433eb0b6dSopenharmony_ci if (panda::JSNApi::HasPendingException(vm_)) { 261533eb0b6dSopenharmony_ci HandleUncaughtException(); 261633eb0b6dSopenharmony_ci return nullptr; 261733eb0b6dSopenharmony_ci } 261833eb0b6dSopenharmony_ci Local<JSValueRef> undefObj = JSValueRef::Undefined(vm_); 261933eb0b6dSopenharmony_ci return JsValueFromLocalValue(scope.Escape(undefObj)); 262033eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 262133eb0b6dSopenharmony_ci} 262233eb0b6dSopenharmony_ci 262333eb0b6dSopenharmony_cipanda::Local<panda::ObjectRef> ArkNativeEngine::LoadArkModule(const void* buffer, 262433eb0b6dSopenharmony_ci int32_t len, const std::string& fileName) 262533eb0b6dSopenharmony_ci{ 262633eb0b6dSopenharmony_ci panda::EscapeLocalScope scope(vm_); 262733eb0b6dSopenharmony_ci Local<ObjectRef> undefObj(JSValueRef::Undefined(vm_)); 262833eb0b6dSopenharmony_ci if (buffer == nullptr || len <= 0 || fileName.empty()) { 262933eb0b6dSopenharmony_ci HILOG_ERROR("fileName is nullptr or source code is nullptr"); 263033eb0b6dSopenharmony_ci return scope.Escape(undefObj); 263133eb0b6dSopenharmony_ci } 263233eb0b6dSopenharmony_ci if (!IsValidScriptBuffer(reinterpret_cast<uint8_t*>(const_cast<void*>(buffer)), len)) { 263333eb0b6dSopenharmony_ci HILOG_ERROR("invalid script buffer"); 263433eb0b6dSopenharmony_ci return scope.Escape(undefObj); 263533eb0b6dSopenharmony_ci } 263633eb0b6dSopenharmony_ci 263733eb0b6dSopenharmony_ci // LCOV_EXCL_START 263833eb0b6dSopenharmony_ci bool res = JSNApi::ExecuteModuleFromBuffer(vm_, buffer, len, fileName); 263933eb0b6dSopenharmony_ci if (!res) { 264033eb0b6dSopenharmony_ci HILOG_ERROR("Execute module failed"); 264133eb0b6dSopenharmony_ci return scope.Escape(undefObj); 264233eb0b6dSopenharmony_ci } 264333eb0b6dSopenharmony_ci 264433eb0b6dSopenharmony_ci Local<ObjectRef> exportObj = JSNApi::GetExportObjectFromBuffer(vm_, fileName, "default"); 264533eb0b6dSopenharmony_ci if (exportObj->IsNull()) { 264633eb0b6dSopenharmony_ci HILOG_ERROR("Get export object failed"); 264733eb0b6dSopenharmony_ci return scope.Escape(undefObj); 264833eb0b6dSopenharmony_ci } 264933eb0b6dSopenharmony_ci 265033eb0b6dSopenharmony_ci HILOG_DEBUG("ArkNativeEngineImpl::LoadModule end"); 265133eb0b6dSopenharmony_ci return scope.Escape(exportObj); 265233eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 265333eb0b6dSopenharmony_ci} 265433eb0b6dSopenharmony_ci 265533eb0b6dSopenharmony_cibool ArkNativeEngine::ExecuteJsBin(const std::string& fileName, bool checkPath) 265633eb0b6dSopenharmony_ci{ 265733eb0b6dSopenharmony_ci if (checkPath && !IsValidPandaFile(fileName.c_str())) { 265833eb0b6dSopenharmony_ci HILOG_ERROR("faild to execute js bin, file is not exist or format is invalid"); 265933eb0b6dSopenharmony_ci return false; 266033eb0b6dSopenharmony_ci } 266133eb0b6dSopenharmony_ci // LCOV_EXCL_START 266233eb0b6dSopenharmony_ci panda::JSExecutionScope executionScope(vm_); 266333eb0b6dSopenharmony_ci LocalScope scope(vm_); 266433eb0b6dSopenharmony_ci bool ret = JSNApi::Execute(vm_, fileName, PANDA_MAIN_FUNCTION); 266533eb0b6dSopenharmony_ci return ret; 266633eb0b6dSopenharmony_ci // LCOV_EXCL_STOP 266733eb0b6dSopenharmony_ci} 2668