1 /*
2 * Copyright (c) 2021-2023 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 "frameworks/bridge/js_frontend/engine/jsi/ark_js_runtime.h"
17
18 #include <unistd.h>
19
20 #include "ecmascript/napi/include/dfx_jsnapi.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 #include "frameworks/bridge/js_frontend/engine/jsi/ark_js_value.h"
23 #include "frameworks/core/common/ace_application_info.h"
24 #include "frameworks/core/common/connect_server_manager.h"
25 #include "frameworks/core/common/hdc_register.h"
26
27 // NOLINTNEXTLINE(readability-identifier-naming)
28 namespace OHOS::Ace::Framework {
29 // NOLINTNEXTLINE(readability-identifier-naming)
30 static constexpr auto PANDA_MAIN_FUNCTION = "_GLOBAL::func_main_0";
31 #if !defined(PREVIEW)
32 constexpr auto DEBUGGER = "@Debugger";
33 #endif
34
FunctionCallback(panda::JsiRuntimeCallInfo * info)35 Local<JSValueRef> FunctionCallback(panda::JsiRuntimeCallInfo* info)
36 {
37 auto package = reinterpret_cast<PandaFunctionData*>(info->GetData());
38 if (package == nullptr) {
39 return JSValueRef::Undefined(info->GetVM());
40 }
41 return package->Callback(info);
42 }
43
FunctionDeleter(void * env,void * nativePointer,void * data)44 void FunctionDeleter(void *env, void *nativePointer, void *data)
45 {
46 auto info = reinterpret_cast<PandaFunctionData*>(data);
47 if (info != nullptr) {
48 delete info;
49 }
50 }
51
52 thread_local EcmaVM* ArkJSRuntime::threadVm_ = nullptr;
53
Initialize(const std::string & libraryPath,bool isDebugMode,int32_t instanceId)54 bool ArkJSRuntime::Initialize(const std::string& libraryPath, bool isDebugMode, int32_t instanceId)
55 {
56 RuntimeOption option;
57 option.SetGcType(RuntimeOption::GC_TYPE::GEN_GC);
58 #ifdef OHOS_PLATFORM
59 option.SetArkProperties(SystemProperties::GetArkProperties());
60 option.SetArkBundleName(SystemProperties::GetArkBundleName());
61 option.SetMemConfigProperty(SystemProperties::GetMemConfigProperty());
62 option.SetGcThreadNum(SystemProperties::GetGcThreadNum());
63 option.SetLongPauseTime(SystemProperties::GetLongPauseTime());
64 option.SetEnableAsmInterpreter(SystemProperties::GetAsmInterpreterEnabled());
65 option.SetAsmOpcodeDisableRange(SystemProperties::GetAsmOpcodeDisableRange());
66 LOGI("Initialize ark properties = %{public}d, bundlename = %{public}s", SystemProperties::GetArkProperties(),
67 SystemProperties::GetArkBundleName().c_str());
68 #endif
69 const int64_t poolSize = 0x10000000; // 256M
70 option.SetGcPoolSize(poolSize);
71 option.SetLogLevel(RuntimeOption::LOG_LEVEL::FOLLOW);
72 option.SetLogBufPrint(print_);
73 option.SetDebuggerLibraryPath(libraryPath);
74 libPath_ = libraryPath;
75 isDebugMode_ = isDebugMode;
76 instanceId_ = instanceId;
77
78 vm_ = JSNApi::CreateJSVM(option);
79 #if defined(PREVIEW)
80 if (!pkgNameMap_.empty()) {
81 JSNApi::SetPkgNameList(vm_, pkgNameMap_);
82 }
83 if (!pkgAliasMap_.empty()) {
84 JSNApi::SetPkgAliasList(vm_, pkgAliasMap_);
85 }
86 if (!pkgContextInfoMap_.empty()) {
87 JSNApi::SetpkgContextInfoList(vm_, pkgContextInfoMap_);
88 }
89 #endif
90 return vm_ != nullptr;
91 }
92
InitializeFromExistVM(EcmaVM * vm)93 bool ArkJSRuntime::InitializeFromExistVM(EcmaVM* vm)
94 {
95 vm_ = vm;
96 usingExistVM_ = true;
97 return vm_ != nullptr;
98 }
99
Reset()100 void ArkJSRuntime::Reset()
101 {
102 if (vm_ != nullptr) {
103 if (!usingExistVM_) {
104 #if !defined(PREVIEW)
105 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
106 HdcRegister::Get().StopHdcRegister(instanceId_);
107 ConnectServerManager::Get().RemoveInstance(instanceId_);
108 #endif
109 JSNApi::StopDebugger(vm_);
110 #endif
111 JSNApi::DestroyJSVM(vm_);
112 vm_ = nullptr;
113 }
114 }
115 #if defined(PREVIEW)
116 previewComponents_.clear();
117 #endif
118 }
119
SetLogPrint(LOG_PRINT out)120 void ArkJSRuntime::SetLogPrint(LOG_PRINT out)
121 {
122 print_ = out;
123 }
124
125 #if !defined(PREVIEW) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
ParseHdcRegisterOption(std::string & option)126 static int ParseHdcRegisterOption(std::string& option)
127 {
128 LOGI("hdc option is %{public}s ", option.c_str());
129 if (option.find(":") == std::string::npos) {
130 return -1;
131 }
132 std::size_t pos = option.find_first_of(":");
133 std::string idStr = option.substr(pos + 1);
134 if (idStr.find(DEBUGGER) == std::string::npos) {
135 return -1;
136 }
137 pos = idStr.find(DEBUGGER);
138 idStr = idStr.substr(0, pos);
139 if (idStr.find("@") != std::string::npos) {
140 pos = idStr.find("@");
141 idStr = idStr.substr(pos + 1);
142 }
143 return static_cast<uint32_t>(std::atol(idStr.c_str()));
144 }
145
StartDebuggerForSocketPair(std::string & option,uint32_t socketFd)146 void ArkJSRuntime::StartDebuggerForSocketPair(std::string& option, uint32_t socketFd)
147 {
148 CHECK_NULL_VOID(vm_);
149 int identifierId = ParseHdcRegisterOption(option);
150 panda::JSNApi::StartDebuggerForSocketPair(identifierId, socketFd);
151 }
152 #endif
153
StartDebugger()154 bool ArkJSRuntime::StartDebugger()
155 {
156 bool ret = false;
157 #if !defined(PREVIEW)
158 if (!libPath_.empty()) {
159 bool isDebugApp = AceApplicationInfo::GetInstance().IsDebugVersion();
160 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
161 auto callback = [weak = weak_from_this(), isDebugApp](int socketFd, std::string option) {
162 LOGI("HdcRegister callback socket %{public}d, option %{public}s.", socketFd, option.c_str());
163 if (option.find(DEBUGGER) == std::string::npos) {
164 if (isDebugApp) {
165 ConnectServerManager::Get().StopConnectServer();
166 }
167 ConnectServerManager::Get().StartConnectServerWithSocketPair(socketFd);
168 } else {
169 auto runtime = weak.lock();
170 CHECK_NULL_VOID(runtime);
171 if (isDebugApp) {
172 JSNApi::StopDebugger(ParseHdcRegisterOption(option));
173 }
174 runtime->StartDebuggerForSocketPair(option, socketFd);
175 }
176 };
177
178 HdcRegister::Get().StartHdcRegister(instanceId_, callback);
179 ConnectServerManager::Get().SetDebugMode();
180 #endif
181 //FA:true port:-1
182 JSNApi::DebugOption debugOption = { libPath_.c_str(), isDebugApp ? isDebugMode_ : false, -1, true };
183 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
184 ConnectServerManager::Get().AddInstance(gettid(), language_);
185 ret = JSNApi::NotifyDebugMode(gettid(), vm_, debugOption, gettid(), debuggerPostTask_, isDebugApp);
186 #elif defined(ANDROID_PLATFORM)
187 ret = JSNApi::StartDebugger(vm_, debugOption, instanceId_, debuggerPostTask_);
188 #endif
189 }
190 #if defined(IOS_PLATFORM)
191 JSNApi::DebugOption debugOption = { nullptr, isDebugMode_, -1, true }; //FA:true port:-1
192 ret = JSNApi::StartDebugger(vm_, debugOption, instanceId_, debuggerPostTask_);
193 #endif
194 #endif
195 return ret;
196 }
197
IsExecuteModuleInAbcFile(const std::string & bundleName,const std::string & moduleName,const std::string & ohmurl)198 bool ArkJSRuntime::IsExecuteModuleInAbcFile(
199 const std::string &bundleName, const std::string &moduleName, const std::string &ohmurl)
200 {
201 JSExecutionScope executionScope(vm_);
202 LocalScope scope(vm_);
203 panda::TryCatch trycatch(vm_);
204 bool ret = JSNApi::IsExecuteModuleInAbcFile(vm_, bundleName, moduleName, ohmurl);
205 HandleUncaughtException(trycatch);
206 return ret;
207 }
208
IsStaticOrInvalidFile(const uint8_t * data,int32_t size)209 bool ArkJSRuntime::IsStaticOrInvalidFile(const uint8_t *data, int32_t size)
210 {
211 JSExecutionScope executionScope(vm_);
212 LocalScope scope(vm_);
213 panda::TryCatch trycatch(vm_);
214 JSNApi::PandaFileType fileType = JSNApi::GetFileType(data, size);
215 bool ret;
216 switch (fileType) {
217 case JSNApi::PandaFileType::FILE_DYNAMIC:
218 ret = false;
219 LOGI("ArkJSRuntime::IsStaticOrInvalidFile, file is dynamic");
220 break;
221 case JSNApi::PandaFileType::FILE_STATIC:
222 ret = true;
223 LOGI("ArkJSRuntime::IsStaticOrInvalidFile, file is static");
224 break;
225 case JSNApi::PandaFileType::FILE_FORMAT_INVALID:
226 ret = true;
227 LOGE("ArkJSRuntime::IsStaticOrInvalidFile, file is invalid. reason is param invalid");
228 break;
229 default:
230 ret = true;
231 LOGE("ArkJSRuntime::IsStaticOrInvalidFile, file is invalid");
232 }
233
234 HandleUncaughtException(trycatch);
235 return ret;
236 }
237
ExecuteModuleBuffer(const uint8_t * data,int32_t size,const std::string & filename,bool needUpdate)238 bool ArkJSRuntime::ExecuteModuleBuffer(const uint8_t* data, int32_t size, const std::string& filename, bool needUpdate)
239 {
240 JSExecutionScope executionScope(vm_);
241 LocalScope scope(vm_);
242 panda::TryCatch trycatch(vm_);
243 bool ret = JSNApi::ExecuteModuleBuffer(vm_, data, size, filename, needUpdate);
244 HandleUncaughtException(trycatch);
245 return ret;
246 }
247
EvaluateJsCode(const std::string & src)248 shared_ptr<JsValue> ArkJSRuntime::EvaluateJsCode([[maybe_unused]] const std::string& src)
249 {
250 return NewUndefined();
251 }
252
EvaluateJsCode(const uint8_t * buffer,int32_t size,const std::string & filePath,bool needUpdate)253 bool ArkJSRuntime::EvaluateJsCode(const uint8_t* buffer, int32_t size, const std::string& filePath, bool needUpdate)
254 {
255 JSExecutionScope executionScope(vm_);
256 LocalScope scope(vm_);
257 panda::TryCatch trycatch(vm_);
258 bool ret = JSNApi::Execute(vm_, buffer, size, PANDA_MAIN_FUNCTION, filePath, needUpdate);
259 HandleUncaughtException(trycatch);
260 return ret;
261 }
262
ExecuteJsBin(const std::string & fileName,const std::function<void (const std::string &,int32_t)> & errorCallback)263 bool ArkJSRuntime::ExecuteJsBin(const std::string& fileName,
264 const std::function<void(const std::string&, int32_t)>& errorCallback)
265 {
266 JSExecutionScope executionScope(vm_);
267 LocalScope scope(vm_);
268 panda::TryCatch trycatch(vm_);
269 bool ret = JSNApi::Execute(vm_, fileName, PANDA_MAIN_FUNCTION);
270 HandleUncaughtException(trycatch, errorCallback);
271 return ret;
272 }
273
ExecuteJsBinForAOT(const std::string & fileName,const std::function<void (const std::string &,int32_t)> & errorCallback)274 bool ArkJSRuntime::ExecuteJsBinForAOT(const std::string& fileName,
275 const std::function<void(const std::string&, int32_t)>& errorCallback)
276 {
277 JSExecutionScope executionScope(vm_);
278 LocalScope scope(vm_);
279 panda::TryCatch trycatch(vm_);
280 bool ret = JSNApi::ExecuteForAbsolutePath(vm_, fileName, PANDA_MAIN_FUNCTION);
281 HandleUncaughtException(trycatch, errorCallback);
282 return ret;
283 }
284
GetGlobal()285 shared_ptr<JsValue> ArkJSRuntime::GetGlobal()
286 {
287 LocalScope scope(vm_);
288 return std::make_shared<ArkJSValue>(shared_from_this(), JSNApi::GetGlobalObject(vm_));
289 }
290
GetGlobal(ArkNativeEngine * nativeArkEngine)291 shared_ptr<JsValue> ArkJSRuntime::GetGlobal(ArkNativeEngine* nativeArkEngine)
292 {
293 LocalScope scope(vm_);
294 CHECK_NULL_RETURN(nativeArkEngine, nullptr);
295 return std::make_shared<ArkJSValue>(
296 shared_from_this(), JSNApi::GetGlobalObject(vm_, nativeArkEngine->GetContext()));
297 }
298
RunGC()299 void ArkJSRuntime::RunGC()
300 {
301 JSExecutionScope executionScope(vm_);
302 LocalScope scope(vm_);
303 JSNApi::HintGC(vm_, JSNApi::MemoryReduceDegree::LOW, panda::ecmascript::GCReason::TRIGGER_BY_ARKUI);
304 }
305
RunFullGC()306 void ArkJSRuntime::RunFullGC()
307 {
308 JSExecutionScope executionScope(vm_);
309 LocalScope scope(vm_);
310 JSNApi::HintGC(vm_, JSNApi::MemoryReduceDegree::HIGH, panda::ecmascript::GCReason::TRIGGER_BY_ARKUI);
311 }
312
NewInt32(int32_t value)313 shared_ptr<JsValue> ArkJSRuntime::NewInt32(int32_t value)
314 {
315 LocalScope scope(vm_);
316 return std::make_shared<ArkJSValue>(shared_from_this(), IntegerRef::New(vm_, value));
317 }
318
NewBoolean(bool value)319 shared_ptr<JsValue> ArkJSRuntime::NewBoolean(bool value)
320 {
321 LocalScope scope(vm_);
322 return std::make_shared<ArkJSValue>(shared_from_this(), BooleanRef::New(vm_, value));
323 }
324
NewNumber(double d)325 shared_ptr<JsValue> ArkJSRuntime::NewNumber(double d)
326 {
327 LocalScope scope(vm_);
328 return std::make_shared<ArkJSValue>(shared_from_this(), NumberRef::New(vm_, d));
329 }
330
NewNull()331 shared_ptr<JsValue> ArkJSRuntime::NewNull()
332 {
333 LocalScope scope(vm_);
334 return std::make_shared<ArkJSValue>(shared_from_this(), JSValueRef::Null(vm_));
335 }
336
NewUndefined()337 shared_ptr<JsValue> ArkJSRuntime::NewUndefined()
338 {
339 LocalScope scope(vm_);
340 return std::make_shared<ArkJSValue>(shared_from_this(), JSValueRef::Undefined(vm_));
341 }
342
NewString(const std::string & str)343 shared_ptr<JsValue> ArkJSRuntime::NewString(const std::string& str)
344 {
345 LocalScope scope(vm_);
346 return std::make_shared<ArkJSValue>(shared_from_this(), StringRef::NewFromUtf8(vm_, str.c_str()));
347 }
348
ParseJson(const std::string & str)349 shared_ptr<JsValue> ArkJSRuntime::ParseJson(const std::string& str)
350 {
351 LocalScope scope(vm_);
352 Local<StringRef> string = StringRef::NewFromUtf8(vm_, str.c_str());
353 return std::make_shared<ArkJSValue>(shared_from_this(), JSON::Parse(vm_, string));
354 }
355
NewObject()356 shared_ptr<JsValue> ArkJSRuntime::NewObject()
357 {
358 LocalScope scope(vm_);
359 return std::make_shared<ArkJSValue>(shared_from_this(), ObjectRef::New(vm_));
360 }
361
NewArray()362 shared_ptr<JsValue> ArkJSRuntime::NewArray()
363 {
364 LocalScope scope(vm_);
365 return std::make_shared<ArkJSValue>(shared_from_this(), ArrayRef::New(vm_));
366 }
367
NewFunction(RegisterFunctionType func)368 shared_ptr<JsValue> ArkJSRuntime::NewFunction(RegisterFunctionType func)
369 {
370 LocalScope scope(vm_);
371 auto data = new PandaFunctionData(shared_from_this(), func);
372 return std::make_shared<ArkJSValue>(shared_from_this(),
373 FunctionRef::NewConcurrent(vm_, FunctionCallback, FunctionDeleter, data));
374 }
375
NewNativePointer(void * ptr)376 shared_ptr<JsValue> ArkJSRuntime::NewNativePointer(void* ptr)
377 {
378 LocalScope scope(vm_);
379 return std::make_shared<ArkJSValue>(shared_from_this(), NativePointerRef::New(vm_, ptr));
380 }
381
ThrowError(const std::string & msg,int32_t code)382 void ArkJSRuntime::ThrowError(const std::string& msg, int32_t code)
383 {
384 auto errorVal = panda::Exception::Error(vm_, panda::StringRef::NewFromUtf8(vm_, msg.c_str()));
385 auto codeVal = panda::Exception::Error(vm_, panda::StringRef::NewFromUtf8(vm_, std::to_string(code).c_str()));
386 Local<StringRef> codeKey = StringRef::NewFromUtf8(vm_, "code");
387 Local<ObjectRef> errorObj(errorVal);
388 errorObj->Set(vm_, codeKey, codeVal);
389 panda::JSNApi::ThrowException(vm_, errorObj);
390 }
391
RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback)392 void ArkJSRuntime::RegisterUncaughtExceptionHandler(UncaughtExceptionCallback callback)
393 {
394 JSNApi::EnableUserUncaughtErrorHandler(vm_);
395 uncaughtErrorHandler_ = callback;
396 }
397
HasPendingException()398 bool ArkJSRuntime::HasPendingException()
399 {
400 return JSNApi::HasPendingException(vm_);
401 }
402
HandleUncaughtException(panda::TryCatch & trycatch,const std::function<void (const std::string &,int32_t)> & errorCallback)403 void ArkJSRuntime::HandleUncaughtException(panda::TryCatch& trycatch,
404 const std::function<void(const std::string&, int32_t)>& errorCallback)
405 {
406 if (errorCallback != nullptr) {
407 Local<ObjectRef> exception = trycatch.GetAndClearException();
408 if (!exception.IsEmpty() && !exception->IsHole()) {
409 errorCallback("loading js file has crash or the uri of router is not exist.",
410 ERROR_CODE_URI_ERROR);
411 return;
412 }
413 }
414
415 // Handle the uncaught exception by native engine created by ability runtime in the stage model project.
416 if (nativeEngine_) {
417 nativeEngine_->HandleUncaughtException();
418 return;
419 }
420
421 // Handle the uncaught exception without native engine, such as oom error
422 HandleUncaughtExceptionWithoutNativeEngine(trycatch, errorCallback);
423 }
424
HandleUncaughtExceptionWithoutNativeEngine(panda::TryCatch & trycatch,const std::function<void (const std::string &,int32_t)> & errorCallback)425 void ArkJSRuntime::HandleUncaughtExceptionWithoutNativeEngine(panda::TryCatch& trycatch,
426 const std::function<void(const std::string&, int32_t)>& errorCallback)
427 {
428 if (uncaughtErrorHandler_ == nullptr) {
429 return;
430 }
431
432 Local<ObjectRef> exception = trycatch.GetAndClearException();
433 if (!exception.IsEmpty() && !exception->IsHole()) {
434 shared_ptr<JsValue> errorPtr =
435 std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(shared_from_this(), exception));
436 uncaughtErrorHandler_(errorPtr, shared_from_this());
437 }
438 }
439
ExecutePendingJob()440 void ArkJSRuntime::ExecutePendingJob()
441 {
442 LocalScope scope(vm_);
443 JSNApi::ExecutePendingJob(vm_);
444 }
445
NotifyUIIdle()446 void ArkJSRuntime::NotifyUIIdle()
447 {
448 LocalScope scope(vm_);
449 panda::JSNApi::NotifyUIIdle(vm_, 0);
450 }
451
452 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
DumpHeapSnapshot(bool isPrivate)453 void ArkJSRuntime::DumpHeapSnapshot(bool isPrivate)
454 {
455 panda::ecmascript::DumpSnapShotOption dumpOption;
456 dumpOption.dumpFormat = panda::ecmascript::DumpFormat::JSON;
457 dumpOption.isVmMode = true;
458 dumpOption.isPrivate = isPrivate;
459 dumpOption.isSync = false;
460 LocalScope scope(vm_);
461 panda::DFXJSNApi::DumpHeapSnapshot(vm_, dumpOption);
462 }
463 #else
DumpHeapSnapshot(bool isPrivate)464 void ArkJSRuntime::DumpHeapSnapshot(bool isPrivate)
465 {
466 LOGE("Do not support Ark DumpHeapSnapshot on Windows or MacOS");
467 }
468 #endif
469
470 #if !defined(PREVIEW) && !defined(IOS_PLATFORM)
DestroyHeapProfiler()471 void ArkJSRuntime::DestroyHeapProfiler()
472 {
473 LocalScope scope(vm_);
474 panda::DFXJSNApi::DestroyHeapProfiler(vm_);
475 }
476 #else
DestroyHeapProfiler()477 void ArkJSRuntime::DestroyHeapProfiler()
478 {
479 LOGE("Do not support Ark DestroyHeapProfiler on Windows or MacOS");
480 }
481 #endif
482
Callback(panda::JsiRuntimeCallInfo * info) const483 Local<JSValueRef> PandaFunctionData::Callback(panda::JsiRuntimeCallInfo* info) const
484 {
485 auto runtime = runtime_.lock();
486 if (runtime == nullptr) {
487 return Local<JSValueRef>();
488 }
489 EscapeLocalScope scope(runtime->GetEcmaVm());
490 shared_ptr<JsValue> thisPtr =
491 std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime, info->GetThisRef()));
492
493 std::vector<shared_ptr<JsValue>> argv;
494 uint32_t length = info->GetArgsNumber();
495 argv.reserve(length);
496 for (uint32_t i = 0; i < length; ++i) {
497 argv.emplace_back(
498 std::static_pointer_cast<JsValue>(std::make_shared<ArkJSValue>(runtime, info->GetCallArgRef(i))));
499 }
500 shared_ptr<JsValue> result = func_(runtime, thisPtr, argv, length);
501 return scope.Escape(std::static_pointer_cast<ArkJSValue>(result)->GetValue(runtime));
502 }
503
LoadDestinationFile(const std::string & bundleName,const std::string & moduleName,const std::string & pageSourceFile,bool isSingleton)504 int32_t ArkJSRuntime::LoadDestinationFile(const std::string& bundleName, const std::string& moduleName,
505 const std::string& pageSourceFile, bool isSingleton)
506 {
507 JSExecutionScope executionScope(vm_);
508 LocalScope scope(vm_);
509 panda::TryCatch trycatch(vm_);
510 std::string module = moduleName;
511 int ret = JSNApi::ExecuteWithSingletonPatternFlag(vm_, bundleName, module, pageSourceFile, isSingleton);
512 HandleUncaughtException(trycatch);
513 if (ret != 0) {
514 TAG_LOGE(AceLogTag::ACE_NAVIGATION, "load pageSourceFile failed code is: %{public}d", ret);
515 }
516 return ret;
517 }
518 } // namespace OHOS::Ace::Framework
519