@@ -173,6 +173,23 @@ struct napi_env__ {
173
173
(out) = v8::type::New ((buffer), (byte_offset), (length)); \
174
174
} while (0 )
175
175
176
+ #define NAPI_CALL_INTO_MODULE (env, call, handle_exception ) \
177
+ do { \
178
+ int open_handle_scopes = (env)->open_handle_scopes ; \
179
+ int open_callback_scopes = (env)->open_callback_scopes ; \
180
+ napi_clear_last_error ((env)); \
181
+ call; \
182
+ CHECK_EQ ((env)->open_handle_scopes , open_handle_scopes); \
183
+ CHECK_EQ ((env)->open_callback_scopes , open_callback_scopes); \
184
+ if (!(env)->last_exception .IsEmpty ()) { \
185
+ handle_exception ( \
186
+ v8::Local<v8::Value>::New ((env)->isolate , (env)->last_exception )); \
187
+ (env)->last_exception .Reset (); \
188
+ } \
189
+ } while (0 )
190
+
191
+ #define NAPI_CALL_INTO_MODULE_THROW (env, call ) \
192
+ NAPI_CALL_INTO_MODULE ((env), call, (env)->isolate->ThrowException)
176
193
177
194
namespace {
178
195
namespace v8impl {
@@ -352,10 +369,11 @@ class Finalizer {
352
369
static void FinalizeBufferCallback (char * data, void * hint) {
353
370
Finalizer* finalizer = static_cast <Finalizer*>(hint);
354
371
if (finalizer->_finalize_callback != nullptr ) {
355
- finalizer->_finalize_callback (
356
- finalizer->_env ,
357
- data,
358
- finalizer->_finalize_hint );
372
+ NAPI_CALL_INTO_MODULE_THROW (finalizer->_env ,
373
+ finalizer->_finalize_callback (
374
+ finalizer->_env ,
375
+ data,
376
+ finalizer->_finalize_hint ));
359
377
}
360
378
361
379
Delete (finalizer);
@@ -467,10 +485,11 @@ class Reference : private Finalizer {
467
485
bool delete_self = reference->_delete_self ;
468
486
469
487
if (reference->_finalize_callback != nullptr ) {
470
- reference->_finalize_callback (
471
- reference->_env ,
472
- reference->_finalize_data ,
473
- reference->_finalize_hint );
488
+ NAPI_CALL_INTO_MODULE_THROW (reference->_env ,
489
+ reference->_finalize_callback (
490
+ reference->_env ,
491
+ reference->_finalize_data ,
492
+ reference->_finalize_hint ));
474
493
}
475
494
476
495
if (delete_self) {
@@ -555,32 +574,17 @@ class CallbackWrapperBase : public CallbackWrapper {
555
574
napi_callback cb = reinterpret_cast <napi_callback>(
556
575
v8::Local<v8::External>::Cast (
557
576
_cbdata->GetInternalField (kInternalFieldIndex ))->Value ());
558
- v8::Isolate* isolate = _cbinfo.GetIsolate ();
559
577
560
578
napi_env env = static_cast <napi_env>(
561
579
v8::Local<v8::External>::Cast (
562
580
_cbdata->GetInternalField (kEnvIndex ))->Value ());
563
581
564
- // Make sure any errors encountered last time we were in N-API are gone.
565
- napi_clear_last_error (env);
566
-
567
- int open_handle_scopes = env->open_handle_scopes ;
568
- int open_callback_scopes = env->open_callback_scopes ;
569
-
570
- napi_value result = cb (env, cbinfo_wrapper);
582
+ napi_value result;
583
+ NAPI_CALL_INTO_MODULE_THROW (env, result = cb (env, cbinfo_wrapper));
571
584
572
585
if (result != nullptr ) {
573
586
this ->SetReturnValue (result);
574
587
}
575
-
576
- CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
577
- CHECK_EQ (env->open_callback_scopes , open_callback_scopes);
578
-
579
- if (!env->last_exception .IsEmpty ()) {
580
- isolate->ThrowException (
581
- v8::Local<v8::Value>::New (isolate, env->last_exception ));
582
- env->last_exception .Reset ();
583
- }
584
588
}
585
589
586
590
const Info& _cbinfo;
@@ -888,8 +892,10 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
888
892
// one is found.
889
893
napi_env env = v8impl::GetEnv (context);
890
894
891
- napi_value _exports =
892
- mod->nm_register_func (env, v8impl::JsValueFromV8LocalValue (exports));
895
+ napi_value _exports;
896
+ NAPI_CALL_INTO_MODULE_THROW (env,
897
+ _exports = mod->nm_register_func (env,
898
+ v8impl::JsValueFromV8LocalValue (exports)));
893
899
894
900
// If register function returned a non-null exports object different from
895
901
// the exports object we passed it, set that as the "exports" property of
@@ -3384,19 +3390,17 @@ class Work : public node::AsyncResource {
3384
3390
v8::HandleScope scope (env->isolate );
3385
3391
CallbackScope callback_scope (work);
3386
3392
3387
- work->_complete (env, ConvertUVErrorCode (status), work->_data );
3393
+ NAPI_CALL_INTO_MODULE (env,
3394
+ work->_complete (env, ConvertUVErrorCode (status), work->_data ),
3395
+ [env] (v8::Local<v8::Value> local_err) {
3396
+ // If there was an unhandled exception in the complete callback,
3397
+ // report it as a fatal exception. (There is no JavaScript on the
3398
+ // callstack that can possibly handle it.)
3399
+ v8impl::trigger_fatal_exception (env, local_err);
3400
+ });
3388
3401
3389
3402
// Note: Don't access `work` after this point because it was
3390
3403
// likely deleted by the complete callback.
3391
-
3392
- // If there was an unhandled exception in the complete callback,
3393
- // report it as a fatal exception. (There is no JavaScript on the
3394
- // callstack that can possibly handle it.)
3395
- if (!env->last_exception .IsEmpty ()) {
3396
- v8::Local<v8::Value> local_err = v8::Local<v8::Value>::New (
3397
- env->isolate , env->last_exception );
3398
- v8impl::trigger_fatal_exception (env, local_err);
3399
- }
3400
3404
}
3401
3405
}
3402
3406
0 commit comments