@@ -45,6 +45,7 @@ struct napi_env__ {
45
45
v8::Persistent<v8::ObjectTemplate> accessor_data_template;
46
46
bool has_instance_available;
47
47
napi_extended_error_info last_error;
48
+ int open_handle_scopes = 0 ;
48
49
};
49
50
50
51
#define ENV_OBJECT_TEMPLATE (env, prefix, destination, field_count ) \
@@ -201,19 +202,23 @@ class EscapableHandleScopeWrapper {
201
202
bool escape_called_;
202
203
};
203
204
205
+ static
204
206
napi_handle_scope JsHandleScopeFromV8HandleScope (HandleScopeWrapper* s) {
205
207
return reinterpret_cast <napi_handle_scope>(s);
206
208
}
207
209
210
+ static
208
211
HandleScopeWrapper* V8HandleScopeFromJsHandleScope (napi_handle_scope s) {
209
212
return reinterpret_cast <HandleScopeWrapper*>(s);
210
213
}
211
214
215
+ static
212
216
napi_escapable_handle_scope JsEscapableHandleScopeFromV8EscapableHandleScope (
213
217
EscapableHandleScopeWrapper* s) {
214
218
return reinterpret_cast <napi_escapable_handle_scope>(s);
215
219
}
216
220
221
+ static
217
222
EscapableHandleScopeWrapper*
218
223
V8EscapableHandleScopeFromJsEscapableHandleScope (
219
224
napi_escapable_handle_scope s) {
@@ -227,18 +232,22 @@ V8EscapableHandleScopeFromJsEscapableHandleScope(
227
232
static_assert (sizeof (v8::Local<v8::Value>) == sizeof (napi_value),
228
233
" Cannot convert between v8::Local<v8::Value> and napi_value" );
229
234
235
+ static
230
236
napi_deferred JsDeferredFromV8Persistent (v8::Persistent<v8::Value>* local) {
231
237
return reinterpret_cast <napi_deferred>(local);
232
238
}
233
239
240
+ static
234
241
v8::Persistent<v8::Value>* V8PersistentFromJsDeferred (napi_deferred local) {
235
242
return reinterpret_cast <v8::Persistent<v8::Value>*>(local);
236
243
}
237
244
245
+ static
238
246
napi_value JsValueFromV8LocalValue (v8::Local<v8::Value> local) {
239
247
return reinterpret_cast <napi_value>(*local);
240
248
}
241
249
250
+ static
242
251
v8::Local<v8::Value> V8LocalValueFromJsValue (napi_value v) {
243
252
v8::Local<v8::Value> local;
244
253
memcpy (&local, &v, sizeof (v));
@@ -502,12 +511,16 @@ class CallbackWrapperBase : public CallbackWrapper {
502
511
// Make sure any errors encountered last time we were in N-API are gone.
503
512
napi_clear_last_error (env);
504
513
514
+ int open_handle_scopes = env->open_handle_scopes ;
515
+
505
516
napi_value result = cb (env, cbinfo_wrapper);
506
517
507
518
if (result != nullptr ) {
508
519
this ->SetReturnValue (result);
509
520
}
510
521
522
+ CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
523
+
511
524
if (!env->last_exception .IsEmpty ()) {
512
525
isolate->ThrowException (
513
526
v8::Local<v8::Value>::New (isolate, env->last_exception ));
@@ -637,6 +650,7 @@ class SetterCallbackWrapper
637
650
638
651
// Creates an object to be made available to the static function callback
639
652
// wrapper, used to retrieve the native callback function and data pointer.
653
+ static
640
654
v8::Local<v8::Object> CreateFunctionCallbackData (napi_env env,
641
655
napi_callback cb,
642
656
void * data) {
@@ -662,6 +676,7 @@ v8::Local<v8::Object> CreateFunctionCallbackData(napi_env env,
662
676
// Creates an object to be made available to the static getter/setter
663
677
// callback wrapper, used to retrieve the native getter/setter callback
664
678
// function and data pointer.
679
+ static
665
680
v8::Local<v8::Object> CreateAccessorCallbackData (napi_env env,
666
681
napi_callback getter,
667
682
napi_callback setter,
@@ -704,6 +719,7 @@ const char napi_wrap_name[] = "N-API Wrapper";
704
719
// Search the object's prototype chain for the wrapper object. Usually the
705
720
// wrapper would be the first in the chain, but it is OK for other objects to
706
721
// be inserted in the prototype chain.
722
+ static
707
723
bool FindWrapper (v8::Local<v8::Object> obj,
708
724
v8::Local<v8::Object>* result = nullptr ,
709
725
v8::Local<v8::Object>* parent = nullptr ) {
@@ -737,6 +753,7 @@ static void DeleteEnv(napi_env env, void* data, void* hint) {
737
753
delete env;
738
754
}
739
755
756
+ static
740
757
napi_env GetEnv (v8::Local<v8::Context> context) {
741
758
napi_env result;
742
759
@@ -772,6 +789,7 @@ napi_env GetEnv(v8::Local<v8::Context> context) {
772
789
return result;
773
790
}
774
791
792
+ static
775
793
napi_status Unwrap (napi_env env,
776
794
napi_value js_object,
777
795
void ** result,
@@ -795,6 +813,7 @@ napi_status Unwrap(napi_env env,
795
813
return napi_ok;
796
814
}
797
815
816
+ static
798
817
napi_status ConcludeDeferred (napi_env env,
799
818
napi_deferred deferred,
800
819
napi_value result,
@@ -854,12 +873,8 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
854
873
855
874
// Registers a NAPI module.
856
875
void napi_module_register (napi_module* mod) {
857
- int module_version = -1 ;
858
- #ifdef EXTERNAL_NAPI
859
- module_version = NODE_MODULE_VERSION;
860
- #endif // EXTERNAL_NAPI
861
876
node::node_module* nm = new node::node_module {
862
- module_version ,
877
+ NODE_MODULE_VERSION ,
863
878
mod->nm_flags ,
864
879
nullptr ,
865
880
mod->nm_filename ,
@@ -873,6 +888,7 @@ void napi_module_register(napi_module* mod) {
873
888
}
874
889
875
890
// Warning: Keep in-sync with napi_status enum
891
+ static
876
892
const char * error_messages[] = {nullptr ,
877
893
" Invalid argument" ,
878
894
" An object was expected" ,
@@ -1209,10 +1225,10 @@ napi_status napi_delete_property(napi_env env,
1209
1225
return GET_RETURN_STATUS (env);
1210
1226
}
1211
1227
1212
- NAPI_EXTERN napi_status napi_has_own_property (napi_env env,
1213
- napi_value object,
1214
- napi_value key,
1215
- bool * result) {
1228
+ napi_status napi_has_own_property (napi_env env,
1229
+ napi_value object,
1230
+ napi_value key,
1231
+ bool * result) {
1216
1232
NAPI_PREAMBLE (env);
1217
1233
CHECK_ARG (env, key);
1218
1234
@@ -2583,6 +2599,7 @@ napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result) {
2583
2599
2584
2600
*result = v8impl::JsHandleScopeFromV8HandleScope (
2585
2601
new v8impl::HandleScopeWrapper (env->isolate ));
2602
+ env->open_handle_scopes ++;
2586
2603
return napi_clear_last_error (env);
2587
2604
}
2588
2605
@@ -2591,7 +2608,11 @@ napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope) {
2591
2608
// JS exceptions.
2592
2609
CHECK_ENV (env);
2593
2610
CHECK_ARG (env, scope);
2611
+ if (env->open_handle_scopes == 0 ) {
2612
+ return napi_handle_scope_mismatch;
2613
+ }
2594
2614
2615
+ env->open_handle_scopes --;
2595
2616
delete v8impl::V8HandleScopeFromJsHandleScope (scope);
2596
2617
return napi_clear_last_error (env);
2597
2618
}
@@ -2606,6 +2627,7 @@ napi_status napi_open_escapable_handle_scope(
2606
2627
2607
2628
*result = v8impl::JsEscapableHandleScopeFromV8EscapableHandleScope (
2608
2629
new v8impl::EscapableHandleScopeWrapper (env->isolate ));
2630
+ env->open_handle_scopes ++;
2609
2631
return napi_clear_last_error (env);
2610
2632
}
2611
2633
@@ -2616,8 +2638,12 @@ napi_status napi_close_escapable_handle_scope(
2616
2638
// JS exceptions.
2617
2639
CHECK_ENV (env);
2618
2640
CHECK_ARG (env, scope);
2641
+ if (env->open_handle_scopes == 0 ) {
2642
+ return napi_handle_scope_mismatch;
2643
+ }
2619
2644
2620
2645
delete v8impl::V8EscapableHandleScopeFromJsEscapableHandleScope (scope);
2646
+ env->open_handle_scopes --;
2621
2647
return napi_clear_last_error (env);
2622
2648
}
2623
2649
@@ -3313,6 +3339,7 @@ napi_status napi_adjust_external_memory(napi_env env,
3313
3339
return napi_clear_last_error (env);
3314
3340
}
3315
3341
3342
+ namespace {
3316
3343
namespace uvimpl {
3317
3344
3318
3345
static napi_status ConvertUVErrorCode (int code) {
@@ -3411,6 +3438,7 @@ class Work : public node::AsyncResource {
3411
3438
};
3412
3439
3413
3440
} // end of namespace uvimpl
3441
+ } // end of anonymous namespace
3414
3442
3415
3443
#define CALL_UV (env, condition ) \
3416
3444
do { \
@@ -3493,9 +3521,9 @@ napi_status napi_cancel_async_work(napi_env env, napi_async_work work) {
3493
3521
return napi_clear_last_error (env);
3494
3522
}
3495
3523
3496
- NAPI_EXTERN napi_status napi_create_promise (napi_env env,
3497
- napi_deferred* deferred,
3498
- napi_value* promise) {
3524
+ napi_status napi_create_promise (napi_env env,
3525
+ napi_deferred* deferred,
3526
+ napi_value* promise) {
3499
3527
NAPI_PREAMBLE (env);
3500
3528
CHECK_ARG (env, deferred);
3501
3529
CHECK_ARG (env, promise);
@@ -3512,21 +3540,21 @@ NAPI_EXTERN napi_status napi_create_promise(napi_env env,
3512
3540
return GET_RETURN_STATUS (env);
3513
3541
}
3514
3542
3515
- NAPI_EXTERN napi_status napi_resolve_deferred (napi_env env,
3516
- napi_deferred deferred,
3517
- napi_value resolution) {
3543
+ napi_status napi_resolve_deferred (napi_env env,
3544
+ napi_deferred deferred,
3545
+ napi_value resolution) {
3518
3546
return v8impl::ConcludeDeferred (env, deferred, resolution, true );
3519
3547
}
3520
3548
3521
- NAPI_EXTERN napi_status napi_reject_deferred (napi_env env,
3522
- napi_deferred deferred,
3523
- napi_value resolution) {
3549
+ napi_status napi_reject_deferred (napi_env env,
3550
+ napi_deferred deferred,
3551
+ napi_value resolution) {
3524
3552
return v8impl::ConcludeDeferred (env, deferred, resolution, false );
3525
3553
}
3526
3554
3527
- NAPI_EXTERN napi_status napi_is_promise (napi_env env,
3528
- napi_value promise,
3529
- bool * is_promise) {
3555
+ napi_status napi_is_promise (napi_env env,
3556
+ napi_value promise,
3557
+ bool * is_promise) {
3530
3558
CHECK_ENV (env);
3531
3559
CHECK_ARG (env, promise);
3532
3560
CHECK_ARG (env, is_promise);
@@ -3536,9 +3564,9 @@ NAPI_EXTERN napi_status napi_is_promise(napi_env env,
3536
3564
return napi_clear_last_error (env);
3537
3565
}
3538
3566
3539
- NAPI_EXTERN napi_status napi_run_script (napi_env env,
3540
- napi_value script,
3541
- napi_value* result) {
3567
+ napi_status napi_run_script (napi_env env,
3568
+ napi_value script,
3569
+ napi_value* result) {
3542
3570
NAPI_PREAMBLE (env);
3543
3571
CHECK_ARG (env, script);
3544
3572
CHECK_ARG (env, result);
0 commit comments