diff options
author | Bobby Holley <bobbyholley@gmail.com> | 2016-01-11 19:17:33 -0800 |
---|---|---|
committer | Bobby Holley <bobbyholley@gmail.com> | 2016-01-11 19:38:43 -0800 |
commit | dec296ddbcbc870b54fbde1de7a57c8cf162c38b (patch) | |
tree | 25696ff9b7d921ea8ad7017b7f8c3433e412e789 /components | |
parent | 384cdfcfff157afb3d02c5fafb7fbf1e347f5e7b (diff) | |
download | servo-dec296ddbcbc870b54fbde1de7a57c8cf162c38b.tar.gz servo-dec296ddbcbc870b54fbde1de7a57c8cf162c38b.zip |
Use features to prevent the util component from entraining the world in GeckoLib builds.
Diffstat (limited to 'components')
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 2 | ||||
-rw-r--r-- | components/script/dom/bindings/utils.rs | 2 | ||||
-rw-r--r-- | components/servo/Cargo.toml | 1 | ||||
-rw-r--r-- | components/util/Cargo.toml | 16 | ||||
-rw-r--r-- | components/util/lib.rs | 11 | ||||
-rw-r--r-- | components/util/mem.rs | 81 | ||||
-rw-r--r-- | components/util/non_geckolib.rs | 171 | ||||
-rw-r--r-- | components/util/str.rs | 87 |
8 files changed, 202 insertions, 169 deletions
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index f9031d3369d..1509276db31 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -55,8 +55,8 @@ use js::rust::ToString; use libc; use num::Float; use std::{ptr, mem, slice}; +pub use util::non_geckolib::{StringificationBehavior, jsstring_to_str}; use util::str::DOMString; -pub use util::str::{StringificationBehavior, jsstring_to_str}; /// A trait to check whether a given `JSObject` implements an IDL interface. pub trait IDLInterface { diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 9aa4b9cf0b6..46ea2e78aa1 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -50,7 +50,7 @@ use std::default::Default; use std::ffi::CString; use std::ptr; use util::mem::HeapSizeOf; -use util::str::jsstring_to_str; +use util::non_geckolib::jsstring_to_str; /// Proxy handler for a WindowProxy. pub struct WindowProxyHandler(pub *const libc::c_void); diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 917e7d1de1d..8df856c6967 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -81,6 +81,7 @@ path = "../profile_traits" [dependencies.util] path = "../util" +features = ["non-geckolib"] [dependencies.script] path = "../script" diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index 5a73b0b8144..4dbe032de5b 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -15,19 +15,31 @@ path = "lib.rs" # See https://github.com/rust-lang/rust/issues/21246 doctest = false +[features] + +# This feature allows us to avoid depending on various things we don't need for +# GeckoLib builds. Conceptually, it would make more sense to have a "geckolib" +# feature, but Cargo is generally set up for features to add dependencies, not +# remove them. So we do it this way, and request that all non-GeckoLib builds +# set this feature. +non-geckolib = ["azure", "js", "layers", "html5ever", "hyper"] + [dependencies.plugins] path = "../plugins" [dependencies.azure] git = "https://github.com/servo/rust-azure" features = ["plugins"] +optional = true [dependencies.js] git = "https://github.com/servo/rust-mozjs" +optional = true [dependencies.layers] git = "https://github.com/servo/rust-layers" features = ["plugins"] +optional = true [dependencies.ipc-channel] git = "https://github.com/servo/ipc-channel" @@ -37,7 +49,7 @@ app_units = {version = "0.1", features = ["plugins"]} cssparser = { version = "0.4", features = [ "serde-serialization" ] } log = "0.3" bitflags = "0.3" -html5ever = { version = "0.2.1", features = ["unstable"] } +html5ever = { version = "0.2.1", features = ["unstable"], optional = true } libc = "0.2" rand = "0.3" rustc-serialize = "0.3" @@ -51,6 +63,6 @@ serde_macros = "0.6" string_cache = "0.2" lazy_static = "0.1" getopts = "0.2.11" -hyper = "0.7" +hyper = { version = "0.7", optional = true } url = {version = "0.5.2", features = ["serde_serialization"]} uuid = "0.1.17" diff --git a/components/util/lib.rs b/components/util/lib.rs index 2630d83fbe6..660945d4c1a 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -6,7 +6,7 @@ #![feature(box_syntax)] #![feature(core_intrinsics)] #![feature(custom_derive)] -#![feature(decode_utf16)] +#![cfg_attr(feature = "non-geckolib", feature(decode_utf16))] #![feature(fnbox)] #![feature(hashmap_hasher)] #![feature(heap_api)] @@ -22,6 +22,7 @@ extern crate alloc; extern crate app_units; +#[cfg(feature = "non-geckolib")] extern crate azure; #[macro_use] extern crate bitflags; @@ -29,10 +30,14 @@ extern crate bitflags; extern crate cssparser; extern crate euclid; extern crate getopts; +#[cfg(feature = "non-geckolib")] extern crate html5ever; +#[cfg(feature = "non-geckolib")] extern crate hyper; extern crate ipc_channel; +#[cfg(feature = "non-geckolib")] extern crate js; +#[cfg(feature = "non-geckolib")] extern crate layers; #[macro_use] extern crate lazy_static; @@ -61,7 +66,9 @@ pub mod geometry; pub mod ipc; pub mod linked_list; pub mod logical_geometry; -pub mod mem; +#[macro_use] pub mod mem; +#[cfg(feature = "non-geckolib")] +pub mod non_geckolib; pub mod opts; pub mod persistent_list; pub mod prefs; diff --git a/components/util/mem.rs b/components/util/mem.rs index 6c60186ff0e..bc7fe82663c 100644 --- a/components/util/mem.rs +++ b/components/util/mem.rs @@ -5,7 +5,6 @@ //! Data structure measurement. use app_units::Au; -use azure::azure_hl::Color; use cssparser::Color as CSSParserColor; use cssparser::{RGBA, TokenSerializationType}; use cursor::Cursor; @@ -13,15 +12,6 @@ use euclid::length::Length; use euclid::scale_factor::ScaleFactor; use euclid::{Matrix2D, Matrix4, Point2D, Rect, SideOffsets2D, Size2D}; use geometry::{PagePx, ViewportPx}; -use html5ever::tree_builder::QuirksMode; -use hyper::header::ContentType; -use hyper::http::RawStatus; -use hyper::method::Method; -use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; -use js::jsapi::Heap; -use js::jsval::JSVal; -use js::rust::GCMethods; -use layers::geometry::DevicePixel; use libc::{c_void, size_t}; use logical_geometry::WritingMode; use rand::OsRng; @@ -303,22 +293,6 @@ macro_rules! known_heap_size( ); ); -// This is measured properly by the heap measurement implemented in SpiderMonkey. -impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> { - fn heap_size_of_children(&self) -> usize { - 0 - } -} - -impl HeapSizeOf for Method { - fn heap_size_of_children(&self) -> usize { - match *self { - Method::Extension(ref str) => str.heap_size_of_children(), - _ => 0 - } - } -} - impl<T: HeapSizeOf, U: HeapSizeOf> HeapSizeOf for Result<T, U> { fn heap_size_of_children(&self) -> usize { match *self { @@ -365,57 +339,6 @@ impl HeapSizeOf for SimpleSelector { } } -impl HeapSizeOf for ContentType { - fn heap_size_of_children(&self) -> usize { - let &ContentType(ref mime) = self; - mime.heap_size_of_children() - } -} - -impl HeapSizeOf for Mime { - fn heap_size_of_children(&self) -> usize { - let &Mime(ref top_level, ref sub_level, ref vec) = self; - top_level.heap_size_of_children() + sub_level.heap_size_of_children() + - vec.heap_size_of_children() - } -} - -impl HeapSizeOf for TopLevel { - fn heap_size_of_children(&self) -> usize { - match *self { - TopLevel::Ext(ref str) => str.heap_size_of_children(), - _ => 0 - } - } -} - -impl HeapSizeOf for SubLevel { - fn heap_size_of_children(&self) -> usize { - match *self { - SubLevel::Ext(ref str) => str.heap_size_of_children(), - _ => 0 - } - } -} - -impl HeapSizeOf for Attr { - fn heap_size_of_children(&self) -> usize { - match *self { - Attr::Ext(ref str) => str.heap_size_of_children(), - _ => 0 - } - } -} - -impl HeapSizeOf for Value { - fn heap_size_of_children(&self) -> usize { - match *self { - Value::Ext(ref str) => str.heap_size_of_children(), - _ => 0 - } - } -} - known_heap_size!(0, u8, u16, u32, u64, usize); known_heap_size!(0, i8, i16, i32, i64, isize); known_heap_size!(0, bool, f32, f64); @@ -424,8 +347,8 @@ known_heap_size!(0, AtomicIsize, AtomicUsize); known_heap_size!(0, Rect<T>, Point2D<T>, Size2D<T>, Matrix2D<T>, SideOffsets2D<T>, Range<T>); known_heap_size!(0, Length<T, U>, ScaleFactor<T, U, V>); -known_heap_size!(0, Au, WritingMode, CSSParserColor, Color, RGBA, Cursor, Matrix4, QualName, Atom, Namespace); -known_heap_size!(0, JSVal, PagePx, ViewportPx, DevicePixel, QuirksMode, OsRng, RawStatus); +known_heap_size!(0, Au, WritingMode, CSSParserColor, RGBA, Cursor, Matrix4, QualName, Atom, Namespace); +known_heap_size!(0, PagePx, ViewportPx, OsRng); known_heap_size!(0, TokenSerializationType, LengthOrPercentageOrAuto); known_heap_size!(0, ElementState, Combinator, PseudoElement, str); diff --git a/components/util/non_geckolib.rs b/components/util/non_geckolib.rs new file mode 100644 index 00000000000..f7e6fc401da --- /dev/null +++ b/components/util/non_geckolib.rs @@ -0,0 +1,171 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +///! Miscellaneous Code which depends on large libraries that we don't +/// depend on in GeckoLib builds. + +use azure::azure_hl::Color; +use html5ever::tree_builder::QuirksMode; +use hyper::header::ContentType; +use hyper::http::RawStatus; +use hyper::method::Method; +use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; +use js::conversions::{FromJSValConvertible, ToJSValConvertible, latin1_to_string}; +use js::jsapi::{JSContext, JSString, HandleValue, Heap, MutableHandleValue}; +use js::jsapi::{JS_GetTwoByteStringCharsAndLength, JS_StringHasLatin1Chars}; +use js::jsval::JSVal; +use js::rust::{GCMethods, ToString}; +use layers::geometry::DevicePixel; +use mem::HeapSizeOf; +use opts; +use std::char; +use std::ptr; +use std::slice; +use str::DOMString; + +/// Behavior for stringification of `JSVal`s. +#[derive(PartialEq)] +pub enum StringificationBehavior { + /// Convert `null` to the string `"null"`. + Default, + /// Convert `null` to the empty string. + Empty, +} + +// https://heycam.github.io/webidl/#es-DOMString +impl ToJSValConvertible for DOMString { + unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { + (**self).to_jsval(cx, rval); + } +} + +// https://heycam.github.io/webidl/#es-DOMString +impl FromJSValConvertible for DOMString { + type Config = StringificationBehavior; + unsafe fn from_jsval(cx: *mut JSContext, + value: HandleValue, + null_behavior: StringificationBehavior) + -> Result<DOMString, ()> { + if null_behavior == StringificationBehavior::Empty && + value.get().is_null() { + Ok(DOMString::new()) + } else { + let jsstr = ToString(cx, value); + if jsstr.is_null() { + debug!("ToString failed"); + Err(()) + } else { + Ok(jsstring_to_str(cx, jsstr)) + } + } + } +} + +/// Convert the given `JSString` to a `DOMString`. Fails if the string does not +/// contain valid UTF-16. +pub unsafe fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString { + let latin1 = JS_StringHasLatin1Chars(s); + DOMString::from_string(if latin1 { + latin1_to_string(cx, s) + } else { + let mut length = 0; + let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), s, &mut length); + assert!(!chars.is_null()); + let potentially_ill_formed_utf16 = slice::from_raw_parts(chars, length as usize); + let mut s = String::with_capacity(length as usize); + for item in char::decode_utf16(potentially_ill_formed_utf16.iter().cloned()) { + match item { + Ok(c) => s.push(c), + Err(_) => { + // FIXME: Add more info like document URL in the message? + macro_rules! message { + () => { + "Found an unpaired surrogate in a DOM string. \ + If you see this in real web content, \ + please comment on https://github.com/servo/servo/issues/6564" + } + } + if opts::get().replace_surrogates { + error!(message!()); + s.push('\u{FFFD}'); + } else { + panic!(concat!(message!(), " Use `-Z replace-surrogates` \ + on the command line to make this non-fatal.")); + } + } + } + } + s + }) +} + +// This is measured properly by the heap measurement implemented in SpiderMonkey. +impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> { + fn heap_size_of_children(&self) -> usize { + 0 + } +} + +impl HeapSizeOf for ContentType { + fn heap_size_of_children(&self) -> usize { + let &ContentType(ref mime) = self; + mime.heap_size_of_children() + } +} + +impl HeapSizeOf for Method { + fn heap_size_of_children(&self) -> usize { + match *self { + Method::Extension(ref str) => str.heap_size_of_children(), + _ => 0 + } + } +} + +impl HeapSizeOf for Mime { + fn heap_size_of_children(&self) -> usize { + let &Mime(ref top_level, ref sub_level, ref vec) = self; + top_level.heap_size_of_children() + sub_level.heap_size_of_children() + + vec.heap_size_of_children() + } +} + +impl HeapSizeOf for TopLevel { + fn heap_size_of_children(&self) -> usize { + match *self { + TopLevel::Ext(ref str) => str.heap_size_of_children(), + _ => 0 + } + } +} + +impl HeapSizeOf for SubLevel { + fn heap_size_of_children(&self) -> usize { + match *self { + SubLevel::Ext(ref str) => str.heap_size_of_children(), + _ => 0 + } + } +} + +impl HeapSizeOf for Attr { + fn heap_size_of_children(&self) -> usize { + match *self { + Attr::Ext(ref str) => str.heap_size_of_children(), + _ => 0 + } + } +} + +impl HeapSizeOf for Value { + fn heap_size_of_children(&self) -> usize { + match *self { + Value::Ext(ref str) => str.heap_size_of_children(), + _ => 0 + } + } +} + + +known_heap_size!(0, Color, DevicePixel, JSVal, QuirksMode, RawStatus); diff --git a/components/util/str.rs b/components/util/str.rs index fdcdcb8877a..2d068617b46 100644 --- a/components/util/str.rs +++ b/components/util/str.rs @@ -5,23 +5,15 @@ use app_units::Au; use cssparser::{self, Color, RGBA}; use euclid::num::Zero; -use js::conversions::{FromJSValConvertible, ToJSValConvertible, latin1_to_string}; -use js::jsapi::{JSContext, JSString, HandleValue, MutableHandleValue}; -use js::jsapi::{JS_GetTwoByteStringCharsAndLength, JS_StringHasLatin1Chars}; -use js::rust::ToString; use libc::c_char; use num_lib::ToPrimitive; -use opts; use std::ascii::AsciiExt; use std::borrow::ToOwned; -use std::char; use std::convert::AsRef; use std::ffi::CStr; use std::fmt; use std::iter::{Filter, Peekable}; use std::ops::{Deref, DerefMut}; -use std::ptr; -use std::slice; use std::str::{CharIndices, FromStr, Split, from_utf8}; #[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Deserialize, Serialize, Hash, Debug)] @@ -33,6 +25,9 @@ impl DOMString { pub fn new() -> DOMString { DOMString(String::new()) } + pub fn from_string(s: String) -> DOMString { + DOMString(s) + } // FIXME(ajeffrey): implement more of the String methods on DOMString? pub fn push_str(&mut self, string: &str) { self.0.push_str(string) @@ -113,82 +108,6 @@ impl Into<Vec<u8>> for DOMString { } } -// https://heycam.github.io/webidl/#es-DOMString -impl ToJSValConvertible for DOMString { - unsafe fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) { - (**self).to_jsval(cx, rval); - } -} - -/// Behavior for stringification of `JSVal`s. -#[derive(PartialEq)] -pub enum StringificationBehavior { - /// Convert `null` to the string `"null"`. - Default, - /// Convert `null` to the empty string. - Empty, -} - -/// Convert the given `JSString` to a `DOMString`. Fails if the string does not -/// contain valid UTF-16. -pub unsafe fn jsstring_to_str(cx: *mut JSContext, s: *mut JSString) -> DOMString { - let latin1 = JS_StringHasLatin1Chars(s); - DOMString(if latin1 { - latin1_to_string(cx, s) - } else { - let mut length = 0; - let chars = JS_GetTwoByteStringCharsAndLength(cx, ptr::null(), s, &mut length); - assert!(!chars.is_null()); - let potentially_ill_formed_utf16 = slice::from_raw_parts(chars, length as usize); - let mut s = String::with_capacity(length as usize); - for item in char::decode_utf16(potentially_ill_formed_utf16.iter().cloned()) { - match item { - Ok(c) => s.push(c), - Err(_) => { - // FIXME: Add more info like document URL in the message? - macro_rules! message { - () => { - "Found an unpaired surrogate in a DOM string. \ - If you see this in real web content, \ - please comment on https://github.com/servo/servo/issues/6564" - } - } - if opts::get().replace_surrogates { - error!(message!()); - s.push('\u{FFFD}'); - } else { - panic!(concat!(message!(), " Use `-Z replace-surrogates` \ - on the command line to make this non-fatal.")); - } - } - } - } - s - }) -} - -// https://heycam.github.io/webidl/#es-DOMString -impl FromJSValConvertible for DOMString { - type Config = StringificationBehavior; - unsafe fn from_jsval(cx: *mut JSContext, - value: HandleValue, - null_behavior: StringificationBehavior) - -> Result<DOMString, ()> { - if null_behavior == StringificationBehavior::Empty && - value.get().is_null() { - Ok(DOMString::new()) - } else { - let jsstr = ToString(cx, value); - if jsstr.is_null() { - debug!("ToString failed"); - Err(()) - } else { - Ok(jsstring_to_str(cx, jsstr)) - } - } - } -} - impl Extend<char> for DOMString { fn extend<I>(&mut self, iterable: I) where I: IntoIterator<Item=char> { self.0.extend(iterable) |