Update to selectors 0.8.2

This commit is contained in:
Simon Sapin 2016-07-15 10:24:10 +02:00
parent f419db834c
commit fdb2071b2d
28 changed files with 455 additions and 286 deletions

View file

@ -2,10 +2,11 @@
* 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/. */
#[macro_use]
#[macro_use] #[no_link]
extern crate cfg_if;
extern crate gecko_bindings;
extern crate heapsize;
extern crate selectors;
extern crate serde;
use gecko_bindings::bindings::Gecko_AddRefAtom;
@ -15,13 +16,15 @@ use gecko_bindings::bindings::Gecko_GetAtomAsUTF16;
use gecko_bindings::bindings::Gecko_ReleaseAtom;
use gecko_bindings::structs::nsIAtom;
use heapsize::HeapSizeOf;
use selectors::bloom::BloomHash;
use selectors::parser::FromCowStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::borrow::Cow;
use std::char;
use std::borrow::{Cow, Borrow};
use std::char::{self, DecodeUtf16};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem::transmute;
use std::iter::Cloned;
use std::mem;
use std::ops::Deref;
use std::slice;
@ -30,90 +33,88 @@ pub mod atom_macro;
#[macro_export]
macro_rules! ns {
() => { $crate::Namespace(atom!("")) };
() => { atom!("") }
}
pub type Namespace = Atom;
#[allow(non_snake_case)]
#[inline]
pub fn Namespace(atom: Atom) -> Atom {
atom
}
/// A strong reference to a Gecko atom.
#[derive(PartialEq, Eq)]
pub struct Atom(*mut nsIAtom);
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
pub struct Namespace(pub Atom);
pub struct Atom(*mut WeakAtom);
pub struct BorrowedAtom<'a> {
weak_ptr: *mut nsIAtom,
chain: PhantomData<&'a ()>,
}
/// An atom *without* a strong reference.
///
/// Only usable as `&'a WeakAtom`,
/// where `'a` is the lifetime of something that holds a strong reference to that atom.
pub struct WeakAtom(nsIAtom);
impl<'a> BorrowedAtom<'a> {
pub unsafe fn new(atom: *mut nsIAtom) -> Self {
BorrowedAtom {
weak_ptr: atom,
chain: PhantomData,
}
}
}
pub type BorrowedAtom<'a> = &'a WeakAtom;
impl<'a> Deref for BorrowedAtom<'a> {
type Target = Atom;
fn deref(&self) -> &Atom {
impl Deref for Atom {
type Target = WeakAtom;
#[inline]
fn deref(&self) -> &WeakAtom {
unsafe {
transmute(self)
&*self.0
}
}
}
impl<'a> PartialEq<Atom> for BorrowedAtom<'a> {
fn eq(&self, other: &Atom) -> bool {
self.weak_ptr == other.as_ptr()
impl Borrow<WeakAtom> for Atom {
#[inline]
fn borrow(&self) -> &WeakAtom {
self
}
}
pub struct BorrowedNamespace<'a> {
weak_ptr: *mut nsIAtom,
chain: PhantomData<&'a ()>,
}
impl<'a> BorrowedNamespace<'a> {
pub unsafe fn new(atom: *mut nsIAtom) -> Self {
BorrowedNamespace {
weak_ptr: atom,
chain: PhantomData,
}
}
}
impl<'a> Deref for BorrowedNamespace<'a> {
type Target = Namespace;
fn deref(&self) -> &Namespace {
unsafe {
transmute(self)
}
}
}
impl<'a> PartialEq<Namespace> for BorrowedNamespace<'a> {
fn eq(&self, other: &Namespace) -> bool {
self.weak_ptr == other.0.as_ptr()
impl Eq for WeakAtom {}
impl PartialEq for WeakAtom {
#[inline]
fn eq(&self, other: &Self) -> bool {
let weak: *const WeakAtom = self;
let other: *const WeakAtom = other;
weak == other
}
}
unsafe impl Send for Atom {}
unsafe impl Sync for Atom {}
unsafe impl Sync for WeakAtom {}
impl WeakAtom {
#[inline]
pub unsafe fn new<'a>(atom: *mut nsIAtom) -> &'a mut Self {
&mut *(atom as *mut WeakAtom)
}
#[inline]
pub fn clone(&self) -> Atom {
Atom::from(self.as_ptr())
}
impl Atom {
pub fn get_hash(&self) -> u32 {
unsafe {
(*self.0).mHash
}
self.0.mHash
}
pub fn as_slice(&self) -> &[u16] {
unsafe {
let mut len = 0;
let ptr = Gecko_GetAtomAsUTF16(self.0, &mut len);
let ptr = Gecko_GetAtomAsUTF16(self.as_ptr(), &mut len);
slice::from_raw_parts(ptr, len as usize)
}
}
pub fn chars(&self) -> DecodeUtf16<Cloned<slice::Iter<u16>>> {
char::decode_utf16(self.as_slice().iter().cloned())
}
pub fn with_str<F, Output>(&self, cb: F) -> Output
where F: FnOnce(&str) -> Output {
// FIXME(bholley): We should measure whether it makes more sense to
@ -124,7 +125,7 @@ impl Atom {
pub fn eq_str_ignore_ascii_case(&self, s: &str) -> bool {
unsafe {
Gecko_AtomEqualsUTF8IgnoreCase(self.0, s.as_ptr() as *const _, s.len() as u32)
Gecko_AtomEqualsUTF8IgnoreCase(self.as_ptr(), s.as_ptr() as *const _, s.len() as u32)
}
}
@ -132,29 +133,43 @@ impl Atom {
String::from_utf16(self.as_slice()).unwrap()
}
#[inline]
pub fn as_ptr(&self) -> *mut nsIAtom {
self.0
let const_ptr: *const nsIAtom = &self.0;
const_ptr as *mut nsIAtom
}
}
impl Atom {
pub unsafe fn with<F>(ptr: *mut nsIAtom, callback: &mut F) where F: FnMut(&Atom) {
callback(transmute(&ptr))
}
let atom = Atom(WeakAtom::new(ptr));
callback(&atom);
mem::forget(atom);
}
}
// Static atoms have a dummy AddRef/Release, so we don't bother calling
// AddRef() here. This would cause memory corruption with non-static atoms
// both because (a) we wouldn't hold the atom alive, and (b) we can't avoid
// calling Release() when the Atom is dropped, since we can't tell the
// difference between static and non-static atoms without bloating the
// size of Atom beyond word-size.
pub unsafe fn from_static(ptr: *mut nsIAtom) -> Atom {
Atom(ptr)
impl BloomHash for Atom {
#[inline]
fn bloom_hash(&self) -> u32 {
self.get_hash()
}
}
impl BloomHash for WeakAtom {
#[inline]
fn bloom_hash(&self) -> u32 {
self.get_hash()
}
}
impl Hash for Atom {
fn hash<H>(&self, state: &mut H)
where H: Hasher
{
fn hash<H>(&self, state: &mut H) where H: Hasher {
state.write_u32(self.get_hash());
}
}
impl Hash for WeakAtom {
fn hash<H>(&self, state: &mut H) where H: Hasher {
state.write_u32(self.get_hash());
}
}
@ -162,10 +177,7 @@ impl Hash for Atom {
impl Clone for Atom {
#[inline(always)]
fn clone(&self) -> Atom {
unsafe {
Gecko_AddRefAtom(self.0);
}
Atom(self.0)
Atom::from(self.as_ptr())
}
}
@ -173,18 +185,19 @@ impl Drop for Atom {
#[inline]
fn drop(&mut self) {
unsafe {
Gecko_ReleaseAtom(self.0);
Gecko_ReleaseAtom(self.as_ptr());
}
}
}
impl HeapSizeOf for Atom {
fn heap_size_of_children(&self) -> usize {
0
impl Default for Atom {
#[inline]
fn default() -> Self {
atom!("")
}
}
impl HeapSizeOf for Namespace {
impl HeapSizeOf for Atom {
fn heap_size_of_children(&self) -> usize {
0
}
@ -222,9 +235,11 @@ impl<'a> From<&'a str> for Atom {
#[inline]
fn from(string: &str) -> Atom {
assert!(string.len() <= u32::max_value() as usize);
Atom(unsafe {
Gecko_Atomize(string.as_ptr() as *const _, string.len() as u32)
})
unsafe {
Atom(WeakAtom::new(
Gecko_Atomize(string.as_ptr() as *const _, string.len() as u32)
))
}
}
}
@ -235,6 +250,13 @@ impl<'a> From<Cow<'a, str>> for Atom {
}
}
impl FromCowStr for Atom {
#[inline]
fn from_cow_str(string: Cow<str>) -> Atom {
Atom::from(&*string)
}
}
impl From<String> for Atom {
#[inline]
fn from(string: String) -> Atom {
@ -243,10 +265,11 @@ impl From<String> for Atom {
}
impl From<*mut nsIAtom> for Atom {
#[inline]
fn from(ptr: *mut nsIAtom) -> Atom {
unsafe {
Gecko_AddRefAtom(ptr);
Atom(ptr)
Atom(WeakAtom::new(ptr))
}
}
}