mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-03 15:14:35 +00:00
Fix SharedArray length in bytes to be a multiple of pointer alignment
This commit is contained in:
parent
f646809ff4
commit
89a05245f9
1 changed files with 18 additions and 16 deletions
|
@ -15,25 +15,27 @@ struct PaddingFillingIter<'a, U> {
|
||||||
iter: &'a mut dyn Iterator<Item = MaybeUninit<U>>,
|
iter: &'a mut dyn Iterator<Item = MaybeUninit<U>>,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
|
padding_elements: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, U> PaddingFillingIter<'a, U> {
|
impl<'a, U> PaddingFillingIter<'a, U> {
|
||||||
fn new(len: usize, iter: &'a mut dyn Iterator<Item = MaybeUninit<U>>) -> Self {
|
fn new(len: usize, iter: &'a mut dyn Iterator<Item = MaybeUninit<U>>) -> Self {
|
||||||
Self { iter, pos: 0, len }
|
let alignment = core::mem::align_of::<usize>();
|
||||||
}
|
let mut padding_elements = if len == 0 { 1 } else { 0 }; // ThinArc can't deal with empty arrays, so add padding for empty arrays.
|
||||||
|
|
||||||
fn padded_length(&self) -> usize {
|
// Add padding to ensure that the size in bytes is a multiple of the pointer alignment. This can mean different
|
||||||
// add some padding at the end since the size of the inner will anyway have to be padded
|
// increments depending on whether sizeof(U) is less or greater than align_of(usize).
|
||||||
let align = core::mem::align_of::<usize>() / core::mem::size_of::<U>();
|
loop {
|
||||||
if self.len > 0 {
|
let size_in_bytes = (len + padding_elements) * core::mem::size_of::<U>();
|
||||||
if align > 0 {
|
let byte_aligned_size = (size_in_bytes + alignment - 1) & !(alignment - 1);
|
||||||
(self.len + align - 1) & !(align - 1)
|
let padding_bytes = byte_aligned_size - size_in_bytes;
|
||||||
} else {
|
if padding_bytes == 0 {
|
||||||
self.len
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
padding_elements += 1;
|
||||||
align
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self { iter, pos: 0, len, padding_elements }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,14 +46,14 @@ impl<'a, U: Clone> Iterator for PaddingFillingIter<'a, U> {
|
||||||
self.pos += 1;
|
self.pos += 1;
|
||||||
if pos < self.len {
|
if pos < self.len {
|
||||||
self.iter.next()
|
self.iter.next()
|
||||||
} else if pos < self.padded_length() {
|
} else if pos < self.len + self.padding_elements {
|
||||||
Some(MaybeUninit::uninit())
|
Some(MaybeUninit::uninit())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
let l = self.padded_length() - self.pos;
|
let l = self.len + self.padding_elements;
|
||||||
(l, Some(l))
|
(l, Some(l))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,7 +82,7 @@ impl<T: Clone> SharedArray<T> {
|
||||||
|
|
||||||
SharedArray {
|
SharedArray {
|
||||||
inner: servo_arc::Arc::into_thin(servo_arc::Arc::from_header_and_iter(
|
inner: servo_arc::Arc::into_thin(servo_arc::Arc::from_header_and_iter(
|
||||||
servo_arc::HeaderWithLength::new(len, iter.padded_length()),
|
servo_arc::HeaderWithLength::new(len, iter.size_hint().0),
|
||||||
iter,
|
iter,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,7 @@ impl<T: Clone + Copy + Default + Sized + 'static> StaticNull for T {
|
||||||
let iter = PaddingFillingIter::new(len, null_iter);
|
let iter = PaddingFillingIter::new(len, null_iter);
|
||||||
|
|
||||||
servo_arc::Arc::into_thin(servo_arc::Arc::from_header_and_iter(
|
servo_arc::Arc::into_thin(servo_arc::Arc::from_header_and_iter(
|
||||||
servo_arc::HeaderWithLength::new(len, iter.padded_length()),
|
servo_arc::HeaderWithLength::new(len, iter.size_hint().0),
|
||||||
iter,
|
iter,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue