diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2023-04-28 00:02:45 +0000 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2023-11-21 15:36:35 +0100 |
commit | 93e07111944f78eaceeebae3b00077e9871f316b (patch) | |
tree | 3bce39358a430f4c657aa76b0f1588f87fdc8a63 /components/servo_arc/lib.rs | |
parent | f9a48e15aae7c1244b0db77d687eaa88f8324d79 (diff) | |
download | servo-93e07111944f78eaceeebae3b00077e9871f316b.tar.gz servo-93e07111944f78eaceeebae3b00077e9871f316b.zip |
style: [css-nesting] Process nested rules at cascade data rebuild
More nesting plumbing. Still does nothing because we don't parse the
nested rules.
Should be trivial to prove this patch doesn't change any behavior so
far, but I want to land it on its own because it can have performance
implications.
This follows the pattern of what we do with other rules like layers and
container conditions, that is, keep the ancestor selectors in a stack,
and poke at the last one in order to replace the ancestor.
This changes the behavior of replace_parent_selector as with the newer
version of the spec, stuff like:
div {
.foo {
stuff
}
}
Should work as `div .foo`. A test is added for this case.
Differential Revision: https://phabricator.services.mozilla.com/D176560
Diffstat (limited to 'components/servo_arc/lib.rs')
-rw-r--r-- | components/servo_arc/lib.rs | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/components/servo_arc/lib.rs b/components/servo_arc/lib.rs index 505d7d51c89..24d79cef68a 100644 --- a/components/servo_arc/lib.rs +++ b/components/servo_arc/lib.rs @@ -688,10 +688,16 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { /// then `alloc` must return an allocation that can be dellocated /// by calling Box::from_raw::<ArcInner<HeaderSlice<H, T>>> on it. #[inline] - fn from_header_and_iter_alloc<F, I>(alloc: F, header: H, mut items: I, is_static: bool) -> Self + fn from_header_and_iter_alloc<F, I>( + alloc: F, + header: H, + mut items: I, + num_items: usize, + is_static: bool, + ) -> Self where F: FnOnce(Layout) -> *mut u8, - I: Iterator<Item = T> + ExactSizeIterator, + I: Iterator<Item = T>, { assert_ne!(size_of::<T>(), 0, "Need to think about ZST"); @@ -699,7 +705,6 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { debug_assert!(inner_align >= align_of::<T>()); // Compute the required size for the allocation. - let num_items = items.len(); let size = { // Next, synthesize a totally garbage (but properly aligned) pointer // to a sequence of T. @@ -770,8 +775,7 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { // We should have consumed the buffer exactly, maybe accounting // for some padding from the alignment. debug_assert!( - (buffer.add(size) as usize - current as *mut u8 as usize) < - inner_align + (buffer.add(size) as usize - current as *mut u8 as usize) < inner_align ); } assert!( @@ -779,7 +783,6 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { "ExactSizeIterator under-reported length" ); } - #[cfg(feature = "gecko_refcount_logging")] unsafe { if !is_static { @@ -803,12 +806,12 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { } } - /// Creates an Arc for a HeaderSlice using the given header struct and - /// iterator to generate the slice. The resulting Arc will be fat. + /// Creates an Arc for a HeaderSlice using the given header struct and iterator to generate the + /// slice. Panics if num_items doesn't match the number of items. #[inline] - pub fn from_header_and_iter<I>(header: H, items: I) -> Self + pub fn from_header_and_iter_with_size<I>(header: H, items: I, num_items: usize) -> Self where - I: Iterator<Item = T> + ExactSizeIterator, + I: Iterator<Item = T>, { Arc::from_header_and_iter_alloc( |layout| { @@ -825,12 +828,22 @@ impl<H, T> Arc<HeaderSlice<H, [T]>> { }, header, items, + num_items, /* is_static = */ false, ) } + /// Creates an Arc for a HeaderSlice using the given header struct and + /// iterator to generate the slice. The resulting Arc will be fat. + pub fn from_header_and_iter<I>(header: H, items: I) -> Self + where + I: Iterator<Item = T> + ExactSizeIterator, + { + let len = items.len(); + Self::from_header_and_iter_with_size(header, items, len) + } + #[inline] - #[allow(clippy::uninit_vec)] unsafe fn allocate_buffer<W>(size: usize) -> *mut u8 { // We use Vec because the underlying allocation machinery isn't // available in stable Rust. To avoid alignment issues, we allocate @@ -857,10 +870,7 @@ pub struct HeaderWithLength<H> { impl<H> HeaderWithLength<H> { /// Creates a new HeaderWithLength. pub fn new(header: H, length: usize) -> Self { - HeaderWithLength { - header, - length, - } + HeaderWithLength { header, length } } } @@ -958,9 +968,10 @@ impl<H, T> ThinArc<H, T> { F: FnOnce(Layout) -> *mut u8, I: Iterator<Item = T> + ExactSizeIterator, { - let header = HeaderWithLength::new(header, items.len()); + let len = items.len(); + let header = HeaderWithLength::new(header, len); Arc::into_thin(Arc::from_header_and_iter_alloc( - alloc, header, items, /* is_static = */ true, + alloc, header, items, len, /* is_static = */ true, )) } @@ -1057,6 +1068,14 @@ impl<H, T> UniqueArc<HeaderSliceWithLength<H, [T]>> { Self(Arc::from_header_and_iter(header, items)) } + #[inline] + pub fn from_header_and_iter_with_size<I>(header: HeaderWithLength<H>, items: I, num_items: usize) -> Self + where + I: Iterator<Item = T>, + { + Self(Arc::from_header_and_iter_with_size(header, items, num_items)) + } + /// Returns a mutable reference to the header. pub fn header_mut(&mut self) -> &mut H { // We know this to be uniquely owned |