@@ -45,6 +45,7 @@ struct napi_env__ {
4545 v8::Persistent<v8::ObjectTemplate> accessor_data_template;
4646 bool has_instance_available;
4747 napi_extended_error_info last_error;
48+ int open_handle_scopes = 0 ;
4849};
4950
5051#define ENV_OBJECT_TEMPLATE (env, prefix, destination, field_count ) \
@@ -201,19 +202,23 @@ class EscapableHandleScopeWrapper {
201202 bool escape_called_;
202203};
203204
205+ static
204206napi_handle_scope JsHandleScopeFromV8HandleScope (HandleScopeWrapper* s) {
205207 return reinterpret_cast <napi_handle_scope>(s);
206208}
207209
210+ static
208211HandleScopeWrapper* V8HandleScopeFromJsHandleScope (napi_handle_scope s) {
209212 return reinterpret_cast <HandleScopeWrapper*>(s);
210213}
211214
215+ static
212216napi_escapable_handle_scope JsEscapableHandleScopeFromV8EscapableHandleScope (
213217 EscapableHandleScopeWrapper* s) {
214218 return reinterpret_cast <napi_escapable_handle_scope>(s);
215219}
216220
221+ static
217222EscapableHandleScopeWrapper*
218223V8EscapableHandleScopeFromJsEscapableHandleScope (
219224 napi_escapable_handle_scope s) {
@@ -227,18 +232,22 @@ V8EscapableHandleScopeFromJsEscapableHandleScope(
227232static_assert (sizeof (v8::Local<v8::Value>) == sizeof (napi_value),
228233 " Cannot convert between v8::Local<v8::Value> and napi_value" );
229234
235+ static
230236napi_deferred JsDeferredFromV8Persistent (v8::Persistent<v8::Value>* local) {
231237 return reinterpret_cast <napi_deferred>(local);
232238}
233239
240+ static
234241v8::Persistent<v8::Value>* V8PersistentFromJsDeferred (napi_deferred local) {
235242 return reinterpret_cast <v8::Persistent<v8::Value>*>(local);
236243}
237244
245+ static
238246napi_value JsValueFromV8LocalValue (v8::Local<v8::Value> local) {
239247 return reinterpret_cast <napi_value>(*local);
240248}
241249
250+ static
242251v8::Local<v8::Value> V8LocalValueFromJsValue (napi_value v) {
243252 v8::Local<v8::Value> local;
244253 memcpy (&local, &v, sizeof (v));
@@ -502,12 +511,16 @@ class CallbackWrapperBase : public CallbackWrapper {
502511 // Make sure any errors encountered last time we were in N-API are gone.
503512 napi_clear_last_error (env);
504513
514+ int open_handle_scopes = env->open_handle_scopes ;
515+
505516 napi_value result = cb (env, cbinfo_wrapper);
506517
507518 if (result != nullptr ) {
508519 this ->SetReturnValue (result);
509520 }
510521
522+ CHECK_EQ (env->open_handle_scopes , open_handle_scopes);
523+
511524 if (!env->last_exception .IsEmpty ()) {
512525 isolate->ThrowException (
513526 v8::Local<v8::Value>::New (isolate, env->last_exception ));
@@ -637,6 +650,7 @@ class SetterCallbackWrapper
637650
638651// Creates an object to be made available to the static function callback
639652// wrapper, used to retrieve the native callback function and data pointer.
653+ static
640654v8::Local<v8::Object> CreateFunctionCallbackData (napi_env env,
641655 napi_callback cb,
642656 void * data) {
@@ -662,6 +676,7 @@ v8::Local<v8::Object> CreateFunctionCallbackData(napi_env env,
662676// Creates an object to be made available to the static getter/setter
663677// callback wrapper, used to retrieve the native getter/setter callback
664678// function and data pointer.
679+ static
665680v8::Local<v8::Object> CreateAccessorCallbackData (napi_env env,
666681 napi_callback getter,
667682 napi_callback setter,
@@ -704,6 +719,7 @@ const char napi_wrap_name[] = "N-API Wrapper";
704719// Search the object's prototype chain for the wrapper object. Usually the
705720// wrapper would be the first in the chain, but it is OK for other objects to
706721// be inserted in the prototype chain.
722+ static
707723bool FindWrapper (v8::Local<v8::Object> obj,
708724 v8::Local<v8::Object>* result = nullptr ,
709725 v8::Local<v8::Object>* parent = nullptr ) {
@@ -737,6 +753,7 @@ static void DeleteEnv(napi_env env, void* data, void* hint) {
737753 delete env;
738754}
739755
756+ static
740757napi_env GetEnv (v8::Local<v8::Context> context) {
741758 napi_env result;
742759
@@ -772,6 +789,7 @@ napi_env GetEnv(v8::Local<v8::Context> context) {
772789 return result;
773790}
774791
792+ static
775793napi_status Unwrap (napi_env env,
776794 napi_value js_object,
777795 void ** result,
@@ -795,6 +813,7 @@ napi_status Unwrap(napi_env env,
795813 return napi_ok;
796814}
797815
816+ static
798817napi_status ConcludeDeferred (napi_env env,
799818 napi_deferred deferred,
800819 napi_value result,
@@ -854,12 +873,8 @@ void napi_module_register_cb(v8::Local<v8::Object> exports,
854873
855874// Registers a NAPI module.
856875void 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
861876 node::node_module* nm = new node::node_module {
862- module_version ,
877+ NODE_MODULE_VERSION ,
863878 mod->nm_flags ,
864879 nullptr ,
865880 mod->nm_filename ,
@@ -873,6 +888,7 @@ void napi_module_register(napi_module* mod) {
873888}
874889
875890// Warning: Keep in-sync with napi_status enum
891+ static
876892const char * error_messages[] = {nullptr ,
877893 " Invalid argument" ,
878894 " An object was expected" ,
@@ -1209,10 +1225,10 @@ napi_status napi_delete_property(napi_env env,
12091225 return GET_RETURN_STATUS (env);
12101226}
12111227
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) {
12161232 NAPI_PREAMBLE (env);
12171233 CHECK_ARG (env, key);
12181234
@@ -2583,6 +2599,7 @@ napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result) {
25832599
25842600 *result = v8impl::JsHandleScopeFromV8HandleScope (
25852601 new v8impl::HandleScopeWrapper (env->isolate ));
2602+ env->open_handle_scopes ++;
25862603 return napi_clear_last_error (env);
25872604}
25882605
@@ -2591,7 +2608,11 @@ napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope) {
25912608 // JS exceptions.
25922609 CHECK_ENV (env);
25932610 CHECK_ARG (env, scope);
2611+ if (env->open_handle_scopes == 0 ) {
2612+ return napi_handle_scope_mismatch;
2613+ }
25942614
2615+ env->open_handle_scopes --;
25952616 delete v8impl::V8HandleScopeFromJsHandleScope (scope);
25962617 return napi_clear_last_error (env);
25972618}
@@ -2606,6 +2627,7 @@ napi_status napi_open_escapable_handle_scope(
26062627
26072628 *result = v8impl::JsEscapableHandleScopeFromV8EscapableHandleScope (
26082629 new v8impl::EscapableHandleScopeWrapper (env->isolate ));
2630+ env->open_handle_scopes ++;
26092631 return napi_clear_last_error (env);
26102632}
26112633
@@ -2616,8 +2638,12 @@ napi_status napi_close_escapable_handle_scope(
26162638 // JS exceptions.
26172639 CHECK_ENV (env);
26182640 CHECK_ARG (env, scope);
2641+ if (env->open_handle_scopes == 0 ) {
2642+ return napi_handle_scope_mismatch;
2643+ }
26192644
26202645 delete v8impl::V8EscapableHandleScopeFromJsEscapableHandleScope (scope);
2646+ env->open_handle_scopes --;
26212647 return napi_clear_last_error (env);
26222648}
26232649
@@ -3313,6 +3339,7 @@ napi_status napi_adjust_external_memory(napi_env env,
33133339 return napi_clear_last_error (env);
33143340}
33153341
3342+ namespace {
33163343namespace uvimpl {
33173344
33183345static napi_status ConvertUVErrorCode (int code) {
@@ -3411,6 +3438,7 @@ class Work : public node::AsyncResource {
34113438};
34123439
34133440} // end of namespace uvimpl
3441+ } // end of anonymous namespace
34143442
34153443#define CALL_UV (env, condition ) \
34163444 do { \
@@ -3493,9 +3521,9 @@ napi_status napi_cancel_async_work(napi_env env, napi_async_work work) {
34933521 return napi_clear_last_error (env);
34943522}
34953523
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) {
34993527 NAPI_PREAMBLE (env);
35003528 CHECK_ARG (env, deferred);
35013529 CHECK_ARG (env, promise);
@@ -3512,21 +3540,21 @@ NAPI_EXTERN napi_status napi_create_promise(napi_env env,
35123540 return GET_RETURN_STATUS (env);
35133541}
35143542
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) {
35183546 return v8impl::ConcludeDeferred (env, deferred, resolution, true );
35193547}
35203548
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) {
35243552 return v8impl::ConcludeDeferred (env, deferred, resolution, false );
35253553}
35263554
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) {
35303558 CHECK_ENV (env);
35313559 CHECK_ARG (env, promise);
35323560 CHECK_ARG (env, is_promise);
@@ -3536,9 +3564,9 @@ NAPI_EXTERN napi_status napi_is_promise(napi_env env,
35363564 return napi_clear_last_error (env);
35373565}
35383566
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) {
35423570 NAPI_PREAMBLE (env);
35433571 CHECK_ARG (env, script);
35443572 CHECK_ARG (env, result);
0 commit comments