@@ -218,7 +218,12 @@ inline napi_status Unwrap(napi_env env,
218218 if (action == RemoveWrap) {
219219 CHECK (obj->DeletePrivate (context, NAPI_PRIVATE_KEY (context, wrapper))
220220 .FromJust ());
221- delete reference;
221+ if (reference->ownership () == Ownership::kUserland ) {
222+ // When the wrap is been removed, the finalizer should be reset.
223+ reference->ResetFinalizer ();
224+ } else {
225+ delete reference;
226+ }
222227 }
223228
224229 return GET_RETURN_STATUS (env);
@@ -245,7 +250,8 @@ class CallbackBundle {
245250 bundle->env = env;
246251
247252 v8::Local<v8::Value> cbdata = v8::External::New (env->isolate , bundle);
248- Reference::New (env, cbdata, 0 , true , Delete, bundle, nullptr );
253+ Reference::New (
254+ env, cbdata, 0 , Ownership::kRuntime , Delete, bundle, nullptr );
249255 return cbdata;
250256 }
251257 napi_env env; // Necessary to invoke C++ NAPI callback
@@ -429,16 +435,21 @@ inline napi_status Wrap(napi_env env,
429435 // before then, then the finalize callback will never be invoked.)
430436 // Therefore a finalize callback is required when returning a reference.
431437 CHECK_ARG (env, finalize_cb);
432- reference = v8impl::Reference::New (
433- env, obj, 0 , false , finalize_cb, native_object, finalize_hint);
438+ reference = v8impl::Reference::New (env,
439+ obj,
440+ 0 ,
441+ v8impl::Ownership::kUserland ,
442+ finalize_cb,
443+ native_object,
444+ finalize_hint);
434445 *result = reinterpret_cast <napi_ref>(reference);
435446 } else {
436447 // Create a self-deleting reference.
437448 reference = v8impl::Reference::New (
438449 env,
439450 obj,
440451 0 ,
441- true ,
452+ v8impl::Ownership:: kRuntime ,
442453 finalize_cb,
443454 native_object,
444455 finalize_cb == nullptr ? nullptr : finalize_hint);
@@ -456,16 +467,22 @@ inline napi_status Wrap(napi_env env,
456467
457468} // end of anonymous namespace
458469
470+ void Finalizer::ResetFinalizer () {
471+ finalize_callback_ = nullptr ;
472+ finalize_data_ = nullptr ;
473+ finalize_hint_ = nullptr ;
474+ }
475+
459476// Wrapper around v8impl::Persistent that implements reference counting.
460477RefBase::RefBase (napi_env env,
461478 uint32_t initial_refcount,
462- bool delete_self ,
479+ Ownership ownership ,
463480 napi_finalize finalize_callback,
464481 void * finalize_data,
465482 void * finalize_hint)
466483 : Finalizer(env, finalize_callback, finalize_data, finalize_hint),
467484 refcount_(initial_refcount),
468- delete_self_(delete_self ) {
485+ ownership_(ownership ) {
469486 Link (finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist );
470487}
471488
@@ -480,13 +497,13 @@ RefBase::~RefBase() {
480497
481498RefBase* RefBase::New (napi_env env,
482499 uint32_t initial_refcount,
483- bool delete_self ,
500+ Ownership ownership ,
484501 napi_finalize finalize_callback,
485502 void * finalize_data,
486503 void * finalize_hint) {
487504 return new RefBase (env,
488505 initial_refcount,
489- delete_self ,
506+ ownership ,
490507 finalize_callback,
491508 finalize_data,
492509 finalize_hint);
@@ -512,27 +529,29 @@ uint32_t RefBase::RefCount() {
512529}
513530
514531void RefBase::Finalize () {
515- bool delete_self = delete_self_ ;
532+ Ownership ownership = ownership_ ;
516533 // Swap out the field finalize_callback so that it can not be accidentally
517534 // called more than once.
518535 napi_finalize finalize_callback = finalize_callback_;
519- finalize_callback_ = nullptr ;
536+ void * finalize_data = finalize_data_;
537+ void * finalize_hint = finalize_hint_;
538+ ResetFinalizer ();
520539
521540 // Either the RefBase is going to be deleted in the finalize_callback or not,
522541 // it should be removed from the tracked list.
523542 Unlink ();
524543 // 1. If the finalize_callback is present, it should either delete the
525- // RefBase, or set the flag `delete_self` .
544+ // RefBase, or set ownership with Ownership::kRuntime .
526545 // 2. If the finalizer is not present, the RefBase can be deleted after the
527546 // call.
528547 if (finalize_callback != nullptr ) {
529- env_->CallFinalizer (finalize_callback, finalize_data_, finalize_hint_ );
548+ env_->CallFinalizer (finalize_callback, finalize_data, finalize_hint );
530549 // No access to `this` after finalize_callback is called.
531550 }
532551
533- // If the RefBase is not self-destructive , userland code should delete it.
534- // Now delete it if it is self-destructive .
535- if (delete_self ) {
552+ // If the RefBase is not Ownership::kRuntime , userland code should delete it.
553+ // Now delete it if it is Ownership::kRuntime .
554+ if (ownership == Ownership:: kRuntime ) {
536555 delete this ;
537556 }
538557}
@@ -554,14 +573,14 @@ Reference::~Reference() {
554573Reference* Reference::New (napi_env env,
555574 v8::Local<v8::Value> value,
556575 uint32_t initial_refcount,
557- bool delete_self ,
576+ Ownership ownership ,
558577 napi_finalize finalize_callback,
559578 void * finalize_data,
560579 void * finalize_hint) {
561580 return new Reference (env,
562581 value,
563582 initial_refcount,
564- delete_self ,
583+ ownership ,
565584 finalize_callback,
566585 finalize_data,
567586 finalize_hint);
@@ -2297,8 +2316,13 @@ napi_status NAPI_CDECL napi_create_external(napi_env env,
22972316 if (finalize_cb) {
22982317 // The Reference object will delete itself after invoking the finalizer
22992318 // callback.
2300- v8impl::Reference::New (
2301- env, external_value, 0 , true , finalize_cb, data, finalize_hint);
2319+ v8impl::Reference::New (env,
2320+ external_value,
2321+ 0 ,
2322+ v8impl::Ownership::kRuntime ,
2323+ finalize_cb,
2324+ data,
2325+ finalize_hint);
23022326 }
23032327
23042328 *result = v8impl::JsValueFromV8LocalValue (external_value);
@@ -2407,8 +2431,8 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env,
24072431 return napi_set_last_error (env, napi_invalid_arg);
24082432 }
24092433
2410- v8impl::Reference* reference =
2411- v8impl::Reference::New ( env, v8_value, initial_refcount, false );
2434+ v8impl::Reference* reference = v8impl::Reference::New (
2435+ env, v8_value, initial_refcount, v8impl::Ownership:: kUserland );
24122436
24132437 *result = reinterpret_cast <napi_ref>(reference);
24142438 return napi_clear_last_error (env);
@@ -3115,8 +3139,8 @@ napi_status NAPI_CDECL napi_set_instance_data(napi_env env,
31153139 delete old_data;
31163140 }
31173141
3118- env->instance_data =
3119- v8impl::RefBase::New ( env, 0 , true , finalize_cb, data, finalize_hint);
3142+ env->instance_data = v8impl::RefBase::New (
3143+ env, 0 , v8impl::Ownership:: kRuntime , finalize_cb, data, finalize_hint);
31203144
31213145 return napi_clear_last_error (env);
31223146}
0 commit comments