@@ -218,7 +218,12 @@ inline napi_status Unwrap(napi_env env,
218
218
if (action == RemoveWrap) {
219
219
CHECK (obj->DeletePrivate (context, NAPI_PRIVATE_KEY (context, wrapper))
220
220
.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
+ }
222
227
}
223
228
224
229
return GET_RETURN_STATUS (env);
@@ -245,7 +250,8 @@ class CallbackBundle {
245
250
bundle->env = env;
246
251
247
252
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 );
249
255
return cbdata;
250
256
}
251
257
napi_env env; // Necessary to invoke C++ NAPI callback
@@ -429,16 +435,21 @@ inline napi_status Wrap(napi_env env,
429
435
// before then, then the finalize callback will never be invoked.)
430
436
// Therefore a finalize callback is required when returning a reference.
431
437
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);
434
445
*result = reinterpret_cast <napi_ref>(reference);
435
446
} else {
436
447
// Create a self-deleting reference.
437
448
reference = v8impl::Reference::New (
438
449
env,
439
450
obj,
440
451
0 ,
441
- true ,
452
+ v8impl::Ownership:: kRuntime ,
442
453
finalize_cb,
443
454
native_object,
444
455
finalize_cb == nullptr ? nullptr : finalize_hint);
@@ -456,16 +467,22 @@ inline napi_status Wrap(napi_env env,
456
467
457
468
} // end of anonymous namespace
458
469
470
+ void Finalizer::ResetFinalizer () {
471
+ finalize_callback_ = nullptr ;
472
+ finalize_data_ = nullptr ;
473
+ finalize_hint_ = nullptr ;
474
+ }
475
+
459
476
// Wrapper around v8impl::Persistent that implements reference counting.
460
477
RefBase::RefBase (napi_env env,
461
478
uint32_t initial_refcount,
462
- bool delete_self ,
479
+ Ownership ownership ,
463
480
napi_finalize finalize_callback,
464
481
void * finalize_data,
465
482
void * finalize_hint)
466
483
: Finalizer(env, finalize_callback, finalize_data, finalize_hint),
467
484
refcount_(initial_refcount),
468
- delete_self_(delete_self ) {
485
+ ownership_(ownership ) {
469
486
Link (finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist );
470
487
}
471
488
@@ -480,13 +497,13 @@ RefBase::~RefBase() {
480
497
481
498
RefBase* RefBase::New (napi_env env,
482
499
uint32_t initial_refcount,
483
- bool delete_self ,
500
+ Ownership ownership ,
484
501
napi_finalize finalize_callback,
485
502
void * finalize_data,
486
503
void * finalize_hint) {
487
504
return new RefBase (env,
488
505
initial_refcount,
489
- delete_self ,
506
+ ownership ,
490
507
finalize_callback,
491
508
finalize_data,
492
509
finalize_hint);
@@ -512,27 +529,29 @@ uint32_t RefBase::RefCount() {
512
529
}
513
530
514
531
void RefBase::Finalize () {
515
- bool delete_self = delete_self_ ;
532
+ Ownership ownership = ownership_ ;
516
533
// Swap out the field finalize_callback so that it can not be accidentally
517
534
// called more than once.
518
535
napi_finalize finalize_callback = finalize_callback_;
519
- finalize_callback_ = nullptr ;
536
+ void * finalize_data = finalize_data_;
537
+ void * finalize_hint = finalize_hint_;
538
+ ResetFinalizer ();
520
539
521
540
// Either the RefBase is going to be deleted in the finalize_callback or not,
522
541
// it should be removed from the tracked list.
523
542
Unlink ();
524
543
// 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 .
526
545
// 2. If the finalizer is not present, the RefBase can be deleted after the
527
546
// call.
528
547
if (finalize_callback != nullptr ) {
529
- env_->CallFinalizer (finalize_callback, finalize_data_, finalize_hint_ );
548
+ env_->CallFinalizer (finalize_callback, finalize_data, finalize_hint );
530
549
// No access to `this` after finalize_callback is called.
531
550
}
532
551
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 ) {
536
555
delete this ;
537
556
}
538
557
}
@@ -554,14 +573,14 @@ Reference::~Reference() {
554
573
Reference* Reference::New (napi_env env,
555
574
v8::Local<v8::Value> value,
556
575
uint32_t initial_refcount,
557
- bool delete_self ,
576
+ Ownership ownership ,
558
577
napi_finalize finalize_callback,
559
578
void * finalize_data,
560
579
void * finalize_hint) {
561
580
return new Reference (env,
562
581
value,
563
582
initial_refcount,
564
- delete_self ,
583
+ ownership ,
565
584
finalize_callback,
566
585
finalize_data,
567
586
finalize_hint);
@@ -2297,8 +2316,13 @@ napi_status NAPI_CDECL napi_create_external(napi_env env,
2297
2316
if (finalize_cb) {
2298
2317
// The Reference object will delete itself after invoking the finalizer
2299
2318
// 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);
2302
2326
}
2303
2327
2304
2328
*result = v8impl::JsValueFromV8LocalValue (external_value);
@@ -2407,8 +2431,8 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env,
2407
2431
return napi_set_last_error (env, napi_invalid_arg);
2408
2432
}
2409
2433
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 );
2412
2436
2413
2437
*result = reinterpret_cast <napi_ref>(reference);
2414
2438
return napi_clear_last_error (env);
@@ -3115,8 +3139,8 @@ napi_status NAPI_CDECL napi_set_instance_data(napi_env env,
3115
3139
delete old_data;
3116
3140
}
3117
3141
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);
3120
3144
3121
3145
return napi_clear_last_error (env);
3122
3146
}
0 commit comments