1/* 2 * Copyright (c) 2021 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 "ecmascript/napi/include/jsnapi.h" 17#include "napi/native_node_api.h" 18#include "native_api_internal.h" 19#include "native_engine/impl/ark/ark_native_options.h" 20#include "native_engine/native_async_hook_context.h" 21#include "native_engine/native_engine.h" 22#include "native_engine/native_utils.h" 23#include "utils/log.h" 24 25using panda::Local; 26using panda::StringRef; 27 28static constexpr int32_t MAX_THREAD_SAFE_COUNT = 128; 29 30NAPI_EXTERN void napi_module_register(napi_module* mod) 31{ 32 if (mod == nullptr) { 33 HILOG_ERROR("mod is nullptr"); 34 return; 35 } 36 37 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 38 NativeModule module; 39 40 module.version = mod->nm_version; 41 module.fileName = mod->nm_filename; 42 module.name = mod->nm_modname; 43 module.flags = mod->nm_flags; 44 module.registerCallback = (RegisterCallback)mod->nm_register_func; 45 46 moduleManager->Register(&module); 47} 48 49NAPI_EXTERN void napi_module_with_js_register(napi_module_with_js* mod) 50{ 51 if (mod == nullptr) { 52 HILOG_ERROR("mod is nullptr"); 53 return; 54 } 55 56 NativeModuleManager* moduleManager = NativeModuleManager::GetInstance(); 57 NativeModule module; 58 59 module.version = mod->nm_version; 60 module.fileName = mod->nm_filename; 61 module.name = mod->nm_modname; 62 module.registerCallback = (RegisterCallback)mod->nm_register_func; 63 module.getJSCode = (GetJSCodeCallback)mod->nm_get_js_code; 64 module.getABCCode = (GetJSCodeCallback)mod->nm_get_abc_code; 65 66 moduleManager->Register(&module); 67} 68 69NAPI_EXTERN NAPI_NO_RETURN void napi_fatal_error(const char* location, 70 size_t location_len, 71 const char* message, 72 size_t message_len) 73{ 74 (void)location_len; 75 (void)message_len; 76 HILOG_FATAL("FATAL ERROR: %{public}s %{public}s\n", location, message); 77} 78 79NAPI_EXTERN napi_status napi_create_limit_runtime(napi_env env, napi_env* result_env) 80{ 81 CHECK_ENV(env); 82 CHECK_ARG(env, result_env); 83 84 auto engine = reinterpret_cast<NativeEngine*>(env); 85 86 auto result = engine->CreateRuntime(true); 87 *result_env = reinterpret_cast<napi_env>(result); 88 89 return napi_clear_last_error(env); 90} 91 92NAPI_EXTERN napi_status napi_fatal_exception(napi_env env, napi_value err) 93{ 94 NAPI_PREAMBLE(env); 95 CHECK_ENV(env); 96 CHECK_ARG(env, err); 97 98 auto exceptionValue = LocalValueFromJsValue(err); 99 auto ecmaVm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm(); 100 RETURN_STATUS_IF_FALSE(env, exceptionValue->IsError(ecmaVm), napi_invalid_arg); 101 102 auto engine = reinterpret_cast<NativeEngine*>(env); 103 engine->TriggerFatalException(exceptionValue); 104 return napi_ok; 105} 106 107// Methods to manage simple async operations 108NAPI_EXTERN napi_status napi_create_async_work(napi_env env, 109 napi_value async_resource, 110 napi_value async_resource_name, 111 napi_async_execute_callback execute, 112 napi_async_complete_callback complete, 113 void* data, 114 napi_async_work* result) 115{ 116 CHECK_ENV(env); 117 CHECK_ARG(env, async_resource_name); 118 CHECK_ARG(env, execute); 119 CHECK_ARG(env, complete); 120 CHECK_ARG(env, result); 121 122 auto engine = reinterpret_cast<NativeEngine*>(env); 123 auto ecmaVm = engine->GetEcmaVm(); 124 auto asyncResource = LocalValueFromJsValue(async_resource); 125 auto asyncResourceName = LocalValueFromJsValue(async_resource_name); 126 auto asyncExecute = reinterpret_cast<NativeAsyncExecuteCallback>(execute); 127 auto asyncComplete = reinterpret_cast<NativeAsyncCompleteCallback>(complete); 128 (void)asyncResource; 129 (void)asyncResourceName; 130 char name[64] = {0}; // 64:NAME_BUFFER_SIZE 131 if (!asyncResourceName->IsNull()) { 132 panda::Local<panda::StringRef> nativeString(asyncResourceName); 133 uint32_t copied = nativeString->WriteUtf8(ecmaVm, name, 63, true) - 1; // 63:NAME_BUFFER_SIZE 134 name[copied] = '\0'; 135 } 136 auto asyncWork = new NativeAsyncWork(engine, asyncExecute, asyncComplete, name, data); 137 *result = reinterpret_cast<napi_async_work>(asyncWork); 138 return napi_status::napi_ok; 139} 140 141NAPI_EXTERN napi_status napi_delete_async_work(napi_env env, napi_async_work work) 142{ 143 CHECK_ENV(env); 144 CHECK_ARG(env, work); 145 146 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work); 147 delete asyncWork; 148 asyncWork = nullptr; 149 150 return napi_status::napi_ok; 151} 152 153NAPI_EXTERN napi_status napi_queue_async_work(napi_env env, napi_async_work work) 154{ 155 CHECK_ENV(env); 156 CHECK_ARG(env, work); 157 158 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work); 159 160 asyncWork->Queue(); 161 return napi_status::napi_ok; 162} 163 164NAPI_EXTERN napi_status napi_cancel_async_work(napi_env env, napi_async_work work) 165{ 166 CHECK_ENV(env); 167 CHECK_ARG(env, work); 168 169 auto asyncWork = reinterpret_cast<NativeAsyncWork*>(work); 170 171 asyncWork->Cancel(); 172 return napi_status::napi_ok; 173} 174 175// Version management 176NAPI_EXTERN napi_status napi_get_node_version(napi_env env, const napi_node_version** version) 177{ 178 (void)version; 179 return napi_status::napi_ok; 180} 181 182// Return the current libuv event loop for a given environment 183NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env, struct uv_loop_s** loop) 184{ 185 CHECK_ENV(env); 186 CHECK_ARG(env, loop); 187 188 auto engine = reinterpret_cast<NativeEngine*>(env); 189 if (!NativeEngine::IsAlive(engine)) { 190 HILOG_ERROR("napi_env has been destoryed!"); 191 return napi_status::napi_generic_failure; 192 } 193 *loop = engine->GetUVLoop(); 194 195 return napi_status::napi_ok; 196} 197 198NAPI_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg) 199{ 200 CHECK_ENV(env); 201 CHECK_ARG(env, fun); 202 WEAK_CROSS_THREAD_CHECK(env); 203 204 auto engine = reinterpret_cast<NativeEngine*>(env); 205 engine->AddCleanupHook(fun, arg); 206 207 return napi_clear_last_error(env); 208} 209 210NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, void (*fun)(void* arg), void* arg) 211{ 212 CHECK_ENV(env); 213 CHECK_ARG(env, fun); 214 WEAK_CROSS_THREAD_CHECK(env); 215 216 auto engine = reinterpret_cast<NativeEngine*>(env); 217 engine->RemoveCleanupHook(fun, arg); 218 219 return napi_clear_last_error(env); 220} 221 222using CleanupHook = void (*)(void* arg); 223using AsyncCleanupHook = void (*)(void* arg, void (*)(void*), void*); 224 225struct AsyncCleanupHookInfo final { 226 napi_env env_; 227 AsyncCleanupHook fun_; 228 void* arg_; 229 bool started_ = false; 230 // Use a self-reference to make sure the storage is kept alive while the 231 // cleanup hook is registered but not yet finished. 232 std::shared_ptr<AsyncCleanupHookInfo> self_; 233}; 234 235// Opaque type that is basically an alias for `shared_ptr<AsyncCleanupHookInfo>` 236// (but not publicly so for easier ABI/API changes). In particular, 237// std::shared_ptr does not generally maintain a consistent ABI even on a 238// specific platform. 239struct ACHHandle final { 240 std::shared_ptr<AsyncCleanupHookInfo> info_; 241}; 242 243struct DeleteACHHandle { 244 void operator()(ACHHandle* handle) const 245 { 246 delete handle; 247 }; 248}; 249using AsyncCleanupHookHandle = std::unique_ptr<ACHHandle, DeleteACHHandle>; 250 251static void FinishAsyncCleanupHook(void* arg) 252{ 253 HILOG_INFO("%{public}s, start.", __func__); 254 AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg); 255 std::shared_ptr<AsyncCleanupHookInfo> keep_alive = info->self_; 256 auto engine = reinterpret_cast<NativeEngine*>(info->env_); 257 engine->DecreaseWaitingRequestCounter(); 258 info->self_.reset(); 259 HILOG_INFO("%{public}s, end.", __func__); 260} 261 262static void RunAsyncCleanupHook(void* arg) 263{ 264 HILOG_INFO("%{public}s, start.", __func__); 265 AsyncCleanupHookInfo* info = static_cast<AsyncCleanupHookInfo*>(arg); 266 auto engine = reinterpret_cast<NativeEngine*>(info->env_); 267 engine->IncreaseWaitingRequestCounter(); 268 info->started_ = true; 269 info->fun_(info->arg_, FinishAsyncCleanupHook, info); 270 HILOG_INFO("%{public}s, end.", __func__); 271} 272 273static AsyncCleanupHookHandle AddEnvironmentCleanupHook(napi_env env, AsyncCleanupHook fun, void* arg) 274{ 275 HILOG_INFO("%{public}s, start.", __func__); 276 auto info = std::make_shared<AsyncCleanupHookInfo>(); 277 info->env_ = env; 278 info->fun_ = fun; 279 info->arg_ = arg; 280 info->self_ = info; 281 auto engine = reinterpret_cast<NativeEngine*>(env); 282 engine->AddCleanupHook(RunAsyncCleanupHook, info.get()); 283 HILOG_INFO("%{public}s, end.", __func__); 284 return AsyncCleanupHookHandle(new ACHHandle { info }); 285} 286 287static void RemoveEnvironmentCleanupHook(AsyncCleanupHookHandle handle) 288{ 289 if (handle->info_->started_) { 290 return; 291 } 292 handle->info_->self_.reset(); 293 auto engine = reinterpret_cast<NativeEngine*>(handle->info_->env_); 294 engine->RemoveCleanupHook(RunAsyncCleanupHook, handle->info_.get()); 295} 296 297struct napi_async_cleanup_hook_handle__ { 298 napi_async_cleanup_hook_handle__(napi_env env, napi_async_cleanup_hook user_hook, void* user_data) 299 : env_(env), user_hook_(user_hook), user_data_(user_data) 300 { 301 handle_ = AddEnvironmentCleanupHook(env, Hook, this); 302 } 303 304 ~napi_async_cleanup_hook_handle__() 305 { 306 RemoveEnvironmentCleanupHook(std::move(handle_)); 307 if (done_cb_ != nullptr) { 308 done_cb_(done_data_); 309 } 310 } 311 312 static void Hook(void* data, void (*done_cb)(void*), void* done_data) 313 { 314 auto handle = static_cast<napi_async_cleanup_hook_handle__*>(data); 315 handle->done_cb_ = done_cb; 316 handle->done_data_ = done_data; 317 handle->user_hook_(handle, handle->user_data_); 318 } 319 320 AsyncCleanupHookHandle handle_; 321 napi_env env_ = nullptr; 322 napi_async_cleanup_hook user_hook_ = nullptr; 323 void* user_data_ = nullptr; 324 void (*done_cb_)(void*) = nullptr; 325 void* done_data_ = nullptr; 326}; 327 328NAPI_EXTERN napi_status napi_add_async_cleanup_hook( 329 napi_env env, napi_async_cleanup_hook hook, void* arg, napi_async_cleanup_hook_handle* remove_handle) 330{ 331 CHECK_ENV(env); 332 CHECK_ARG(env, hook); 333 CROSS_THREAD_CHECK(env); 334 335 napi_async_cleanup_hook_handle__* handle = new napi_async_cleanup_hook_handle__(env, hook, arg); 336 337 if (remove_handle != nullptr) 338 *remove_handle = handle; 339 340 return napi_clear_last_error(env); 341} 342 343NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(napi_async_cleanup_hook_handle remove_handle) 344{ 345 if (remove_handle == nullptr) { 346 return napi_invalid_arg; 347 } 348 349 delete remove_handle; 350 return napi_ok; 351} 352 353// Methods to manager threadsafe 354NAPI_EXTERN napi_status napi_create_threadsafe_function(napi_env env, napi_value func, napi_value async_resource, 355 napi_value async_resource_name, size_t max_queue_size, size_t initial_thread_count, void* thread_finalize_data, 356 napi_finalize thread_finalize_cb, void* context, napi_threadsafe_function_call_js call_js_cb, 357 napi_threadsafe_function* result) 358{ 359 CHECK_ENV(env); 360 CHECK_ARG(env, async_resource_name); 361 RETURN_STATUS_IF_FALSE(env, max_queue_size >= 0, napi_invalid_arg); 362 RETURN_STATUS_IF_FALSE( 363 env, initial_thread_count > 0 && initial_thread_count <= MAX_THREAD_SAFE_COUNT, napi_invalid_arg); 364 CHECK_ARG(env, result); 365 if (func == nullptr) { 366 CHECK_ARG(env, call_js_cb); 367 } 368 369 auto engine = reinterpret_cast<NativeEngine*>(env); 370 auto finalizeCallback = reinterpret_cast<NativeFinalize>(thread_finalize_cb); 371 auto callJsCallback = reinterpret_cast<NativeThreadSafeFunctionCallJs>(call_js_cb); 372 auto safeAsyncWork = engine->CreateSafeAsyncWork(func, async_resource, async_resource_name, max_queue_size, 373 initial_thread_count, thread_finalize_data, finalizeCallback, context, callJsCallback); 374 CHECK_ENV(safeAsyncWork); 375 376 auto ret = safeAsyncWork->Init(); 377 if (ret) { 378 *result = reinterpret_cast<napi_threadsafe_function>(safeAsyncWork); 379 } else { 380 return napi_status::napi_generic_failure; 381 } 382 383 return napi_status::napi_ok; 384} 385 386NAPI_EXTERN napi_status napi_call_threadsafe_function( 387 napi_threadsafe_function func, void* data, napi_threadsafe_function_call_mode is_blocking) 388{ 389 CHECK_ENV(func); 390 391 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 392 auto callMode = static_cast<NativeThreadSafeFunctionCallMode>(is_blocking); 393 394 napi_status status = napi_status::napi_ok; 395 auto code = safeAsyncWork->Send(data, callMode); 396 switch (code) { 397 case SafeAsyncCode::SAFE_ASYNC_OK: 398 status = napi_status::napi_ok; 399 break; 400 case SafeAsyncCode::SAFE_ASYNC_QUEUE_FULL: 401 status = napi_status::napi_queue_full; 402 break; 403 case SafeAsyncCode::SAFE_ASYNC_INVALID_ARGS: 404 status = napi_status::napi_invalid_arg; 405 break; 406 case SafeAsyncCode::SAFE_ASYNC_CLOSED: 407 status = napi_status::napi_closing; 408 break; 409 case SafeAsyncCode::SAFE_ASYNC_FAILED: 410 status = napi_status::napi_generic_failure; 411 break; 412 default: 413 HILOG_FATAL("this branch is unreachable, code is %{public}d", code); 414 break; 415 } 416 417 return status; 418} 419 420NAPI_EXTERN napi_status napi_acquire_threadsafe_function(napi_threadsafe_function func) 421{ 422 CHECK_ENV(func); 423 424 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 425 426 auto ret = safeAsyncWork->Acquire(); 427 if (ret != SafeAsyncCode::SAFE_ASYNC_OK) { 428 return napi_status::napi_generic_failure; 429 } 430 431 return napi_status::napi_ok; 432} 433 434NAPI_EXTERN napi_status napi_release_threadsafe_function( 435 napi_threadsafe_function func, napi_threadsafe_function_release_mode mode) 436{ 437 CHECK_ENV(func); 438 439 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 440 auto releaseMode = static_cast<NativeThreadSafeFunctionReleaseMode>(mode); 441 442 auto ret = safeAsyncWork->Release(releaseMode); 443 if (ret != SafeAsyncCode::SAFE_ASYNC_OK) { 444 return napi_status::napi_generic_failure; 445 } 446 447 return napi_status::napi_ok; 448} 449 450NAPI_EXTERN napi_status napi_get_threadsafe_function_context(napi_threadsafe_function func, void** result) 451{ 452 CHECK_ENV(func); 453 CHECK_ENV(result); 454 455 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 456 *result = safeAsyncWork->GetContext(); 457 458 return napi_status::napi_ok; 459} 460 461NAPI_EXTERN napi_status napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func) 462{ 463 CHECK_ENV(env); 464 CHECK_ARG(env, func); 465 466 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 467 auto ret = safeAsyncWork->Ref(); 468 if (!ret) { 469 return napi_status::napi_generic_failure; 470 } 471 472 return napi_status::napi_ok; 473} 474 475NAPI_EXTERN napi_status napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func) 476{ 477 CHECK_ENV(env); 478 CHECK_ARG(env, func); 479 480 auto safeAsyncWork = reinterpret_cast<NativeSafeAsyncWork*>(func); 481 auto ret = safeAsyncWork->Unref(); 482 if (!ret) { 483 return napi_status::napi_generic_failure; 484 } 485 486 return napi_status::napi_ok; 487} 488 489NAPI_EXTERN napi_status napi_async_init( 490 napi_env env, napi_value async_resource, napi_value async_resource_name, napi_async_context* result) 491{ 492 CHECK_ENV(env); 493 CHECK_ARG(env, async_resource_name); 494 CHECK_ARG(env, result); 495 496 auto ecmaVm = reinterpret_cast<NativeEngine*>(env)->GetEcmaVm(); 497 panda::Local<panda::ObjectRef> resource; 498 bool isExternalResource; 499 if (async_resource != nullptr) { 500 auto nativeValue = LocalValueFromJsValue(async_resource); 501 resource = nativeValue->ToObject(ecmaVm); 502 isExternalResource = true; 503 } else { 504 resource = panda::ObjectRef::New(ecmaVm); 505 isExternalResource = false; 506 } 507 508 auto nativeValue = LocalValueFromJsValue(async_resource_name); 509 auto resourceName = nativeValue->ToString(ecmaVm); 510 511 auto asyncContext = new NativeAsyncHookContext(reinterpret_cast<NativeEngine*>(env), 512 resource, 513 resourceName, 514 isExternalResource); 515 516 *result = reinterpret_cast<napi_async_context>(asyncContext); 517 518 return napi_clear_last_error(env); 519} 520 521NAPI_EXTERN napi_status napi_async_destroy(napi_env env, napi_async_context async_context) 522{ 523 CHECK_ENV(env); 524 CHECK_ARG(env, async_context); 525 526 NativeAsyncHookContext* nativeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context); 527 528 delete nativeAsyncContext; 529 530 return napi_clear_last_error(env); 531} 532 533NAPI_EXTERN napi_status napi_open_callback_scope( 534 napi_env env, napi_value, napi_async_context async_context_handle, napi_callback_scope* result) 535{ 536 CHECK_ENV(env); 537 CHECK_ARG(env, result); 538 539 NativeAsyncHookContext* nodeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context_handle); 540 541 *result = reinterpret_cast<napi_callback_scope>(nodeAsyncContext->OpenCallbackScope()); 542 543 return napi_clear_last_error(env); 544} 545 546NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env, napi_callback_scope scope) 547{ 548 CHECK_ENV(env); 549 CHECK_ARG(env, scope); 550 551 auto ret = NativeAsyncHookContext::CloseCallbackScope(reinterpret_cast<NativeEngine*>(env), 552 reinterpret_cast<NativeCallbackScope*>(scope)); 553 if (ret == CALLBACK_SCOPE_MISMATCH) { 554 return napi_callback_scope_mismatch; 555 } else if (ret != CALLBACK_SCOPE_OK) { 556 return napi_invalid_arg; 557 } 558 559 return napi_clear_last_error(env); 560} 561 562NAPI_EXTERN napi_status napi_set_instance_data( 563 napi_env env, void* data, napi_finalize finalize_cb, void* finalize_hint) 564{ 565 CHECK_ENV(env); 566 CROSS_THREAD_CHECK(env); 567 auto engine = reinterpret_cast<NativeEngine*>(env); 568 auto callback = reinterpret_cast<NativeFinalize>(finalize_cb); 569 engine->SetInstanceData(data, callback, finalize_hint); 570 return napi_clear_last_error(env); 571} 572 573NAPI_EXTERN napi_status napi_get_instance_data(napi_env env, void** data) 574{ 575 CHECK_ENV(env); 576 CHECK_ARG(env, data); 577 CROSS_THREAD_CHECK(env); 578 auto engine = reinterpret_cast<NativeEngine*>(env); 579 engine->GetInstanceData(data); 580 return napi_clear_last_error(env); 581} 582 583NAPI_EXTERN napi_status node_api_get_module_file_name(napi_env env, const char** result) 584{ 585 CHECK_ENV(env); 586 CHECK_ARG(env, result); 587 auto engine = reinterpret_cast<NativeEngine*>(env); 588 *result = engine->GetModuleFileName(); 589 HILOG_INFO("%{public}s, napi called fileName : %{public}s", __func__, *result); 590 return napi_clear_last_error(env); 591} 592 593NAPI_EXTERN napi_status napi_make_callback(napi_env env, 594 napi_async_context async_context, 595 napi_value recv, 596 napi_value func, 597 size_t argc, 598 const napi_value* argv, 599 napi_value* result) 600{ 601 NAPI_PREAMBLE(env); 602 CHECK_ARG(env, func); 603 CHECK_ARG(env, recv); 604 if (argc > 0) { 605 CHECK_ARG(env, argv); 606 } 607 auto engine = reinterpret_cast<NativeEngine*>(env); 608 auto vm = engine->GetEcmaVm(); 609 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(recv)->IsObject(vm), napi_object_expected); 610 RETURN_STATUS_IF_FALSE(env, reinterpret_cast<panda::JSValueRef *>(func)->IsFunction(vm), napi_function_expected); 611 panda::JSValueRef* Obj = reinterpret_cast<panda::JSValueRef *>(recv); 612 panda::FunctionRef* funRef = reinterpret_cast<panda::FunctionRef *>(func); 613 panda::JSValueRef* callBackRst; 614 if (async_context == nullptr) { 615 callBackRst = MakeCallback(engine, funRef, Obj, 616 argc, reinterpret_cast<panda::JSValueRef* const*>(argv), nullptr); 617 } else { 618 NativeAsyncHookContext* nativeAsyncContext = reinterpret_cast<NativeAsyncHookContext*>(async_context); 619 callBackRst = nativeAsyncContext->MakeCallback(funRef, Obj, 620 reinterpret_cast<panda::JSValueRef* const*>(argv), argc); 621 } 622 if (tryCatch.HasCaught()) { 623 HILOG_ERROR("print exception info: "); 624 panda::JSNApi::PrintExceptionInfo(vm); 625 return napi_set_last_error(env, napi_pending_exception); 626 } 627 if (result) { 628 *result = reinterpret_cast<napi_value>(callBackRst); 629 } 630 return GET_RETURN_STATUS(env); 631} 632