1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "js_runtime.h" 17 18#include <cerrno> 19#include <climits> 20#include <cstdlib> 21#include <fstream> 22#include <mutex> 23#include <regex> 24 25#include <atomic> 26#include <sys/epoll.h> 27#include <unistd.h> 28 29#include "file_ex.h" 30#include "accesstoken_kit.h" 31#include "config_policy_utils.h" 32#include "constants.h" 33#include "connect_server_manager.h" 34#include "ecmascript/napi/include/jsnapi.h" 35#include "extract_resource_manager.h" 36#include "file_mapper.h" 37#include "file_path_utils.h" 38#include "hdc_register.h" 39#include "hilog_tag_wrapper.h" 40#include "hitrace_meter.h" 41#include "ipc_skeleton.h" 42#include "iservice_registry.h" 43#include "js_environment.h" 44#include "js_module_reader.h" 45#include "js_module_searcher.h" 46#include "js_quickfix_callback.h" 47#include "js_runtime_utils.h" 48#include "js_utils.h" 49#include "js_worker.h" 50#include "module_checker_delegate.h" 51#include "napi/native_api.h" 52#include "native_engine/impl/ark/ark_native_engine.h" 53#include "native_engine/native_create_env.h" 54#include "native_engine/native_engine.h" 55#include "js_runtime_lite.h" 56#include "ohos_js_env_logger.h" 57#include "ohos_js_environment_impl.h" 58#include "parameters.h" 59#include "extractor.h" 60#include "system_ability_definition.h" 61#include "source_map.h" 62#include "source_map_operator.h" 63 64#ifdef SUPPORT_SCREEN 65#include "hot_reloader.h" 66#include "ace_forward_compatibility.h" 67#include "declarative_module_preloader.h" 68#endif //SUPPORT_SCREEN 69 70#include "syscap_ts.h" 71 72using namespace OHOS::AbilityBase; 73using Extractor = OHOS::AbilityBase::Extractor; 74 75namespace OHOS { 76namespace AbilityRuntime { 77namespace { 78constexpr size_t PARAM_TWO = 2; 79constexpr uint8_t SYSCAP_MAX_SIZE = 100; 80constexpr int64_t DEFAULT_GC_POOL_SIZE = 0x10000000; // 256MB 81constexpr int32_t DEFAULT_INTER_VAL = 500; 82constexpr int32_t API8 = 8; 83const std::string SANDBOX_ARK_CACHE_PATH = "/data/storage/ark-cache/"; 84const std::string SANDBOX_ARK_PROIFILE_PATH = "/data/storage/ark-profile"; 85const std::string DEBUGGER = "@Debugger"; 86 87constexpr char MERGE_ABC_PATH[] = "/ets/modules.abc"; 88constexpr char BUNDLE_INSTALL_PATH[] = "/data/storage/el1/bundle/"; 89constexpr const char* PERMISSION_RUN_ANY_CODE = "ohos.permission.RUN_ANY_CODE"; 90 91const std::string CONFIG_PATH = "/etc/system_kits_config.json"; 92const std::string SYSTEM_KITS_CONFIG_PATH = "/system/etc/system_kits_config.json"; 93 94const std::string SYSTEM_KITS = "systemkits"; 95const std::string NAMESPACE = "namespace"; 96const std::string TARGET_OHM = "targetohm"; 97const std::string SINCE_VERSION = "sinceVersion"; 98 99constexpr char DEVELOPER_MODE_STATE[] = "const.security.developermode.state"; 100static auto PermissionCheckFunc = []() { 101 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID(); 102 103 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, PERMISSION_RUN_ANY_CODE); 104 if (result == Security::AccessToken::PermissionState::PERMISSION_GRANTED) { 105 return true; 106 } else { 107 return false; 108 } 109}; 110 111int32_t PrintVmLog(int32_t, int32_t, const char*, const char*, const char* message) 112{ 113 TAG_LOGI(AAFwkTag::JSRUNTIME, "ArkLog: %{public}s", message); 114 return 0; 115} 116} // namespace 117 118std::atomic<bool> JsRuntime::hasInstance(false); 119JsRuntime::JsRuntime() 120{ 121 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 122} 123 124JsRuntime::~JsRuntime() 125{ 126 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 127 Deinitialize(); 128 StopDebugMode(); 129} 130 131std::unique_ptr<JsRuntime> JsRuntime::Create(const Options& options) 132{ 133 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 134 std::unique_ptr<JsRuntime> instance; 135 JsRuntimeLite::InitJsRuntimeLite(options); 136 if (!options.preload && options.isStageModel) { 137 auto preloadedInstance = Runtime::GetPreloaded(); 138#ifdef SUPPORT_SCREEN 139 // reload ace if compatible mode changes 140 if (Ace::AceForwardCompatibility::PipelineChanged() && preloadedInstance) { 141 preloadedInstance.reset(); 142 } 143#endif 144 if (preloadedInstance && preloadedInstance->GetLanguage() == Runtime::Language::JS) { 145 instance.reset(static_cast<JsRuntime*>(preloadedInstance.release())); 146 } else { 147 instance = std::make_unique<JsRuntime>(); 148 } 149 } else { 150 instance = std::make_unique<JsRuntime>(); 151 } 152 153 if (!instance->Initialize(options)) { 154 return std::unique_ptr<JsRuntime>(); 155 } 156 return instance; 157} 158 159void JsRuntime::StartDebugMode(const DebugOption dOption) 160{ 161 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 162 if (!system::GetBoolParameter(DEVELOPER_MODE_STATE, false)) { 163 TAG_LOGE(AAFwkTag::JSRUNTIME, "Developer Mode is false."); 164 return; 165 } 166 CHECK_POINTER(jsEnv_); 167 if (jsEnv_->GetDebugMode()) { 168 TAG_LOGI(AAFwkTag::JSRUNTIME, "debugMode"); 169 return; 170 } 171 // Set instance id to tid after the first instance. 172 if (JsRuntime::hasInstance.exchange(true, std::memory_order_relaxed)) { 173 instanceId_ = static_cast<uint32_t>(getproctid()); 174 } 175 176 bool isStartWithDebug = dOption.isStartWithDebug; 177 bool isDebugApp = dOption.isDebugApp; 178 TAG_LOGD(AAFwkTag::JSRUNTIME, "Ark VM is starting debug mode [%{public}s]", isStartWithDebug ? "break" : "normal"); 179 StartDebuggerInWorkerModule(isDebugApp, dOption.isStartWithNative); 180 const std::string bundleName = bundleName_; 181 uint32_t instanceId = instanceId_; 182 auto weak = jsEnv_; 183 std::string inputProcessName = bundleName_ != dOption.processName ? dOption.processName : ""; 184 HdcRegister::Get().StartHdcRegister(bundleName_, inputProcessName, isDebugApp, [bundleName, 185 isStartWithDebug, instanceId, weak, isDebugApp] (int socketFd, std::string option) { 186 TAG_LOGI(AAFwkTag::JSRUNTIME, "HdcRegister msg, fd= %{public}d, option= %{public}s", 187 socketFd, option.c_str()); 188 if (weak == nullptr) { 189 TAG_LOGE(AAFwkTag::JSRUNTIME, "null weak"); 190 return; 191 } 192 if (option.find(DEBUGGER) == std::string::npos) { 193 if (isDebugApp) { 194 ConnectServerManager::Get().StopConnectServer(false); 195 } 196 ConnectServerManager::Get().SendDebuggerInfo(isStartWithDebug, isDebugApp); 197 ConnectServerManager::Get().StartConnectServer(bundleName, socketFd, false); 198 } else { 199 if (isDebugApp) { 200 weak->StopDebugger(option); 201 } 202 weak->StartDebugger(option, socketFd, isDebugApp); 203 } 204 }); 205 if (isDebugApp) { 206 ConnectServerManager::Get().StartConnectServer(bundleName_, -1, true); 207 } 208 209 DebuggerConnectionHandler(isDebugApp, isStartWithDebug); 210} 211 212void JsRuntime::DebuggerConnectionHandler(bool isDebugApp, bool isStartWithDebug) 213{ 214 ConnectServerManager::Get().StoreInstanceMessage(getproctid(), instanceId_); 215 EcmaVM* vm = GetEcmaVm(); 216 auto dTask = jsEnv_->GetDebuggerPostTask(); 217 panda::JSNApi::DebugOption option = {ARK_DEBUGGER_LIB_PATH, isDebugApp ? isStartWithDebug : false}; 218 ConnectServerManager::Get().StoreDebuggerInfo(getproctid(), reinterpret_cast<void*>(vm), option, dTask, isDebugApp); 219 jsEnv_->NotifyDebugMode(getproctid(), ARK_DEBUGGER_LIB_PATH, instanceId_, isDebugApp, isStartWithDebug); 220} 221 222void JsRuntime::StopDebugMode() 223{ 224 CHECK_POINTER(jsEnv_); 225 if (jsEnv_->GetDebugMode()) { 226 ConnectServerManager::Get().RemoveInstance(instanceId_); 227 StopDebugger(); 228 } 229} 230 231void JsRuntime::InitConsoleModule() 232{ 233 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 234 CHECK_POINTER(jsEnv_); 235 jsEnv_->InitConsoleModule(); 236} 237 238bool JsRuntime::StartDebugger(bool needBreakPoint, uint32_t instanceId) 239{ 240 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 241 return true; 242} 243 244void JsRuntime::StopDebugger() 245{ 246 CHECK_POINTER(jsEnv_); 247 jsEnv_->StopDebugger(); 248} 249 250int32_t JsRuntime::JsperfProfilerCommandParse(const std::string &command, int32_t defaultValue) 251{ 252 TAG_LOGD(AAFwkTag::JSRUNTIME, "profiler command parse %{public}s", command.c_str()); 253 auto findPos = command.find("jsperf"); 254 if (findPos == std::string::npos) { 255 // jsperf command not found, so not to do, return zero. 256 TAG_LOGD(AAFwkTag::JSRUNTIME, "jsperf command not found"); 257 return 0; 258 } 259 260 // match jsperf command 261 auto jsPerfStr = command.substr(findPos, command.length() - findPos); 262 const std::regex regexJsperf(R"(^jsperf($|\s+($|\d*\s*($|nativeperf.*))))"); 263 std::match_results<std::string::const_iterator> matchResults; 264 if (!std::regex_match(jsPerfStr, matchResults, regexJsperf)) { 265 TAG_LOGD(AAFwkTag::JSRUNTIME, "the order not match"); 266 return defaultValue; 267 } 268 269 // get match resuflt 270 std::string jsperfResuflt; 271 constexpr size_t matchResultIndex = 1; 272 if (matchResults.size() < PARAM_TWO) { 273 TAG_LOGE(AAFwkTag::JSRUNTIME, "no results need to be matched"); 274 return defaultValue; 275 } 276 277 jsperfResuflt = matchResults[matchResultIndex].str(); 278 // match number result 279 const std::regex regexJsperfNum(R"(^\s*(\d+).*)"); 280 std::match_results<std::string::const_iterator> jsperfMatchResults; 281 if (!std::regex_match(jsperfResuflt, jsperfMatchResults, regexJsperfNum)) { 282 TAG_LOGD(AAFwkTag::JSRUNTIME, "the jsperf results not match"); 283 return defaultValue; 284 } 285 286 // get match result 287 std::string interval; 288 constexpr size_t matchNumResultIndex = 1; 289 if (jsperfMatchResults.size() < PARAM_TWO) { 290 TAG_LOGE(AAFwkTag::JSRUNTIME, "jsperfMatchResults not match"); 291 return defaultValue; 292 } 293 294 interval = jsperfMatchResults[matchNumResultIndex].str(); 295 if (interval.empty()) { 296 TAG_LOGD(AAFwkTag::JSRUNTIME, "empty interval"); 297 return defaultValue; 298 } 299 300 return std::stoi(interval); 301} 302 303void JsRuntime::StartProfiler(const DebugOption dOption) 304{ 305 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 306 if (!system::GetBoolParameter(DEVELOPER_MODE_STATE, false)) { 307 TAG_LOGE(AAFwkTag::JSRUNTIME, "Developer Mode is false."); 308 return; 309 } 310 CHECK_POINTER(jsEnv_); 311 if (JsRuntime::hasInstance.exchange(true, std::memory_order_relaxed)) { 312 instanceId_ = static_cast<uint32_t>(getproctid()); 313 } 314 315 bool isStartWithDebug = dOption.isStartWithDebug; 316 bool isDebugApp = dOption.isDebugApp; 317 StartDebuggerInWorkerModule(isDebugApp, dOption.isStartWithNative); 318 const std::string bundleName = bundleName_; 319 auto weak = jsEnv_; 320 uint32_t instanceId = instanceId_; 321 std::string inputProcessName = bundleName_ != dOption.processName ? dOption.processName : ""; 322 HdcRegister::Get().StartHdcRegister(bundleName_, inputProcessName, isDebugApp, 323 [bundleName, isStartWithDebug, instanceId, weak, isDebugApp](int socketFd, std::string option) { 324 TAG_LOGI(AAFwkTag::JSRUNTIME, "HdcRegister msg, fd= %{public}d, option= %{public}s", socketFd, option.c_str()); 325 if (weak == nullptr) { 326 TAG_LOGE(AAFwkTag::JSRUNTIME, "null jsEnv"); 327 return; 328 } 329 if (option.find(DEBUGGER) == std::string::npos) { 330 if (isDebugApp) { 331 ConnectServerManager::Get().StopConnectServer(false); 332 } 333 ConnectServerManager::Get().SendDebuggerInfo(isStartWithDebug, isDebugApp); 334 ConnectServerManager::Get().StartConnectServer(bundleName, socketFd, false); 335 } else { 336 if (isDebugApp) { 337 weak->StopDebugger(option); 338 } 339 weak->StartDebugger(option, socketFd, isDebugApp); 340 } 341 }); 342 343 DebuggerConnectionManager(isDebugApp, isStartWithDebug, dOption); 344} 345 346void JsRuntime::DebuggerConnectionManager(bool isDebugApp, bool isStartWithDebug, const DebugOption dOption) 347{ 348 if (isDebugApp) { 349 ConnectServerManager::Get().StartConnectServer(bundleName_, 0, true); 350 } 351 ConnectServerManager::Get().StoreInstanceMessage(getproctid(), instanceId_); 352 JsEnv::JsEnvironment::PROFILERTYPE profiler = JsEnv::JsEnvironment::PROFILERTYPE::PROFILERTYPE_HEAP; 353 int32_t interval = 0; 354 const std::string profilerCommand("profile"); 355 if (dOption.perfCmd.find(profilerCommand) != std::string::npos) { 356 profiler = JsEnv::JsEnvironment::PROFILERTYPE::PROFILERTYPE_CPU; 357 interval = JsperfProfilerCommandParse(dOption.perfCmd, DEFAULT_INTER_VAL); 358 } 359 EcmaVM* vm = GetEcmaVm(); 360 auto dTask = jsEnv_->GetDebuggerPostTask(); 361 panda::JSNApi::DebugOption option = {ARK_DEBUGGER_LIB_PATH, isDebugApp ? isStartWithDebug : false}; 362 ConnectServerManager::Get().StoreDebuggerInfo(getproctid(), reinterpret_cast<void*>(vm), option, dTask, isDebugApp); 363 TAG_LOGD(AAFwkTag::JSRUNTIME, "profiler:%{public}d interval:%{public}d", profiler, interval); 364 jsEnv_->StartProfiler(ARK_DEBUGGER_LIB_PATH, instanceId_, profiler, interval, getproctid(), isDebugApp); 365} 366 367bool JsRuntime::GetFileBuffer(const std::string& filePath, std::string& fileFullName, std::vector<uint8_t>& buffer, 368 bool isABC) 369{ 370 Extractor extractor(filePath); 371 if (!extractor.Init()) { 372 TAG_LOGE(AAFwkTag::JSRUNTIME, "Extractor of %{private}s init failed", filePath.c_str()); 373 return false; 374 } 375 376 std::vector<std::string> fileNames; 377 if (isABC) { 378 extractor.GetSpecifiedTypeFiles(fileNames, ".abc"); 379 } else { 380 extractor.GetSpecifiedTypeFiles(fileNames, ".map"); 381 } 382 if (fileNames.empty()) { 383 TAG_LOGW( 384 AAFwkTag::JSRUNTIME, "no .abc in hap/hqf %{private}s", filePath.c_str()); 385 return true; 386 } 387 388 std::string fileName = fileNames.front(); 389 fileFullName = filePath + "/" + fileName; 390 std::unique_ptr<uint8_t[]> data; 391 size_t dataLen = 0; 392 if (!extractor.ExtractToBufByName(fileName, data, dataLen)) { 393 TAG_LOGE(AAFwkTag::JSRUNTIME, "Extract %{public}s failed", fileFullName.c_str()); 394 return false; 395 } 396 397 buffer.assign(data.get(), data.get() + dataLen); 398 return true; 399} 400 401std::shared_ptr<AbilityBase::FileMapper> JsRuntime::GetSafeData(const std::string& path, std::string& fileFullName) 402{ 403 bool newCreate = false; 404 auto extractor = ExtractorUtil::GetExtractor(path, newCreate, true); 405 if (extractor == nullptr) { 406 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get extractor failed. path: %{private}s", path.c_str()); 407 return nullptr; 408 } 409 410 std::vector<std::string> fileNames; 411 extractor->GetSpecifiedTypeFiles(fileNames, ".abc"); 412 if (fileNames.empty()) { 413 TAG_LOGI(AAFwkTag::JSRUNTIME, "There's no abc file in hap or hqf: %{private}s", path.c_str()); 414 return nullptr; 415 } 416 std::string fileName = fileNames.front(); 417 fileFullName = path + "/" + fileName; 418 419 auto safeData = extractor->GetSafeData(fileName); 420 if (safeData == nullptr) { 421 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get safe data failed. path: %{private}s", path.c_str()); 422 return nullptr; 423 } 424 425 return safeData; 426} 427 428bool JsRuntime::LoadRepairPatch(const std::string& hqfFile, const std::string& hapPath) 429{ 430 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 431 auto vm = GetEcmaVm(); 432 CHECK_POINTER_AND_RETURN(vm, false); 433 434 InitSourceMap(hqfFile); 435 436 std::string patchFile; 437 auto hqfSafeData = GetSafeData(hqfFile, patchFile); 438 if (hqfSafeData == nullptr) { 439 if (patchFile.empty()) { 440 TAG_LOGI(AAFwkTag::JSRUNTIME, "No need to load patch cause no ets. path: %{private}s", hqfFile.c_str()); 441 return true; 442 } 443 return false; 444 } 445 446 std::string baseFile; 447 auto hapSafeData = GetSafeData(hapPath, baseFile); 448 if (hapSafeData == nullptr) { 449 return false; 450 } 451 452 std::string resolvedHapPath; 453 auto position = hapPath.find(".hap"); 454 if (position != std::string::npos) { 455 resolvedHapPath = hapPath.substr(0, position) + MERGE_ABC_PATH; 456 } 457 458 auto hspPosition = hapPath.find(".hsp"); 459 if (hspPosition != std::string::npos) { 460 resolvedHapPath = hapPath.substr(0, hspPosition) + MERGE_ABC_PATH; 461 } 462 463 TAG_LOGD(AAFwkTag::JSRUNTIME, "LoadPatch, patchFile: %{private}s, baseFile: %{private}s", 464 patchFile.c_str(), resolvedHapPath.c_str()); 465 auto ret = panda::JSNApi::LoadPatch(vm, patchFile, hqfSafeData->GetDataPtr(), hqfSafeData->GetDataLen(), 466 resolvedHapPath, hapSafeData->GetDataPtr(), hapSafeData->GetDataLen()); 467 if (ret != panda::JSNApi::PatchErrorCode::SUCCESS) { 468 TAG_LOGE(AAFwkTag::JSRUNTIME, "LoadPatch failed:%{public}d", static_cast<int32_t>(ret)); 469 return false; 470 } 471 472 TAG_LOGD(AAFwkTag::JSRUNTIME, "Load patch %{private}s succeed", patchFile.c_str()); 473 return true; 474} 475 476bool JsRuntime::UnLoadRepairPatch(const std::string& hqfFile) 477{ 478 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 479 auto vm = GetEcmaVm(); 480 CHECK_POINTER_AND_RETURN(vm, false); 481 482 Extractor extractor(hqfFile); 483 if (!extractor.Init()) { 484 TAG_LOGE(AAFwkTag::JSRUNTIME, "Extractor of %{private}s init failed", hqfFile.c_str()); 485 return false; 486 } 487 488 std::vector<std::string> fileNames; 489 extractor.GetSpecifiedTypeFiles(fileNames, ".abc"); 490 if (fileNames.empty()) { 491 TAG_LOGW(AAFwkTag::JSRUNTIME, "no .abc in hqf %{private}s", hqfFile.c_str()); 492 return true; 493 } 494 495 for (const auto &fileName : fileNames) { 496 std::string patchFile = hqfFile + "/" + fileName; 497 TAG_LOGD(AAFwkTag::JSRUNTIME, "UnloadPatch, patchFile: %{private}s", patchFile.c_str()); 498 auto ret = panda::JSNApi::UnloadPatch(vm, patchFile); 499 if (ret != panda::JSNApi::PatchErrorCode::SUCCESS) { 500 TAG_LOGW(AAFwkTag::JSRUNTIME, "UnLoadPatch failed with %{public}d", static_cast<int32_t>(ret)); 501 } 502 TAG_LOGD(AAFwkTag::JSRUNTIME, "UnLoad patch %{private}s succeed", patchFile.c_str()); 503 } 504 505 return true; 506} 507 508bool JsRuntime::NotifyHotReloadPage() 509{ 510 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 511#ifdef SUPPORT_SCREEN 512 Ace::HotReloader::HotReload(); 513#endif // SUPPORT_SCREEN 514 return true; 515} 516 517bool JsRuntime::LoadScript(const std::string& path, std::vector<uint8_t>* buffer, bool isBundle) 518{ 519 TAG_LOGD(AAFwkTag::JSRUNTIME, "path: %{private}s", path.c_str()); 520 CHECK_POINTER_AND_RETURN(jsEnv_, false); 521 return jsEnv_->LoadScript(path, buffer, isBundle); 522} 523 524bool JsRuntime::LoadScript(const std::string& path, uint8_t* buffer, size_t len, bool isBundle, 525 const std::string& srcEntrance) 526{ 527 TAG_LOGD(AAFwkTag::JSRUNTIME, "path: %{private}s", path.c_str()); 528 CHECK_POINTER_AND_RETURN(jsEnv_, false); 529 if (isOhmUrl_ && !moduleName_.empty()) { 530 auto vm = GetEcmaVm(); 531 CHECK_POINTER_AND_RETURN(vm, false); 532 std::string srcFilename = ""; 533 srcFilename = BUNDLE_INSTALL_PATH + moduleName_ + MERGE_ABC_PATH; 534 return panda::JSNApi::ExecuteSecureWithOhmUrl(vm, buffer, len, srcFilename, srcEntrance); 535 } 536 return jsEnv_->LoadScript(path, buffer, len, isBundle); 537} 538 539std::unique_ptr<NativeReference> JsRuntime::LoadSystemModuleByEngine( 540 napi_env env, const std::string& moduleName, const napi_value* argv, size_t argc) 541{ 542 TAG_LOGD(AAFwkTag::JSRUNTIME, "ModuleName %{public}s", moduleName.c_str()); 543 if (env == nullptr) { 544 TAG_LOGI(AAFwkTag::JSRUNTIME, "invalid engine"); 545 return nullptr; 546 } 547 548 napi_value globalObj = nullptr; 549 napi_get_global(env, &globalObj); 550 napi_value propertyValue = nullptr; 551 napi_get_named_property(env, globalObj, "requireNapi", &propertyValue); 552 553 std::unique_ptr<NativeReference> methodRequireNapiRef_; 554 napi_ref tmpRef = nullptr; 555 napi_create_reference(env, propertyValue, 1, &tmpRef); 556 methodRequireNapiRef_.reset(reinterpret_cast<NativeReference*>(tmpRef)); 557 if (!methodRequireNapiRef_) { 558 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to create reference for global.requireNapi"); 559 return nullptr; 560 } 561 562 napi_value className = nullptr; 563 napi_create_string_utf8(env, moduleName.c_str(), moduleName.length(), &className); 564 auto refValue = methodRequireNapiRef_->GetNapiValue(); 565 napi_value args[1] = { className }; 566 napi_value classValue = nullptr; 567 napi_call_function(env, globalObj, refValue, 1, args, &classValue); 568 napi_value instanceValue = nullptr; 569 napi_new_instance(env, classValue, argc, argv, &instanceValue); 570 if (instanceValue == nullptr) { 571 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to create object instance"); 572 return nullptr; 573 } 574 575 napi_ref resultRef = nullptr; 576 napi_create_reference(env, instanceValue, 1, &resultRef); 577 return std::unique_ptr<NativeReference>(reinterpret_cast<NativeReference*>(resultRef)); 578} 579 580void JsRuntime::FinishPreload() 581{ 582 auto vm = GetEcmaVm(); 583 CHECK_POINTER(vm); 584 panda::JSNApi::PreFork(vm); 585} 586 587void JsRuntime::PostPreload(const Options& options) 588{ 589 auto vm = GetEcmaVm(); 590 CHECK_POINTER(vm); 591 auto env = GetNapiEnv(); 592 CHECK_POINTER(env); 593 panda::RuntimeOption postOption; 594 postOption.SetBundleName(options.bundleName); 595 if (!options.arkNativeFilePath.empty()) { 596 std::string sandBoxAnFilePath = SANDBOX_ARK_CACHE_PATH + options.arkNativeFilePath; 597 postOption.SetAnDir(sandBoxAnFilePath); 598 } 599 if (options.isMultiThread) { 600 TAG_LOGD(AAFwkTag::JSRUNTIME, "Multi-Thread Mode: %{public}d", options.isMultiThread); 601 panda::JSNApi::SetMultiThreadCheck(); 602 } 603 if (options.isErrorInfoEnhance) { 604 TAG_LOGD(AAFwkTag::JSRUNTIME, "Start Error-Info-Enhance Mode: %{public}d.", options.isErrorInfoEnhance); 605 panda::JSNApi::SetErrorInfoEnhance(); 606 } 607 bool profileEnabled = OHOS::system::GetBoolParameter("ark.profile", false); 608 postOption.SetEnableProfile(profileEnabled); 609 TAG_LOGD(AAFwkTag::JSRUNTIME, "ASMM JIT Verify PostFork, jitEnabled: %{public}d", options.jitEnabled); 610 postOption.SetEnableJIT(options.jitEnabled); 611 postOption.SetAOTCompileStatusMap(options.aotCompileStatusMap); 612 { 613 HITRACE_METER_NAME(HITRACE_TAG_APP, "panda::JSNApi::PostFork"); 614 panda::JSNApi::PostFork(vm, postOption); 615 } 616 reinterpret_cast<NativeEngine*>(env)->ReinitUVLoop(); 617 uv_loop_s* loop = nullptr; 618 napi_get_uv_event_loop(env, &loop); 619 panda::JSNApi::SetLoop(vm, loop); 620} 621 622void JsRuntime::LoadAotFile(const Options& options) 623{ 624 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 625 auto vm = GetEcmaVm(); 626 CHECK_POINTER(vm); 627 if (options.hapPath.empty()) { 628 return; 629 } 630 631 bool newCreate = false; 632 std::string loadPath = ExtractorUtil::GetLoadFilePath(options.hapPath); 633 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(loadPath, newCreate, true); 634 if (extractor != nullptr && newCreate) { 635 panda::JSNApi::LoadAotFile(vm, options.moduleName); 636 } 637} 638 639bool JsRuntime::Initialize(const Options& options) 640{ 641 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 642#ifdef SUPPORT_SCREEN 643 if (Ace::AceForwardCompatibility::PipelineChanged()) { 644 preloaded_ = false; 645 } 646#endif 647 if (!preloaded_) { 648 if (!CreateJsEnv(options)) { 649 TAG_LOGE(AAFwkTag::JSRUNTIME, "Create jsEnv failed"); 650 return false; 651 } 652 } 653 apiTargetVersion_ = options.apiTargetVersion; 654 TAG_LOGD(AAFwkTag::JSRUNTIME, "Initialize: %{public}d", apiTargetVersion_); 655 bool isModular = false; 656 if (IsUseAbilityRuntime(options)) { 657 auto env = GetNapiEnv(); 658 auto nativeEngine = reinterpret_cast<NativeEngine*>(env); 659 CHECK_POINTER_AND_RETURN(nativeEngine, false); 660 661 auto vm = GetEcmaVm(); 662 CHECK_POINTER_AND_RETURN(vm, false); 663 664 if (preloaded_) { 665 PostPreload(options); 666 } 667 HandleScope handleScope(*this); 668 napi_value globalObj = nullptr; 669 napi_get_global(env, &globalObj); 670 CHECK_POINTER_AND_RETURN(globalObj, false); 671 672 if (!preloaded_) { 673 InitSyscapModule(env); 674 675 // Simple hook function 'isSystemplugin' 676 const char* moduleName = "JsRuntime"; 677 BindNativeFunction(env, globalObj, "isSystemplugin", moduleName, 678 [](napi_env env, napi_callback_info cbinfo) -> napi_value { 679 return CreateJsUndefined(env); 680 }); 681 682 napi_value propertyValue = nullptr; 683 napi_get_named_property(env, globalObj, "requireNapi", &propertyValue); 684 napi_ref tmpRef = nullptr; 685 napi_create_reference(env, propertyValue, 1, &tmpRef); 686 methodRequireNapiRef_.reset(reinterpret_cast<NativeReference*>(tmpRef)); 687 if (!methodRequireNapiRef_) { 688 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to create reference for global.requireNapi"); 689 return false; 690 } 691 TAG_LOGD(AAFwkTag::JSRUNTIME, "PreloadAce start"); 692 PreloadAce(options); 693 TAG_LOGD(AAFwkTag::JSRUNTIME, "PreloadAce end"); 694 nativeEngine->RegisterPermissionCheck(PermissionCheckFunc); 695 } 696 697 if (!options.preload) { 698 isBundle_ = options.isBundle; 699 bundleName_ = options.bundleName; 700 codePath_ = options.codePath; 701 panda::JSNApi::SetSearchHapPathTracker( 702 vm, [options](const std::string moduleName, std::string &hapPath) -> bool { 703 if (options.hapModulePath.find(moduleName) == options.hapModulePath.end()) { 704 return false; 705 } 706 hapPath = options.hapModulePath.find(moduleName)->second; 707 return true; 708 }); 709 ReInitJsEnvImpl(options); 710 LoadAotFile(options); 711 panda::JSNApi::SetBundle(vm, options.isBundle); 712 panda::JSNApi::SetBundleName(vm, options.bundleName); 713 panda::JSNApi::SetHostResolveBufferTracker( 714 vm, JsModuleReader(options.bundleName, options.hapPath, options.isUnique)); 715 isModular = !panda::JSNApi::IsBundle(vm); 716 std::vector<panda::HmsMap> systemKitsMap = GetSystemKitsMap(apiTargetVersion_); 717 panda::JSNApi::SetHmsModuleList(vm, systemKitsMap); 718 std::map<std::string, std::vector<std::vector<std::string>>> pkgContextInfoMap; 719 std::map<std::string, std::string> pkgAliasMap; 720 pkgContextInfoJsonStringMap_ = options.pkgContextInfoJsonStringMap; 721 packageNameList_ = options.packageNameList; 722 JsRuntimeLite::GetInstance().GetPkgContextInfoListMap( 723 options.pkgContextInfoJsonStringMap, pkgContextInfoMap, pkgAliasMap); 724 panda::JSNApi::SetpkgContextInfoList(vm, pkgContextInfoMap); 725 panda::JSNApi::SetPkgAliasList(vm, pkgAliasMap); 726 panda::JSNApi::SetPkgNameList(vm, options.packageNameList); 727 } 728 } 729 730 if (!preloaded_) { 731 InitConsoleModule(); 732 } 733 734 if (!options.preload) { 735 auto operatorObj = std::make_shared<JsEnv::SourceMapOperator>(options.bundleName, isModular, 736 options.isDebugVersion); 737 InitSourceMap(operatorObj); 738 739 if (options.isUnique) { 740 TAG_LOGD(AAFwkTag::JSRUNTIME, "Not supported TimerModule when form render"); 741 } else { 742 InitTimerModule(); 743 } 744 745 InitWorkerModule(options); 746 SetModuleLoadChecker(options.moduleCheckerDelegate); 747 SetRequestAotCallback(); 748 749 if (!InitLoop(options.isStageModel)) { 750 TAG_LOGE(AAFwkTag::JSRUNTIME, "Init loop failed"); 751 return false; 752 } 753 } 754 755 preloaded_ = options.preload; 756 return true; 757} 758 759bool JsRuntime::CreateJsEnv(const Options& options) 760{ 761 panda::RuntimeOption pandaOption; 762 int arkProperties = OHOS::system::GetIntParameter<int>("persist.ark.properties", -1); 763 std::string bundleName = OHOS::system::GetParameter("persist.ark.arkbundlename", ""); 764 std::string memConfigProperty = OHOS::system::GetParameter("persist.ark.mem_config_property", ""); 765 size_t gcThreadNum = OHOS::system::GetUintParameter<size_t>("persist.ark.gcthreads", 7); 766 size_t longPauseTime = OHOS::system::GetUintParameter<size_t>("persist.ark.longpausetime", 40); 767 pandaOption.SetArkProperties(arkProperties); 768 pandaOption.SetArkBundleName(bundleName); 769 pandaOption.SetMemConfigProperty(memConfigProperty); 770 pandaOption.SetGcThreadNum(gcThreadNum); 771 pandaOption.SetLongPauseTime(longPauseTime); 772 TAG_LOGD(AAFwkTag::JSRUNTIME, "ark properties=%{public}d bundlename=%{public}s", 773 arkProperties, bundleName.c_str()); 774 pandaOption.SetGcType(panda::RuntimeOption::GC_TYPE::GEN_GC); 775 pandaOption.SetGcPoolSize(DEFAULT_GC_POOL_SIZE); 776 pandaOption.SetLogLevel(panda::RuntimeOption::LOG_LEVEL::FOLLOW); 777 pandaOption.SetLogBufPrint(PrintVmLog); 778 779 bool asmInterpreterEnabled = OHOS::system::GetBoolParameter("persist.ark.asminterpreter", true); 780 std::string asmOpcodeDisableRange = OHOS::system::GetParameter("persist.ark.asmopcodedisablerange", ""); 781 pandaOption.SetEnableAsmInterpreter(asmInterpreterEnabled); 782 pandaOption.SetAsmOpcodeDisableRange(asmOpcodeDisableRange); 783 TAG_LOGD(AAFwkTag::JSRUNTIME, "ASMM JIT Verify CreateJsEnv, jitEnabled: %{public}d", options.jitEnabled); 784 pandaOption.SetEnableJIT(options.jitEnabled); 785 786 if (options.isMultiThread) { 787 TAG_LOGD(AAFwkTag::JSRUNTIME, "Start Multi Thread Mode: %{public}d", options.isMultiThread); 788 panda::JSNApi::SetMultiThreadCheck(); 789 } 790 791 if (options.isErrorInfoEnhance) { 792 TAG_LOGD(AAFwkTag::JSRUNTIME, "Start Error Info Enhance Mode: %{public}d.", options.isErrorInfoEnhance); 793 panda::JSNApi::SetErrorInfoEnhance(); 794 } 795 796 if (IsUseAbilityRuntime(options)) { 797 // aot related 798 bool aotEnabled = OHOS::system::GetBoolParameter("persist.ark.aot", true); 799 pandaOption.SetEnableAOT(aotEnabled); 800 pandaOption.SetProfileDir(SANDBOX_ARK_PROIFILE_PATH); 801 } 802 803 OHOSJsEnvLogger::RegisterJsEnvLogger(); 804 jsEnv_ = std::make_shared<JsEnv::JsEnvironment>(std::make_unique<OHOSJsEnvironmentImpl>(options.eventRunner)); 805 if (jsEnv_ == nullptr || !jsEnv_->Initialize(pandaOption, static_cast<void*>(this))) { 806 TAG_LOGE(AAFwkTag::JSRUNTIME, "Init jsEnv failed"); 807 return false; 808 } 809 810 return true; 811} 812 813void JsRuntime::PreloadAce(const Options& options) 814{ 815 auto nativeEngine = GetNativeEnginePointer(); 816 CHECK_POINTER(nativeEngine); 817#ifdef SUPPORT_SCREEN 818 if (options.loadAce) { 819 // ArkTsCard start 820 if (options.isUnique) { 821 OHOS::Ace::DeclarativeModulePreloader::PreloadCard( 822 *nativeEngine, options.bundleName, options.pkgContextInfoJsonStringMap); 823 } else { 824 OHOS::Ace::DeclarativeModulePreloader::Preload(*nativeEngine); 825 } 826 // ArkTsCard end 827 } 828#endif 829} 830 831void JsRuntime::ReloadFormComponent() 832{ 833 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 834 auto nativeEngine = GetNativeEnginePointer(); 835 CHECK_POINTER(nativeEngine); 836 // ArkTsCard update condition, need to reload new component 837#ifdef SUPPORT_SCREEN 838 OHOS::Ace::DeclarativeModulePreloader::ReloadCard(*nativeEngine, bundleName_, pkgContextInfoJsonStringMap_); 839#endif 840} 841 842bool JsRuntime::InitLoop(bool isStage) 843{ 844 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 845 CHECK_POINTER_AND_RETURN(jsEnv_, false); 846 return jsEnv_->InitLoop(isStage); 847} 848 849void JsRuntime::SetAppLibPath(const AppLibPathMap& appLibPaths, const bool& isSystemApp) 850{ 851 TAG_LOGD(AAFwkTag::JSRUNTIME, "Set library path"); 852 853 if (appLibPaths.size() == 0) { 854 TAG_LOGW(AAFwkTag::JSRUNTIME, "no lib path to set"); 855 return; 856 } 857 858 auto moduleManager = NativeModuleManager::GetInstance(); 859 if (moduleManager == nullptr) { 860 TAG_LOGE(AAFwkTag::JSRUNTIME, "null moduleManager"); 861 return; 862 } 863 864 for (const auto &appLibPath : appLibPaths) { 865 moduleManager->SetAppLibPath(appLibPath.first, appLibPath.second, isSystemApp); 866 } 867} 868 869void JsRuntime::InitSourceMap(const std::shared_ptr<JsEnv::SourceMapOperator> operatorObj) 870{ 871 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 872 CHECK_POINTER(jsEnv_); 873 jsEnv_->InitSourceMap(operatorObj); 874 JsEnv::SourceMap::RegisterReadSourceMapCallback(JsRuntime::ReadSourceMapData); 875 JsEnv::SourceMap::RegisterGetHapPathCallback(JsModuleReader::GetHapPathList); 876} 877 878void JsRuntime::InitSourceMap(const std::string hqfFilePath) 879{ 880 std::string patchSoureMapFile; 881 std::vector<uint8_t> soureMapBuffer; 882 if (!GetFileBuffer(hqfFilePath, patchSoureMapFile, soureMapBuffer, false)) { 883 TAG_LOGE(AAFwkTag::JSRUNTIME, "get patchSoureMap file buffer failed"); 884 return; 885 } 886 std::string str(soureMapBuffer.begin(), soureMapBuffer.end()); 887 auto sourceMapOperator = jsEnv_->GetSourceMapOperator(); 888 if (sourceMapOperator != nullptr) { 889 auto sourceMapObj = sourceMapOperator->GetSourceMapObj(); 890 if (sourceMapObj != nullptr) { 891 sourceMapObj->SplitSourceMap(str); 892 } 893 } 894} 895 896void JsRuntime::Deinitialize() 897{ 898 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 899 for (auto it = modules_.begin(); it != modules_.end(); it = modules_.erase(it)) { 900 delete it->second; 901 it->second = nullptr; 902 } 903 904 methodRequireNapiRef_.reset(); 905 906 CHECK_POINTER(jsEnv_); 907 jsEnv_->DeInitLoop(); 908} 909 910napi_value JsRuntime::LoadJsBundle(const std::string& path, const std::string& hapPath, bool useCommonChunk) 911{ 912 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 913 auto env = GetNapiEnv(); 914 CHECK_POINTER_AND_RETURN(env, nullptr); 915 napi_value globalObj = nullptr; 916 napi_get_global(env, &globalObj); 917 napi_value exports = nullptr; 918 napi_create_object(env, &exports); 919 napi_set_named_property(env, globalObj, "exports", exports); 920 921 if (!RunScript(path, hapPath, useCommonChunk)) { 922 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to run script: %{private}s", path.c_str()); 923 return nullptr; 924 } 925 926 napi_value exportsObj = nullptr; 927 napi_get_named_property(env, globalObj, "exports", &exportsObj); 928 if (exportsObj == nullptr) { 929 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to get exports objcect: %{private}s", path.c_str()); 930 return nullptr; 931 } 932 933 napi_value exportObj = nullptr; 934 napi_get_named_property(env, exportsObj, "default", &exportObj); 935 if (exportObj == nullptr) { 936 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to get default objcect: %{private}s", path.c_str()); 937 return nullptr; 938 } 939 940 return exportObj; 941} 942 943napi_value JsRuntime::LoadJsModule(const std::string& path, const std::string& hapPath, const std::string& srcEntrance) 944{ 945 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 946 if (!RunScript(path, hapPath, false, srcEntrance)) { 947 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to run script: %{private}s", path.c_str()); 948 return nullptr; 949 } 950 951 auto vm = GetEcmaVm(); 952 CHECK_POINTER_AND_RETURN(vm, nullptr); 953 panda::Local<panda::ObjectRef> exportObj; 954 if (isOhmUrl_) { 955 exportObj = panda::JSNApi::GetExportObjectFromOhmUrl(vm, srcEntrance, "default"); 956 } else { 957 exportObj = panda::JSNApi::GetExportObject(vm, path, "default"); 958 } 959 960 if (exportObj->IsNull()) { 961 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get export object failed"); 962 return nullptr; 963 } 964 965 auto env = GetNapiEnv(); 966 CHECK_POINTER_AND_RETURN(env, nullptr); 967 return ArkNativeEngine::ArkValueToNapiValue(env, exportObj); 968} 969 970std::unique_ptr<NativeReference> JsRuntime::LoadModule(const std::string& moduleName, const std::string& modulePath, 971 const std::string& hapPath, bool esmodule, bool useCommonChunk, const std::string& srcEntrance) 972{ 973 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__); 974 TAG_LOGD(AAFwkTag::JSRUNTIME, "Load module(%{public}s, %{private}s, %{private}s, %{public}s)", 975 moduleName.c_str(), modulePath.c_str(), hapPath.c_str(), esmodule ? "true" : "false"); 976 auto vm = GetEcmaVm(); 977 CHECK_POINTER_AND_RETURN(vm, std::unique_ptr<NativeReference>()); 978 // use for debugger, js engine need to know load module to handle debug event 979 panda::JSNApi::NotifyLoadModule(vm); 980 auto env = GetNapiEnv(); 981 CHECK_POINTER_AND_RETURN(env, std::unique_ptr<NativeReference>()); 982 isOhmUrl_ = panda::JSNApi::IsOhmUrl(srcEntrance); 983 984 HandleScope handleScope(*this); 985 986 std::string path = moduleName; 987 auto pos = path.find("::"); 988 if (pos != std::string::npos) { 989 path.erase(pos, path.size() - pos); 990 moduleName_ = path; 991 } 992 993 napi_value classValue = nullptr; 994 995 auto it = modules_.find(modulePath); 996 if (it != modules_.end()) { 997 classValue = it->second->GetNapiValue(); 998 } else { 999 std::string fileName; 1000 if (!hapPath.empty()) { 1001 fileName.append(codePath_).append(Constants::FILE_SEPARATOR).append(modulePath); 1002 std::regex pattern(std::string(Constants::FILE_DOT) + std::string(Constants::FILE_SEPARATOR)); 1003 fileName = std::regex_replace(fileName, pattern, ""); 1004 } else { 1005 if (!MakeFilePath(codePath_, modulePath, fileName)) { 1006 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to make module file path: %{private}s", modulePath.c_str()); 1007 return std::unique_ptr<NativeReference>(); 1008 } 1009 } 1010 classValue = esmodule ? LoadJsModule(fileName, hapPath, srcEntrance) 1011 : LoadJsBundle(fileName, hapPath, useCommonChunk); 1012 if (classValue == nullptr) { 1013 return std::unique_ptr<NativeReference>(); 1014 } 1015 1016 napi_ref tmpRef = nullptr; 1017 napi_create_reference(env, classValue, 1, &tmpRef); 1018 modules_.emplace(modulePath, reinterpret_cast<NativeReference*>(tmpRef)); 1019 } 1020 1021 napi_value instanceValue = nullptr; 1022 napi_new_instance(env, classValue, 0, nullptr, &instanceValue); 1023 if (instanceValue == nullptr) { 1024 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to create object instance"); 1025 return std::unique_ptr<NativeReference>(); 1026 } 1027 1028 napi_ref resultRef = nullptr; 1029 napi_create_reference(env, instanceValue, 1, &resultRef); 1030 return std::unique_ptr<NativeReference>(reinterpret_cast<NativeReference*>(resultRef)); 1031} 1032 1033std::unique_ptr<NativeReference> JsRuntime::LoadSystemModule( 1034 const std::string& moduleName, const napi_value* argv, size_t argc) 1035{ 1036 TAG_LOGD(AAFwkTag::JSRUNTIME, "SystemModule %{public}s", moduleName.c_str()); 1037 napi_env env = GetNapiEnv(); 1038 CHECK_POINTER_AND_RETURN(env, std::unique_ptr<NativeReference>()); 1039 1040 HandleScope handleScope(*this); 1041 1042 napi_value className = nullptr; 1043 napi_create_string_utf8(env, moduleName.c_str(), moduleName.length(), &className); 1044 napi_value globalObj = nullptr; 1045 napi_get_global(env, &globalObj); 1046 napi_value refValue = methodRequireNapiRef_->GetNapiValue(); 1047 napi_value args[1] = { className }; 1048 napi_value classValue = nullptr; 1049 napi_call_function(env, globalObj, refValue, 1, args, &classValue); 1050 napi_value instanceValue = nullptr; 1051 napi_new_instance(env, classValue, argc, argv, &instanceValue); 1052 if (instanceValue == nullptr) { 1053 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to create object instance"); 1054 return std::unique_ptr<NativeReference>(); 1055 } 1056 1057 napi_ref resultRef = nullptr; 1058 napi_create_reference(env, instanceValue, 1, &resultRef); 1059 return std::unique_ptr<NativeReference>(reinterpret_cast<NativeReference*>(resultRef)); 1060} 1061 1062bool JsRuntime::RunScript(const std::string& srcPath, const std::string& hapPath, bool useCommonChunk, 1063 const std::string& srcEntrance) 1064{ 1065 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1066 auto vm = GetEcmaVm(); 1067 CHECK_POINTER_AND_RETURN(vm, false); 1068 std::string commonsPath = std::string(Constants::LOCAL_CODE_PATH) + "/" + moduleName_ + "/ets/commons.abc"; 1069 std::string vendorsPath = std::string(Constants::LOCAL_CODE_PATH) + "/" + moduleName_ + "/ets/vendors.abc"; 1070 if (hapPath.empty()) { 1071 if (useCommonChunk) { 1072 (void)LoadScript(commonsPath); 1073 (void)LoadScript(vendorsPath); 1074 } 1075 return LoadScript(srcPath); 1076 } 1077 1078 bool newCreate = false; 1079 std::string loadPath = ExtractorUtil::GetLoadFilePath(hapPath); 1080 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor(loadPath, newCreate, true); 1081 if (!extractor) { 1082 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get extractor failed. hapPath[%{private}s]", hapPath.c_str()); 1083 return false; 1084 } 1085 if (newCreate) { 1086 panda::JSNApi::LoadAotFile(vm, moduleName_); 1087 auto resourceManager = AbilityBase::ExtractResourceManager::GetExtractResourceManager().GetGlobalObject(); 1088 if (resourceManager) { 1089 resourceManager->AddResource(loadPath.c_str()); 1090 } 1091 } 1092 1093 auto func = [&](std::string modulePath, const std::string abcPath) { 1094 bool useSafeMempry = apiTargetVersion_ == 0 || apiTargetVersion_ > API8; 1095 if (!extractor->IsHapCompress(modulePath) && useSafeMempry) { 1096 auto safeData = extractor->GetSafeData(modulePath); 1097 if (!safeData) { 1098 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get safeData abc file failed"); 1099 return false; 1100 } 1101 return LoadScript(abcPath, safeData->GetDataPtr(), safeData->GetDataLen(), isBundle_, srcEntrance); 1102 } else { 1103 std::unique_ptr<uint8_t[]> data; 1104 size_t dataLen = 0; 1105 if (!extractor->ExtractToBufByName(modulePath, data, dataLen)) { 1106 TAG_LOGE(AAFwkTag::JSRUNTIME, "Get File Buffer abc file failed"); 1107 return false; 1108 } 1109 std::vector<uint8_t> buffer; 1110 buffer.assign(data.get(), data.get() + dataLen); 1111 1112 return LoadScript(abcPath, &buffer, isBundle_); 1113 } 1114 }; 1115 1116 if (useCommonChunk) { 1117 (void)func(commonsPath, commonsPath); 1118 (void)func(vendorsPath, vendorsPath); 1119 } 1120 1121 std::string path = srcPath; 1122 if (!isBundle_) { 1123 if (moduleName_.empty()) { 1124 TAG_LOGE(AAFwkTag::JSRUNTIME, "moduleName is hole"); 1125 return false; 1126 } 1127 path = BUNDLE_INSTALL_PATH + moduleName_ + MERGE_ABC_PATH; 1128 panda::JSNApi::SetAssetPath(vm, path); 1129 panda::JSNApi::SetModuleName(vm, moduleName_); 1130 } 1131 return func(path, srcPath); 1132} 1133 1134bool JsRuntime::RunSandboxScript(const std::string& path, const std::string& hapPath) 1135{ 1136 std::string fileName; 1137 if (!hapPath.empty()) { 1138 fileName.append(codePath_).append(Constants::FILE_SEPARATOR).append(path); 1139 std::regex pattern(std::string(Constants::FILE_DOT) + std::string(Constants::FILE_SEPARATOR)); 1140 fileName = std::regex_replace(fileName, pattern, ""); 1141 } else { 1142 if (!MakeFilePath(codePath_, path, fileName)) { 1143 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to make module file path: %{private}s", path.c_str()); 1144 return false; 1145 } 1146 } 1147 1148 if (!RunScript(fileName, hapPath)) { 1149 TAG_LOGE(AAFwkTag::JSRUNTIME, "Failed to run script: %{public}s", fileName.c_str()); 1150 return false; 1151 } 1152 return true; 1153} 1154 1155void JsRuntime::PostTask(const std::function<void()>& task, const std::string& name, int64_t delayTime) 1156{ 1157 CHECK_POINTER(jsEnv_); 1158 jsEnv_->PostTask(task, name, delayTime); 1159} 1160 1161void JsRuntime::PostSyncTask(const std::function<void()>& task, const std::string& name) 1162{ 1163 CHECK_POINTER(jsEnv_); 1164 jsEnv_->PostSyncTask(task, name); 1165} 1166 1167void JsRuntime::RemoveTask(const std::string& name) 1168{ 1169 CHECK_POINTER(jsEnv_); 1170 jsEnv_->RemoveTask(name); 1171} 1172 1173void JsRuntime::DumpCpuProfile() 1174{ 1175 auto nativeEngine = GetNativeEnginePointer(); 1176 CHECK_POINTER(nativeEngine); 1177 nativeEngine->DumpCpuProfile(); 1178} 1179 1180void JsRuntime::DumpHeapSnapshot(bool isPrivate) 1181{ 1182 auto nativeEngine = GetNativeEnginePointer(); 1183 CHECK_POINTER(nativeEngine); 1184 nativeEngine->DumpHeapSnapshot(true, DumpFormat::JSON, isPrivate, false); 1185} 1186 1187void JsRuntime::DumpHeapSnapshot(uint32_t tid, bool isFullGC) 1188{ 1189 auto vm = GetEcmaVm(); 1190 CHECK_POINTER(vm); 1191 panda::ecmascript::DumpSnapShotOption dumpOption; 1192 dumpOption.dumpFormat = panda::ecmascript::DumpFormat::JSON; 1193 dumpOption.isVmMode = true; 1194 dumpOption.isPrivate = false; 1195 dumpOption.captureNumericValue = true; 1196 dumpOption.isFullGC = isFullGC; 1197 dumpOption.isSync = false; 1198 DFXJSNApi::DumpHeapSnapshot(vm, dumpOption, tid); 1199} 1200 1201void JsRuntime::ForceFullGC(uint32_t tid) 1202{ 1203 auto vm = GetEcmaVm(); 1204 CHECK_POINTER(vm); 1205 DFXJSNApi::TriggerGC(vm, tid); 1206} 1207 1208void JsRuntime::DestroyHeapProfiler() 1209{ 1210 CHECK_POINTER(jsEnv_); 1211 jsEnv_->DestroyHeapProfiler(); 1212} 1213 1214void JsRuntime::ForceFullGC() 1215{ 1216 auto vm = GetEcmaVm(); 1217 CHECK_POINTER(vm); 1218 panda::JSNApi::TriggerGC(vm, panda::ecmascript::GCReason::TRIGGER_BY_ABILITY, 1219 panda::JSNApi::TRIGGER_GC_TYPE::FULL_GC); 1220} 1221 1222void JsRuntime::AllowCrossThreadExecution() 1223{ 1224 auto vm = GetEcmaVm(); 1225 CHECK_POINTER(vm); 1226 panda::JSNApi::AllowCrossThreadExecution(vm); 1227} 1228 1229void JsRuntime::GetHeapPrepare() 1230{ 1231 CHECK_POINTER(jsEnv_); 1232 jsEnv_->GetHeapPrepare(); 1233} 1234 1235void JsRuntime::NotifyApplicationState(bool isBackground) 1236{ 1237 auto nativeEngine = GetNativeEnginePointer(); 1238 CHECK_POINTER(nativeEngine); 1239 nativeEngine->NotifyApplicationState(isBackground); 1240 TAG_LOGD(AAFwkTag::JSRUNTIME, "isBackground %{public}d", isBackground); 1241} 1242 1243bool JsRuntime::SuspendVM(uint32_t tid) 1244{ 1245 auto nativeEngine = GetNativeEnginePointer(); 1246 CHECK_POINTER_AND_RETURN(nativeEngine, false); 1247 return nativeEngine->SuspendVMById(tid); 1248} 1249 1250void JsRuntime::ResumeVM(uint32_t tid) 1251{ 1252 auto nativeEngine = GetNativeEnginePointer(); 1253 CHECK_POINTER(nativeEngine); 1254 nativeEngine->ResumeVMById(tid); 1255} 1256 1257void JsRuntime::PreloadSystemModule(const std::string& moduleName) 1258{ 1259 HandleScope handleScope(*this); 1260 auto env = GetNapiEnv(); 1261 CHECK_POINTER(env); 1262 napi_value className = nullptr; 1263 napi_create_string_utf8(env, moduleName.c_str(), moduleName.length(), &className); 1264 napi_value globalObj = nullptr; 1265 napi_get_global(env, &globalObj); 1266 napi_value refValue = methodRequireNapiRef_->GetNapiValue(); 1267 napi_value args[1] = { className }; 1268 napi_call_function(env, globalObj, refValue, 1, args, nullptr); 1269} 1270 1271NativeEngine& JsRuntime::GetNativeEngine() const 1272{ 1273 return *GetNativeEnginePointer(); 1274} 1275 1276napi_env JsRuntime::GetNapiEnv() const 1277{ 1278 return reinterpret_cast<napi_env>(GetNativeEnginePointer()); 1279} 1280 1281NativeEngine* JsRuntime::GetNativeEnginePointer() const 1282{ 1283 CHECK_POINTER_AND_RETURN(jsEnv_, nullptr); 1284 return jsEnv_->GetNativeEngine(); 1285} 1286 1287panda::ecmascript::EcmaVM* JsRuntime::GetEcmaVm() const 1288{ 1289 CHECK_POINTER_AND_RETURN(jsEnv_, nullptr); 1290 return jsEnv_->GetVM(); 1291} 1292 1293bool JsRuntime::IsUseAbilityRuntime(const Options& options) const 1294{ 1295 return (options.isStageModel) || (options.isTestFramework); 1296} 1297 1298void JsRuntime::UpdateModuleNameAndAssetPath(const std::string& moduleName) 1299{ 1300 if (isBundle_) { 1301 return; 1302 } 1303 1304 auto vm = GetEcmaVm(); 1305 if (!vm || moduleName.empty()) { 1306 TAG_LOGE(AAFwkTag::JSRUNTIME, "vm is nullptr or moduleName is empty"); 1307 return; 1308 } 1309 1310 moduleName_ = moduleName; 1311 std::string path = BUNDLE_INSTALL_PATH + moduleName_ + MERGE_ABC_PATH; 1312 panda::JSNApi::SetAssetPath(vm, path); 1313 panda::JSNApi::SetModuleName(vm, moduleName_); 1314} 1315 1316void JsRuntime::RegisterUncaughtExceptionHandler(const JsEnv::UncaughtExceptionInfo& uncaughtExceptionInfo) 1317{ 1318 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1319 CHECK_POINTER(jsEnv_); 1320 jsEnv_->RegisterUncaughtExceptionHandler(uncaughtExceptionInfo); 1321} 1322 1323void JsRuntime::RegisterQuickFixQueryFunc(const std::map<std::string, std::string>& moduleAndPath) 1324{ 1325 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1326 auto vm = GetEcmaVm(); 1327 CHECK_POINTER(vm); 1328 for (auto it = moduleAndPath.begin(); it != moduleAndPath.end(); it++) { 1329 std::string hqfFile(AbilityBase::GetLoadPath(it->second)); 1330 InitSourceMap(hqfFile); 1331 } 1332 panda::JSNApi::RegisterQuickFixQueryFunc(vm, JsQuickfixCallback(moduleAndPath)); 1333} 1334 1335bool JsRuntime::ReadSourceMapData(const std::string& hapPath, const std::string& sourceMapPath, std::string& content) 1336{ 1337 // Source map relative path, FA: "/assets/js", Stage: "/ets" 1338 if (hapPath.empty()) { 1339 TAG_LOGE(AAFwkTag::JSRUNTIME, "empty hapPath"); 1340 return false; 1341 } 1342 bool newCreate = false; 1343 std::shared_ptr<Extractor> extractor = ExtractorUtil::GetExtractor( 1344 ExtractorUtil::GetLoadFilePath(hapPath), newCreate); 1345 if (extractor == nullptr) { 1346 TAG_LOGE(AAFwkTag::JSRUNTIME, "hap's path: %{public}s, get extractor failed", hapPath.c_str()); 1347 return false; 1348 } 1349 std::unique_ptr<uint8_t[]> dataPtr = nullptr; 1350 size_t len = 0; 1351 if (!extractor->ExtractToBufByName(sourceMapPath, dataPtr, len)) { 1352 TAG_LOGD(AAFwkTag::JSRUNTIME, "can't find source map, and switch to stage model"); 1353 std::string tempPath = std::regex_replace(sourceMapPath, std::regex("ets"), "assets/js"); 1354 if (!extractor->ExtractToBufByName(tempPath, dataPtr, len)) { 1355 TAG_LOGD(AAFwkTag::JSRUNTIME, "get mergeSourceMapData fileBuffer failed, map path: %{private}s", 1356 tempPath.c_str()); 1357 return false; 1358 } 1359 } 1360 content.assign(dataPtr.get(), dataPtr.get() + len); 1361 return true; 1362} 1363 1364void JsRuntime::FreeNativeReference(std::unique_ptr<NativeReference> reference) 1365{ 1366 FreeNativeReference(std::move(reference), nullptr); 1367} 1368 1369void JsRuntime::FreeNativeReference(std::shared_ptr<NativeReference>&& reference) 1370{ 1371 FreeNativeReference(nullptr, std::move(reference)); 1372} 1373 1374struct JsNativeReferenceDeleterObject { 1375 std::unique_ptr<NativeReference> uniqueNativeRef_ = nullptr; 1376 std::shared_ptr<NativeReference> sharedNativeRef_ = nullptr; 1377}; 1378 1379void JsRuntime::FreeNativeReference(std::unique_ptr<NativeReference> uniqueNativeRef, 1380 std::shared_ptr<NativeReference>&& sharedNativeRef) 1381{ 1382 if (uniqueNativeRef == nullptr && sharedNativeRef == nullptr) { 1383 TAG_LOGW(AAFwkTag::JSRUNTIME, "invalid nativeRef"); 1384 return; 1385 } 1386 1387 auto nativeEngine = GetNativeEnginePointer(); 1388 CHECK_POINTER(nativeEngine); 1389 auto uvLoop = nativeEngine->GetUVLoop(); 1390 CHECK_POINTER(uvLoop); 1391 1392 auto work = new (std::nothrow) uv_work_t; 1393 if (work == nullptr) { 1394 TAG_LOGE(AAFwkTag::JSRUNTIME, "null work"); 1395 return; 1396 } 1397 1398 auto cb = new (std::nothrow) JsNativeReferenceDeleterObject(); 1399 if (cb == nullptr) { 1400 TAG_LOGE(AAFwkTag::JSRUNTIME, "null cb"); 1401 delete work; 1402 work = nullptr; 1403 return; 1404 } 1405 1406 if (uniqueNativeRef != nullptr) { 1407 cb->uniqueNativeRef_ = std::move(uniqueNativeRef); 1408 } 1409 if (sharedNativeRef != nullptr) { 1410 cb->sharedNativeRef_ = std::move(sharedNativeRef); 1411 } 1412 work->data = reinterpret_cast<void*>(cb); 1413 int ret = uv_queue_work(uvLoop, work, [](uv_work_t *work) {}, 1414 [](uv_work_t *work, int status) { 1415 if (work != nullptr) { 1416 if (work->data != nullptr) { 1417 delete reinterpret_cast<JsNativeReferenceDeleterObject*>(work->data); 1418 work->data = nullptr; 1419 } 1420 delete work; 1421 work = nullptr; 1422 } 1423 }); 1424 if (ret != 0) { 1425 delete reinterpret_cast<JsNativeReferenceDeleterObject*>(work->data); 1426 work->data = nullptr; 1427 delete work; 1428 work = nullptr; 1429 } 1430} 1431 1432void JsRuntime::InitTimerModule() 1433{ 1434 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1435 CHECK_POINTER(jsEnv_); 1436 jsEnv_->InitTimerModule(); 1437} 1438 1439void JsRuntime::InitWorkerModule(const Options& options) 1440{ 1441 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1442 CHECK_POINTER(jsEnv_); 1443 std::shared_ptr<JsEnv::WorkerInfo> workerInfo = std::make_shared<JsEnv::WorkerInfo>(); 1444 workerInfo->codePath = panda::panda_file::StringPacProtect(options.codePath); 1445 workerInfo->isDebugVersion = options.isDebugVersion; 1446 workerInfo->isBundle = options.isBundle; 1447 workerInfo->packagePathStr = options.packagePathStr; 1448 workerInfo->assetBasePathStr = options.assetBasePathStr; 1449 workerInfo->hapPath = panda::panda_file::StringPacProtect(options.hapPath); 1450 workerInfo->isStageModel = panda::panda_file::BoolPacProtect(options.isStageModel); 1451 workerInfo->moduleName = options.moduleName; 1452 workerInfo->apiTargetVersion = panda::panda_file::DataProtect(static_cast<uintptr_t>(options.apiTargetVersion)); 1453 if (options.isJsFramework) { 1454 SetJsFramework(); 1455 } 1456 jsEnv_->InitWorkerModule(workerInfo); 1457} 1458 1459void JsRuntime::ReInitJsEnvImpl(const Options& options) 1460{ 1461 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1462 CHECK_POINTER(jsEnv_); 1463 jsEnv_->ReInitJsEnvImpl(std::make_unique<OHOSJsEnvironmentImpl>(options.eventRunner)); 1464} 1465 1466void JsRuntime::SetModuleLoadChecker(const std::shared_ptr<ModuleCheckerDelegate> moduleCheckerDelegate) const 1467{ 1468 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1469 CHECK_POINTER(jsEnv_); 1470 jsEnv_->SetModuleLoadChecker(moduleCheckerDelegate); 1471} 1472 1473void JsRuntime::SetRequestAotCallback() 1474{ 1475 HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 1476 CHECK_POINTER(jsEnv_); 1477 auto callback = [](const std::string& bundleName, const std::string& moduleName, int32_t triggerMode) -> int32_t { 1478 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 1479 if (systemAbilityMgr == nullptr) { 1480 TAG_LOGE(AAFwkTag::JSRUNTIME, "get SaMgr failed"); 1481 return ERR_INVALID_VALUE; 1482 } 1483 1484 auto remoteObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); 1485 if (remoteObj == nullptr) { 1486 TAG_LOGE(AAFwkTag::JSRUNTIME, "null remoteObject"); 1487 return ERR_INVALID_VALUE; 1488 } 1489 1490 auto bundleMgr = iface_cast<AppExecFwk::IBundleMgr>(remoteObj); 1491 if (bundleMgr == nullptr) { 1492 TAG_LOGE(AAFwkTag::JSRUNTIME, "get bms failed"); 1493 return ERR_INVALID_VALUE; 1494 } 1495 1496 TAG_LOGD(AAFwkTag::JSRUNTIME, 1497 "Reset compile status, bundleName: %{public}s, moduleName: %{public}s, triggerMode: %{public}d", 1498 bundleName.c_str(), moduleName.c_str(), triggerMode); 1499 return bundleMgr->ResetAOTCompileStatus(bundleName, moduleName, triggerMode); 1500 }; 1501 1502 jsEnv_->SetRequestAotCallback(callback); 1503} 1504 1505void JsRuntime::SetDeviceDisconnectCallback(const std::function<bool()> &cb) 1506{ 1507 TAG_LOGD(AAFwkTag::JSRUNTIME, "called"); 1508 CHECK_POINTER(jsEnv_); 1509 jsEnv_->SetDeviceDisconnectCallback(cb); 1510} 1511 1512std::string JsRuntime::GetSystemKitPath() 1513{ 1514 char buf[MAX_PATH_LEN] = { 0 }; 1515 char *configPath = GetOneCfgFile(CONFIG_PATH.c_str(), buf, MAX_PATH_LEN); 1516 if (configPath == nullptr || configPath[0] == '\0' || strlen(configPath) > MAX_PATH_LEN) { 1517 return SYSTEM_KITS_CONFIG_PATH; 1518 } 1519 return configPath; 1520} 1521 1522std::vector<panda::HmsMap> JsRuntime::GetSystemKitsMap(uint32_t version) 1523{ 1524 std::vector<panda::HmsMap> systemKitsMap; 1525 nlohmann::json jsonBuf; 1526 std::string configPath = GetSystemKitPath(); 1527 if (configPath == "" || access(configPath.c_str(), F_OK) != 0) { 1528 return systemKitsMap; 1529 } 1530 1531 std::fstream in; 1532 char errBuf[256]; 1533 errBuf[0] = '\0'; 1534 in.open(configPath, std::ios_base::in); 1535 if (!in.is_open()) { 1536 strerror_r(errno, errBuf, sizeof(errBuf)); 1537 return systemKitsMap; 1538 } 1539 1540 in.seekg(0, std::ios::end); 1541 int64_t size = in.tellg(); 1542 if (size <= 0) { 1543 in.close(); 1544 return systemKitsMap; 1545 } 1546 1547 in.seekg(0, std::ios::beg); 1548 jsonBuf = nlohmann::json::parse(in, nullptr, false); 1549 in.close(); 1550 if (jsonBuf.is_discarded()) { 1551 return systemKitsMap; 1552 } 1553 1554 if (!jsonBuf.contains(SYSTEM_KITS)) { 1555 return systemKitsMap; 1556 } 1557 for (auto &item : jsonBuf.at(SYSTEM_KITS).items()) { 1558 nlohmann::json& jsonObject = item.value(); 1559 if (!jsonObject.contains(NAMESPACE) || !jsonObject.at(NAMESPACE).is_string() || 1560 !jsonObject.contains(TARGET_OHM) || !jsonObject.at(TARGET_OHM).is_string() || 1561 !jsonObject.contains(SINCE_VERSION) || !jsonObject.at(SINCE_VERSION).is_number()) { 1562 continue; 1563 } 1564 uint32_t sinceVersion = jsonObject.at(SINCE_VERSION).get<uint32_t>(); 1565 if (version >= sinceVersion) { 1566 panda::HmsMap hmsMap = { 1567 .originalPath = jsonObject.at(NAMESPACE).get<std::string>(), 1568 .targetPath = jsonObject.at(TARGET_OHM).get<std::string>(), 1569 .sinceVersion = sinceVersion 1570 }; 1571 systemKitsMap.emplace_back(hmsMap); 1572 } 1573 } 1574 TAG_LOGD(AAFwkTag::JSRUNTIME, "The size of the map is %{public}zu", systemKitsMap.size()); 1575 return systemKitsMap; 1576} 1577 1578void JsRuntime::UpdatePkgContextInfoJson(std::string moduleName, std::string hapPath, std::string packageName) 1579{ 1580 auto iterator = pkgContextInfoJsonStringMap_.find(moduleName); 1581 if (iterator == pkgContextInfoJsonStringMap_.end()) { 1582 pkgContextInfoJsonStringMap_[moduleName] = hapPath; 1583 packageNameList_[moduleName] = packageName; 1584 auto vm = GetEcmaVm(); 1585 std::map<std::string, std::vector<std::vector<std::string>>> pkgContextInfoMap; 1586 std::map<std::string, std::string> pkgAliasMap; 1587 JsRuntimeLite::GetInstance().GetPkgContextInfoListMap( 1588 pkgContextInfoJsonStringMap_, pkgContextInfoMap, pkgAliasMap); 1589 panda::JSNApi::SetpkgContextInfoList(vm, pkgContextInfoMap); 1590 panda::JSNApi::SetPkgAliasList(vm, pkgAliasMap); 1591 panda::JSNApi::SetPkgNameList(vm, packageNameList_); 1592 } 1593} 1594} // namespace AbilityRuntime 1595} // namespace OHOS 1596