From a342dc8e5c81836d37c9f8ef3b85624c2c4db55a Mon Sep 17 00:00:00 2001 From: snek Date: Wed, 12 Feb 2025 09:43:48 +0100 Subject: [PATCH] feat: add get_contents_raw_parts (#1704) * feat: add get_contents_raw_parts * fix type * fix null deref --- src/array_buffer_view.rs | 37 +++++++++++++++++++++++++++++-------- src/binding.cc | 3 +-- src/support.h | 2 +- src/template.rs | 2 +- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/array_buffer_view.rs b/src/array_buffer_view.rs index e49a04a8..d0354982 100644 --- a/src/array_buffer_view.rs +++ b/src/array_buffer_view.rs @@ -87,20 +87,41 @@ impl ArrayBufferView { } } + /// Returns the contents of the ArrayBufferView's buffer as a MemorySpan. If + /// the contents are on the V8 heap, they get copied into `storage`. Otherwise + /// a view into the off-heap backing store is returned. The provided storage + /// should be at least as large as the maximum on-heap size of a TypedArray, + /// which is available as `v8::TYPED_ARRAY_MAX_SIZE_IN_HEAP`. + #[inline(always)] + pub unsafe fn get_contents_raw_parts( + &self, + storage: &mut [u8], + ) -> (*mut u8, usize) { + unsafe { + let span = v8__ArrayBufferView__GetContents( + self, + memory_span_t { + data: storage.as_mut_ptr(), + size: storage.len(), + }, + ); + (span.data, span.size) + } + } + + /// Returns the contents of the ArrayBufferView's buffer as a MemorySpan. If + /// the contents are on the V8 heap, they get copied into `storage`. Otherwise + /// a view into the off-heap backing store is returned. The provided storage + /// should be at least as large as the maximum on-heap size of a TypedArray, + /// which is available as `v8::TYPED_ARRAY_MAX_SIZE_IN_HEAP`. #[inline(always)] pub fn get_contents<'s, 'a>(&'s self, storage: &'a mut [u8]) -> &'a [u8] where 's: 'a, { unsafe { - let span = v8__ArrayBufferView__GetContents( - self, - memory_span_t { - data: storage.as_mut_ptr() as _, - size: storage.len(), - }, - ); - std::slice::from_raw_parts(span.data as _, span.size) + let (data, size) = self.get_contents_raw_parts(storage); + std::slice::from_raw_parts(data, size) } } } diff --git a/src/binding.cc b/src/binding.cc index c3519cb5..1bce7c85 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1887,8 +1887,7 @@ size_t v8__ArrayBufferView__CopyContents(const v8::ArrayBufferView& self, memory_span_t v8__ArrayBufferView__GetContents(const v8::ArrayBufferView& self, memory_span_t rstorage) { - v8::MemorySpan storage{static_cast(rstorage.data), - rstorage.size}; + v8::MemorySpan storage{rstorage.data, rstorage.size}; v8::MemorySpan span = ptr_to_local(&self)->GetContents(storage); return {span.data(), span.size()}; } diff --git a/src/support.h b/src/support.h index 505a8a26..b256bb61 100644 --- a/src/support.h +++ b/src/support.h @@ -179,7 +179,7 @@ struct three_pointers_t { } // namespace support struct memory_span_t { - void* data; + uint8_t* data; size_t size; }; diff --git a/src/template.rs b/src/template.rs index 8a8a50ce..963d9c82 100644 --- a/src/template.rs +++ b/src/template.rs @@ -1017,7 +1017,7 @@ impl ObjectTemplate { let getter = getter.map_or_else(std::ptr::null, |v| &*v); let setter = setter.map_or_else(std::ptr::null, |v| &*v); v8__ObjectTemplate__SetAccessorProperty( - self, &*key, &*getter, &*setter, attr, + self, &*key, getter, setter, attr, ); } }