aboutsummaryrefslogtreecommitdiffstats
path: root/components/util
diff options
context:
space:
mode:
Diffstat (limited to 'components/util')
-rw-r--r--components/util/Cargo.toml8
-rw-r--r--components/util/bloom.rs12
-rw-r--r--components/util/cache.rs99
-rw-r--r--components/util/cursor.rs5
-rw-r--r--components/util/deque/mod.rs268
-rw-r--r--components/util/fnv.rs34
-rw-r--r--components/util/geometry.rs78
-rw-r--r--components/util/lib.rs21
-rw-r--r--components/util/logical_geometry.rs85
-rw-r--r--components/util/memory.rs24
-rw-r--r--components/util/opts.rs18
-rw-r--r--components/util/persistent_list.rs4
-rw-r--r--components/util/range.rs92
-rw-r--r--components/util/smallvec.rs73
-rw-r--r--components/util/sort.rs3
-rw-r--r--components/util/str.rs37
-rw-r--r--components/util/task.rs47
-rw-r--r--components/util/task_state.rs8
-rw-r--r--components/util/taskpool.rs18
-rw-r--r--components/util/tid.rs6
-rw-r--r--components/util/time.rs50
-rw-r--r--components/util/vec.rs2
-rw-r--r--components/util/workqueue.rs33
23 files changed, 421 insertions, 604 deletions
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml
index c418d0b2880..d9209c74e4f 100644
--- a/components/util/Cargo.toml
+++ b/components/util/Cargo.toml
@@ -36,11 +36,7 @@ git = "https://github.com/servo/string-cache"
[dependencies.string_cache_macros]
git = "https://github.com/servo/string-cache"
-[dependencies.url]
-git = "https://github.com/servo/rust-url"
-
-[dependencies.time]
-git = "https://github.com/rust-lang/time"
-
[dependencies]
text_writer = "0.1.1"
+url = "*"
+time = "*" \ No newline at end of file
diff --git a/components/util/bloom.rs b/components/util/bloom.rs
index 2bed80e9e13..6fd5d17e775 100644
--- a/components/util/bloom.rs
+++ b/components/util/bloom.rs
@@ -58,7 +58,7 @@ const KEY_SHIFT: uint = 16;
/// positive rate for N == 100 and to quite bad false positive
/// rates for larger N.
pub struct BloomFilter {
- counters: [u8, ..ARRAY_SIZE],
+ counters: [u8; ARRAY_SIZE],
}
impl Clone for BloomFilter {
@@ -75,7 +75,7 @@ impl BloomFilter {
#[inline]
pub fn new() -> BloomFilter {
BloomFilter {
- counters: [0, ..ARRAY_SIZE],
+ counters: [0; ARRAY_SIZE],
}
}
@@ -101,7 +101,7 @@ impl BloomFilter {
#[inline]
pub fn clear(&mut self) {
- self.counters = [0, ..ARRAY_SIZE]
+ self.counters = [0; ARRAY_SIZE]
}
#[inline]
@@ -231,7 +231,7 @@ fn create_and_insert_some_stuff() {
let false_positives =
range(1001u, 2000).filter(|i| bf.might_contain(i)).count();
- assert!(false_positives < 10) // 1%.
+ assert!(false_positives < 10); // 1%.
for i in range(0u, 100) {
bf.remove(&i);
@@ -256,7 +256,7 @@ fn create_and_insert_some_stuff() {
mod bench {
extern crate test;
- use std::hash::hash;
+ use std::hash::{hash, SipHasher};
use std::iter;
use super::BloomFilter;
@@ -331,7 +331,7 @@ mod bench {
fn hash_a_uint(b: &mut test::Bencher) {
let mut i = 0u;
b.iter(|| {
- test::black_box(hash(&i));
+ test::black_box(hash::<uint, SipHasher>(&i));
i += 1;
})
}
diff --git a/components/util/cache.rs b/components/util/cache.rs
index 35390d309bf..99e086cdbfe 100644
--- a/components/util/cache.rs
+++ b/components/util/cache.rs
@@ -2,69 +2,59 @@
* 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/. */
+#![old_impl_check]
+
use std::collections::HashMap;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::collections::hash_state::DefaultState;
use rand::Rng;
-use std::hash::{Hash, sip};
+use std::hash::{Hash, SipHasher};
use std::iter::repeat;
-use std::rand::task_rng;
-use std::slice::Items;
+use std::rand;
+use std::slice::Iter;
#[cfg(test)]
use std::cell::Cell;
-pub trait Cache<K: PartialEq, V: Clone> {
- fn insert(&mut self, key: K, value: V);
- fn find(&mut self, key: &K) -> Option<V>;
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V;
- fn evict_all(&mut self);
-}
-
pub struct HashCache<K, V> {
- entries: HashMap<K, V>,
+ entries: HashMap<K, V, DefaultState<SipHasher>>,
}
-impl<K: Clone + PartialEq + Eq + Hash, V: Clone> HashCache<K,V> {
- pub fn new() -> HashCache<K, V> {
+impl<K, V> HashCache<K,V>
+ where K: Clone + PartialEq + Eq + Hash<SipHasher>,
+ V: Clone,
+{
+ pub fn new() -> HashCache<K,V> {
HashCache {
- entries: HashMap::new(),
+ entries: HashMap::with_hash_state(DefaultState),
}
}
-}
-impl<K: Clone + PartialEq + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
- fn insert(&mut self, key: K, value: V) {
+ pub fn insert(&mut self, key: K, value: V) {
self.entries.insert(key, value);
}
- fn find(&mut self, key: &K) -> Option<V> {
+ pub fn find(&self, key: &K) -> Option<V> {
match self.entries.get(key) {
Some(v) => Some(v.clone()),
- None => None,
+ None => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.entries.entry(key.clone()) {
Occupied(occupied) => {
(*occupied.get()).clone()
}
Vacant(vacant) => {
- (*vacant.set(blk(key))).clone()
+ (*vacant.insert(blk(key))).clone()
}
}
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
self.entries.clear();
}
-
-}
-
-impl<K,V> HashCache<K,V> where K: Clone + PartialEq + Eq + Hash, V: Clone {
- pub fn find_equiv<'a,Sized? Q>(&'a self, key: &Q) -> Option<&'a V> where Q: Hash + Equiv<K> {
- self.entries.find_equiv(key)
- }
}
#[test]
@@ -98,32 +88,30 @@ impl<K: Clone + PartialEq, V: Clone> LRUCache<K,V> {
let last_index = self.entries.len() - 1;
if pos != last_index {
let entry = self.entries.remove(pos);
- self.entries.push(entry.unwrap());
+ self.entries.push(entry);
}
- self.entries[last_index].ref1().clone()
+ self.entries[last_index].1.clone()
}
- pub fn iter<'a>(&'a self) -> Items<'a,(K,V)> {
+ pub fn iter<'a>(&'a self) -> Iter<'a,(K,V)> {
self.entries.iter()
}
-}
-impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> {
- fn insert(&mut self, key: K, val: V) {
+ pub fn insert(&mut self, key: K, val: V) {
if self.entries.len() == self.cache_size {
self.entries.remove(0);
}
self.entries.push((key, val));
}
- fn find(&mut self, key: &K) -> Option<V> {
- match self.entries.iter().position(|&(ref k, _)| *k == *key) {
+ pub fn find(&mut self, key: &K) -> Option<V> {
+ match self.entries.iter().position(|&(ref k, _)| key == k) {
Some(pos) => Some(self.touch(pos)),
None => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.entries.iter().position(|&(ref k, _)| *k == *key) {
Some(pos) => self.touch(pos),
None => {
@@ -134,7 +122,7 @@ impl<K: Clone + PartialEq, V: Clone> Cache<K,V> for LRUCache<K,V> {
}
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
self.entries.clear();
}
}
@@ -145,9 +133,9 @@ pub struct SimpleHashCache<K,V> {
k1: u64,
}
-impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> {
+impl<K:Clone+Eq+Hash<SipHasher>,V:Clone> SimpleHashCache<K,V> {
pub fn new(cache_size: uint) -> SimpleHashCache<K,V> {
- let mut r = task_rng();
+ let mut r = rand::thread_rng();
SimpleHashCache {
entries: repeat(None).take(cache_size).collect(),
k0: r.gen(),
@@ -161,35 +149,26 @@ impl<K:Clone+PartialEq+Hash,V:Clone> SimpleHashCache<K,V> {
}
#[inline]
- fn bucket_for_key<Q:Hash>(&self, key: &Q) -> uint {
- self.to_bucket(sip::hash_with_keys(self.k0, self.k1, key) as uint)
+ fn bucket_for_key<Q:Hash<SipHasher>>(&self, key: &Q) -> uint {
+ let mut hasher = SipHasher::new_with_keys(self.k0, self.k1);
+ key.hash(&mut hasher);
+ self.to_bucket(hasher.result() as uint)
}
- #[inline]
- pub fn find_equiv<'a,Q:Hash+Equiv<K>>(&'a self, key: &Q) -> Option<&'a V> {
- let bucket_index = self.bucket_for_key(key);
- match self.entries[bucket_index] {
- Some((ref existing_key, ref value)) if key.equiv(existing_key) => Some(value),
- _ => None,
- }
- }
-}
-
-impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> {
- fn insert(&mut self, key: K, value: V) {
+ pub fn insert(&mut self, key: K, value: V) {
let bucket_index = self.bucket_for_key(&key);
self.entries[bucket_index] = Some((key, value));
}
- fn find(&mut self, key: &K) -> Option<V> {
+ pub fn find<Q>(&self, key: &Q) -> Option<V> where Q: PartialEq<K> + Hash<SipHasher> + Eq {
let bucket_index = self.bucket_for_key(key);
match self.entries[bucket_index] {
- Some((ref existing_key, ref value)) if existing_key == key => Some((*value).clone()),
+ Some((ref existing_key, ref value)) if key == existing_key => Some((*value).clone()),
_ => None,
}
}
- fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
+ pub fn find_or_create<F>(&mut self, key: &K, blk: F) -> V where F: Fn(&K) -> V {
match self.find(key) {
Some(value) => return value,
None => {}
@@ -199,7 +178,7 @@ impl<K:Clone+PartialEq+Hash,V:Clone> Cache<K,V> for SimpleHashCache<K,V> {
value
}
- fn evict_all(&mut self) {
+ pub fn evict_all(&mut self) {
for slot in self.entries.iter_mut() {
*slot = None
}
diff --git a/components/util/cursor.rs b/components/util/cursor.rs
index 23ca2c0af4a..ff203f1a0e7 100644
--- a/components/util/cursor.rs
+++ b/components/util/cursor.rs
@@ -8,10 +8,9 @@ use cssparser::ToCss;
use std::ascii::AsciiExt;
use text_writer::TextWriter;
-
macro_rules! define_cursor {
($( $css: expr => $variant: ident = $value: expr, )+) => {
- #[deriving(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)]
+ #[derive(Clone, Copy, PartialEq, Eq, FromPrimitive, Show)]
#[repr(u8)]
pub enum Cursor {
$( $variant = $value ),+
@@ -19,7 +18,7 @@ macro_rules! define_cursor {
impl Cursor {
pub fn from_css_keyword(keyword: &str) -> Result<Cursor, ()> {
- match_ignore_ascii_case! { keyword:
+ match_ignore_ascii_case! { keyword,
$( concat!($css) => Ok(Cursor::$variant) ),+
_ => Err(())
}
diff --git a/components/util/deque/mod.rs b/components/util/deque/mod.rs
index b98c872cf0f..505b09ab021 100644
--- a/components/util/deque/mod.rs
+++ b/components/util/deque/mod.rs
@@ -54,12 +54,13 @@ pub use self::Stolen::{Empty, Abort, Data};
use alloc::arc::Arc;
use alloc::heap::{allocate, deallocate};
-use std::kinds::marker;
+use std::marker;
use std::mem::{forget, min_align_of, size_of, transmute};
use std::ptr;
use std::sync::Mutex;
-use std::sync::atomic::{AtomicInt, AtomicPtr, SeqCst};
+use std::sync::atomic::{AtomicInt, AtomicPtr};
+use std::sync::atomic::Ordering::SeqCst;
// Once the queue is less than 1/K full, then it will be downsized. Note that
// the deque requires that this number be less than 2.
@@ -97,7 +98,7 @@ pub struct Stealer<T> {
}
/// When stealing some data, this is an enumeration of the possible outcomes.
-#[deriving(PartialEq, Show)]
+#[derive(PartialEq, Show)]
pub enum Stolen<T> {
/// The deque was empty at the time of stealing
Empty,
@@ -141,6 +142,8 @@ struct Buffer<T> {
log_size: uint,
}
+unsafe impl<T: 'static> Send for Buffer<T> { }
+
impl<T: Send> BufferPool<T> {
/// Allocates a new buffer pool which in turn can be used to allocate new
/// deques.
@@ -159,16 +162,16 @@ impl<T: Send> BufferPool<T> {
fn alloc(&mut self, bits: uint) -> Box<Buffer<T>> {
unsafe {
- let mut pool = self.pool.lock();
+ let mut pool = self.pool.lock().unwrap();
match pool.iter().position(|x| x.size() >= (1 << bits)) {
- Some(i) => pool.remove(i).unwrap(),
+ Some(i) => pool.remove(i),
None => box Buffer::new(bits)
}
}
}
fn free(&self, buf: Box<Buffer<T>>) {
- let mut pool = self.pool.lock();
+ let mut pool = self.pool.lock().unwrap();
match pool.iter().position(|v| v.size() > buf.size()) {
Some(i) => pool.insert(i, buf),
None => pool.push(buf),
@@ -403,256 +406,3 @@ impl<T: Send> Drop for Buffer<T> {
unsafe { deallocate(self.storage as *mut u8, size, min_align_of::<T>()) }
}
}
-
-#[cfg(test)]
-mod tests {
- use super::{Data, BufferPool, Abort, Empty, Worker, Stealer};
-
- use std::mem;
- use rustrt::thread::Thread;
- use std::rand;
- use std::rand::Rng;
- use std::sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, SeqCst,
- AtomicUint, INIT_ATOMIC_UINT};
- use std::vec;
-
- #[test]
- fn smoke() {
- let pool = BufferPool::new();
- let (w, s) = pool.deque();
- assert_eq!(w.pop(), None);
- assert_eq!(s.steal(), Empty);
- w.push(1i);
- assert_eq!(w.pop(), Some(1));
- w.push(1);
- assert_eq!(s.steal(), Data(1));
- w.push(1);
- assert_eq!(s.clone().steal(), Data(1));
- }
-
- #[test]
- fn stealpush() {
- static AMT: int = 100000;
- let pool = BufferPool::<int>::new();
- let (w, s) = pool.deque();
- let t = Thread::start(proc() {
- let mut left = AMT;
- while left > 0 {
- match s.steal() {
- Data(i) => {
- assert_eq!(i, 1);
- left -= 1;
- }
- Abort | Empty => {}
- }
- }
- });
-
- for _ in range(0, AMT) {
- w.push(1);
- }
-
- t.join();
- }
-
- #[test]
- fn stealpush_large() {
- static AMT: int = 100000;
- let pool = BufferPool::<(int, int)>::new();
- let (w, s) = pool.deque();
- let t = Thread::start(proc() {
- let mut left = AMT;
- while left > 0 {
- match s.steal() {
- Data((1, 10)) => { left -= 1; }
- Data(..) => panic!(),
- Abort | Empty => {}
- }
- }
- });
-
- for _ in range(0, AMT) {
- w.push((1, 10));
- }
-
- t.join();
- }
-
- fn stampede(w: Worker<Box<int>>, s: Stealer<Box<int>>,
- nthreads: int, amt: uint) {
- for _ in range(0, amt) {
- w.push(box 20);
- }
- let mut remaining = AtomicUint::new(amt);
- let unsafe_remaining: *mut AtomicUint = &mut remaining;
-
- let threads = range(0, nthreads).map(|_| {
- let s = s.clone();
- Thread::start(proc() {
- unsafe {
- while (*unsafe_remaining).load(SeqCst) > 0 {
- match s.steal() {
- Data(box 20) => {
- (*unsafe_remaining).fetch_sub(1, SeqCst);
- }
- Data(..) => panic!(),
- Abort | Empty => {}
- }
- }
- }
- })
- }).collect::<Vec<Thread<()>>>();
-
- while remaining.load(SeqCst) > 0 {
- match w.pop() {
- Some(box 20) => { remaining.fetch_sub(1, SeqCst); }
- Some(..) => panic!(),
- None => {}
- }
- }
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-
- #[test]
- fn run_stampede() {
- let pool = BufferPool::<Box<int>>::new();
- let (w, s) = pool.deque();
- stampede(w, s, 8, 10000);
- }
-
- #[test]
- fn many_stampede() {
- static AMT: uint = 4;
- let pool = BufferPool::<Box<int>>::new();
- let threads = range(0, AMT).map(|_| {
- let (w, s) = pool.deque();
- Thread::start(proc() {
- stampede(w, s, 4, 10000);
- })
- }).collect::<Vec<Thread<()>>>();
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-
- #[test]
- fn stress() {
- static AMT: int = 100000;
- static NTHREADS: int = 8;
- static DONE: AtomicBool = INIT_ATOMIC_BOOL;
- static HITS: AtomicUint = INIT_ATOMIC_UINT;
- let pool = BufferPool::<int>::new();
- let (w, s) = pool.deque();
-
- let threads = range(0, NTHREADS).map(|_| {
- let s = s.clone();
- Thread::start(proc() {
- loop {
- match s.steal() {
- Data(2) => { HITS.fetch_add(1, SeqCst); }
- Data(..) => panic!(),
- _ if DONE.load(SeqCst) => break,
- _ => {}
- }
- }
- })
- }).collect::<Vec<Thread<()>>>();
-
- let mut rng = rand::task_rng();
- let mut expected = 0;
- while expected < AMT {
- if rng.gen_range(0i, 3) == 2 {
- match w.pop() {
- None => {}
- Some(2) => { HITS.fetch_add(1, SeqCst); },
- Some(_) => panic!(),
- }
- } else {
- expected += 1;
- w.push(2);
- }
- }
-
- while HITS.load(SeqCst) < AMT as uint {
- match w.pop() {
- None => {}
- Some(2) => { HITS.fetch_add(1, SeqCst); },
- Some(_) => panic!(),
- }
- }
- DONE.store(true, SeqCst);
-
- for thread in threads.into_iter() {
- thread.join();
- }
-
- assert_eq!(HITS.load(SeqCst), expected as uint);
- }
-
- #[test]
- #[cfg_attr(windows, ignore)] // apparently windows scheduling is weird?
- fn no_starvation() {
- static AMT: int = 10000;
- static NTHREADS: int = 4;
- static DONE: AtomicBool = INIT_ATOMIC_BOOL;
- let pool = BufferPool::<(int, uint)>::new();
- let (w, s) = pool.deque();
-
- let (threads, hits) = vec::unzip(range(0, NTHREADS).map(|_| {
- let s = s.clone();
- let unique_box = box AtomicUint::new(0);
- let thread_box = unsafe {
- *mem::transmute::<&Box<AtomicUint>,
- *const *mut AtomicUint>(&unique_box)
- };
- (Thread::start(proc() {
- unsafe {
- loop {
- match s.steal() {
- Data((1, 2)) => {
- (*thread_box).fetch_add(1, SeqCst);
- }
- Data(..) => panic!(),
- _ if DONE.load(SeqCst) => break,
- _ => {}
- }
- }
- }
- }), unique_box)
- }));
-
- let mut rng = rand::task_rng();
- let mut myhit = false;
- 'outer: loop {
- for _ in range(0, rng.gen_range(0, AMT)) {
- if !myhit && rng.gen_range(0i, 3) == 2 {
- match w.pop() {
- None => {}
- Some((1, 2)) => myhit = true,
- Some(_) => panic!(),
- }
- } else {
- w.push((1, 2));
- }
- }
-
- for slot in hits.iter() {
- let amt = slot.load(SeqCst);
- if amt == 0 { continue 'outer; }
- }
- if myhit {
- break
- }
- }
-
- DONE.store(true, SeqCst);
-
- for thread in threads.into_iter() {
- thread.join();
- }
- }
-}
diff --git a/components/util/fnv.rs b/components/util/fnv.rs
index 13c8e1c28ad..61b4cd73d48 100644
--- a/components/util/fnv.rs
+++ b/components/util/fnv.rs
@@ -4,7 +4,8 @@
//! This file stolen wholesale from rustc/src/librustc/util/nodemap.rs
-pub use std::hash::{Hash, Hasher, Writer};
+use std::default::Default;
+use std::hash::{Hasher, Writer};
/// A speedy hash algorithm for node ids and def ids. The hashmap in
/// libcollections by default uses SipHash which isn't quite as speedy as we
@@ -13,33 +14,26 @@ pub use std::hash::{Hash, Hasher, Writer};
///
/// This uses FNV hashing, as described here:
/// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-#[deriving(Clone)]
-pub struct FnvHasher;
+#[allow(missing_copy_implementations)]
+pub struct FnvHasher(u64);
-pub struct FnvState(u64);
+impl Default for FnvHasher {
+ fn default() -> FnvHasher { FnvHasher(0xcbf29ce484222325) }
+}
-impl Hasher<FnvState> for FnvHasher {
- fn hash<Sized? T: Hash<FnvState>>(&self, t: &T) -> u64 {
- let mut state = FnvState(0xcbf29ce484222325);
- t.hash(&mut state);
- let FnvState(ret) = state;
- return ret;
- }
+impl Hasher for FnvHasher {
+ type Output = u64;
+ fn reset(&mut self) { *self = Default::default(); }
+ fn finish(&self) -> u64 { self.0 }
}
-impl Writer for FnvState {
+impl Writer for FnvHasher {
fn write(&mut self, bytes: &[u8]) {
- let FnvState(mut hash) = *self;
+ let FnvHasher(mut hash) = *self;
for byte in bytes.iter() {
hash = hash ^ (*byte as u64);
hash = hash * 0x100000001b3;
}
- *self = FnvState(hash);
+ *self = FnvHasher(hash);
}
}
-
-#[inline(always)]
-pub fn hash<T: Hash<FnvState>>(t: &T) -> u64 {
- let s = FnvHasher;
- s.hash(t)
-}
diff --git a/components/util/geometry.rs b/components/util/geometry.rs
index 5c3ee808b43..a30849eaf5d 100644
--- a/components/util/geometry.rs
+++ b/components/util/geometry.rs
@@ -8,11 +8,13 @@ use geom::rect::Rect;
use geom::size::Size2D;
use geom::num::Zero;
-use serialize::{Encodable, Encoder};
use std::default::Default;
use std::i32;
-use std::num::{Float, NumCast};
+use std::num::{Float, NumCast, ToPrimitive};
use std::fmt;
+use std::ops::{Add, Sub, Neg, Mul, Div, Rem};
+
+use rustc_serialize::{Encoder, Encodable};
// Units for use with geom::length and geom::scale_factor.
@@ -29,7 +31,7 @@ use std::fmt;
///
/// The ratio between ScreenPx and DevicePixel for a given display be found by calling
/// `servo::windowing::WindowMethods::hidpi_factor`.
-#[deriving(Show, Copy)]
+#[derive(Show, Copy)]
pub enum ScreenPx {}
/// One CSS "px" in the coordinate system of the "initial viewport":
@@ -41,7 +43,7 @@ pub enum ScreenPx {}
///
/// At the default zoom level of 100%, one PagePx is equal to one ScreenPx. However, if the
/// document is zoomed in or out then this scale may be larger or smaller.
-#[deriving(Encodable, Show, Copy)]
+#[derive(RustcEncodable, Show, Copy)]
pub enum ViewportPx {}
/// One CSS "px" in the root coordinate system for the content document.
@@ -50,7 +52,7 @@ pub enum ViewportPx {}
/// This is the mobile-style "pinch zoom" that enlarges content without reflowing it. When the
/// viewport zoom is not equal to 1.0, then the layout viewport is no longer the same physical size
/// as the viewable area.
-#[deriving(Encodable, Show, Copy)]
+#[derive(RustcEncodable, Show, Copy)]
pub enum PagePx {}
// In summary, the hierarchy of pixel units and the factors to convert from one to the next:
@@ -65,7 +67,7 @@ pub enum PagePx {}
// See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
//
// FIXME: Implement Au using Length and ScaleFactor instead of a custom type.
-#[deriving(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
+#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
pub struct Au(pub i32);
impl Default for Au {
@@ -112,8 +114,8 @@ pub static MAX_RECT: Rect<Au> = Rect {
pub const MIN_AU: Au = Au(i32::MIN);
pub const MAX_AU: Au = Au(i32::MAX);
-impl<E, S: Encoder<E>> Encodable<S, E> for Au {
- fn encode(&self, e: &mut S) -> Result<(), E> {
+impl Encodable for Au {
+ fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
e.emit_f64(to_frac_px(*self))
}
}
@@ -123,53 +125,65 @@ impl fmt::Show for Au {
write!(f, "{}px", to_frac_px(*self))
}}
-impl Add<Au,Au> for Au {
+impl Add for Au {
+ type Output = Au;
+
#[inline]
- fn add(&self, other: &Au) -> Au {
- let Au(s) = *self;
- let Au(o) = *other;
+ fn add(self, other: Au) -> Au {
+ let Au(s) = self;
+ let Au(o) = other;
Au(s + o)
}
}
-impl Sub<Au,Au> for Au {
+impl Sub for Au {
+ type Output = Au;
+
#[inline]
- fn sub(&self, other: &Au) -> Au {
- let Au(s) = *self;
- let Au(o) = *other;
+ fn sub(self, other: Au) -> Au {
+ let Au(s) = self;
+ let Au(o) = other;
Au(s - o)
}
}
-impl Mul<i32, Au> for Au {
+impl Mul<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn mul(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s * *other)
+ fn mul(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s * other)
}
}
-impl Div<i32, Au> for Au {
+impl Div<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn div(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s / *other)
+ fn div(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s / other)
}
}
-impl Rem<i32, Au> for Au {
+impl Rem<i32> for Au {
+ type Output = Au;
+
#[inline]
- fn rem(&self, other: &i32) -> Au {
- let Au(s) = *self;
- Au(s % *other)
+ fn rem(self, other: i32) -> Au {
+ let Au(s) = self;
+ Au(s % other)
}
}
-impl Neg<Au> for Au {
+impl Neg for Au {
+ type Output = Au;
+
#[inline]
- fn neg(&self) -> Au {
- let Au(s) = *self;
+ fn neg(self) -> Au {
+ let Au(s) = self;
Au(-s)
}
}
@@ -323,7 +337,7 @@ pub fn to_pt(au: Au) -> f64 {
/// Returns true if the rect contains the given point. Points on the top or left sides of the rect
/// are considered inside the rectangle, while points on the right or bottom sides of the rect are
/// not considered inside the rectangle.
-pub fn rect_contains_point<T:PartialOrd + Add<T,T>>(rect: Rect<T>, point: Point2D<T>) -> bool {
+pub fn rect_contains_point<T:PartialOrd + Add<T, Output=T>>(rect: Rect<T>, point: Point2D<T>) -> bool {
point.x >= rect.origin.x && point.x < rect.origin.x + rect.size.width &&
point.y >= rect.origin.y && point.y < rect.origin.y + rect.size.height
}
diff --git a/components/util/lib.rs b/components/util/lib.rs
index 9a97bdbbf78..bceab7a3014 100644
--- a/components/util/lib.rs
+++ b/components/util/lib.rs
@@ -2,15 +2,18 @@
* 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/. */
-#![feature(default_type_params,macro_rules,unsafe_destructor)]
+#![feature(unsafe_destructor)]
+#![feature(plugin)]
+#![feature(int_uint)]
+#![feature(old_impl_check)]
+#![feature(box_syntax)]
#![deny(unused_imports)]
#![deny(unused_variables)]
#![allow(missing_copy_implementations)]
+#![allow(unstable)]
-#![feature(phase)]
-#[phase(plugin, link)]
-extern crate log;
+#[macro_use] extern crate log;
extern crate alloc;
extern crate collections;
@@ -19,9 +22,9 @@ extern crate geom;
extern crate getopts;
extern crate layers;
extern crate libc;
+#[no_link] #[macro_use] extern crate cssparser;
extern crate rand;
-extern crate rustrt;
-extern crate serialize;
+extern crate "serialize" as rustc_serialize;
#[cfg(target_os="macos")]
extern crate task_info;
extern crate "time" as std_time;
@@ -30,9 +33,9 @@ extern crate string_cache;
extern crate unicode;
extern crate url;
-#[phase(plugin)] extern crate plugins;
-#[phase(plugin)] extern crate string_cache_macros;
-#[phase(plugin)] extern crate lazy_static;
+#[no_link] #[macro_use] #[plugin]
+extern crate string_cache_macros;
+extern crate lazy_static;
use std::sync::Arc;
diff --git a/components/util/logical_geometry.rs b/components/util/logical_geometry.rs
index eebd0735b81..a76bd1ca21e 100644
--- a/components/util/logical_geometry.rs
+++ b/components/util/logical_geometry.rs
@@ -8,16 +8,17 @@ use geom::{Size2D, Point2D, SideOffsets2D, Rect};
use geom::num::Zero;
use std::cmp::{min, max};
use std::fmt::{Show, Formatter, Error};
+use std::ops::{Add, Sub};
bitflags!(
- #[deriving(Encodable, Copy)]
+ #[derive(RustcEncodable)]
flags WritingMode: u8 {
const FLAG_RTL = 1 << 0,
const FLAG_VERTICAL = 1 << 1,
const FLAG_VERTICAL_LR = 1 << 2,
const FLAG_SIDEWAYS_LEFT = 1 << 3
}
-)
+);
impl WritingMode {
#[inline]
@@ -79,11 +80,11 @@ impl Show for WritingMode {
/// (in addition to taking it as a parameter to methods) and check it.
/// In non-debug builds, make this storage zero-size and the checks no-ops.
#[cfg(ndebug)]
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
struct DebugWritingMode;
#[cfg(not(ndebug))]
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
struct DebugWritingMode {
mode: WritingMode
}
@@ -134,7 +135,7 @@ impl Show for DebugWritingMode {
/// A 2D size in flow-relative dimensions
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalSize<T> {
pub inline: T, // inline-size, a.k.a. logical width, a.k.a. measure
pub block: T, // block-size, a.k.a. logical height, a.k.a. extent
@@ -143,7 +144,7 @@ pub struct LogicalSize<T> {
impl<T: Show> Show for LogicalSize<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
- write!(formatter, "LogicalSize({}, i{}×b{})",
+ write!(formatter, "LogicalSize({:?}, i{:?}×b{:?})",
self.debug_writing_mode, self.inline, self.block)
}
}
@@ -240,9 +241,11 @@ impl<T: Copy> LogicalSize<T> {
}
}
-impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
+impl<T: Add<T, Output=T>> Add for LogicalSize<T> {
+ type Output = LogicalSize<T>;
+
#[inline]
- fn add(&self, other: &LogicalSize<T>) -> LogicalSize<T> {
+ fn add(self, other: LogicalSize<T>) -> LogicalSize<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalSize {
debug_writing_mode: self.debug_writing_mode,
@@ -252,9 +255,11 @@ impl<T: Add<T, T>> Add<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
}
}
-impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
+impl<T: Sub<T, Output=T>> Sub for LogicalSize<T> {
+ type Output = LogicalSize<T>;
+
#[inline]
- fn sub(&self, other: &LogicalSize<T>) -> LogicalSize<T> {
+ fn sub(self, other: LogicalSize<T>) -> LogicalSize<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalSize {
debug_writing_mode: self.debug_writing_mode,
@@ -266,7 +271,7 @@ impl<T: Sub<T, T>> Sub<LogicalSize<T>, LogicalSize<T>> for LogicalSize<T> {
/// A 2D point in flow-relative dimensions
-#[deriving(PartialEq, Encodable, Eq, Clone, Copy)]
+#[derive(PartialEq, RustcEncodable, Eq, Clone, Copy)]
pub struct LogicalPoint<T> {
pub i: T, /// inline-axis coordinate
pub b: T, /// block-axis coordinate
@@ -275,7 +280,7 @@ pub struct LogicalPoint<T> {
impl<T: Show> Show for LogicalPoint<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
- write!(formatter, "LogicalPoint({} (i{}, b{}))",
+ write!(formatter, "LogicalPoint({:?} (i{:?}, b{:?}))",
self.debug_writing_mode, self.i, self.b)
}
}
@@ -303,7 +308,7 @@ impl<T: Copy> LogicalPoint<T> {
}
}
-impl<T: Copy + Sub<T, T>> LogicalPoint<T> {
+impl<T: Copy + Sub<T, Output=T>> LogicalPoint<T> {
#[inline]
pub fn from_physical(mode: WritingMode, point: Point2D<T>, container_size: Size2D<T>)
-> LogicalPoint<T> {
@@ -391,7 +396,7 @@ impl<T: Copy + Sub<T, T>> LogicalPoint<T> {
}
}
-impl<T: Add<T,T>> LogicalPoint<T> {
+impl<T: Copy + Add<T, Output=T>> LogicalPoint<T> {
/// This doesn’t really makes sense,
/// but happens when dealing with multiple origins.
#[inline]
@@ -405,9 +410,11 @@ impl<T: Add<T,T>> LogicalPoint<T> {
}
}
-impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
+impl<T: Copy + Add<T,Output=T>> Add<LogicalSize<T>> for LogicalPoint<T> {
+ type Output = LogicalPoint<T>;
+
#[inline]
- fn add(&self, other: &LogicalSize<T>) -> LogicalPoint<T> {
+ fn add(self, other: LogicalSize<T>) -> LogicalPoint<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalPoint {
debug_writing_mode: self.debug_writing_mode,
@@ -417,9 +424,11 @@ impl<T: Add<T,T>> Add<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
}
}
-impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
+impl<T: Copy + Sub<T,Output=T>> Sub<LogicalSize<T>> for LogicalPoint<T> {
+ type Output = LogicalPoint<T>;
+
#[inline]
- fn sub(&self, other: &LogicalSize<T>) -> LogicalPoint<T> {
+ fn sub(self, other: LogicalSize<T>) -> LogicalPoint<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalPoint {
debug_writing_mode: self.debug_writing_mode,
@@ -434,7 +443,7 @@ impl<T: Sub<T,T>> Sub<LogicalSize<T>, LogicalPoint<T>> for LogicalPoint<T> {
/// Represents the four sides of the margins, borders, or padding of a CSS box,
/// or a combination of those.
/// A positive "margin" can be added to a rectangle to obtain a bigger rectangle.
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalMargin<T> {
pub block_start: T,
pub inline_end: T,
@@ -446,7 +455,7 @@ pub struct LogicalMargin<T> {
impl<T: Show> Show for LogicalMargin<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter,
- "LogicalMargin({}, inline: {}..{} block: {}..{})",
+ "LogicalMargin({:?}, inline: {:?}..{:?} block: {:?}..{:?})",
self.debug_writing_mode,
self.inline_start,
self.inline_end,
@@ -656,7 +665,7 @@ impl<T: PartialEq + Zero> LogicalMargin<T> {
}
}
-impl<T: Add<T, T>> LogicalMargin<T> {
+impl<T: Copy + Add<T, Output=T>> LogicalMargin<T> {
#[inline]
pub fn inline_start_end(&self) -> T {
self.inline_start + self.inline_end
@@ -688,9 +697,11 @@ impl<T: Add<T, T>> LogicalMargin<T> {
}
}
-impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> {
+impl<T: Add<T, Output=T>> Add for LogicalMargin<T> {
+ type Output = LogicalMargin<T>;
+
#[inline]
- fn add(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> {
+ fn add(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalMargin {
debug_writing_mode: self.debug_writing_mode,
@@ -702,9 +713,11 @@ impl<T: Add<T, T>> Add<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
}
}
-impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T> {
+impl<T: Sub<T, Output=T>> Sub for LogicalMargin<T> {
+ type Output = LogicalMargin<T>;
+
#[inline]
- fn sub(&self, other: &LogicalMargin<T>) -> LogicalMargin<T> {
+ fn sub(self, other: LogicalMargin<T>) -> LogicalMargin<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalMargin {
debug_writing_mode: self.debug_writing_mode,
@@ -718,7 +731,7 @@ impl<T: Sub<T, T>> Sub<LogicalMargin<T>, LogicalMargin<T>> for LogicalMargin<T>
/// A rectangle in flow-relative dimensions
-#[deriving(Encodable, PartialEq, Eq, Clone, Copy)]
+#[derive(RustcEncodable, PartialEq, Eq, Clone, Copy)]
pub struct LogicalRect<T> {
pub start: LogicalPoint<T>,
pub size: LogicalSize<T>,
@@ -728,7 +741,7 @@ pub struct LogicalRect<T> {
impl<T: Show> Show for LogicalRect<T> {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
write!(formatter,
- "LogicalRect({}, i{}×b{}, @ (i{},b{}))",
+ "LogicalRect({:?}, i{:?}×b{:?}, @ (i{:?},b{:?}))",
self.debug_writing_mode,
self.size.inline,
self.size.block,
@@ -772,7 +785,7 @@ impl<T: Copy> LogicalRect<T> {
}
}
-impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> {
#[inline]
pub fn from_physical(mode: WritingMode, rect: Rect<T>, container_size: Size2D<T>)
-> LogicalRect<T> {
@@ -881,7 +894,7 @@ impl<T: Copy + Add<T, T> + Sub<T, T>> LogicalRect<T> {
}
}
-impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> {
+impl<T: Copy + Ord + Add<T, Output=T> + Sub<T, Output=T>> LogicalRect<T> {
#[inline]
pub fn union(&self, other: &LogicalRect<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
@@ -904,9 +917,11 @@ impl<T: Copy + Ord + Add<T, T> + Sub<T, T>> LogicalRect<T> {
}
}
-impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Add<LogicalMargin<T>> for LogicalRect<T> {
+ type Output = LogicalRect<T>;
+
#[inline]
- fn add(&self, other: &LogicalMargin<T>) -> LogicalRect<T> {
+ fn add(self, other: LogicalMargin<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalRect {
start: LogicalPoint {
@@ -927,9 +942,11 @@ impl<T: Add<T, T> + Sub<T, T>> Add<LogicalMargin<T>, LogicalRect<T>> for Logical
}
-impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for LogicalRect<T> {
+impl<T: Copy + Add<T, Output=T> + Sub<T, Output=T>> Sub<LogicalMargin<T>> for LogicalRect<T> {
+ type Output = LogicalRect<T>;
+
#[inline]
- fn sub(&self, other: &LogicalMargin<T>) -> LogicalRect<T> {
+ fn sub(self, other: LogicalMargin<T>) -> LogicalRect<T> {
self.debug_writing_mode.check_debug(other.debug_writing_mode);
LogicalRect {
start: LogicalPoint {
@@ -950,7 +967,7 @@ impl<T: Add<T, T> + Sub<T, T>> Sub<LogicalMargin<T>, LogicalRect<T>> for Logical
}
#[cfg(test)]
-fn modes() -> [WritingMode, ..10] {
+fn modes() -> [WritingMode; 10] {
[
WritingMode::empty(),
FLAG_VERTICAL,
diff --git a/components/util/memory.rs b/components/util/memory.rs
index 278a5a448fb..5e3033e2aa5 100644
--- a/components/util/memory.rs
+++ b/components/util/memory.rs
@@ -6,13 +6,16 @@
use libc::{c_char,c_int,c_void,size_t};
use std::borrow::ToOwned;
+use std::ffi::CString;
use std::io::timer::sleep;
#[cfg(target_os="linux")]
use std::io::File;
+use std::mem;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::os::page_size;
use std::ptr::null_mut;
+use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
@@ -45,16 +48,16 @@ impl MemoryProfiler {
Some(period) => {
let period = Duration::milliseconds((period * 1000f64) as i64);
let chan = chan.clone();
- spawn_named("Memory profiler timer".to_owned(), proc() {
+ spawn_named("Memory profiler timer".to_owned(), move || {
loop {
sleep(period);
- if chan.send_opt(MemoryProfilerMsg::Print).is_err() {
+ if chan.send(MemoryProfilerMsg::Print).is_err() {
break;
}
}
});
// Spawn the memory profiler.
- spawn_named("Memory profiler".to_owned(), proc() {
+ spawn_named("Memory profiler".to_owned(), move || {
let memory_profiler = MemoryProfiler::new(port);
memory_profiler.start();
});
@@ -62,9 +65,9 @@ impl MemoryProfiler {
None => {
// No-op to handle messages when the memory profiler is
// inactive.
- spawn_named("Memory profiler".to_owned(), proc() {
+ spawn_named("Memory profiler".to_owned(), move || {
loop {
- match port.recv_opt() {
+ match port.recv() {
Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
_ => {}
}
@@ -84,7 +87,7 @@ impl MemoryProfiler {
pub fn start(&self) {
loop {
- match self.port.recv_opt() {
+ match self.port.recv() {
Ok(msg) => {
if !self.handle_msg(msg) {
break
@@ -151,12 +154,13 @@ extern {
fn get_jemalloc_stat(name: &'static str) -> Option<u64> {
let mut old: size_t = 0;
- let c_name = name.to_c_str();
+ let c_name = CString::from_slice(name.as_bytes());
let oldp = &mut old as *mut _ as *mut c_void;
let mut oldlen = size_of::<size_t>() as size_t;
let rv: c_int;
unsafe {
- rv = je_mallctl(c_name.into_inner(), oldp, &mut oldlen, null_mut(), 0);
+ rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0);
+ mem::forget(c_name); // XXX correct?
}
if rv == 0 { Some(old as u64) } else { None }
}
@@ -164,7 +168,7 @@ fn get_jemalloc_stat(name: &'static str) -> Option<u64> {
// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
($e:expr) => (match $e { Some(e) => e, None => return None })
-)
+);
#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
@@ -172,7 +176,7 @@ fn get_proc_self_statm_field(field: uint) -> Option<u64> {
match f.read_to_string() {
Ok(contents) => {
let s = option_try!(contents.as_slice().words().nth(field));
- let npages: u64 = option_try!(from_str(s));
+ let npages: u64 = option_try!(s.parse());
Some(npages * (page_size() as u64))
}
Err(_) => None
diff --git a/components/util/opts.rs b/components/util/opts.rs
index 1ed2eae0608..ae19723b975 100644
--- a/components/util/opts.rs
+++ b/components/util/opts.rs
@@ -20,7 +20,7 @@ use std::ptr;
use std::rt;
/// Global flags for Servo, currently set on the command line.
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct Opts {
/// The initial URLs to load.
pub urls: Vec<String>,
@@ -241,31 +241,31 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
};
let tile_size: uint = match opt_match.opt_str("s") {
- Some(tile_size_str) => from_str(tile_size_str.as_slice()).unwrap(),
+ Some(tile_size_str) => tile_size_str.parse().unwrap(),
None => 512,
};
let device_pixels_per_px = opt_match.opt_str("device-pixel-ratio").map(|dppx_str|
- ScaleFactor(from_str(dppx_str.as_slice()).unwrap())
+ ScaleFactor(dppx_str.parse().unwrap())
);
let mut n_paint_threads: uint = match opt_match.opt_str("t") {
- Some(n_paint_threads_str) => from_str(n_paint_threads_str.as_slice()).unwrap(),
+ Some(n_paint_threads_str) => n_paint_threads_str.parse().unwrap(),
None => 1, // FIXME: Number of cores.
};
// If only the flag is present, default to a 5 second period for both profilers.
let time_profiler_period = opt_match.opt_default("p", "5").map(|period| {
- from_str(period.as_slice()).unwrap()
+ period.parse().unwrap()
});
let memory_profiler_period = opt_match.opt_default("m", "5").map(|period| {
- from_str(period.as_slice()).unwrap()
+ period.parse().unwrap()
});
let gpu_painting = !FORCE_CPU_PAINTING && opt_match.opt_present("g");
let mut layout_threads: uint = match opt_match.opt_str("y") {
- Some(layout_threads_str) => from_str(layout_threads_str.as_slice()).unwrap(),
+ Some(layout_threads_str) => layout_threads_str.parse().unwrap(),
None => cmp::max(rt::default_sched_threads() * 3 / 4, 1),
};
@@ -280,12 +280,12 @@ pub fn from_cmdline_args(args: &[String]) -> bool {
}
let devtools_port = opt_match.opt_default("devtools", "6000").map(|port| {
- from_str(port.as_slice()).unwrap()
+ port.parse().unwrap()
});
let initial_window_size = match opt_match.opt_str("resolution") {
Some(res_string) => {
- let res: Vec<uint> = res_string.as_slice().split('x').map(|r| from_str(r).unwrap()).collect();
+ let res: Vec<uint> = res_string.split('x').map(|r| r.parse().unwrap()).collect();
TypedSize2D(res[0], res[1])
}
None => {
diff --git a/components/util/persistent_list.rs b/components/util/persistent_list.rs
index 458c4c96a2a..f20edff3d38 100644
--- a/components/util/persistent_list.rs
+++ b/components/util/persistent_list.rs
@@ -74,7 +74,9 @@ pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync {
entry: Option<&'a PersistentListEntry<T>>,
}
-impl<'a,T> Iterator<&'a T> for PersistentListIterator<'a,T> where T: Send + Sync {
+impl<'a,T> Iterator for PersistentListIterator<'a,T> where T: Send + Sync {
+ type Item = &'a T;
+
#[inline]
fn next(&mut self) -> Option<&'a T> {
let entry = match self.entry {
diff --git a/components/util/range.rs b/components/util/range.rs
index ef6e7e0ff47..fbf14f38400 100644
--- a/components/util/range.rs
+++ b/components/util/range.rs
@@ -26,7 +26,7 @@ impl RangeIndex<int> for int {
#[macro_export]
macro_rules! int_range_index {
($(#[$attr:meta])* struct $Self:ident($T:ty)) => (
- #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)]
+ #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Show, Copy)]
$(#[$attr])*
pub struct $Self(pub $T);
@@ -74,40 +74,42 @@ macro_rules! int_range_index {
}
}
- impl Add<$Self, $Self> for $Self {
+ impl Add<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn add(&self, other: &$Self) -> $Self {
+ fn add(self, other: $Self) -> $Self {
$Self(self.get() + other.get())
}
}
- impl Sub<$Self, $Self> for $Self {
+ impl Sub<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn sub(&self, other: &$Self) -> $Self {
+ fn sub(self, other: $Self) -> $Self {
$Self(self.get() - other.get())
}
}
- impl Mul<$Self, $Self> for $Self {
+ impl Mul<$Self> for $Self {
+ type Output = $Self;
+
#[inline]
- fn mul(&self, other: &$Self) -> $Self {
+ fn mul(self, other: $Self) -> $Self {
$Self(self.get() * other.get())
}
}
- impl Neg<$Self> for $Self {
+ impl Neg for $Self {
+ type Output = $Self;
+
#[inline]
- fn neg(&self) -> $Self {
+ fn neg(self) -> $Self {
$Self(-self.get())
}
}
- impl ::std::num::One for $Self {
- fn one() -> $Self {
- $Self(1)
- }
- }
-
impl ToPrimitive for $Self {
fn to_i64(&self) -> Option<i64> {
Some(self.get() as i64)
@@ -124,66 +126,75 @@ macro_rules! int_range_index {
}
}
- impl Div<$Self, $Self> for $Self {
- fn div(&self, other: &$Self) -> $Self {
+ impl Div<$Self> for $Self {
+ type Output = $Self;
+ fn div(self, other: $Self) -> $Self {
$Self(self.get() / other.get())
}
}
- impl Rem<$Self, $Self> for $Self {
- fn rem(&self, other: &$Self) -> $Self {
+ impl Rem<$Self> for $Self {
+ type Output = $Self;
+ fn rem(self, other: $Self) -> $Self {
$Self(self.get() % other.get())
}
}
- impl Not<$Self> for $Self {
- fn not(&self) -> $Self {
+ impl Not for $Self {
+ type Output = $Self;
+ fn not(self) -> $Self {
$Self(!self.get())
}
}
- impl BitAnd<$Self, $Self> for $Self {
- fn bitand(&self, other: &$Self) -> $Self {
+ impl BitAnd<$Self> for $Self {
+ type Output = $Self;
+ fn bitand(self, other: $Self) -> $Self {
$Self(self.get() & other.get())
}
}
- impl BitOr<$Self, $Self> for $Self {
- fn bitor(&self, other: &$Self) -> $Self {
+ impl BitOr<$Self> for $Self {
+ type Output = $Self;
+ fn bitor(self, other: $Self) -> $Self {
$Self(self.get() | other.get())
}
}
- impl BitXor<$Self, $Self> for $Self {
- fn bitxor(&self, other: &$Self) -> $Self {
+ impl BitXor<$Self> for $Self {
+ type Output = $Self;
+ fn bitxor(self, other: $Self) -> $Self {
$Self(self.get() ^ other.get())
}
}
- impl Shl<uint, $Self> for $Self {
- fn shl(&self, n: &uint) -> $Self {
- $Self(self.get() << *n)
+ impl Shl<uint> for $Self {
+ type Output = $Self;
+ fn shl(self, n: uint) -> $Self {
+ $Self(self.get() << n)
}
}
- impl Shr<uint, $Self> for $Self {
- fn shr(&self, n: &uint) -> $Self {
- $Self(self.get() >> *n)
+ impl Shr<uint> for $Self {
+ type Output = $Self;
+ fn shr(self, n: uint) -> $Self {
+ $Self(self.get() >> n)
}
}
)
}
/// A range of indices
-#[deriving(Clone, Encodable, Copy)]
+#[derive(Clone, RustcEncodable, Copy)]
pub struct Range<I> {
begin: I,
length: I,
}
+#[old_impl_check]
impl<I: RangeIndex<T>, T> fmt::Show for Range<I> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "[{} .. {})", self.begin(), self.end())
+ write!(f, "[{:?} .. {:?})", self.begin(), self.end())
}
}
@@ -196,7 +207,9 @@ pub fn each_index<T: Int, I: RangeIndex<T>>(start: I, stop: I) -> EachIndex<T, I
EachIndex { it: iter::range(start.get(), stop.get()) }
}
-impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> {
+impl<T: Int, I: RangeIndex<T>> Iterator for EachIndex<T, I> {
+ type Item = I;
+
#[inline]
fn next(&mut self) -> Option<I> {
self.it.next().map(|i| RangeIndex::new(i))
@@ -208,6 +221,7 @@ impl<T: Int, I: RangeIndex<T>> Iterator<I> for EachIndex<T, I> {
}
}
+#[old_impl_check]
impl<I: RangeIndex<T>, T> Range<I> {
/// Create a new range from beginning and length offsets. This could be
/// denoted as `[begin, begin + length)`.
@@ -345,6 +359,7 @@ impl<I: RangeIndex<T>, T> Range<I> {
}
/// Methods for `Range`s with indices based on integer values
+#[old_impl_check]
impl<T: Int, I: RangeIndex<T>> Range<I> {
/// Returns an iterater that increments over `[begin, end)`.
#[inline]
@@ -363,8 +378,9 @@ impl<T: Int, I: RangeIndex<T>> Range<I> {
&& self.length() <= len
},
None => {
- debug!("Range<T>::is_valid_for_string: string length (len={}) is longer than the \
- max value for the range index (max={})", s_len,
+ debug!("Range<T>::is_valid_for_string: string length \
+ (len={:?}) is longer than the max value for the range \
+ index (max={:?})", s_len,
{
let max: T = Int::max_value();
let val: I = RangeIndex::new(max);
diff --git a/components/util/smallvec.rs b/components/util/smallvec.rs
index 2153398d3c3..efd1bfc7f35 100644
--- a/components/util/smallvec.rs
+++ b/components/util/smallvec.rs
@@ -9,7 +9,8 @@ use std::mem::zeroed as i;
use std::cmp;
use std::fmt;
use std::intrinsics;
-use std::kinds::marker::ContravariantLifetime;
+use std::iter::FromIterator;
+use std::marker::ContravariantLifetime;
use std::mem;
use std::ptr;
use std::raw::Slice;
@@ -249,7 +250,9 @@ pub struct SmallVecIterator<'a,T> {
lifetime: ContravariantLifetime<'a>
}
-impl<'a,T> Iterator<&'a T> for SmallVecIterator<'a,T> {
+impl<'a,T> Iterator for SmallVecIterator<'a,T> {
+ type Item = &'a T;
+
#[inline]
fn next(&mut self) -> Option<&'a T> {
unsafe {
@@ -273,7 +276,9 @@ pub struct SmallVecMutIterator<'a,T> {
lifetime: ContravariantLifetime<'a>,
}
-impl<'a,T> Iterator<&'a mut T> for SmallVecMutIterator<'a,T> {
+impl<'a,T> Iterator for SmallVecMutIterator<'a,T> {
+ type Item = &'a mut T;
+
#[inline]
fn next(&mut self) -> Option<&'a mut T> {
unsafe {
@@ -298,7 +303,9 @@ pub struct SmallVecMoveIterator<'a,T> {
lifetime: ContravariantLifetime<'a>,
}
-impl<'a, T: 'a> Iterator<T> for SmallVecMoveIterator<'a,T> {
+impl<'a, T: 'a> Iterator for SmallVecMoveIterator<'a,T> {
+ type Item = T;
+
#[inline]
fn next(&mut self) -> Option<T> {
unsafe {
@@ -341,7 +348,7 @@ macro_rules! def_small_vector(
len: uint,
cap: uint,
ptr: *const T,
- data: [T, ..$size],
+ data: [T; $size],
}
impl<T> SmallVecPrivate<T> for $name<T> {
@@ -403,7 +410,7 @@ macro_rules! def_small_vector(
}
impl<T> FromIterator<T> for $name<T> {
- fn from_iter<I: Iterator<T>>(mut iter: I) -> $name<T> {
+ fn from_iter<I: Iterator<Item=T>>(mut iter: I) -> $name<T> {
let mut v = $name::new();
let (lower_size_bound, _) = iter.size_hint();
@@ -421,7 +428,7 @@ macro_rules! def_small_vector(
}
impl<T> $name<T> {
- pub fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
+ pub fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) {
let (lower_size_bound, _) = iter.size_hint();
let target_len = self.len() + lower_size_bound;
@@ -438,7 +445,7 @@ macro_rules! def_small_vector(
impl<T: fmt::Show> fmt::Show for $name<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}", self.as_slice())
+ write!(f, "{:?}", self.as_slice())
}
}
@@ -456,15 +463,15 @@ macro_rules! def_small_vector(
}
}
)
-)
+);
-def_small_vector!(SmallVec1, 1)
-def_small_vector!(SmallVec2, 2)
-def_small_vector!(SmallVec4, 4)
-def_small_vector!(SmallVec8, 8)
-def_small_vector!(SmallVec16, 16)
-def_small_vector!(SmallVec24, 24)
-def_small_vector!(SmallVec32, 32)
+def_small_vector!(SmallVec1, 1);
+def_small_vector!(SmallVec2, 2);
+def_small_vector!(SmallVec4, 4);
+def_small_vector!(SmallVec8, 8);
+def_small_vector!(SmallVec16, 16);
+def_small_vector!(SmallVec24, 24);
+def_small_vector!(SmallVec32, 32);
macro_rules! def_small_vector_drop_impl(
($name:ident, $size:expr) => (
@@ -488,15 +495,15 @@ macro_rules! def_small_vector_drop_impl(
}
}
)
-)
+);
-def_small_vector_drop_impl!(SmallVec1, 1)
-def_small_vector_drop_impl!(SmallVec2, 2)
-def_small_vector_drop_impl!(SmallVec4, 4)
-def_small_vector_drop_impl!(SmallVec8, 8)
-def_small_vector_drop_impl!(SmallVec16, 16)
-def_small_vector_drop_impl!(SmallVec24, 24)
-def_small_vector_drop_impl!(SmallVec32, 32)
+def_small_vector_drop_impl!(SmallVec1, 1);
+def_small_vector_drop_impl!(SmallVec2, 2);
+def_small_vector_drop_impl!(SmallVec4, 4);
+def_small_vector_drop_impl!(SmallVec8, 8);
+def_small_vector_drop_impl!(SmallVec16, 16);
+def_small_vector_drop_impl!(SmallVec24, 24);
+def_small_vector_drop_impl!(SmallVec32, 32);
macro_rules! def_small_vector_clone_impl(
($name:ident) => (
@@ -510,15 +517,15 @@ macro_rules! def_small_vector_clone_impl(
}
}
)
-)
-
-def_small_vector_clone_impl!(SmallVec1)
-def_small_vector_clone_impl!(SmallVec2)
-def_small_vector_clone_impl!(SmallVec4)
-def_small_vector_clone_impl!(SmallVec8)
-def_small_vector_clone_impl!(SmallVec16)
-def_small_vector_clone_impl!(SmallVec24)
-def_small_vector_clone_impl!(SmallVec32)
+);
+
+def_small_vector_clone_impl!(SmallVec1);
+def_small_vector_clone_impl!(SmallVec2);
+def_small_vector_clone_impl!(SmallVec4);
+def_small_vector_clone_impl!(SmallVec8);
+def_small_vector_clone_impl!(SmallVec16);
+def_small_vector_clone_impl!(SmallVec24);
+def_small_vector_clone_impl!(SmallVec32);
#[cfg(test)]
pub mod tests {
diff --git a/components/util/sort.rs b/components/util/sort.rs
index d31948cb0e8..ce7ab4d86c9 100644
--- a/components/util/sort.rs
+++ b/components/util/sort.rs
@@ -81,6 +81,7 @@ pub fn quicksort_by<T>(arr: &mut [T], compare: fn(&T, &T) -> Ordering) {
#[cfg(test)]
pub mod test {
+ use std::cmp::Ordering;
use std::rand;
use std::rand::Rng;
@@ -88,7 +89,7 @@ pub mod test {
#[test]
pub fn random() {
- let mut rng = rand::task_rng();
+ let mut rng = rand::thread_rng();
for _ in range(0u32, 50000u32) {
let len: uint = rng.gen();
let mut v: Vec<int> = rng.gen_iter::<int>().take((len % 32) + 1).collect();
diff --git a/components/util/str.rs b/components/util/str.rs
index db5a6328cdb..352876919d4 100644
--- a/components/util/str.rs
+++ b/components/util/str.rs
@@ -5,12 +5,14 @@
use geometry::Au;
use cssparser::{mod, RGBA, Color};
+
+use libc::c_char;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
+use std::ffi::c_str_to_bytes;
use std::iter::Filter;
-use std::num::Int;
-use std::str::{CharEq, CharSplits, FromStr};
-use unicode::char::UnicodeChar;
+use std::num::{Int, ToPrimitive};
+use std::str::{from_utf8, CharEq, FromStr, Split};
pub type DOMString = String;
pub type StaticCharVec = &'static [char];
@@ -65,15 +67,16 @@ pub static HTML_SPACE_CHARACTERS: StaticCharVec = &[
'\u{000d}',
];
-pub fn split_html_space_chars<'a>(s: &'a str)
- -> Filter<'a, &'a str, CharSplits<'a, StaticCharVec>> {
- s.split(HTML_SPACE_CHARACTERS).filter(|&split| !split.is_empty())
+pub fn split_html_space_chars<'a>(s: &'a str) ->
+ Filter<&'a str, Split<'a, StaticCharVec>, fn(&&str) -> bool> {
+ fn not_empty(&split: &&str) -> bool { !split.is_empty() }
+ s.split(HTML_SPACE_CHARACTERS).filter(not_empty as fn(&&str) -> bool)
}
/// Shared implementation to parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-integers> or
/// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>.
-fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> {
+fn do_parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i64> {
fn is_ascii_digit(c: &char) -> bool {
match *c {
'0'...'9' => true,
@@ -118,7 +121,7 @@ fn do_parse_integer<T: Iterator<char>>(input: T) -> Option<i64> {
/// Parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-integers>.
-pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> {
+pub fn parse_integer<T: Iterator<Item=char>>(input: T) -> Option<i32> {
do_parse_integer(input).and_then(|result| {
result.to_i32()
})
@@ -126,13 +129,13 @@ pub fn parse_integer<T: Iterator<char>>(input: T) -> Option<i32> {
/// Parse an integer according to
/// <http://www.whatwg.org/html/#rules-for-parsing-non-negative-integers>.
-pub fn parse_unsigned_integer<T: Iterator<char>>(input: T) -> Option<u32> {
+pub fn parse_unsigned_integer<T: Iterator<Item=char>>(input: T) -> Option<u32> {
do_parse_integer(input).and_then(|result| {
result.to_u32()
})
}
-#[deriving(Copy)]
+#[derive(Copy)]
pub enum LengthOrPercentageOrAuto {
Auto,
Percentage(f64),
@@ -141,14 +144,14 @@ pub enum LengthOrPercentageOrAuto {
/// Parses a length per HTML5 § 2.4.4.4. If unparseable, `Auto` is returned.
pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto {
- value = value.trim_left_chars(Whitespace);
+ value = value.trim_left_matches(Whitespace);
if value.len() == 0 {
return LengthOrPercentageOrAuto::Auto
}
if value.starts_with("+") {
value = value.slice_from(1)
}
- value = value.trim_left_chars('0');
+ value = value.trim_left_matches('0');
if value.len() == 0 {
return LengthOrPercentageOrAuto::Auto
}
@@ -197,7 +200,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> {
}
// Step 3.
- input = input.trim_left_chars(Whitespace).trim_right_chars(Whitespace);
+ input = input.trim_left_matches(Whitespace).trim_right_matches(Whitespace);
// Step 4.
if input.eq_ignore_ascii_case("transparent") {
@@ -321,7 +324,7 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA,()> {
}
-#[deriving(Clone, Eq, PartialEq, Hash, Show)]
+#[derive(Clone, Eq, PartialEq, Hash, Show)]
pub struct LowercaseString {
inner: String,
}
@@ -340,3 +343,9 @@ impl Str for LowercaseString {
self.inner.as_slice()
}
}
+
+/// Creates a String from the given null-terminated buffer.
+/// Panics if the buffer does not contain UTF-8.
+pub unsafe fn c_str_to_string(s: *const c_char) -> String {
+ from_utf8(c_str_to_bytes(&s)).unwrap().to_owned()
+}
diff --git a/components/util/task.rs b/components/util/task.rs
index 44c2ff284dc..2045d0c3e83 100644
--- a/components/util/task.rs
+++ b/components/util/task.rs
@@ -3,33 +3,37 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use std::borrow::ToOwned;
-use std::task;
-use std::comm::Sender;
-use std::task::TaskBuilder;
use task_state;
+use std::thread;
+use std::sync::mpsc::Sender;
+use std::thread::Builder;
-pub fn spawn_named(name: String, f: proc():Send) {
- let builder = task::TaskBuilder::new().named(name);
- builder.spawn(proc() {
- f();
+pub fn spawn_named<F>(name: String, f: F)
+ where F: FnOnce() + Send
+{
+ let builder = thread::Builder::new().name(name);
+ builder.spawn(move || {
+ f()
});
}
/// Arrange to send a particular message to a channel if the task fails.
-pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str,
- state: task_state::TaskState,
- f: proc(): Send,
- msg: T,
- dest: Sender<T>) {
- let future_result = TaskBuilder::new().named(name).try_future(proc() {
+pub fn spawn_named_with_send_on_failure<F, T>(name: &'static str,
+ state: task_state::TaskState,
+ f: F,
+ msg: T,
+ dest: Sender<T>)
+ where F: FnOnce() + Send,
+ T: Send
+{
+ let future_handle = thread::Builder::new().name(name.to_owned()).scoped(move || {
task_state::initialize(state);
- f();
+ f()
});
- let watched_name = name.to_owned();
- let watcher_name = format!("{}Watcher", watched_name);
- TaskBuilder::new().named(watcher_name).spawn(proc() {
- match future_result.into_inner() {
+ let watcher_name = format!("{}Watcher", name);
+ Builder::new().name(watcher_name).spawn(move || {
+ match future_handle.join() {
Ok(()) => (),
Err(..) => {
debug!("{} failed, notifying constellation", name);
@@ -38,3 +42,10 @@ pub fn spawn_named_with_send_on_failure<T: Send>(name: &'static str,
}
});
}
+
+#[test]
+fn spawn_named_test() {
+ spawn_named("Test".to_owned(), move || {
+ debug!("I can run!");
+ });
+}
diff --git a/components/util/task_state.rs b/components/util/task_state.rs
index 3915eeb3059..ef1dbb2ed3e 100644
--- a/components/util/task_state.rs
+++ b/components/util/task_state.rs
@@ -11,7 +11,7 @@
pub use self::imp::{initialize, get, enter, exit};
bitflags! {
- #[deriving(Show, Copy)]
+ #[derive(Show)]
flags TaskState: u32 {
const SCRIPT = 0x01,
const LAYOUT = 0x02,
@@ -35,7 +35,7 @@ macro_rules! task_types ( ( $( $fun:ident = $flag:ident ; )* ) => (
#[cfg(not(ndebug))]
static TYPES: &'static [TaskState]
= &[ $( $flag ),* ];
-))
+));
task_types! {
is_script = SCRIPT;
@@ -48,12 +48,12 @@ mod imp {
use super::{TaskState, TYPES};
use std::cell::RefCell;
- thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None))
+ thread_local!(static STATE: RefCell<Option<TaskState>> = RefCell::new(None));
pub fn initialize(x: TaskState) {
STATE.with(|ref k| {
match *k.borrow() {
- Some(s) => panic!("Task state already initialized as {}", s),
+ Some(s) => panic!("Task state already initialized as {:?}", s),
None => ()
};
*k.borrow_mut() = Some(x);
diff --git a/components/util/taskpool.rs b/components/util/taskpool.rs
index 8521ef9dc93..7f2d36be936 100644
--- a/components/util/taskpool.rs
+++ b/components/util/taskpool.rs
@@ -17,9 +17,11 @@
use task::spawn_named;
use std::sync::{Arc, Mutex};
+use std::sync::mpsc::{channel, Sender, Receiver};
+use std::thunk::Thunk;
pub struct TaskPool {
- tx: Sender<proc():Send>,
+ tx: Sender<Thunk<()>>,
}
impl TaskPool {
@@ -33,23 +35,25 @@ impl TaskPool {
let state = state.clone();
spawn_named(
format!("TaskPoolWorker {}/{}", i+1, tasks),
- proc() worker(&*state));
+ move || worker(&*state));
}
return TaskPool { tx: tx };
- fn worker(rx: &Mutex<Receiver<proc():Send>>) {
+ fn worker(rx: &Mutex<Receiver<Thunk<()>>>) {
loop {
- let job = rx.lock().recv_opt();
+ let job = rx.lock().unwrap().recv();
match job {
- Ok(job) => job(),
+ Ok(job) => job.invoke(()),
Err(..) => break,
}
}
}
}
- pub fn execute(&self, job: proc():Send) {
- self.tx.send(job);
+ pub fn execute<F>(&self, job: F)
+ where F: FnOnce() + Send
+ {
+ self.tx.send(Thunk::new(job));
}
}
diff --git a/components/util/tid.rs b/components/util/tid.rs
index 62723941fcb..e52dbf7fd61 100644
--- a/components/util/tid.rs
+++ b/components/util/tid.rs
@@ -2,13 +2,13 @@
* 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/. */
-use std::sync::atomic::{AtomicUint, INIT_ATOMIC_UINT, Ordering};
+use std::sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
use std::rc::Rc;
use std::cell::RefCell;
-static mut next_tid: AtomicUint = INIT_ATOMIC_UINT;
+static mut next_tid: AtomicUint = ATOMIC_UINT_INIT;
-thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None)))
+thread_local!(static TASK_LOCAL_TID: Rc<RefCell<Option<uint>>> = Rc::new(RefCell::new(None)));
/// Every task gets one, that's unique.
pub fn tid() -> uint {
diff --git a/components/util/time.rs b/components/util/time.rs
index a47f3a98c8c..b5805dfa092 100644
--- a/components/util/time.rs
+++ b/components/util/time.rs
@@ -4,21 +4,21 @@
//! Timing functions.
-use collections::TreeMap;
+use collections::BTreeMap;
use std::borrow::ToOwned;
use std::cmp::Ordering;
-use std::comm::{Sender, channel, Receiver};
use std::f64;
use std::io::timer::sleep;
use std::iter::AdditiveIterator;
-use std::num::FloatMath;
+use std::num::Float;
+use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use std_time::precise_time_ns;
use task::{spawn_named};
use url::Url;
// front-end representation of the profiler used to communicate with the profiler
-#[deriving(Clone)]
+#[derive(Clone)]
pub struct TimeProfilerChan(pub Sender<TimeProfilerMsg>);
impl TimeProfilerChan {
@@ -28,7 +28,7 @@ impl TimeProfilerChan {
}
}
-#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)]
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
pub struct TimerMetadata {
url: String,
iframe: bool,
@@ -60,7 +60,7 @@ impl Formatable for Option<TimerMetadata> {
}
}
-#[deriving(Clone)]
+#[derive(Clone)]
pub enum TimeProfilerMsg {
/// Normal message used for reporting time
Time((TimeProfilerCategory, Option<TimerMetadata>), f64),
@@ -71,7 +71,7 @@ pub enum TimeProfilerMsg {
}
#[repr(u32)]
-#[deriving(PartialEq, Clone, PartialOrd, Eq, Ord)]
+#[derive(PartialEq, Clone, PartialOrd, Eq, Ord)]
pub enum TimeProfilerCategory {
Compositing,
LayoutPerform,
@@ -130,7 +130,7 @@ impl Formatable for TimeProfilerCategory {
}
}
-type TimeProfilerBuckets = TreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>;
+type TimeProfilerBuckets = BTreeMap<(TimeProfilerCategory, Option<TimerMetadata>), Vec<f64>>;
// back end of the profiler that handles data aggregation and performance metrics
pub struct TimeProfiler {
@@ -146,25 +146,25 @@ impl TimeProfiler {
Some(period) => {
let period = Duration::milliseconds((period * 1000f64) as i64);
let chan = chan.clone();
- spawn_named("Time profiler timer".to_owned(), proc() {
+ spawn_named("Time profiler timer".to_owned(), move || {
loop {
sleep(period);
- if chan.send_opt(TimeProfilerMsg::Print).is_err() {
+ if chan.send(TimeProfilerMsg::Print).is_err() {
break;
}
}
});
// Spawn the time profiler.
- spawn_named("Time profiler".to_owned(), proc() {
+ spawn_named("Time profiler".to_owned(), move || {
let mut profiler = TimeProfiler::new(port);
profiler.start();
});
}
None => {
// No-op to handle messages when the time profiler is inactive.
- spawn_named("Time profiler".to_owned(), proc() {
+ spawn_named("Time profiler".to_owned(), move || {
loop {
- match port.recv_opt() {
+ match port.recv() {
Err(_) | Ok(TimeProfilerMsg::Exit) => break,
_ => {}
}
@@ -179,14 +179,14 @@ impl TimeProfiler {
pub fn new(port: Receiver<TimeProfilerMsg>) -> TimeProfiler {
TimeProfiler {
port: port,
- buckets: TreeMap::new(),
+ buckets: BTreeMap::new(),
last_msg: None,
}
}
pub fn start(&mut self) {
loop {
- let msg = self.port.recv_opt();
+ let msg = self.port.recv();
match msg {
Ok(msg) => {
if !self.handle_msg(msg) {
@@ -249,13 +249,13 @@ impl TimeProfiler {
}
}
-#[deriving(Eq, PartialEq)]
+#[derive(Eq, PartialEq)]
pub enum TimerMetadataFrameType {
RootWindow,
IFrame,
}
-#[deriving(Eq, PartialEq)]
+#[derive(Eq, PartialEq)]
pub enum TimerMetadataReflowType {
Incremental,
FirstReflow,
@@ -263,11 +263,13 @@ pub enum TimerMetadataReflowType {
pub type ProfilerMetadata<'a> = Option<(&'a Url, TimerMetadataFrameType, TimerMetadataReflowType)>;
-pub fn profile<T>(category: TimeProfilerCategory,
- meta: ProfilerMetadata,
- time_profiler_chan: TimeProfilerChan,
- callback: || -> T)
- -> T {
+pub fn profile<T, F>(category: TimeProfilerCategory,
+ meta: ProfilerMetadata,
+ time_profiler_chan: TimeProfilerChan,
+ callback: F)
+ -> T
+ where F: FnOnce() -> T
+{
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
@@ -282,7 +284,9 @@ pub fn profile<T>(category: TimeProfilerCategory,
return val;
}
-pub fn time<T>(msg: &str, callback: || -> T) -> T{
+pub fn time<T, F>(msg: &str, callback: F) -> T
+ where F: Fn() -> T
+{
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
diff --git a/components/util/vec.rs b/components/util/vec.rs
index c34b76a9794..a902a3133df 100644
--- a/components/util/vec.rs
+++ b/components/util/vec.rs
@@ -78,7 +78,7 @@ fn test_miss_all_elems<T: PartialEq + PartialOrd + Eq + Ord + Show>(arr: &[T], m
let mut i = 0;
while i < misses.len() {
let res = arr.binary_search_(&misses[i]);
- debug!("{} == {} ?", misses[i], res);
+ debug!("{:?} == {:?} ?", misses[i], res);
assert!(!test_match(&misses[i], arr.binary_search_(&misses[i])));
i += 1;
}
diff --git a/components/util/workqueue.rs b/components/util/workqueue.rs
index ee14a4d1a50..c83902526fd 100644
--- a/components/util/workqueue.rs
+++ b/components/util/workqueue.rs
@@ -15,6 +15,7 @@ use rand::{Rng, XorShiftRng};
use std::mem;
use std::rand::weak_rng;
use std::sync::atomic::{AtomicUint, Ordering};
+use std::sync::mpsc::{channel, Sender, Receiver};
use deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
/// A unit of work.
@@ -31,7 +32,7 @@ pub struct WorkUnit<QueueData, WorkData> {
}
/// Messages from the supervisor to the worker.
-enum WorkerMsg<QueueData, WorkData> {
+enum WorkerMsg<QueueData: 'static, WorkData: 'static> {
/// Tells the worker to start work.
Start(Worker<WorkUnit<QueueData, WorkData>>, *mut AtomicUint, *const QueueData),
/// Tells the worker to stop. It can be restarted again with a `WorkerMsg::Start`.
@@ -40,14 +41,18 @@ enum WorkerMsg<QueueData, WorkData> {
Exit,
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerMsg<QueueData, WorkData> {}
+
/// Messages to the supervisor.
-enum SupervisorMsg<QueueData, WorkData> {
+enum SupervisorMsg<QueueData: 'static, WorkData: 'static> {
Finished,
ReturnDeque(uint, Worker<WorkUnit<QueueData, WorkData>>),
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for SupervisorMsg<QueueData, WorkData> {}
+
/// Information that the supervisor thread keeps about the worker threads.
-struct WorkerInfo<QueueData, WorkData> {
+struct WorkerInfo<QueueData: 'static, WorkData: 'static> {
/// The communication channel to the workers.
chan: Sender<WorkerMsg<QueueData, WorkData>>,
/// The worker end of the deque, if we have it.
@@ -57,7 +62,7 @@ struct WorkerInfo<QueueData, WorkData> {
}
/// Information specific to each worker thread that the thread keeps.
-struct WorkerThread<QueueData, WorkData> {
+struct WorkerThread<QueueData: 'static, WorkData: 'static> {
/// The index of this worker.
index: uint,
/// The communication port from the supervisor.
@@ -70,6 +75,8 @@ struct WorkerThread<QueueData, WorkData> {
rng: XorShiftRng,
}
+unsafe impl<QueueData: 'static, WorkData: 'static> Send for WorkerThread<QueueData, WorkData> {}
+
static SPIN_COUNT: u32 = 128;
static SPINS_UNTIL_BACKOFF: u32 = 100;
static BACKOFF_INCREMENT_IN_US: u32 = 5;
@@ -80,7 +87,7 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
fn start(&mut self) {
loop {
// Wait for a start message.
- let (mut deque, ref_count, queue_data) = match self.port.recv() {
+ let (mut deque, ref_count, queue_data) = match self.port.recv().unwrap() {
WorkerMsg::Start(deque, ref_count, queue_data) => (deque, ref_count, queue_data),
WorkerMsg::Stop => panic!("unexpected stop message"),
WorkerMsg::Exit => return,
@@ -158,13 +165,13 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
// the last work unit in the queue, then send a message on the channel.
unsafe {
if (*ref_count).fetch_sub(1, Ordering::SeqCst) == 1 {
- self.chan.send(SupervisorMsg::Finished)
+ self.chan.send(SupervisorMsg::Finished).unwrap()
}
}
}
// Give the deque back to the supervisor.
- self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque))
+ self.chan.send(SupervisorMsg::ReturnDeque(self.index, deque)).unwrap()
}
}
}
@@ -196,7 +203,7 @@ impl<'a, QueueData: 'static, WorkData: Send> WorkerProxy<'a, QueueData, WorkData
}
/// A work queue on which units of work can be submitted.
-pub struct WorkQueue<QueueData, WorkData> {
+pub struct WorkQueue<QueueData: 'static, WorkData: 'static> {
/// Information about each of the workers.
workers: Vec<WorkerInfo<QueueData, WorkData>>,
/// A port on which deques can be received from the workers.
@@ -250,7 +257,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
spawn_named(
format!("{} worker {}/{}", task_name, i+1, thread_count),
- proc() {
+ move || {
task_state::initialize(state | task_state::IN_WORKER);
let mut thread = thread;
thread.start()
@@ -283,7 +290,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
// Tell the workers to start.
let mut work_count = AtomicUint::new(self.work_count);
for worker in self.workers.iter_mut() {
- worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data))
+ worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(), &mut work_count, &self.data)).unwrap()
}
// Wait for the work to finish.
@@ -292,12 +299,12 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
// Tell everyone to stop.
for worker in self.workers.iter() {
- worker.chan.send(WorkerMsg::Stop)
+ worker.chan.send(WorkerMsg::Stop).unwrap()
}
// Get our deques back.
for _ in range(0, self.workers.len()) {
- match self.port.recv() {
+ match self.port.recv().unwrap() {
SupervisorMsg::ReturnDeque(index, deque) => self.workers[index].deque = Some(deque),
SupervisorMsg::Finished => panic!("unexpected finished message!"),
}
@@ -306,7 +313,7 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
pub fn shutdown(&mut self) {
for worker in self.workers.iter() {
- worker.chan.send(WorkerMsg::Exit)
+ worker.chan.send(WorkerMsg::Exit).unwrap()
}
}
}