Add slots in PerPseudoElementMap for tree pseudos.

This commit is contained in:
Xidorn Quan 2017-10-20 14:08:35 +11:00
parent b743d68ccd
commit 4ce3dc7729
6 changed files with 203 additions and 185 deletions

View file

@ -185,6 +185,12 @@ pub const EAGER_PSEUDO_COUNT: usize = 4;
/// The number of non-functional pseudo-elements. /// The number of non-functional pseudo-elements.
pub const SIMPLE_PSEUDO_COUNT: usize = 71; pub const SIMPLE_PSEUDO_COUNT: usize = 71;
/// The number of tree pseudo-elements.
pub const TREE_PSEUDO_COUNT: usize = 12;
/// The number of all pseudo-elements.
pub const PSEUDO_COUNT: usize = 83;
/// The list of eager pseudos. /// The list of eager pseudos.
pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [ pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [
PseudoElement::Before, PseudoElement::Before,
@ -286,162 +292,184 @@ impl PseudoElement {
} }
} }
/// Returns an index if the pseudo-element is a simple (non-functional) /// Returns an index of the pseudo-element.
/// pseudo.
#[inline] #[inline]
pub fn simple_index(&self) -> Option<usize> { pub fn index(&self) -> usize {
match *self { match *self {
PseudoElement::After => Some(0), PseudoElement::After => 0,
PseudoElement::Before => Some(1), PseudoElement::Before => 1,
PseudoElement::Backdrop => Some(2), PseudoElement::Backdrop => 2,
PseudoElement::Cue => Some(3), PseudoElement::Cue => 3,
PseudoElement::FirstLetter => Some(4), PseudoElement::FirstLetter => 4,
PseudoElement::FirstLine => Some(5), PseudoElement::FirstLine => 5,
PseudoElement::MozSelection => Some(6), PseudoElement::MozSelection => 6,
PseudoElement::MozFocusInner => Some(7), PseudoElement::MozFocusInner => 7,
PseudoElement::MozFocusOuter => Some(8), PseudoElement::MozFocusOuter => 8,
PseudoElement::MozListBullet => Some(9), PseudoElement::MozListBullet => 9,
PseudoElement::MozListNumber => Some(10), PseudoElement::MozListNumber => 10,
PseudoElement::MozMathAnonymous => Some(11), PseudoElement::MozMathAnonymous => 11,
PseudoElement::MozNumberWrapper => Some(12), PseudoElement::MozNumberWrapper => 12,
PseudoElement::MozNumberText => Some(13), PseudoElement::MozNumberText => 13,
PseudoElement::MozNumberSpinBox => Some(14), PseudoElement::MozNumberSpinBox => 14,
PseudoElement::MozNumberSpinUp => Some(15), PseudoElement::MozNumberSpinUp => 15,
PseudoElement::MozNumberSpinDown => Some(16), PseudoElement::MozNumberSpinDown => 16,
PseudoElement::MozProgressBar => Some(17), PseudoElement::MozProgressBar => 17,
PseudoElement::MozRangeTrack => Some(18), PseudoElement::MozRangeTrack => 18,
PseudoElement::MozRangeProgress => Some(19), PseudoElement::MozRangeProgress => 19,
PseudoElement::MozRangeThumb => Some(20), PseudoElement::MozRangeThumb => 20,
PseudoElement::MozMeterBar => Some(21), PseudoElement::MozMeterBar => 21,
PseudoElement::MozPlaceholder => Some(22), PseudoElement::MozPlaceholder => 22,
PseudoElement::Placeholder => Some(23), PseudoElement::Placeholder => 23,
PseudoElement::MozColorSwatch => Some(24), PseudoElement::MozColorSwatch => 24,
PseudoElement::MozText => Some(25), PseudoElement::MozText => 25,
PseudoElement::OofPlaceholder => Some(26), PseudoElement::OofPlaceholder => 26,
PseudoElement::FirstLetterContinuation => Some(27), PseudoElement::FirstLetterContinuation => 27,
PseudoElement::MozBlockInsideInlineWrapper => Some(28), PseudoElement::MozBlockInsideInlineWrapper => 28,
PseudoElement::MozMathMLAnonymousBlock => Some(29), PseudoElement::MozMathMLAnonymousBlock => 29,
PseudoElement::MozXULAnonymousBlock => Some(30), PseudoElement::MozXULAnonymousBlock => 30,
PseudoElement::HorizontalFramesetBorder => Some(31), PseudoElement::HorizontalFramesetBorder => 31,
PseudoElement::VerticalFramesetBorder => Some(32), PseudoElement::VerticalFramesetBorder => 32,
PseudoElement::MozLineFrame => Some(33), PseudoElement::MozLineFrame => 33,
PseudoElement::ButtonContent => Some(34), PseudoElement::ButtonContent => 34,
PseudoElement::CellContent => Some(35), PseudoElement::CellContent => 35,
PseudoElement::DropDownList => Some(36), PseudoElement::DropDownList => 36,
PseudoElement::FieldsetContent => Some(37), PseudoElement::FieldsetContent => 37,
PseudoElement::FramesetBlank => Some(38), PseudoElement::FramesetBlank => 38,
PseudoElement::MozDisplayComboboxControlFrame => Some(39), PseudoElement::MozDisplayComboboxControlFrame => 39,
PseudoElement::HtmlCanvasContent => Some(40), PseudoElement::HtmlCanvasContent => 40,
PseudoElement::InlineTable => Some(41), PseudoElement::InlineTable => 41,
PseudoElement::Table => Some(42), PseudoElement::Table => 42,
PseudoElement::TableCell => Some(43), PseudoElement::TableCell => 43,
PseudoElement::TableColGroup => Some(44), PseudoElement::TableColGroup => 44,
PseudoElement::TableCol => Some(45), PseudoElement::TableCol => 45,
PseudoElement::TableWrapper => Some(46), PseudoElement::TableWrapper => 46,
PseudoElement::TableRowGroup => Some(47), PseudoElement::TableRowGroup => 47,
PseudoElement::TableRow => Some(48), PseudoElement::TableRow => 48,
PseudoElement::Canvas => Some(49), PseudoElement::Canvas => 49,
PseudoElement::PageBreak => Some(50), PseudoElement::PageBreak => 50,
PseudoElement::Page => Some(51), PseudoElement::Page => 51,
PseudoElement::PageContent => Some(52), PseudoElement::PageContent => 52,
PseudoElement::PageSequence => Some(53), PseudoElement::PageSequence => 53,
PseudoElement::ScrolledContent => Some(54), PseudoElement::ScrolledContent => 54,
PseudoElement::ScrolledCanvas => Some(55), PseudoElement::ScrolledCanvas => 55,
PseudoElement::ScrolledPageSequence => Some(56), PseudoElement::ScrolledPageSequence => 56,
PseudoElement::ColumnContent => Some(57), PseudoElement::ColumnContent => 57,
PseudoElement::Viewport => Some(58), PseudoElement::Viewport => 58,
PseudoElement::ViewportScroll => Some(59), PseudoElement::ViewportScroll => 59,
PseudoElement::AnonymousFlexItem => Some(60), PseudoElement::AnonymousFlexItem => 60,
PseudoElement::AnonymousGridItem => Some(61), PseudoElement::AnonymousGridItem => 61,
PseudoElement::Ruby => Some(62), PseudoElement::Ruby => 62,
PseudoElement::RubyBase => Some(63), PseudoElement::RubyBase => 63,
PseudoElement::RubyBaseContainer => Some(64), PseudoElement::RubyBaseContainer => 64,
PseudoElement::RubyText => Some(65), PseudoElement::RubyText => 65,
PseudoElement::RubyTextContainer => Some(66), PseudoElement::RubyTextContainer => 66,
PseudoElement::MozSVGMarkerAnonChild => Some(67), PseudoElement::MozTreeColumn(..) => 67,
PseudoElement::MozSVGOuterSVGAnonChild => Some(68), PseudoElement::MozTreeRow(..) => 68,
PseudoElement::MozSVGForeignContent => Some(69), PseudoElement::MozTreeSeparator(..) => 69,
PseudoElement::MozSVGText => Some(70), PseudoElement::MozTreeCell(..) => 70,
_ => None, PseudoElement::MozTreeIndentation(..) => 71,
PseudoElement::MozTreeLine(..) => 72,
PseudoElement::MozTreeTwisty(..) => 73,
PseudoElement::MozTreeImage(..) => 74,
PseudoElement::MozTreeCellText(..) => 75,
PseudoElement::MozTreeCheckbox(..) => 76,
PseudoElement::MozTreeProgressmeter(..) => 77,
PseudoElement::MozTreeDropFeedback(..) => 78,
PseudoElement::MozSVGMarkerAnonChild => 79,
PseudoElement::MozSVGOuterSVGAnonChild => 80,
PseudoElement::MozSVGForeignContent => 81,
PseudoElement::MozSVGText => 82,
} }
} }
/// Returns an array of `None` values. /// Returns an array of `None` values.
/// ///
/// FIXME(emilio): Integer generics can't come soon enough. /// FIXME(emilio): Integer generics can't come soon enough.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] { pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
[ [
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None, None,
None None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None
] ]
} }

View file

@ -27,6 +27,12 @@ pub const EAGER_PSEUDO_COUNT: usize = ${len(EAGER_PSEUDOS)};
/// The number of non-functional pseudo-elements. /// The number of non-functional pseudo-elements.
pub const SIMPLE_PSEUDO_COUNT: usize = ${len(SIMPLE_PSEUDOS)}; pub const SIMPLE_PSEUDO_COUNT: usize = ${len(SIMPLE_PSEUDOS)};
/// The number of tree pseudo-elements.
pub const TREE_PSEUDO_COUNT: usize = ${len(TREE_PSEUDOS)};
/// The number of all pseudo-elements.
pub const PSEUDO_COUNT: usize = ${len(PSEUDOS)};
/// The list of eager pseudos. /// The list of eager pseudos.
pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [ pub const EAGER_PSEUDOS: [PseudoElement; EAGER_PSEUDO_COUNT] = [
% for eager_pseudo_name in EAGER_PSEUDOS: % for eager_pseudo_name in EAGER_PSEUDOS:
@ -49,24 +55,22 @@ impl PseudoElement {
} }
} }
/// Returns an index if the pseudo-element is a simple (non-functional) /// Returns an index of the pseudo-element.
/// pseudo.
#[inline] #[inline]
pub fn simple_index(&self) -> Option<usize> { pub fn index(&self) -> usize {
match *self { match *self {
% for i, pseudo in enumerate(SIMPLE_PSEUDOS): % for i, pseudo in enumerate(PSEUDOS):
${pseudo_element_variant(pseudo)} => Some(${i}), ${pseudo_element_variant(pseudo)} => ${i},
% endfor % endfor
_ => None,
} }
} }
/// Returns an array of `None` values. /// Returns an array of `None` values.
/// ///
/// FIXME(emilio): Integer generics can't come soon enough. /// FIXME(emilio): Integer generics can't come soon enough.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] { pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
[ [
${",\n".join(["None" for pseudo in SIMPLE_PSEUDOS])} ${",\n ".join(["None" for pseudo in PSEUDOS])}
] ]
} }

View file

@ -17,7 +17,7 @@ use std::fmt;
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use style_traits::{ParseError, StyleParseErrorKind}; use style_traits::{ParseError, StyleParseErrorKind};
pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, SIMPLE_PSEUDO_COUNT}; pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, PSEUDO_COUNT};
pub use gecko::snapshot::SnapshotMap; pub use gecko::snapshot::SnapshotMap;
bitflags! { bitflags! {

View file

@ -102,16 +102,16 @@ pub enum PseudoElementCascadeType {
Precomputed, Precomputed,
} }
/// A per-functional-pseudo map, from a given pseudo to a `T`. /// A per-pseudo map, from a given pseudo to a `T`.
#[derive(MallocSizeOf)] #[derive(MallocSizeOf)]
pub struct PerPseudoElementMap<T> { pub struct PerPseudoElementMap<T> {
entries: [Option<T>; SIMPLE_PSEUDO_COUNT], entries: [Option<T>; PSEUDO_COUNT],
} }
impl<T> Default for PerPseudoElementMap<T> { impl<T> Default for PerPseudoElementMap<T> {
fn default() -> Self { fn default() -> Self {
Self { Self {
entries: PseudoElement::simple_pseudo_none_array(), entries: PseudoElement::pseudo_none_array(),
} }
} }
} }
@ -137,11 +137,7 @@ where
impl<T> PerPseudoElementMap<T> { impl<T> PerPseudoElementMap<T> {
/// Get an entry in the map. /// Get an entry in the map.
pub fn get(&self, pseudo: &PseudoElement) -> Option<&T> { pub fn get(&self, pseudo: &PseudoElement) -> Option<&T> {
let index = match pseudo.simple_index() { self.entries[pseudo.index()].as_ref()
Some(i) => i,
None => return None,
};
self.entries[index].as_ref()
} }
/// Clear this enumerated array. /// Clear this enumerated array.
@ -161,13 +157,8 @@ impl<T> PerPseudoElementMap<T> {
/// Set an entry value. /// Set an entry value.
/// ///
/// Returns an error if the element is not a simple pseudo. /// Returns an error if the element is not a simple pseudo.
pub fn set(&mut self, pseudo: &PseudoElement, value: T) -> Result<(), ()> { pub fn set(&mut self, pseudo: &PseudoElement, value: T) {
let index = match pseudo.simple_index() { self.entries[pseudo.index()] = Some(value);
Some(i) => i,
None => return Err(()),
};
self.entries[index] = Some(value);
Ok(())
} }
/// Get an entry for `pseudo`, or create it with calling `f`. /// Get an entry for `pseudo`, or create it with calling `f`.
@ -175,18 +166,15 @@ impl<T> PerPseudoElementMap<T> {
&mut self, &mut self,
pseudo: &PseudoElement, pseudo: &PseudoElement,
f: F, f: F,
) -> Result<&mut T, ()> ) -> &mut T
where where
F: FnOnce() -> T, F: FnOnce() -> T,
{ {
let index = match pseudo.simple_index() { let index = pseudo.index();
Some(i) => i,
None => return Err(()),
};
if self.entries[index].is_none() { if self.entries[index].is_none() {
self.entries[index] = Some(f()); self.entries[index] = Some(f());
} }
Ok(self.entries[index].as_mut().unwrap()) self.entries[index].as_mut().unwrap()
} }
/// Get an iterator for the entries. /// Get an iterator for the entries.

View file

@ -62,9 +62,8 @@ pub enum PseudoElement {
ServoInlineAbsolute, ServoInlineAbsolute,
} }
/// The count of simple (non-functional) pseudo-elements (that is, all /// The count of all pseudo-elements.
/// pseudo-elements for now). pub const PSEUDO_COUNT: usize = PseudoElement::ServoInlineAbsolute as usize + 1;
pub const SIMPLE_PSEUDO_COUNT: usize = PseudoElement::ServoInlineAbsolute as usize + 1;
impl ::selectors::parser::PseudoElement for PseudoElement { impl ::selectors::parser::PseudoElement for PseudoElement {
type Impl = SelectorImpl; type Impl = SelectorImpl;
@ -110,12 +109,12 @@ impl PseudoElement {
/// An index for this pseudo-element to be indexed in an enumerated array. /// An index for this pseudo-element to be indexed in an enumerated array.
#[inline] #[inline]
pub fn simple_index(&self) -> Option<usize> { pub fn index(&self) -> usize {
Some(self.clone() as usize) self.clone() as usize
} }
/// An array of `None`, one per simple pseudo-element. /// An array of `None`, one per pseudo-element.
pub fn simple_pseudo_none_array<T>() -> [Option<T>; SIMPLE_PSEUDO_COUNT] { pub fn pseudo_none_array<T>() -> [Option<T>; PSEUDO_COUNT] {
Default::default() Default::default()
} }

View file

@ -1995,7 +1995,6 @@ impl CascadeData {
.as_mut() .as_mut()
.expect("Expected precomputed declarations for the UA level") .expect("Expected precomputed declarations for the UA level")
.get_or_insert_with(&pseudo.canonical(), Vec::new) .get_or_insert_with(&pseudo.canonical(), Vec::new)
.expect("Unexpected tree pseudo-element?")
.push(ApplicableDeclarationBlock::new( .push(ApplicableDeclarationBlock::new(
StyleSource::Style(locked.clone()), StyleSource::Style(locked.clone()),
self.rules_source_order, self.rules_source_order,
@ -2012,7 +2011,7 @@ impl CascadeData {
let mut map = Box::new(SelectorMap::new()); let mut map = Box::new(SelectorMap::new());
map.begin_mutation(); map.begin_mutation();
map map
}).expect("Unexpected tree pseudo-element?") })
} }
}; };