From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- servo/components/style_traits/owned_slice.rs | 198 +++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 servo/components/style_traits/owned_slice.rs (limited to 'servo/components/style_traits/owned_slice.rs') diff --git a/servo/components/style_traits/owned_slice.rs b/servo/components/style_traits/owned_slice.rs new file mode 100644 index 0000000000..36ba3162e5 --- /dev/null +++ b/servo/components/style_traits/owned_slice.rs @@ -0,0 +1,198 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +#![allow(unsafe_code)] + +//! A replacement for `Box<[T]>` that cbindgen can understand. + +use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; +use serde::de::{Deserialize, Deserializer}; +use serde::ser::{Serialize, Serializer}; +use std::marker::PhantomData; +use std::ops::{Deref, DerefMut}; +use std::ptr::NonNull; +use std::{fmt, iter, mem, slice}; +use to_shmem::{self, SharedMemoryBuilder, ToShmem}; + +/// A struct that basically replaces a `Box<[T]>`, but which cbindgen can +/// understand. +/// +/// We could rely on the struct layout of `Box<[T]>` per: +/// +/// https://github.com/rust-lang/unsafe-code-guidelines/blob/master/reference/src/layout/pointers.md +/// +/// But handling fat pointers with cbindgen both in structs and argument +/// positions more generally is a bit tricky. +/// +/// cbindgen:derive-eq=false +/// cbindgen:derive-neq=false +#[repr(C)] +pub struct OwnedSlice { + ptr: NonNull, + len: usize, + _phantom: PhantomData, +} + +impl Default for OwnedSlice { + #[inline] + fn default() -> Self { + Self { + len: 0, + ptr: NonNull::dangling(), + _phantom: PhantomData, + } + } +} + +impl Drop for OwnedSlice { + #[inline] + fn drop(&mut self) { + if self.len != 0 { + let _ = mem::replace(self, Self::default()).into_vec(); + } + } +} + +unsafe impl Send for OwnedSlice {} +unsafe impl Sync for OwnedSlice {} + +impl Clone for OwnedSlice { + #[inline] + fn clone(&self) -> Self { + Self::from_slice(&**self) + } +} + +impl fmt::Debug for OwnedSlice { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.deref().fmt(formatter) + } +} + +impl PartialEq for OwnedSlice { + fn eq(&self, other: &Self) -> bool { + self.deref().eq(other.deref()) + } +} + +impl Eq for OwnedSlice {} + +impl OwnedSlice { + /// Convert the OwnedSlice into a boxed slice. + #[inline] + pub fn into_box(self) -> Box<[T]> { + self.into_vec().into_boxed_slice() + } + + /// Convert the OwnedSlice into a Vec. + #[inline] + pub fn into_vec(self) -> Vec { + let ret = unsafe { Vec::from_raw_parts(self.ptr.as_ptr(), self.len, self.len) }; + mem::forget(self); + ret + } + + /// Convert the regular slice into an owned slice. + #[inline] + pub fn from_slice(s: &[T]) -> Self + where + T: Clone, + { + Self::from(s.to_vec()) + } +} + +impl IntoIterator for OwnedSlice { + type Item = T; + type IntoIter = as IntoIterator>::IntoIter; + + #[inline] + fn into_iter(self) -> Self::IntoIter { + self.into_vec().into_iter() + } +} + +impl Deref for OwnedSlice { + type Target = [T]; + + #[inline(always)] + fn deref(&self) -> &Self::Target { + unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len) } + } +} + +impl DerefMut for OwnedSlice { + #[inline(always)] + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len) } + } +} + +impl From> for OwnedSlice { + #[inline] + fn from(mut b: Box<[T]>) -> Self { + let len = b.len(); + let ptr = unsafe { NonNull::new_unchecked(b.as_mut_ptr()) }; + mem::forget(b); + Self { + len, + ptr, + _phantom: PhantomData, + } + } +} + +impl From> for OwnedSlice { + #[inline] + fn from(b: Vec) -> Self { + Self::from(b.into_boxed_slice()) + } +} + +impl MallocShallowSizeOf for OwnedSlice { + fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + unsafe { ops.malloc_size_of(self.ptr.as_ptr()) } + } +} + +impl MallocSizeOf for OwnedSlice { + fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { + self.shallow_size_of(ops) + (**self).size_of(ops) + } +} + +impl ToShmem for OwnedSlice { + fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> to_shmem::Result { + unsafe { + let dest = to_shmem::to_shmem_slice(self.iter(), builder)?; + Ok(mem::ManuallyDrop::new(Self::from(Box::from_raw(dest)))) + } + } +} + +impl iter::FromIterator for OwnedSlice { + #[inline] + fn from_iter>(iter: I) -> Self { + Vec::from_iter(iter).into() + } +} + +impl Serialize for OwnedSlice { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.deref().serialize(serializer) + } +} + +impl<'de, T: Deserialize<'de>> Deserialize<'de> for OwnedSlice { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let r = Box::<[T]>::deserialize(deserializer)?; + Ok(r.into()) + } +} -- cgit v1.2.3