From a063c65261cbfc4c23e9b7437217317648780f58 Mon Sep 17 00:00:00 2001 From: Cheng Date: Fri, 5 Jul 2024 15:08:47 +0900 Subject: [PATCH] Escape the result when converted function returns napi_value --- src/callback_internal.h | 28 ++++++++++++++++++++++++++++ src/napi_util.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/callback_internal.h b/src/callback_internal.h index 857a0e5..83b7e0e 100644 --- a/src/callback_internal.h +++ b/src/callback_internal.h @@ -447,6 +447,34 @@ struct V8FunctionInvoker { } }; +template +struct V8FunctionInvoker { + static napi_value Go(napi_env env, Persistent* handle, ArgTypes&&... raw) { + EscapableHandleScope handle_scope(env); + napi_value func = handle->Value(); + if (!func) { + ThrowError(env, "The function has been garbage collected"); + return nullptr; + } + std::vector args = { + ToNode(env, std::forward(raw))... + }; + napi_value result; + napi_status s = napi_make_callback(env, nullptr, func, func, args.size(), + args.empty() ? nullptr: &args.front(), + &result); + if (s == napi_ok) { + return handle_scope.Escape(result); + } + if (s == napi_pending_exception) { + napi_value fatal_exception; + napi_get_and_clear_last_exception(env, &fatal_exception); + napi_fatal_exception(env, fatal_exception); + } + return nullptr; + } +}; + } // namespace internal } // namespace ki diff --git a/src/napi_util.h b/src/napi_util.h index e200866..efda41b 100644 --- a/src/napi_util.h +++ b/src/napi_util.h @@ -64,6 +64,37 @@ class HandleScope { napi_handle_scope scope_; }; +class EscapableHandleScope { + public: + explicit EscapableHandleScope(napi_env env) : env_(env) { + napi_status s = napi_open_escapable_handle_scope(env, &scope_); + assert(s == napi_ok); + } + + ~EscapableHandleScope() { + napi_status s = napi_close_escapable_handle_scope(env_, scope_); + assert(s == napi_ok); + } + + napi_value Escape(napi_value handle) { + napi_value result = nullptr; + napi_escape_handle(env_, scope_, handle, &result); + return result; + } + + EscapableHandleScope& operator=(const EscapableHandleScope&) = delete; + EscapableHandleScope(const EscapableHandleScope&) = delete; + + void* operator new(size_t) = delete; + void* operator new[] (size_t) = delete; + void operator delete(void*) = delete; + void operator delete[] (void*) = delete; + + private: + napi_env env_; + napi_escapable_handle_scope scope_; +}; + } // namespace ki #endif // SRC_NAPI_UTIL_H_