mirror of
https://github.com/servo/servo.git
synced 2025-06-23 08:34:42 +01:00
style: Use ArcSlice for quotes.
This saves the intermediate allocation. Differential Revision: https://phabricator.services.mozilla.com/D30546
This commit is contained in:
parent
bbc77e3977
commit
a109fbb7c8
9 changed files with 85 additions and 44 deletions
|
@ -23,7 +23,6 @@ use crate::gecko_bindings::structs::RawServoMediaRule;
|
||||||
use crate::gecko_bindings::structs::RawServoMozDocumentRule;
|
use crate::gecko_bindings::structs::RawServoMozDocumentRule;
|
||||||
use crate::gecko_bindings::structs::RawServoNamespaceRule;
|
use crate::gecko_bindings::structs::RawServoNamespaceRule;
|
||||||
use crate::gecko_bindings::structs::RawServoPageRule;
|
use crate::gecko_bindings::structs::RawServoPageRule;
|
||||||
use crate::gecko_bindings::structs::RawServoQuotes;
|
|
||||||
use crate::gecko_bindings::structs::RawServoStyleRule;
|
use crate::gecko_bindings::structs::RawServoStyleRule;
|
||||||
use crate::gecko_bindings::structs::RawServoStyleSheetContents;
|
use crate::gecko_bindings::structs::RawServoStyleSheetContents;
|
||||||
use crate::gecko_bindings::structs::RawServoSupportsRule;
|
use crate::gecko_bindings::structs::RawServoSupportsRule;
|
||||||
|
@ -40,7 +39,6 @@ use crate::stylesheets::{NamespaceRule, PageRule};
|
||||||
use crate::stylesheets::{StyleRule, StylesheetContents, SupportsRule};
|
use crate::stylesheets::{StyleRule, StylesheetContents, SupportsRule};
|
||||||
use servo_arc::{Arc, ArcBorrow};
|
use servo_arc::{Arc, ArcBorrow};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
use values::computed::QuotePair;
|
|
||||||
|
|
||||||
macro_rules! impl_arc_ffi {
|
macro_rules! impl_arc_ffi {
|
||||||
($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => {
|
($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => {
|
||||||
|
@ -115,9 +113,6 @@ impl_arc_ffi!(Locked<CounterStyleRule> => RawServoCounterStyleRule
|
||||||
impl_arc_ffi!(CssUrlData => RawServoCssUrlData
|
impl_arc_ffi!(CssUrlData => RawServoCssUrlData
|
||||||
[Servo_CssUrlData_AddRef, Servo_CssUrlData_Release]);
|
[Servo_CssUrlData_AddRef, Servo_CssUrlData_Release]);
|
||||||
|
|
||||||
impl_arc_ffi!(Box<[QuotePair]> => RawServoQuotes
|
|
||||||
[Servo_Quotes_AddRef, Servo_Quotes_Release]);
|
|
||||||
|
|
||||||
// ComputedStyle is not an opaque type on any side of FFI.
|
// ComputedStyle is not an opaque type on any side of FFI.
|
||||||
// This means that doing the HasArcFFI type trick is actually unsound,
|
// This means that doing the HasArcFFI type trick is actually unsound,
|
||||||
// since it gives us a way to construct an Arc<ComputedStyle> from
|
// since it gives us a way to construct an Arc<ComputedStyle> from
|
||||||
|
|
|
@ -190,6 +190,7 @@ pub use servo_atoms::Atom;
|
||||||
|
|
||||||
pub use style_traits::arc_slice::ArcSlice;
|
pub use style_traits::arc_slice::ArcSlice;
|
||||||
pub use style_traits::owned_slice::OwnedSlice;
|
pub use style_traits::owned_slice::OwnedSlice;
|
||||||
|
pub use style_traits::owned_str::OwnedStr;
|
||||||
|
|
||||||
/// The CSS properties supported by the style system.
|
/// The CSS properties supported by the style system.
|
||||||
/// Generated from the properties.mako.rs template by build.rs
|
/// Generated from the properties.mako.rs template by build.rs
|
||||||
|
|
|
@ -3302,7 +3302,7 @@ fn static_assert() {
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="List"
|
<%self:impl_trait style_struct_name="List"
|
||||||
skip_longhands="list-style-image list-style-type quotes -moz-image-region">
|
skip_longhands="list-style-image list-style-type -moz-image-region">
|
||||||
|
|
||||||
pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) {
|
pub fn set_list_style_image(&mut self, image: longhands::list_style_image::computed_value::T) {
|
||||||
match image {
|
match image {
|
||||||
|
@ -3378,28 +3378,6 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_quotes(&mut self, other: longhands::quotes::computed_value::T) {
|
|
||||||
self.gecko.mQuotes.set_arc(other.0.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn copy_quotes_from(&mut self, other: &Self) {
|
|
||||||
self.set_quotes(other.clone_quotes());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_quotes(&mut self, other: &Self) {
|
|
||||||
self.copy_quotes_from(other)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clone_quotes(&self) -> longhands::quotes::computed_value::T {
|
|
||||||
use gecko_bindings::sugar::ownership::HasArcFFI;
|
|
||||||
use values::computed::QuotePair;
|
|
||||||
|
|
||||||
let quote_pairs = unsafe { &*self.gecko.mQuotes.mRawPtr };
|
|
||||||
longhands::quotes::computed_value::T(
|
|
||||||
Box::<[QuotePair]>::as_arc("e_pairs).clone_arc()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
|
pub fn set__moz_image_region(&mut self, v: longhands::_moz_image_region::computed_value::T) {
|
||||||
use crate::values::Either;
|
use crate::values::Either;
|
||||||
|
|
|
@ -9,21 +9,19 @@ pub use crate::values::specified::list::ListStyleType;
|
||||||
pub use crate::values::specified::list::MozListReversed;
|
pub use crate::values::specified::list::MozListReversed;
|
||||||
pub use crate::values::specified::list::{QuotePair, Quotes};
|
pub use crate::values::specified::list::{QuotePair, Quotes};
|
||||||
|
|
||||||
use servo_arc::Arc;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref INITIAL_QUOTES: Arc<Box<[QuotePair]>> = Arc::new(
|
static ref INITIAL_QUOTES: crate::ArcSlice<QuotePair> = crate::ArcSlice::from_iter(
|
||||||
vec![
|
vec![
|
||||||
QuotePair {
|
QuotePair {
|
||||||
opening: "\u{201c}".to_owned().into_boxed_str(),
|
opening: "\u{201c}".to_owned().into(),
|
||||||
closing: "\u{201d}".to_owned().into_boxed_str(),
|
closing: "\u{201d}".to_owned().into(),
|
||||||
},
|
},
|
||||||
QuotePair {
|
QuotePair {
|
||||||
opening: "\u{2018}".to_owned().into_boxed_str(),
|
opening: "\u{2018}".to_owned().into(),
|
||||||
closing: "\u{2019}".to_owned().into_boxed_str(),
|
closing: "\u{2019}".to_owned().into(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
.into_boxed_slice()
|
.into_iter()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ use crate::values::generics::CounterStyleOrNone;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use crate::values::CustomIdent;
|
use crate::values::CustomIdent;
|
||||||
use cssparser::{Parser, Token};
|
use cssparser::{Parser, Token};
|
||||||
use servo_arc::Arc;
|
|
||||||
use style_traits::{ParseError, StyleParseErrorKind};
|
use style_traits::{ParseError, StyleParseErrorKind};
|
||||||
|
|
||||||
/// Specified and computed `list-style-type` property.
|
/// Specified and computed `list-style-type` property.
|
||||||
|
@ -96,18 +95,20 @@ impl Parse for ListStyleType {
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct QuotePair {
|
pub struct QuotePair {
|
||||||
/// The opening quote.
|
/// The opening quote.
|
||||||
pub opening: Box<str>,
|
pub opening: crate::OwnedStr,
|
||||||
|
|
||||||
/// The closing quote.
|
/// The closing quote.
|
||||||
pub closing: Box<str>,
|
pub closing: crate::OwnedStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specified and computed `quotes` property.
|
/// Specified and computed `quotes` property.
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Debug,
|
Debug,
|
||||||
|
Default,
|
||||||
MallocSizeOf,
|
MallocSizeOf,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
SpecifiedValueInfo,
|
SpecifiedValueInfo,
|
||||||
|
@ -116,10 +117,11 @@ pub struct QuotePair {
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
|
#[repr(C)]
|
||||||
pub struct Quotes(
|
pub struct Quotes(
|
||||||
#[css(iterable, if_empty = "none")]
|
#[css(iterable, if_empty = "none")]
|
||||||
#[ignore_malloc_size_of = "Arc"]
|
#[ignore_malloc_size_of = "Arc"]
|
||||||
pub Arc<Box<[QuotePair]>>,
|
pub crate::ArcSlice<QuotePair>,
|
||||||
);
|
);
|
||||||
|
|
||||||
impl Parse for Quotes {
|
impl Parse for Quotes {
|
||||||
|
@ -131,24 +133,26 @@ impl Parse for Quotes {
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(Quotes(Arc::new(Box::new([]))));
|
return Ok(Self::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut quotes = Vec::new();
|
let mut quotes = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let opening = match input.next() {
|
let opening = match input.next() {
|
||||||
Ok(&Token::QuotedString(ref value)) => value.as_ref().to_owned().into_boxed_str(),
|
Ok(&Token::QuotedString(ref value)) => {
|
||||||
|
value.as_ref().to_owned().into()
|
||||||
|
},
|
||||||
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
Ok(t) => return Err(location.new_unexpected_token_error(t.clone())),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
|
|
||||||
let closing = input.expect_string()?.as_ref().to_owned().into_boxed_str();
|
let closing = input.expect_string()?.as_ref().to_owned().into();
|
||||||
quotes.push(QuotePair { opening, closing });
|
quotes.push(QuotePair { opening, closing });
|
||||||
}
|
}
|
||||||
|
|
||||||
if !quotes.is_empty() {
|
if !quotes.is_empty() {
|
||||||
Ok(Quotes(Arc::new(quotes.into_boxed_slice())))
|
Ok(Quotes(crate::ArcSlice::from_iter(quotes.into_iter())))
|
||||||
} else {
|
} else {
|
||||||
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,7 @@ pub mod values;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod viewport;
|
pub mod viewport;
|
||||||
pub mod owned_slice;
|
pub mod owned_slice;
|
||||||
|
pub mod owned_str;
|
||||||
|
|
||||||
pub use crate::specified_value_info::{CssType, KeywordsCollectFn, SpecifiedValueInfo};
|
pub use crate::specified_value_info::{CssType, KeywordsCollectFn, SpecifiedValueInfo};
|
||||||
pub use crate::values::{
|
pub use crate::values::{
|
||||||
|
|
53
components/style_traits/owned_str.rs
Normal file
53
components/style_traits/owned_str.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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<str>` that has a defined layout for FFI.
|
||||||
|
|
||||||
|
use crate::owned_slice::OwnedSlice;
|
||||||
|
use std::fmt;
|
||||||
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
|
/// A struct that basically replaces a Box<str>, but with a defined layout,
|
||||||
|
/// suitable for FFI.
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Default, Clone, PartialEq, Eq, MallocSizeOf, ToShmem)]
|
||||||
|
pub struct OwnedStr(OwnedSlice<u8>);
|
||||||
|
|
||||||
|
impl fmt::Debug for OwnedStr {
|
||||||
|
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
self.deref().fmt(formatter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for OwnedStr {
|
||||||
|
type Target = str;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
unsafe { std::str::from_utf8_unchecked(&*self.0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for OwnedStr {
|
||||||
|
#[inline(always)]
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
unsafe { std::str::from_utf8_unchecked_mut(&mut *self.0) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<str>> for OwnedStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(b: Box<str>) -> Self {
|
||||||
|
Self::from(b.into_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<String> for OwnedStr {
|
||||||
|
#[inline]
|
||||||
|
fn from(s: String) -> Self {
|
||||||
|
OwnedStr(s.into_bytes().into())
|
||||||
|
}
|
||||||
|
}
|
|
@ -84,6 +84,7 @@ impl SpecifiedValueInfo for u16 {}
|
||||||
impl SpecifiedValueInfo for u32 {}
|
impl SpecifiedValueInfo for u32 {}
|
||||||
impl SpecifiedValueInfo for str {}
|
impl SpecifiedValueInfo for str {}
|
||||||
impl SpecifiedValueInfo for String {}
|
impl SpecifiedValueInfo for String {}
|
||||||
|
impl SpecifiedValueInfo for crate::owned_str::OwnedStr {}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
impl SpecifiedValueInfo for ::servo_atoms::Atom {}
|
impl SpecifiedValueInfo for ::servo_atoms::Atom {}
|
||||||
|
|
|
@ -75,6 +75,16 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ToCss for crate::owned_str::OwnedStr {
|
||||||
|
#[inline]
|
||||||
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
where
|
||||||
|
W: Write,
|
||||||
|
{
|
||||||
|
serialize_string(self, dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ToCss for str {
|
impl ToCss for str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue