From bd169e33447e5480cad9ec26abc6df0055eeaac4 Mon Sep 17 00:00:00 2001 From: Kyle Farnung Date: Fri, 23 Mar 2018 20:20:33 -0700 Subject: [PATCH] chakrashim,n-api: Add `napi_fatal_exception` Implemented `napi_fatal_exception` in terms of the shim because node core still relies on V8 APIs. Stubbed out `v8::Exception::CreateMessage` as it's not possible to get that data from ChakraCore currently if the exception was not thrown. --- deps/chakrashim/include/v8.h | 2 ++ deps/chakrashim/src/v8exception.cc | 9 +++++++++ src/node_api_jsrt.cc | 31 ++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/deps/chakrashim/include/v8.h b/deps/chakrashim/include/v8.h index e6828ede21d..2aa899b2867 100644 --- a/deps/chakrashim/include/v8.h +++ b/deps/chakrashim/include/v8.h @@ -343,6 +343,7 @@ class Local { friend class Context; friend class Date; friend class Debug; + friend class Exception; friend class External; friend class Function; friend class FunctionCallbackData; @@ -2520,6 +2521,7 @@ class V8_EXPORT Exception { static Local SyntaxError(Handle message); static Local TypeError(Handle message); static Local Error(Handle message); + static Local CreateMessage(Isolate* isolate, Local exception); }; class V8_EXPORT MicrotasksScope { diff --git a/deps/chakrashim/src/v8exception.cc b/deps/chakrashim/src/v8exception.cc index c7af9342ac6..41a0978c119 100644 --- a/deps/chakrashim/src/v8exception.cc +++ b/deps/chakrashim/src/v8exception.cc @@ -51,4 +51,13 @@ Local Exception::Error(Handle message) { return Utils::NewError(message, JsCreateError); } +Local Exception::CreateMessage(Isolate* isolate, + Local exception) { + // ChakraCore doesn't have any way to get metadata about an error that was + // instantiated, but not thrown. Create an empty object to use instead. + JsValueRef metadata; + JsCreateObject(&metadata); + return v8::Local::New(metadata); +} + } // namespace v8 diff --git a/src/node_api_jsrt.cc b/src/node_api_jsrt.cc index beabdcabc33..63a90e74724 100644 --- a/src/node_api_jsrt.cc +++ b/src/node_api_jsrt.cc @@ -109,10 +109,6 @@ namespace v8impl { //=== Conversion between V8 Isolate and napi_env ========================== -v8::Isolate* V8IsolateFromJsEnv(napi_env e) { - return reinterpret_cast(e); -} - class HandleScopeWrapper { public: explicit HandleScopeWrapper( @@ -148,6 +144,15 @@ v8::Local V8LocalValueFromJsValue(napi_value v) { memcpy(&local, &v, sizeof(v)); return local; } + +inline void TriggerFatalException( + napi_env env, v8::Local local_err) { + // The API requires V8 types, so use the shim until there are engine-neutral + // core APIs. + v8::Local local_msg = + v8::Exception::CreateMessage(env->isolate, local_err); + node::FatalException(env->isolate, local_err, local_msg); +} } // end of namespace v8impl namespace jsrtimpl { @@ -619,6 +624,16 @@ napi_status napi_set_last_error(JsErrorCode jsError, void* engine_reserved) { return status; } +napi_status napi_fatal_exception(napi_env env, napi_value err) { + CHECK_ARG(err); + + v8::Local local_err = v8impl::V8LocalValueFromJsValue(err); + v8impl::TriggerFatalException(env, local_err); + + napi_clear_last_error(); + return napi_ok; +} + NAPI_NO_RETURN void napi_fatal_error(const char* location, size_t location_len, const char* message, @@ -2139,7 +2154,7 @@ napi_status napi_make_callback(napi_env env, size_t argc, const napi_value* argv, napi_value* result) { - v8::Isolate* isolate = v8impl::V8IsolateFromJsEnv(env); + v8::Isolate* isolate = env->isolate; v8::Local v8recv = v8impl::V8LocalValueFromJsValue(recv).As(); v8::Local v8func = @@ -2197,7 +2212,7 @@ napi_status napi_create_buffer(napi_env env, // TODO(tawoll): Replace v8impl with jsrt-based version. v8::MaybeLocal maybe = - node::Buffer::New(v8impl::V8IsolateFromJsEnv(env), length); + node::Buffer::New(env->isolate, length); if (maybe.IsEmpty()) { return napi_generic_failure; } @@ -2223,7 +2238,7 @@ napi_status napi_create_external_buffer(napi_env env, jsrtimpl::ExternalData* externalData = new jsrtimpl::ExternalData( env, data, finalize_cb, finalize_hint); v8::MaybeLocal maybe = node::Buffer::New( - v8impl::V8IsolateFromJsEnv(env), + env->isolate, static_cast(data), length, jsrtimpl::ExternalData::FinalizeBuffer, @@ -2247,7 +2262,7 @@ napi_status napi_create_buffer_copy(napi_env env, // chakra shim here. v8::MaybeLocal maybe = node::Buffer::Copy( - v8impl::V8IsolateFromJsEnv(env), static_cast(data), length); + env->isolate, static_cast(data), length); if (maybe.IsEmpty()) { return napi_generic_failure; }