@@ -168,6 +168,24 @@ struct napi_env__ {
168
168
(out) = v8::type::New ((buffer), (byte_offset), (length)); \
169
169
} while (0 )
170
170
171
+ #define NAPI_CALL_INTO_MODULE (env, call, handle_exception ) \
172
+ do { \
173
+ int open_handle_scopes = (env)->open_handle_scopes ; \
174
+ int open_callback_scopes = (env)->open_callback_scopes ; \
175
+ napi_clear_last_error ((env)); \
176
+ call; \
177
+ CHECK_EQ ((env)->open_handle_scopes , open_handle_scopes); \
178
+ CHECK_EQ ((env)->open_callback_scopes , open_callback_scopes); \
179
+ if (!(env)->last_exception .IsEmpty ()) { \
180
+ handle_exception ( \
181
+ v8::Local<v8::Value>::New ((env)->isolate , (env)->last_exception )); \
182
+ (env)->last_exception .Reset (); \
183
+ } \
184
+ } while (0 )
185
+
186
+ #define NAPI_CALL_INTO_MODULE_THROW (env, call ) \
187
+ NAPI_CALL_INTO_MODULE ((env), call, (env)->isolate->ThrowException)
188
+
171
189
namespace v8impl {
172
190
173
191
// convert from n-api property attributes to v8::PropertyAttribute
@@ -349,10 +367,11 @@ class Finalizer {
349
367
static void FinalizeBufferCallback (char * data, void * hint) {
350
368
Finalizer* finalizer = static_cast <Finalizer*>(hint);
351
369
if (finalizer->_finalize_callback != nullptr ) {
352
- finalizer->_finalize_callback (
353
- finalizer->_env ,
354
- data,
355
- finalizer->_finalize_hint );
370
+ NAPI_CALL_INTO_MODULE_THROW (finalizer->_env ,
371
+ finalizer->_finalize_callback (
372
+ finalizer->_env ,
373
+ data,
374
+ finalizer->_finalize_hint ));
356
375
}
357
376
358
377
Delete (finalizer);
@@ -464,10 +483,11 @@ class Reference : private Finalizer {
464
483
bool delete_self = reference->_delete_self ;
465
484
466
485
if (reference->_finalize_callback != nullptr ) {
467
- reference->_finalize_callback (
468
- reference->_env ,
469
- reference->_finalize_data ,
470
- reference->_finalize_hint );
486
+ NAPI_CALL_INTO_MODULE_THROW (reference->_env ,
487
+ reference->_finalize_callback (
488
+ reference->_env ,
489
+ reference->_finalize_data ,
490
+ reference->_finalize_hint ));
471
491
}
472
492
473
493
if (delete_self) {
@@ -552,32 +572,17 @@ class CallbackWrapperBase : public CallbackWrapper {
552
572
napi_callback cb = reinterpret_cast <napi_callback>(
553
573
v8::Local<v8::External>::Cast (
554
574
_cbdata->GetInternalField (kInternalFieldIndex ))->Value ());
555
- v8::Isolate* isolate = _cbinfo.GetIsolate ();
556
575
557
576
napi_env env = static_cast <napi_env>(
558
577
v8::Local<v8::External>::Cast (
559
578
_cbdata->GetInternalField (kEnvIndex ))->Value ());
560
579
561
- // Make sure any errors encountered last time we were in N-API are gone.
562
- napi_clear_last_error (env);
563
-
564
- int open_handle_scopes = env->open_handle_scopes ;
565
- int open_callback_scopes = env->open_callback_scopes ;
566
-
567
- napi_value result = cb (env, cbinfo_wrapper);
580
+ napi_value result;
581
+ NAPI_CALL_INTO_MODULE_THROW (env, result = cb (env, cbinfo_wrapper));
568
582
569
583
if (result != nullptr ) {
570
584
this ->SetReturnValue (result);
571
585
}
572
-
573
- CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
574
- CHECK_EQ (env->open_callback_scopes , open_callback_scopes);
575
-
576
- if (!env->last_exception .IsEmpty ()) {
577
- isolate->ThrowException (
578
- v8::Local<v8::Value>::New (isolate, env->last_exception ));
579
- env->last_exception .Reset ();
580
- }
581
586
}
582
587
583
588
const Info& _cbinfo;
@@ -885,8 +890,10 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
885
890
// one is found.
886
891
napi_env env = v8impl::GetEnv (context);
887
892
888
- napi_value _exports =
889
- mod->nm_register_func (env, v8impl::JsValueFromV8LocalValue (exports));
893
+ napi_value _exports;
894
+ NAPI_CALL_INTO_MODULE_THROW (env,
895
+ _exports = mod->nm_register_func (env,
896
+ v8impl::JsValueFromV8LocalValue (exports)));
890
897
891
898
// If register function returned a non-null exports object different from
892
899
// the exports object we passed it, set that as the "exports" property of
@@ -3465,19 +3472,17 @@ class Work : public node::AsyncResource {
3465
3472
v8::HandleScope scope (env->isolate );
3466
3473
CallbackScope callback_scope (work);
3467
3474
3468
- work->_complete (env, ConvertUVErrorCode (status), work->_data );
3475
+ NAPI_CALL_INTO_MODULE (env,
3476
+ work->_complete (env, ConvertUVErrorCode (status), work->_data ),
3477
+ [env] (v8::Local<v8::Value> local_err) {
3478
+ // If there was an unhandled exception in the complete callback,
3479
+ // report it as a fatal exception. (There is no JavaScript on the
3480
+ // callstack that can possibly handle it.)
3481
+ v8impl::trigger_fatal_exception (env, local_err);
3482
+ });
3469
3483
3470
3484
// Note: Don't access `work` after this point because it was
3471
3485
// likely deleted by the complete callback.
3472
-
3473
- // If there was an unhandled exception in the complete callback,
3474
- // report it as a fatal exception. (There is no JavaScript on the
3475
- // callstack that can possibly handle it.)
3476
- if (!env->last_exception .IsEmpty ()) {
3477
- v8::Local<v8::Value> local_err = v8::Local<v8::Value>::New (
3478
- env->isolate , env->last_exception );
3479
- v8impl::trigger_fatal_exception (env, local_err);
3480
- }
3481
3486
}
3482
3487
}
3483
3488
0 commit comments