Keep initial values in a lazy static instead of passing a parameter around.

Thanks to @Kimundi for https://gist.github.com/Kimundi/8782487
This commit is contained in:
Simon Sapin 2014-05-13 13:44:09 +01:00
parent e5eac5b538
commit 4310f29431
9 changed files with 87 additions and 40 deletions

View file

@ -261,7 +261,7 @@ DONE_script = $(B)src/components/script/libscript.dummy
DEPS_script = $(CRATE_script) $(SRC_script) $(DONE_SUBMODULES) $(DONE_util) $(DONE_style) $(DONE_net) $(DONE_msg) $(DONE_macros) DEPS_script = $(CRATE_script) $(SRC_script) $(DONE_SUBMODULES) $(DONE_util) $(DONE_style) $(DONE_net) $(DONE_msg) $(DONE_macros)
RFLAGS_style = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util RFLAGS_style = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/util -L$(B)src/components/macros
MAKO_ZIP = $(S)src/components/style/Mako-0.9.1.zip MAKO_ZIP = $(S)src/components/style/Mako-0.9.1.zip
MAKO_style = $(S)src/components/style/properties.rs MAKO_style = $(S)src/components/style/properties.rs
MAKO_SRC_style = $(MAKO_style).mako MAKO_SRC_style = $(MAKO_style).mako
@ -269,7 +269,7 @@ SRC_style = $(call rwildcard,$(S)src/components/style/,*.rs) $(MAKO_style)
CRATE_style = $(S)src/components/style/style.rs CRATE_style = $(S)src/components/style/style.rs
DONE_style = $(B)src/components/style/libstyle.dummy DONE_style = $(B)src/components/style/libstyle.dummy
DEPS_style = $(CRATE_style) $(SRC_style) $(DONE_SUBMODULES) $(DONE_util) DEPS_style = $(CRATE_style) $(SRC_style) $(DONE_SUBMODULES) $(DONE_util) $(DONE_macros)
RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net -L $(B)src/components/script -L $(B)src/components/style -L $(B)src/components/msg -L$(B)src/components/macros RFLAGS_servo = $(strip $(CFG_RUSTC_FLAGS)) $(addprefix -L $(B)src/,$(DEPS_SUBMODULES)) -L $(B)src/components/gfx -L $(B)src/components/util -L $(B)src/components/net -L $(B)src/components/script -L $(B)src/components/style -L $(B)src/components/msg -L$(B)src/components/macros

View file

@ -9,6 +9,11 @@
#![feature(macro_rules)] #![feature(macro_rules)]
#[cfg(test)]
extern crate sync;
#[macro_export] #[macro_export]
macro_rules! bitfield( macro_rules! bitfield(
($bitfieldname:ident, $getter:ident, $setter:ident, $value:expr) => ( ($bitfieldname:ident, $getter:ident, $setter:ident, $value:expr) => (
@ -28,3 +33,66 @@ macro_rules! bitfield(
) )
) )
#[macro_export]
macro_rules! lazy_init(
($(static ref $N:ident : $T:ty = $e:expr;)*) => (
$(
#[allow(non_camel_case_types)]
struct $N {__unit__: ()}
static $N: $N = $N {__unit__: ()};
impl Deref<$T> for $N {
fn deref<'a>(&'a self) -> &'a $T {
unsafe {
static mut s: *$T = 0 as *$T;
static mut ONCE: ::sync::one::Once = ::sync::one::ONCE_INIT;
ONCE.doit(|| {
s = ::std::cast::transmute::<~$T, *$T>(~($e));
});
&*s
}
}
}
)*
)
)
#[cfg(test)]
mod tests {
extern crate collections;
lazy_init! {
static ref NUMBER: uint = times_two(3);
static ref VEC: [~uint, ..3] = [~1, ~2, ~3];
static ref OWNED_STRING: ~str = ~"hello";
static ref HASHMAP: collections::HashMap<uint, &'static str> = {
let mut m = collections::HashMap::new();
m.insert(0u, "abc");
m.insert(1, "def");
m.insert(2, "ghi");
m
};
}
fn times_two(n: uint) -> uint {
n * 2
}
#[test]
fn test_basic() {
assert_eq!(*OWNED_STRING, ~"hello");
assert_eq!(*NUMBER, 6);
assert!(HASHMAP.find(&1).is_some());
assert!(HASHMAP.find(&3).is_none());
assert_eq!(VEC.as_slice(), &[~1, ~2, ~3]);
}
#[test]
fn test_repeat() {
assert_eq!(*NUMBER, 6);
assert_eq!(*NUMBER, 6);
assert_eq!(*NUMBER, 6);
}
}

View file

@ -309,7 +309,6 @@ pub trait MatchMethods {
unsafe fn cascade_node(&self, unsafe fn cascade_node(&self,
parent: Option<LayoutNode>, parent: Option<LayoutNode>,
initial_values: &ComputedValues,
applicable_declarations: &ApplicableDeclarations, applicable_declarations: &ApplicableDeclarations,
applicable_declarations_cache: &mut ApplicableDeclarationsCache); applicable_declarations_cache: &mut ApplicableDeclarationsCache);
} }
@ -319,7 +318,6 @@ trait PrivateMatchMethods {
parent_style: Option<&Arc<ComputedValues>>, parent_style: Option<&Arc<ComputedValues>>,
applicable_declarations: &[MatchedProperty], applicable_declarations: &[MatchedProperty],
style: &mut Option<Arc<ComputedValues>>, style: &mut Option<Arc<ComputedValues>>,
initial_values: &ComputedValues,
applicable_declarations_cache: &mut applicable_declarations_cache: &mut
ApplicableDeclarationsCache, ApplicableDeclarationsCache,
shareable: bool); shareable: bool);
@ -335,7 +333,6 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
parent_style: Option<&Arc<ComputedValues>>, parent_style: Option<&Arc<ComputedValues>>,
applicable_declarations: &[MatchedProperty], applicable_declarations: &[MatchedProperty],
style: &mut Option<Arc<ComputedValues>>, style: &mut Option<Arc<ComputedValues>>,
initial_values: &ComputedValues,
applicable_declarations_cache: &mut applicable_declarations_cache: &mut
ApplicableDeclarationsCache, ApplicableDeclarationsCache,
shareable: bool) { shareable: bool) {
@ -352,7 +349,6 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
let (the_style, is_cacheable) = cascade(applicable_declarations, let (the_style, is_cacheable) = cascade(applicable_declarations,
shareable, shareable,
Some(&***parent_style), Some(&***parent_style),
initial_values,
cached_computed_values); cached_computed_values);
cacheable = is_cacheable; cacheable = is_cacheable;
this_style = Arc::new(the_style); this_style = Arc::new(the_style);
@ -361,7 +357,6 @@ impl<'ln> PrivateMatchMethods for LayoutNode<'ln> {
let (the_style, is_cacheable) = cascade(applicable_declarations, let (the_style, is_cacheable) = cascade(applicable_declarations,
shareable, shareable,
None, None,
initial_values,
None); None);
cacheable = is_cacheable; cacheable = is_cacheable;
this_style = Arc::new(the_style); this_style = Arc::new(the_style);
@ -492,9 +487,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
} }
unsafe { unsafe {
let initial_values = &*layout_context.initial_css_values;
self.cascade_node(parent, self.cascade_node(parent,
initial_values,
applicable_declarations, applicable_declarations,
applicable_declarations_cache) applicable_declarations_cache)
} }
@ -528,7 +521,6 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
unsafe fn cascade_node(&self, unsafe fn cascade_node(&self,
parent: Option<LayoutNode>, parent: Option<LayoutNode>,
initial_values: &ComputedValues,
applicable_declarations: &ApplicableDeclarations, applicable_declarations: &ApplicableDeclarations,
applicable_declarations_cache: &mut ApplicableDeclarationsCache) { applicable_declarations_cache: &mut ApplicableDeclarationsCache) {
// Get our parent's style. This must be unsafe so that we don't touch the parent's // Get our parent's style. This must be unsafe so that we don't touch the parent's
@ -559,14 +551,12 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
self.cascade_node_pseudo_element(parent_style, self.cascade_node_pseudo_element(parent_style,
applicable_declarations.normal.as_slice(), applicable_declarations.normal.as_slice(),
&mut layout_data.shared_data.style, &mut layout_data.shared_data.style,
initial_values,
applicable_declarations_cache, applicable_declarations_cache,
applicable_declarations.normal_shareable); applicable_declarations.normal_shareable);
if applicable_declarations.before.len() > 0 { if applicable_declarations.before.len() > 0 {
self.cascade_node_pseudo_element(parent_style, self.cascade_node_pseudo_element(parent_style,
applicable_declarations.before.as_slice(), applicable_declarations.before.as_slice(),
&mut layout_data.data.before_style, &mut layout_data.data.before_style,
initial_values,
applicable_declarations_cache, applicable_declarations_cache,
false); false);
} }
@ -574,7 +564,6 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
self.cascade_node_pseudo_element(parent_style, self.cascade_node_pseudo_element(parent_style,
applicable_declarations.after.as_slice(), applicable_declarations.after.as_slice(),
&mut layout_data.data.after_style, &mut layout_data.data.after_style,
initial_values,
applicable_declarations_cache, applicable_declarations_cache,
false); false);
} }

View file

@ -44,7 +44,7 @@ use std::from_str::FromStr;
use std::iter::AdditiveIterator; use std::iter::AdditiveIterator;
use std::mem; use std::mem;
use std::num::Zero; use std::num::Zero;
use style::{ComputedValues, TElement, TNode, cascade, initial_values}; use style::{ComputedValues, TElement, TNode, cascade};
use style::computed_values::{LengthOrPercentageOrAuto, overflow, LPA_Auto, background_attachment}; use style::computed_values::{LengthOrPercentageOrAuto, overflow, LPA_Auto, background_attachment};
use style::computed_values::{background_repeat, border_style, clear, position, text_align}; use style::computed_values::{background_repeat, border_style, clear, position, text_align};
use style::computed_values::{text_decoration, vertical_align, visibility, white_space}; use style::computed_values::{text_decoration, vertical_align, visibility, white_space};
@ -343,8 +343,7 @@ impl Box {
// //
// Anonymous table boxes, TableRowBox and TableCellBox, are generated around `Foo`, but it shouldn't inherit the border. // Anonymous table boxes, TableRowBox and TableCellBox, are generated around `Foo`, but it shouldn't inherit the border.
let (node_style, _) = cascade(&[], false, Some(&**node.style()), let (node_style, _) = cascade(&[], false, Some(&**node.style()), None);
&initial_values(), None);
Box { Box {
node: OpaqueNodeMethods::from_thread_safe_layout_node(node), node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
style: Arc::new(node_style), style: Arc::new(node_style),

View file

@ -24,8 +24,7 @@ use std::ptr;
use std::rt::local::Local; use std::rt::local::Local;
#[cfg(not(target_os="android"))] #[cfg(not(target_os="android"))]
use std::rt::task::Task; use std::rt::task::Task;
use style::{ComputedValues, Stylist}; use style::Stylist;
use sync::Arc;
use url::Url; use url::Url;
#[cfg(target_os="android")] #[cfg(target_os="android")]
@ -77,9 +76,6 @@ pub struct LayoutContext {
/// FIXME(pcwalton): Make this no longer an unsafe pointer once we have fast `RWArc`s. /// FIXME(pcwalton): Make this no longer an unsafe pointer once we have fast `RWArc`s.
pub stylist: *Stylist, pub stylist: *Stylist,
/// The initial set of CSS properties.
pub initial_css_values: Arc<ComputedValues>,
/// The root node at which we're starting the layout. /// The root node at which we're starting the layout.
pub reflow_root: OpaqueNode, pub reflow_root: OpaqueNode,

View file

@ -59,8 +59,7 @@ use std::comm::{channel, Sender, Receiver};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::task; use std::task;
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist}; use style::{AuthorOrigin, Stylesheet, Stylist};
use style;
use sync::{Arc, Mutex}; use sync::{Arc, Mutex};
use url::Url; use url::Url;
@ -98,9 +97,6 @@ pub struct LayoutTask {
pub stylist: ~Stylist, pub stylist: ~Stylist,
/// The initial set of CSS values.
pub initial_css_values: Arc<ComputedValues>,
/// The workers that we use for parallel operation. /// The workers that we use for parallel operation.
pub parallel_traversal: Option<WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>>, pub parallel_traversal: Option<WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>>,
@ -344,7 +340,6 @@ impl LayoutTask {
display_list: None, display_list: None,
stylist: ~new_stylist(), stylist: ~new_stylist(),
initial_css_values: Arc::new(style::initial_values()),
parallel_traversal: parallel_traversal, parallel_traversal: parallel_traversal,
profiler_chan: profiler_chan, profiler_chan: profiler_chan,
opts: opts.clone(), opts: opts.clone(),
@ -374,7 +369,6 @@ impl LayoutTask {
layout_chan: self.chan.clone(), layout_chan: self.chan.clone(),
font_context_info: font_context_info, font_context_info: font_context_info,
stylist: &*self.stylist, stylist: &*self.stylist,
initial_css_values: self.initial_css_values.clone(),
url: (*url).clone(), url: (*url).clone(),
reflow_root: OpaqueNodeMethods::from_layout_node(reflow_root), reflow_root: OpaqueNodeMethods::from_layout_node(reflow_root),
opts: self.opts.clone(), opts: self.opts.clone(),

View file

@ -274,7 +274,6 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
// Perform the CSS cascade. // Perform the CSS cascade.
node.cascade_node(parent_opt, node.cascade_node(parent_opt,
&*layout_context.initial_css_values,
&applicable_declarations, &applicable_declarations,
layout_context.applicable_declarations_cache()); layout_context.applicable_declarations_cache());

View file

@ -1593,9 +1593,9 @@ impl ComputedValues {
} }
} }
/// Returns the initial values for all style structs as defined by the specification. /// The initial values for all style structs as defined by the specification.
pub fn initial_values() -> ComputedValues { lazy_init! {
ComputedValues { static ref INITIAL_VALUES: ComputedValues = ComputedValues {
% for style_struct in STYLE_STRUCTS: % for style_struct in STYLE_STRUCTS:
${style_struct.name}: CowArc::new(style_structs::${style_struct.name} { ${style_struct.name}: CowArc::new(style_structs::${style_struct.name} {
% for longhand in style_struct.longhands: % for longhand in style_struct.longhands:
@ -1604,7 +1604,7 @@ pub fn initial_values() -> ComputedValues {
}), }),
% endfor % endfor
shareable: true, shareable: true,
} };
} }
/// Fast path for the function below. Only computes new inherited styles. /// Fast path for the function below. Only computes new inherited styles.
@ -1702,8 +1702,6 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
/// ///
/// * `parent_style`: The parent style, if applicable; if `None`, this is the root node. /// * `parent_style`: The parent style, if applicable; if `None`, this is the root node.
/// ///
/// * `initial_values`: The initial set of CSS values as defined by the specification.
///
/// * `cached_style`: If present, cascading is short-circuited for everything but inherited /// * `cached_style`: If present, cascading is short-circuited for everything but inherited
/// values and these values are used instead. Obviously, you must be careful when supplying /// values and these values are used instead. Obviously, you must be careful when supplying
/// this that it is safe to only provide inherited declarations. If `parent_style` is `None`, /// this that it is safe to only provide inherited declarations. If `parent_style` is `None`,
@ -1713,9 +1711,9 @@ fn cascade_with_cached_declarations(applicable_declarations: &[MatchedProperty],
pub fn cascade(applicable_declarations: &[MatchedProperty], pub fn cascade(applicable_declarations: &[MatchedProperty],
shareable: bool, shareable: bool,
parent_style: Option< &ComputedValues >, parent_style: Option< &ComputedValues >,
initial_values: &ComputedValues,
cached_style: Option< &ComputedValues >) cached_style: Option< &ComputedValues >)
-> (ComputedValues, bool) { -> (ComputedValues, bool) {
let initial_values = &*INITIAL_VALUES;
let (is_root_element, inherited_style) = match parent_style { let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style), Some(parent_style) => (false, parent_style),
None => (true, initial_values), None => (true, initial_values),

View file

@ -15,15 +15,19 @@
#![feature(phase)] #![feature(phase)]
#[phase(syntax, link)] extern crate log; #[phase(syntax, link)] extern crate log;
extern crate cssparser;
extern crate collections; extern crate collections;
extern crate encoding;
extern crate num; extern crate num;
extern crate serialize; extern crate serialize;
extern crate servo_util = "util";
extern crate sync; extern crate sync;
extern crate url; extern crate url;
extern crate cssparser;
extern crate encoding;
#[phase(syntax)]
extern crate servo_macros = "macros";
extern crate servo_util = "util";
// Public API // Public API
pub use stylesheets::{Stylesheet, CSSRule, StyleRule}; pub use stylesheets::{Stylesheet, CSSRule, StyleRule};
@ -31,7 +35,7 @@ pub use selector_matching::{Stylist, StylesheetOrigin, UserAgentOrigin, AuthorOr
pub use selector_matching::{MatchedProperty}; pub use selector_matching::{MatchedProperty};
pub use properties::{cascade, PropertyDeclaration, ComputedValues, computed_values, style_structs}; pub use properties::{cascade, PropertyDeclaration, ComputedValues, computed_values, style_structs};
pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes pub use properties::{PropertyDeclarationBlock, parse_style_attribute}; // Style attributes
pub use properties::{initial_values, CSSFloat, DeclaredValue, PropertyDeclarationParseResult}; pub use properties::{CSSFloat, DeclaredValue, PropertyDeclarationParseResult};
pub use properties::longhands; pub use properties::longhands;
pub use errors::with_errors_silenced; pub use errors::with_errors_silenced;
pub use node::{TElement, TNode}; pub use node::{TElement, TNode};