@@ -186,8 +186,8 @@ inline static napi_status ConcludeDeferred(napi_env env,
186
186
}
187
187
188
188
// Wrapper around v8impl::Persistent that implements reference counting.
189
- class Reference : private Finalizer , RefTracker {
190
- private :
189
+ class Reference : protected Finalizer , RefTracker {
190
+ protected :
191
191
Reference (napi_env env,
192
192
v8::Local<v8::Value> value,
193
193
uint32_t initial_refcount,
@@ -289,7 +289,7 @@ class Reference : private Finalizer, RefTracker {
289
289
}
290
290
}
291
291
292
- private :
292
+ protected :
293
293
void Finalize (bool is_env_teardown = false ) override {
294
294
if (_finalize_callback != nullptr ) {
295
295
_env->CallIntoModuleThrow ([&](napi_env env) {
@@ -310,6 +310,7 @@ class Reference : private Finalizer, RefTracker {
310
310
}
311
311
}
312
312
313
+ private:
313
314
// The N-API finalizer callback may make calls into the engine. V8's heap is
314
315
// not in a consistent state during the weak callback, and therefore it does
315
316
// not support calls back into it. However, it provides a mechanism for adding
@@ -335,6 +336,37 @@ class Reference : private Finalizer, RefTracker {
335
336
bool _delete_self;
336
337
};
337
338
339
+ class ArrayBufferReference final : public Reference {
340
+ public:
341
+ // Same signatures for ctor and New() as Reference, except this only works
342
+ // with ArrayBuffers:
343
+ template <typename ... Args>
344
+ explicit ArrayBufferReference (napi_env env,
345
+ v8::Local<v8::ArrayBuffer> value,
346
+ Args&&... args)
347
+ : Reference(env, value, std::forward<Args>(args)...) {}
348
+
349
+ template <typename ... Args>
350
+ static ArrayBufferReference* New (napi_env env,
351
+ v8::Local<v8::ArrayBuffer> value,
352
+ Args&&... args) {
353
+ return new ArrayBufferReference (env, value, std::forward<Args>(args)...);
354
+ }
355
+
356
+ private:
357
+ void Finalize (bool is_env_teardown) override {
358
+ if (is_env_teardown) {
359
+ v8::HandleScope handle_scope (_env->isolate );
360
+ v8::Local<v8::Value> ab = Get ();
361
+ CHECK (!ab.IsEmpty ());
362
+ CHECK (ab->IsArrayBuffer ());
363
+ ab.As <v8::ArrayBuffer>()->Detach ();
364
+ }
365
+
366
+ Reference::Finalize (is_env_teardown);
367
+ }
368
+ };
369
+
338
370
enum UnwrapAction {
339
371
KeepWrap,
340
372
RemoveWrap
@@ -2583,8 +2615,9 @@ napi_status napi_create_external_arraybuffer(napi_env env,
2583
2615
2584
2616
if (finalize_cb != nullptr ) {
2585
2617
// Create a self-deleting weak reference that invokes the finalizer
2586
- // callback.
2587
- v8impl::Reference::New (env,
2618
+ // callback and detaches the ArrayBuffer if it still exists on Environment
2619
+ // teardown.
2620
+ v8impl::ArrayBufferReference::New (env,
2588
2621
buffer,
2589
2622
0 ,
2590
2623
true ,
0 commit comments