diff --git a/libnapi.ndk.json b/libnapi.ndk.json index 83cb2e64ce1d22283647ebbc82908b7ee3d7a79b..1d096106b17dd96d2f39f87df25cd046ec5dc80f 100644 --- a/libnapi.ndk.json +++ b/libnapi.ndk.json @@ -132,5 +132,6 @@ {"name": "napi_create_external_buffer"}, {"name": "napi_get_buffer_info"}, {"name": "napi_queue_async_work_with_qos"}, - {"name": "napi_load_module"} -] \ No newline at end of file + {"name": "napi_load_module"}, + {"name": "napi_call_function_test"} +] diff --git a/native_engine/native_api.cpp b/native_engine/native_api.cpp index 279b040c837a348b74360ff4c5be0d8d1f66e176..8df6a32d9a031e8c1436d78e53a269aea9376e8f 100644 --- a/native_engine/native_api.cpp +++ b/native_engine/native_api.cpp @@ -1098,6 +1098,62 @@ NAPI_EXTERN napi_status napi_call_function(napi_env env, return napi_clear_last_error(env); } +// Methods to work with Functions +NAPI_EXTERN napi_status napi_call_function_test(napi_env env, + napi_value recv, + napi_value func, + size_t argc, + const napi_value* argv, + napi_value* result) +{ + NAPI_PREAMBLE(env); + CHECK_ARG(env, func); + if (argc > 0) { + CHECK_ARG(env, argv); + } + + auto nativeFunc = LocalValueFromJsValue(func); + RETURN_STATUS_IF_FALSE(env, nativeFunc->IsFunction(), napi_function_expected); + auto vm = reinterpret_cast(env)->GetEcmaVm(); + EscapeLocalScope scope(vm); + Local function = nativeFunc->ToObject(vm); + Local thisObj = panda::JSValueRef::Undefined(vm); + if (recv != nullptr) { + thisObj = LocalValueFromJsValue(recv); + } + +#ifdef ENABLE_CONTAINER_SCOPE + int32_t scopeId = OHOS::Ace::ContainerScope::CurrentId(); + auto funcInfo = reinterpret_cast(function->GetData(vm)); + if (funcInfo != nullptr) { + scopeId = funcInfo->scopeId; + } + OHOS::Ace::ContainerScope containerScope(scopeId); +#endif + + std::vector> args; + args.reserve(argc); + for (size_t i = 0; i < argc; i++) { + if (argv[i] != nullptr) { + args.emplace_back(LocalValueFromJsValue(argv[i])); + } else { + args.emplace_back(panda::JSValueRef::Undefined(vm)); + } + } + + Local value = function->Call(vm, thisObj, args.data(), argc); + if (tryCatch.HasCaught()) { + HILOG_ERROR("pending exception when js function called"); + HILOG_ERROR("print exception info: "); + panda::JSNApi::PrintExceptionInfo(vm); + return napi_set_last_error(env, napi_pending_exception); + } + if (result) { + *result = JsValueFromLocalValue(scope.Escape(value)); + } + return napi_clear_last_error(env); +} + NAPI_EXTERN napi_status napi_new_instance(napi_env env, napi_value constructor, size_t argc,