From 9d1505021423052ed657733b7ca6ebe1398b6606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Sat, 12 Nov 2022 01:51:21 +0100 Subject: [PATCH] fix: Rework deprecated v8::ArrayBuffer:detach API (#1121) --- src/array_buffer.rs | 17 +++++++++++++---- src/binding.cc | 6 ++++-- tests/test_api.rs | 7 ++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/array_buffer.rs b/src/array_buffer.rs index e2edc5d5..66b0cdf2 100644 --- a/src/array_buffer.rs +++ b/src/array_buffer.rs @@ -9,6 +9,7 @@ use std::ptr::NonNull; use std::slice; use crate::support::long; +use crate::support::MaybeBool; use crate::support::Opaque; use crate::support::Shared; use crate::support::SharedPtrBase; @@ -19,6 +20,7 @@ use crate::ArrayBuffer; use crate::HandleScope; use crate::Isolate; use crate::Local; +use crate::Value; extern "C" { fn v8__ArrayBuffer__Allocator__NewDefaultAllocator() -> *mut Allocator; @@ -35,7 +37,10 @@ extern "C" { isolate: *mut Isolate, backing_store: *const SharedRef, ) -> *const ArrayBuffer; - fn v8__ArrayBuffer__Detach(this: *const ArrayBuffer); + fn v8__ArrayBuffer__Detach( + this: *const ArrayBuffer, + key: *const Value, + ) -> MaybeBool; fn v8__ArrayBuffer__Data(this: *const ArrayBuffer) -> *mut c_void; fn v8__ArrayBuffer__IsDetachable(this: *const ArrayBuffer) -> bool; fn v8__ArrayBuffer__WasDetached(this: *const ArrayBuffer) -> bool; @@ -402,13 +407,17 @@ impl ArrayBuffer { /// Detaches this ArrayBuffer and all its views (typed arrays). /// Detaching sets the byte length of the buffer and all typed arrays to zero, /// preventing JavaScript from ever accessing underlying backing store. - /// ArrayBuffer should have been externalized and must be detachable. + /// ArrayBuffer should have been externalized and must be detachable. Returns + /// `None` if the key didn't pass the [[ArrayBufferDetachKey]] check, + /// and `Some(true)` otherwise. #[inline(always)] - pub fn detach(&self) { + pub fn detach(&self, key: Local) -> Option { // V8 terminates when the ArrayBuffer is not detachable. Non-detachable // buffers are buffers that are in use by WebAssembly or asm.js. if self.is_detachable() { - unsafe { v8__ArrayBuffer__Detach(self) } + unsafe { v8__ArrayBuffer__Detach(self, &*key) }.into() + } else { + Some(true) } } diff --git a/src/binding.cc b/src/binding.cc index 08d1da16..8e5c4a14 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -820,8 +820,10 @@ void* v8__ArrayBuffer__Data(const v8::ArrayBuffer& self) { return ptr_to_local(&self)->Data(); } -void v8__ArrayBuffer__Detach(const v8::ArrayBuffer& self) { - ptr_to_local(&self)->Detach(); +MaybeBool v8__ArrayBuffer__Detach(const v8::ArrayBuffer& self, + const v8::Value* key) { + return maybe_to_maybe_bool(ptr_to_local(&self)->Detach( + ptr_to_local(key))); } bool v8__ArrayBuffer__IsDetachable(const v8::ArrayBuffer& self) { diff --git a/tests/test_api.rs b/tests/test_api.rs index 202064df..755b3640 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -576,15 +576,16 @@ fn array_buffer() { assert!(!ab.was_detached()); assert!(ab.is_detachable()); - ab.detach(); + let key = v8::undefined(scope); + assert!(ab.detach(key.into()).unwrap()); assert_eq!(0, ab.byte_length()); assert!(ab.was_detached()); - ab.detach(); // Calling it twice should be a no-op. + assert!(ab.detach(key.into()).unwrap()); // Calling it twice should be a no-op. // detecting if it was detached on a zero-length ArrayBuffer should work let empty_ab = v8::ArrayBuffer::new(scope, 0); assert!(!empty_ab.was_detached()); - empty_ab.detach(); + assert!(empty_ab.detach(key.into()).unwrap()); assert!(empty_ab.was_detached()); let bs = v8::ArrayBuffer::new_backing_store(scope, 84);