mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-11 16:42:32 -05:00
refactor: Have BackingStore::data
return Option<NonNull<c_void>>
(#817)
The pointer returned by `BackingStore::data` might be null if the backing store has zero length, but the return type `*mut c_void` does not force the user to consider this case. This change makes the return type `Option<NonNull<c_void>>`, which is semantically equivalent, but which forces users of the API to handle the `None` case. This is a breaking API change.
This commit is contained in:
parent
845aced92c
commit
aac37a6d4f
2 changed files with 17 additions and 8 deletions
|
@ -4,6 +4,7 @@ use std::cell::Cell;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::ptr::null_mut;
|
use std::ptr::null_mut;
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
use crate::support::long;
|
use crate::support::long;
|
||||||
|
@ -260,8 +261,12 @@ impl BackingStore {
|
||||||
/// Return a pointer to the beginning of the memory block for this backing
|
/// Return a pointer to the beginning of the memory block for this backing
|
||||||
/// store. The pointer is only valid as long as this backing store object
|
/// store. The pointer is only valid as long as this backing store object
|
||||||
/// lives.
|
/// lives.
|
||||||
pub fn data(&self) -> *mut c_void {
|
///
|
||||||
unsafe { v8__BackingStore__Data(self as *const _ as *mut Self) }
|
/// Might return `None` if the backing store has zero length.
|
||||||
|
pub fn data(&self) -> Option<NonNull<c_void>> {
|
||||||
|
let raw_ptr =
|
||||||
|
unsafe { v8__BackingStore__Data(self as *const _ as *mut Self) };
|
||||||
|
NonNull::new(raw_ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The length (in bytes) of this backing store.
|
/// The length (in bytes) of this backing store.
|
||||||
|
@ -281,11 +286,12 @@ impl Deref for BackingStore {
|
||||||
|
|
||||||
/// Returns a [u8] slice refencing the data in the backing store.
|
/// Returns a [u8] slice refencing the data in the backing store.
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
use std::ptr::NonNull;
|
// We use a dangling pointer if `self.data()` returns None because it's UB
|
||||||
// `self.data()` will return a null pointer if the backing store has
|
// to create even an empty slice from a null pointer.
|
||||||
// length 0, and it's UB to create even an empty slice from a null pointer.
|
let data = self
|
||||||
let data = NonNull::new(self.data() as *mut Cell<u8>)
|
.data()
|
||||||
.unwrap_or_else(NonNull::dangling);
|
.unwrap_or_else(NonNull::dangling)
|
||||||
|
.cast::<Cell<u8>>();
|
||||||
let len = self.byte_length();
|
let len = self.byte_length();
|
||||||
unsafe { slice::from_raw_parts(data.as_ptr(), len) }
|
unsafe { slice::from_raw_parts(data.as_ptr(), len) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -5527,7 +5527,10 @@ fn compiled_wasm_module() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let foo_bs = foo_ab.get_backing_store();
|
let foo_bs = foo_ab.get_backing_store();
|
||||||
let foo_section = unsafe {
|
let foo_section = unsafe {
|
||||||
std::slice::from_raw_parts(foo_bs.data() as *mut u8, foo_bs.byte_length())
|
std::slice::from_raw_parts(
|
||||||
|
foo_bs.data().unwrap().as_ptr() as *mut u8,
|
||||||
|
foo_bs.byte_length(),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
assert_eq!(foo_section, b"bar");
|
assert_eq!(foo_section, b"bar");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue