@@ -167,6 +167,23 @@ struct napi_env__ {
167
167
(out) = v8::type::New ((buffer), (byte_offset), (length)); \
168
168
} while (0 )
169
169
170
+ #define NAPI_CALL_INTO_MODULE (env, call, handle_exception ) \
171
+ do { \
172
+ int open_handle_scopes = (env)->open_handle_scopes ; \
173
+ int open_callback_scopes = (env)->open_callback_scopes ; \
174
+ napi_clear_last_error ((env)); \
175
+ call; \
176
+ CHECK_EQ ((env)->open_handle_scopes , open_handle_scopes); \
177
+ CHECK_EQ ((env)->open_callback_scopes , open_callback_scopes); \
178
+ if (!(env)->last_exception .IsEmpty ()) { \
179
+ handle_exception ( \
180
+ v8::Local<v8::Value>::New ((env)->isolate , (env)->last_exception )); \
181
+ (env)->last_exception .Reset (); \
182
+ } \
183
+ } while (0 )
184
+
185
+ #define NAPI_CALL_INTO_MODULE_THROW (env, call ) \
186
+ NAPI_CALL_INTO_MODULE ((env), call, (env)->isolate->ThrowException)
170
187
171
188
namespace {
172
189
namespace v8impl {
@@ -346,10 +363,11 @@ class Finalizer {
346
363
static void FinalizeBufferCallback (char * data, void * hint) {
347
364
Finalizer* finalizer = static_cast <Finalizer*>(hint);
348
365
if (finalizer->_finalize_callback != nullptr ) {
349
- finalizer->_finalize_callback (
350
- finalizer->_env ,
351
- data,
352
- finalizer->_finalize_hint );
366
+ NAPI_CALL_INTO_MODULE_THROW (finalizer->_env ,
367
+ finalizer->_finalize_callback (
368
+ finalizer->_env ,
369
+ data,
370
+ finalizer->_finalize_hint ));
353
371
}
354
372
355
373
Delete (finalizer);
@@ -451,10 +469,11 @@ class Reference : private Finalizer {
451
469
bool delete_self = reference->_delete_self ;
452
470
453
471
if (reference->_finalize_callback != nullptr ) {
454
- reference->_finalize_callback (
455
- reference->_env ,
456
- reference->_finalize_data ,
457
- reference->_finalize_hint );
472
+ NAPI_CALL_INTO_MODULE_THROW (reference->_env ,
473
+ reference->_finalize_callback (
474
+ reference->_env ,
475
+ reference->_finalize_data ,
476
+ reference->_finalize_hint ));
458
477
}
459
478
460
479
if (delete_self) {
@@ -539,32 +558,17 @@ class CallbackWrapperBase : public CallbackWrapper {
539
558
napi_callback cb = reinterpret_cast <napi_callback>(
540
559
v8::Local<v8::External>::Cast (
541
560
_cbdata->GetInternalField (kInternalFieldIndex ))->Value ());
542
- v8::Isolate* isolate = _cbinfo.GetIsolate ();
543
561
544
562
napi_env env = static_cast <napi_env>(
545
563
v8::Local<v8::External>::Cast (
546
564
_cbdata->GetInternalField (kEnvIndex ))->Value ());
547
565
548
- // Make sure any errors encountered last time we were in N-API are gone.
549
- napi_clear_last_error (env);
550
-
551
- int open_handle_scopes = env->open_handle_scopes ;
552
- int open_callback_scopes = env->open_callback_scopes ;
553
-
554
- napi_value result = cb (env, cbinfo_wrapper);
566
+ napi_value result;
567
+ NAPI_CALL_INTO_MODULE_THROW (env, result = cb (env, cbinfo_wrapper));
555
568
556
569
if (result != nullptr ) {
557
570
this ->SetReturnValue (result);
558
571
}
559
-
560
- CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
561
- CHECK_EQ (env->open_callback_scopes , open_callback_scopes);
562
-
563
- if (!env->last_exception .IsEmpty ()) {
564
- isolate->ThrowException (
565
- v8::Local<v8::Value>::New (isolate, env->last_exception ));
566
- env->last_exception .Reset ();
567
- }
568
572
}
569
573
570
574
const Info& _cbinfo;
@@ -871,8 +875,10 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
871
875
// one is found.
872
876
napi_env env = v8impl::GetEnv (context);
873
877
874
- napi_value _exports =
875
- mod->nm_register_func (env, v8impl::JsValueFromV8LocalValue (exports));
878
+ napi_value _exports;
879
+ NAPI_CALL_INTO_MODULE_THROW (env,
880
+ _exports = mod->nm_register_func (env,
881
+ v8impl::JsValueFromV8LocalValue (exports)));
876
882
877
883
// If register function returned a non-null exports object different from
878
884
// the exports object we passed it, set that as the "exports" property of
@@ -3367,19 +3373,17 @@ class Work : public node::AsyncResource {
3367
3373
v8::HandleScope scope (env->isolate );
3368
3374
CallbackScope callback_scope (work);
3369
3375
3370
- work->_complete (env, ConvertUVErrorCode (status), work->_data );
3376
+ NAPI_CALL_INTO_MODULE (env,
3377
+ work->_complete (env, ConvertUVErrorCode (status), work->_data ),
3378
+ [env] (v8::Local<v8::Value> local_err) {
3379
+ // If there was an unhandled exception in the complete callback,
3380
+ // report it as a fatal exception. (There is no JavaScript on the
3381
+ // callstack that can possibly handle it.)
3382
+ v8impl::trigger_fatal_exception (env, local_err);
3383
+ });
3371
3384
3372
3385
// Note: Don't access `work` after this point because it was
3373
3386
// likely deleted by the complete callback.
3374
-
3375
- // If there was an unhandled exception in the complete callback,
3376
- // report it as a fatal exception. (There is no JavaScript on the
3377
- // callstack that can possibly handle it.)
3378
- if (!env->last_exception .IsEmpty ()) {
3379
- v8::Local<v8::Value> local_err = v8::Local<v8::Value>::New (
3380
- env->isolate , env->last_exception );
3381
- v8impl::trigger_fatal_exception (env, local_err);
3382
- }
3383
3387
}
3384
3388
}
3385
3389
0 commit comments