@@ -218,7 +218,11 @@ 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
+ reference->Reset ();
223
+ } else {
224
+ delete reference;
225
+ }
222
226
}
223
227
224
228
return GET_RETURN_STATUS (env);
@@ -245,7 +249,8 @@ class CallbackBundle {
245
249
bundle->env = env;
246
250
247
251
v8::Local<v8::Value> cbdata = v8::External::New (env->isolate , bundle);
248
- Reference::New (env, cbdata, 0 , true , Delete, bundle, nullptr );
252
+ Reference::New (
253
+ env, cbdata, 0 , Ownership::kRuntime , Delete, bundle, nullptr );
249
254
return cbdata;
250
255
}
251
256
napi_env env; // Necessary to invoke C++ NAPI callback
@@ -429,16 +434,21 @@ inline napi_status Wrap(napi_env env,
429
434
// before then, then the finalize callback will never be invoked.)
430
435
// Therefore a finalize callback is required when returning a reference.
431
436
CHECK_ARG (env, finalize_cb);
432
- reference = v8impl::Reference::New (
433
- env, obj, 0 , false , finalize_cb, native_object, finalize_hint);
437
+ reference = v8impl::Reference::New (env,
438
+ obj,
439
+ 0 ,
440
+ v8impl::Ownership::kUserland ,
441
+ finalize_cb,
442
+ native_object,
443
+ finalize_hint);
434
444
*result = reinterpret_cast <napi_ref>(reference);
435
445
} else {
436
446
// Create a self-deleting reference.
437
447
reference = v8impl::Reference::New (
438
448
env,
439
449
obj,
440
450
0 ,
441
- true ,
451
+ v8impl::Ownership:: kRuntime ,
442
452
finalize_cb,
443
453
native_object,
444
454
finalize_cb == nullptr ? nullptr : finalize_hint);
@@ -456,16 +466,22 @@ inline napi_status Wrap(napi_env env,
456
466
457
467
} // end of anonymous namespace
458
468
469
+ void Finalizer::Reset () {
470
+ finalize_callback_ = nullptr ;
471
+ finalize_data_ = nullptr ;
472
+ finalize_hint_ = nullptr ;
473
+ }
474
+
459
475
// Wrapper around v8impl::Persistent that implements reference counting.
460
476
RefBase::RefBase (napi_env env,
461
477
uint32_t initial_refcount,
462
- bool delete_self ,
478
+ Ownership ownership ,
463
479
napi_finalize finalize_callback,
464
480
void * finalize_data,
465
481
void * finalize_hint)
466
482
: Finalizer(env, finalize_callback, finalize_data, finalize_hint),
467
483
refcount_(initial_refcount),
468
- delete_self_(delete_self ) {
484
+ ownership_(ownership ) {
469
485
Link (finalize_callback == nullptr ? &env->reflist : &env->finalizing_reflist );
470
486
}
471
487
@@ -480,13 +496,13 @@ RefBase::~RefBase() {
480
496
481
497
RefBase* RefBase::New (napi_env env,
482
498
uint32_t initial_refcount,
483
- bool delete_self ,
499
+ Ownership ownership ,
484
500
napi_finalize finalize_callback,
485
501
void * finalize_data,
486
502
void * finalize_hint) {
487
503
return new RefBase (env,
488
504
initial_refcount,
489
- delete_self ,
505
+ ownership ,
490
506
finalize_callback,
491
507
finalize_data,
492
508
finalize_hint);
@@ -512,27 +528,29 @@ uint32_t RefBase::RefCount() {
512
528
}
513
529
514
530
void RefBase::Finalize () {
515
- bool delete_self = delete_self_ ;
531
+ Ownership ownership = ownership_ ;
516
532
// Swap out the field finalize_callback so that it can not be accidentally
517
533
// called more than once.
518
534
napi_finalize finalize_callback = finalize_callback_;
519
- finalize_callback_ = nullptr ;
535
+ void * finalize_data = finalize_data_;
536
+ void * finalize_hint = finalize_hint_;
537
+ Reset ();
520
538
521
539
// Either the RefBase is going to be deleted in the finalize_callback or not,
522
540
// it should be removed from the tracked list.
523
541
Unlink ();
524
542
// 1. If the finalize_callback is present, it should either delete the
525
- // RefBase, or set the flag `delete_self` .
543
+ // RefBase, or set ownership with Ownership::kRuntime .
526
544
// 2. If the finalizer is not present, the RefBase can be deleted after the
527
545
// call.
528
546
if (finalize_callback != nullptr ) {
529
- env_->CallFinalizer (finalize_callback, finalize_data_, finalize_hint_ );
547
+ env_->CallFinalizer (finalize_callback, finalize_data, finalize_hint );
530
548
// No access to `this` after finalize_callback is called.
531
549
}
532
550
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 ) {
551
+ // If the RefBase is not Ownership::kRuntime , userland code should delete it.
552
+ // Now delete it if it is Ownership::kRuntime .
553
+ if (ownership == Ownership:: kRuntime ) {
536
554
delete this ;
537
555
}
538
556
}
@@ -554,14 +572,14 @@ Reference::~Reference() {
554
572
Reference* Reference::New (napi_env env,
555
573
v8::Local<v8::Value> value,
556
574
uint32_t initial_refcount,
557
- bool delete_self ,
575
+ Ownership ownership ,
558
576
napi_finalize finalize_callback,
559
577
void * finalize_data,
560
578
void * finalize_hint) {
561
579
return new Reference (env,
562
580
value,
563
581
initial_refcount,
564
- delete_self ,
582
+ ownership ,
565
583
finalize_callback,
566
584
finalize_data,
567
585
finalize_hint);
@@ -602,6 +620,11 @@ v8::Local<v8::Value> Reference::Get() {
602
620
}
603
621
}
604
622
623
+ void Reference::Reset () {
624
+ persistent_.Reset ();
625
+ Finalizer::Reset ();
626
+ }
627
+
605
628
void Reference::Finalize () {
606
629
// Unconditionally reset the persistent handle so that no weak callback will
607
630
// be invoked again.
@@ -2297,8 +2320,13 @@ napi_status NAPI_CDECL napi_create_external(napi_env env,
2297
2320
if (finalize_cb) {
2298
2321
// The Reference object will delete itself after invoking the finalizer
2299
2322
// callback.
2300
- v8impl::Reference::New (
2301
- env, external_value, 0 , true , finalize_cb, data, finalize_hint);
2323
+ v8impl::Reference::New (env,
2324
+ external_value,
2325
+ 0 ,
2326
+ v8impl::Ownership::kRuntime ,
2327
+ finalize_cb,
2328
+ data,
2329
+ finalize_hint);
2302
2330
}
2303
2331
2304
2332
*result = v8impl::JsValueFromV8LocalValue (external_value);
@@ -2407,8 +2435,8 @@ napi_status NAPI_CDECL napi_create_reference(napi_env env,
2407
2435
return napi_set_last_error (env, napi_invalid_arg);
2408
2436
}
2409
2437
2410
- v8impl::Reference* reference =
2411
- v8impl::Reference::New ( env, v8_value, initial_refcount, false );
2438
+ v8impl::Reference* reference = v8impl::Reference::New (
2439
+ env, v8_value, initial_refcount, v8impl::Ownership:: kUserland );
2412
2440
2413
2441
*result = reinterpret_cast <napi_ref>(reference);
2414
2442
return napi_clear_last_error (env);
@@ -3115,8 +3143,8 @@ napi_status NAPI_CDECL napi_set_instance_data(napi_env env,
3115
3143
delete old_data;
3116
3144
}
3117
3145
3118
- env->instance_data =
3119
- v8impl::RefBase::New ( env, 0 , true , finalize_cb, data, finalize_hint);
3146
+ env->instance_data = v8impl::RefBase::New (
3147
+ env, 0 , v8impl::Ownership:: kRuntime , finalize_cb, data, finalize_hint);
3120
3148
3121
3149
return napi_clear_last_error (env);
3122
3150
}
0 commit comments