@@ -186,8 +186,8 @@ inline static napi_status ConcludeDeferred(napi_env env,
186186}
187187
188188// Wrapper around v8impl::Persistent that implements reference counting.
189- class Reference : private Finalizer , RefTracker{
190- private :
189+ class Reference : protected Finalizer , RefTracker{
190+ protected :
191191Reference (napi_env env,
192192 v8::Local<v8::Value> value,
193193uint32_t initial_refcount,
@@ -289,7 +289,7 @@ class Reference : private Finalizer, RefTracker{
289289 }
290290 }
291291
292- private :
292+ protected :
293293void Finalize (bool is_env_teardown = false ) override {
294294if (_finalize_callback != nullptr ){
295295 _env->CallIntoModuleThrow ([&](napi_env env){
@@ -310,6 +310,7 @@ class Reference : private Finalizer, RefTracker{
310310 }
311311 }
312312
313+ private:
313314// The N-API finalizer callback may make calls into the engine. V8's heap is
314315// not in a consistent state during the weak callback, and therefore it does
315316// not support calls back into it. However, it provides a mechanism for adding
@@ -335,6 +336,37 @@ class Reference : private Finalizer, RefTracker{
335336bool _delete_self;
336337};
337338
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+
338370enum UnwrapAction{
339371 KeepWrap,
340372 RemoveWrap
@@ -2587,8 +2619,9 @@ napi_status napi_create_external_arraybuffer(napi_env env,
25872619
25882620if (finalize_cb != nullptr ){
25892621// Create a self-deleting weak reference that invokes the finalizer
2590- // callback.
2591- v8impl::Reference::New (env,
2622+ // callback and detaches the ArrayBuffer if it still exists on Environment
2623+ // teardown.
2624+ v8impl::ArrayBufferReference::New (env,
25922625 buffer,
259326260 ,
25942627true ,
0 commit comments