@@ -157,6 +157,23 @@ struct napi_env__ {
157
157
(out) = v8::type::New ((buffer), (byte_offset), (length)); \
158
158
} while (0 )
159
159
160
+ #define NAPI_CALL_INTO_MODULE (env, call, handle_exception ) \
161
+ do { \
162
+ int open_handle_scopes = (env)->open_handle_scopes ; \
163
+ int open_callback_scopes = (env)->open_callback_scopes ; \
164
+ napi_clear_last_error ((env)); \
165
+ call; \
166
+ CHECK_EQ ((env)->open_handle_scopes , open_handle_scopes); \
167
+ CHECK_EQ ((env)->open_callback_scopes , open_callback_scopes); \
168
+ if (!(env)->last_exception .IsEmpty ()) { \
169
+ handle_exception ( \
170
+ v8::Local<v8::Value>::New ((env)->isolate , (env)->last_exception )); \
171
+ (env)->last_exception .Reset (); \
172
+ } \
173
+ } while (0 )
174
+
175
+ #define NAPI_CALL_INTO_MODULE_THROW (env, call ) \
176
+ NAPI_CALL_INTO_MODULE ((env), call, (env)->isolate->ThrowException)
160
177
161
178
namespace {
162
179
namespace v8impl {
@@ -336,10 +353,11 @@ class Finalizer {
336
353
static void FinalizeBufferCallback (char * data, void * hint) {
337
354
Finalizer* finalizer = static_cast <Finalizer*>(hint);
338
355
if (finalizer->_finalize_callback != nullptr ) {
339
- finalizer->_finalize_callback (
340
- finalizer->_env ,
341
- data,
342
- finalizer->_finalize_hint );
356
+ NAPI_CALL_INTO_MODULE_THROW (finalizer->_env ,
357
+ finalizer->_finalize_callback (
358
+ finalizer->_env ,
359
+ data,
360
+ finalizer->_finalize_hint ));
343
361
}
344
362
345
363
Delete (finalizer);
@@ -441,10 +459,11 @@ class Reference : private Finalizer {
441
459
bool delete_self = reference->_delete_self ;
442
460
443
461
if (reference->_finalize_callback != nullptr ) {
444
- reference->_finalize_callback (
445
- reference->_env ,
446
- reference->_finalize_data ,
447
- reference->_finalize_hint );
462
+ NAPI_CALL_INTO_MODULE_THROW (reference->_env ,
463
+ reference->_finalize_callback (
464
+ reference->_env ,
465
+ reference->_finalize_data ,
466
+ reference->_finalize_hint ));
448
467
}
449
468
450
469
if (delete_self) {
@@ -529,32 +548,17 @@ class CallbackWrapperBase : public CallbackWrapper {
529
548
napi_callback cb = reinterpret_cast <napi_callback>(
530
549
v8::Local<v8::External>::Cast (
531
550
_cbdata->GetInternalField (kInternalFieldIndex ))->Value ());
532
- v8::Isolate* isolate = _cbinfo.GetIsolate ();
533
551
534
552
napi_env env = static_cast <napi_env>(
535
553
v8::Local<v8::External>::Cast (
536
554
_cbdata->GetInternalField (kEnvIndex ))->Value ());
537
555
538
- // Make sure any errors encountered last time we were in N-API are gone.
539
- napi_clear_last_error (env);
540
-
541
- int open_handle_scopes = env->open_handle_scopes ;
542
- int open_callback_scopes = env->open_callback_scopes ;
543
-
544
- napi_value result = cb (env, cbinfo_wrapper);
556
+ napi_value result;
557
+ NAPI_CALL_INTO_MODULE_THROW (env, result = cb (env, cbinfo_wrapper));
545
558
546
559
if (result != nullptr ) {
547
560
this ->SetReturnValue (result);
548
561
}
549
-
550
- CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
551
- CHECK_EQ (env->open_callback_scopes , open_callback_scopes);
552
-
553
- if (!env->last_exception .IsEmpty ()) {
554
- isolate->ThrowException (
555
- v8::Local<v8::Value>::New (isolate, env->last_exception ));
556
- env->last_exception .Reset ();
557
- }
558
562
}
559
563
560
564
const Info& _cbinfo;
@@ -861,8 +865,10 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
861
865
// one is found.
862
866
napi_env env = v8impl::GetEnv (context);
863
867
864
- napi_value _exports =
865
- mod->nm_register_func (env, v8impl::JsValueFromV8LocalValue (exports));
868
+ napi_value _exports;
869
+ NAPI_CALL_INTO_MODULE_THROW (env,
870
+ _exports = mod->nm_register_func (env,
871
+ v8impl::JsValueFromV8LocalValue (exports)));
866
872
867
873
// If register function returned a non-null exports object different from
868
874
// the exports object we passed it, set that as the "exports" property of
@@ -3357,19 +3363,17 @@ class Work : public node::AsyncResource {
3357
3363
v8::HandleScope scope (env->isolate );
3358
3364
CallbackScope callback_scope (work);
3359
3365
3360
- work->_complete (env, ConvertUVErrorCode (status), work->_data );
3366
+ NAPI_CALL_INTO_MODULE (env,
3367
+ work->_complete (env, ConvertUVErrorCode (status), work->_data ),
3368
+ [env] (v8::Local<v8::Value> local_err) {
3369
+ // If there was an unhandled exception in the complete callback,
3370
+ // report it as a fatal exception. (There is no JavaScript on the
3371
+ // callstack that can possibly handle it.)
3372
+ v8impl::trigger_fatal_exception (env, local_err);
3373
+ });
3361
3374
3362
3375
// Note: Don't access `work` after this point because it was
3363
3376
// likely deleted by the complete callback.
3364
-
3365
- // If there was an unhandled exception in the complete callback,
3366
- // report it as a fatal exception. (There is no JavaScript on the
3367
- // callstack that can possibly handle it.)
3368
- if (!env->last_exception .IsEmpty ()) {
3369
- v8::Local<v8::Value> local_err = v8::Local<v8::Value>::New (
3370
- env->isolate , env->last_exception );
3371
- v8impl::trigger_fatal_exception (env, local_err);
3372
- }
3373
3377
}
3374
3378
}
3375
3379
0 commit comments