aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2017-10-14 12:27:26 +0200
committerSimon Sapin <simon.sapin@exyr.org>2017-10-16 20:19:19 +0200
commit9e4865b6c89267e987b2b638295ad6d872f260ca (patch)
tree7aab36dc182ee185caf56be6b54498a11fadfde9
parent4ee1b26b6cf315b6f026f7e96a36877285f79573 (diff)
downloadservo-9e4865b6c89267e987b2b638295ad6d872f260ca.tar.gz
servo-9e4865b6c89267e987b2b638295ad6d872f260ca.zip
Replace NonZeroU32 and NonZeroUsize with a generic NonZero
The API is identical to core::nonzero::NonZero
-rw-r--r--components/canvas_traits/webgl.rs6
-rw-r--r--components/compositing/compositor.rs4
-rw-r--r--components/layout_thread/dom_wrapper.rs5
-rw-r--r--components/msg/constellation_msg.rs14
-rw-r--r--components/nonzero/lib.rs135
-rw-r--r--components/remutex/lib.rs10
-rw-r--r--components/script_layout_interface/lib.rs6
7 files changed, 114 insertions, 66 deletions
diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs
index 98c4115c69c..47205c09635 100644
--- a/components/canvas_traits/webgl.rs
+++ b/components/canvas_traits/webgl.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use euclid::Size2D;
-use nonzero::NonZeroU32;
+use nonzero::NonZero;
use offscreen_gl_context::{GLContextAttributes, GLLimits};
use std::fmt;
use webrender_api;
@@ -242,13 +242,13 @@ pub enum WebGLCommand {
macro_rules! define_resource_id_struct {
($name:ident) => {
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
- pub struct $name(NonZeroU32);
+ pub struct $name(NonZero<u32>);
impl $name {
#[allow(unsafe_code)]
#[inline]
pub unsafe fn new(id: u32) -> Self {
- $name(NonZeroU32::new_unchecked(id))
+ $name(NonZero::new_unchecked(id))
}
#[inline]
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index 7e77157b845..85bab91a835 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -13,7 +13,7 @@ use image::{DynamicImage, ImageFormat, RgbImage};
use ipc_channel::ipc::{self, IpcSharedMemory};
use msg::constellation_msg::{PipelineId, PipelineIndex, PipelineNamespaceId};
use net_traits::image::base::{Image, PixelFormat};
-use nonzero::NonZeroU32;
+use nonzero::NonZero;
use profile_traits::time::{self, ProfilerCategory, profile};
use script_traits::{AnimationState, AnimationTickType, ConstellationControlMsg};
use script_traits::{ConstellationMsg, LayoutControlMsg, MouseButton};
@@ -62,7 +62,7 @@ impl ConvertPipelineIdFromWebRender for webrender_api::PipelineId {
fn from_webrender(&self) -> PipelineId {
PipelineId {
namespace_id: PipelineNamespaceId(self.0),
- index: PipelineIndex(NonZeroU32::new(self.1).expect("Webrender pipeline zero?")),
+ index: PipelineIndex(NonZero::new(self.1).expect("Webrender pipeline zero?")),
}
}
}
diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs
index 2863d840ce5..08d628a6d6c 100644
--- a/components/layout_thread/dom_wrapper.rs
+++ b/components/layout_thread/dom_wrapper.rs
@@ -36,7 +36,7 @@ use html5ever::{LocalName, Namespace};
use layout::data::StyleAndLayoutData;
use layout::wrapper::GetRawData;
use msg::constellation_msg::{BrowsingContextId, PipelineId};
-use nonzero::NonZeroUsize;
+use nonzero::NonZero;
use range::Range;
use script::layout_exports::{CAN_BE_FRAGMENTED, HAS_DIRTY_DESCENDANTS, IS_IN_DOC};
use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId};
@@ -235,8 +235,7 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
let ptr: *mut StyleAndLayoutData =
Box::into_raw(Box::new(StyleAndLayoutData::new()));
let opaque = OpaqueStyleAndLayoutData {
- ptr: NonZeroUsize::new_unchecked(ptr as usize),
- phantom: PhantomData,
+ ptr: NonZero::new_unchecked(ptr as *mut StyleData),
};
self.init_style_and_layout_data(opaque);
};
diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs
index da9bb3ea0cb..40c1827b262 100644
--- a/components/msg/constellation_msg.rs
+++ b/components/msg/constellation_msg.rs
@@ -5,7 +5,7 @@
//! The high-level interface from script to constellation. Using this abstract interface helps
//! reduce coupling between these two components.
-use nonzero::NonZeroU32;
+use nonzero::NonZero;
use std::cell::Cell;
use std::fmt;
use webrender_api;
@@ -195,9 +195,9 @@ impl PipelineNamespace {
});
}
- fn next_index(&mut self) -> NonZeroU32 {
+ fn next_index(&mut self) -> NonZero<u32> {
self.index += 1;
- NonZeroU32::new(self.index).expect("pipeline id index wrapped!")
+ NonZero::new(self.index).expect("pipeline id index wrapped!")
}
fn next_pipeline_id(&mut self) -> PipelineId {
@@ -221,7 +221,7 @@ thread_local!(pub static PIPELINE_NAMESPACE: Cell<Option<PipelineNamespace>> = C
pub struct PipelineNamespaceId(pub u32);
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
-pub struct PipelineIndex(pub NonZeroU32);
+pub struct PipelineIndex(pub NonZero<u32>);
known_heap_size!(0, PipelineIndex);
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
@@ -264,7 +264,7 @@ impl fmt::Display for PipelineId {
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
-pub struct BrowsingContextIndex(pub NonZeroU32);
+pub struct BrowsingContextIndex(pub NonZero<u32>);
known_heap_size!(0, BrowsingContextIndex);
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, HeapSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
@@ -340,13 +340,13 @@ impl PartialEq<BrowsingContextId> for TopLevelBrowsingContextId {
pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234);
#[allow(unsafe_code)]
#[cfg(feature = "unstable")]
-pub const TEST_PIPELINE_INDEX: PipelineIndex = unsafe { PipelineIndex(NonZeroU32::new_unchecked(5678)) };
+pub const TEST_PIPELINE_INDEX: PipelineIndex = unsafe { PipelineIndex(NonZero::new_unchecked(5678)) };
#[cfg(feature = "unstable")]
pub const TEST_PIPELINE_ID: PipelineId = PipelineId { namespace_id: TEST_NAMESPACE, index: TEST_PIPELINE_INDEX };
#[allow(unsafe_code)]
#[cfg(feature = "unstable")]
pub const TEST_BROWSING_CONTEXT_INDEX: BrowsingContextIndex =
- unsafe { BrowsingContextIndex(NonZeroU32::new_unchecked(8765)) };
+ unsafe { BrowsingContextIndex(NonZero::new_unchecked(8765)) };
#[cfg(feature = "unstable")]
pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId =
BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX };
diff --git a/components/nonzero/lib.rs b/components/nonzero/lib.rs
index 665dc7448f8..b44cf73c7d6 100644
--- a/components/nonzero/lib.rs
+++ b/components/nonzero/lib.rs
@@ -9,7 +9,7 @@
#![cfg_attr(feature = "unstable", feature(const_fn))]
#![cfg_attr(feature = "unstable", feature(const_nonzero_new))]
-#[macro_use]
+#[cfg_attr(not(feature = "unstable"), macro_use)]
extern crate serde;
pub use imp::*;
@@ -17,74 +17,125 @@ pub use imp::*;
#[cfg(feature = "unstable")]
mod imp {
extern crate core;
- use self::core::nonzero::NonZero;
+ use self::core::nonzero::NonZero as CoreNonZero;
+ use serde::{Serialize, Serializer, Deserialize, Deserializer};
- #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
- pub struct NonZeroU32(NonZero<u32>);
+ pub use self::core::nonzero::Zeroable;
- #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
- pub struct NonZeroUsize(NonZero<usize>);
+ #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+ pub struct NonZero<T: Zeroable>(CoreNonZero<T>);
+
+ impl<T: Zeroable> NonZero<T> {
+ #[inline]
+ pub const unsafe fn new_unchecked(x: T) -> Self {
+ NonZero(CoreNonZero::new_unchecked(x))
+ }
- impl NonZeroU32 {
- #[inline] pub const unsafe fn new_unchecked(x: u32) -> Self { NonZeroU32(NonZero::new_unchecked(x)) }
- #[inline] pub fn new(x: u32) -> Option<Self> { NonZero::new(x).map(NonZeroU32) }
- #[inline] pub fn get(self) -> u32 { self.0.get() }
+ #[inline]
+ pub fn new(x: T) -> Option<Self> {
+ CoreNonZero::new(x).map(NonZero)
+ }
+
+ #[inline]
+ pub fn get(self) -> T {
+ self.0.get()
+ }
+ }
+
+ // Not using derive because of the additional Clone bound required by the inner impl
+
+ impl<T> Serialize for NonZero<T>
+ where
+ T: Serialize + Zeroable + Clone,
+ {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
}
- impl NonZeroUsize {
- #[inline] pub const unsafe fn new_unchecked(x: usize) -> Self { NonZeroUsize(NonZero::new_unchecked(x)) }
- #[inline] pub fn new(x: usize) -> Option<Self> { NonZero::new(x).map(NonZeroUsize) }
- #[inline] pub fn get(self) -> usize { self.0.get() }
+ impl<'de, T> Deserialize<'de> for NonZero<T>
+ where
+ T: Deserialize<'de> + Zeroable,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ CoreNonZero::deserialize(deserializer).map(NonZero)
+ }
}
}
#[cfg(not(feature = "unstable"))]
mod imp {
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
- pub struct NonZeroU32(u32);
+ pub struct NonZero<T: Zeroable>(T);
- impl NonZeroU32 {
+ impl<T: Zeroable> NonZero<T> {
#[inline]
- pub fn new(x: u32) -> Option<Self> {
- if x != 0 {
- Some(NonZeroU32(x))
- } else {
- None
- }
+ pub unsafe fn new_unchecked(x: T) -> Self {
+ NonZero(x)
}
#[inline]
- pub unsafe fn new_unchecked(x: u32) -> Self {
- NonZeroU32(x)
+ pub fn new(x: T) -> Option<Self> {
+ if x.is_zero() {
+ None
+ } else {
+ Some(NonZero(x))
+ }
}
#[inline]
- pub fn get(self) -> u32 {
+ pub fn get(self) -> T {
self.0
}
}
- #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
- pub struct NonZeroUsize(usize);
+ /// Unsafe trait to indicate what types are usable with the NonZero struct
+ pub unsafe trait Zeroable {
+ /// Whether this value is zero
+ fn is_zero(&self) -> bool;
+ }
- impl NonZeroUsize {
- #[inline]
- pub fn new(x: usize) -> Option<Self> {
- if x != 0 {
- Some(NonZeroUsize(x))
- } else {
- None
- }
+ macro_rules! impl_zeroable_for_pointer_types {
+ ( $( $Ptr: ty )+ ) => {
+ $(
+ /// For fat pointers to be considered "zero", only the "data" part needs to be null.
+ unsafe impl<T: ?Sized> Zeroable for $Ptr {
+ #[inline]
+ fn is_zero(&self) -> bool {
+ // Cast because `is_null` is only available on thin pointers
+ (*self as *mut u8).is_null()
+ }
+ }
+ )+
}
+ }
- #[inline]
- pub unsafe fn new_unchecked(x: usize) -> Self {
- NonZeroUsize(x)
+ macro_rules! impl_zeroable_for_integer_types {
+ ( $( $Int: ty )+ ) => {
+ $(
+ unsafe impl Zeroable for $Int {
+ #[inline]
+ fn is_zero(&self) -> bool {
+ *self == 0
+ }
+ }
+ )+
}
+ }
- #[inline]
- pub fn get(self) -> usize {
- self.0
- }
+ impl_zeroable_for_pointer_types! {
+ *const T
+ *mut T
+ }
+
+ impl_zeroable_for_integer_types! {
+ usize u8 u16 u32 u64
+ isize i8 i16 i32 i64
}
}
diff --git a/components/remutex/lib.rs b/components/remutex/lib.rs
index 2589a6d1162..5fbbad40bf0 100644
--- a/components/remutex/lib.rs
+++ b/components/remutex/lib.rs
@@ -14,7 +14,7 @@ extern crate nonzero;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
-use nonzero::NonZeroUsize;
+use nonzero::NonZero;
use std::cell::{Cell, UnsafeCell};
use std::ops::Deref;
use std::sync::{LockResult, Mutex, MutexGuard, PoisonError, TryLockError, TryLockResult};
@@ -25,7 +25,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
// TODO: can we use the thread-id crate for this?
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
-pub struct ThreadId(NonZeroUsize);
+pub struct ThreadId(NonZero<usize>);
lazy_static!{ static ref THREAD_COUNT: AtomicUsize = AtomicUsize::new(1); }
@@ -33,7 +33,7 @@ impl ThreadId {
#[allow(unsafe_code)]
fn new() -> ThreadId {
let number = THREAD_COUNT.fetch_add(1, Ordering::SeqCst);
- ThreadId(NonZeroUsize::new(number).unwrap())
+ ThreadId(NonZero::new(number).unwrap())
}
pub fn current() -> ThreadId {
THREAD_ID.with(|tls| tls.clone())
@@ -57,13 +57,13 @@ impl AtomicOptThreadId {
#[allow(unsafe_code)]
pub fn load(&self, ordering: Ordering) -> Option<ThreadId> {
let number = self.0.load(ordering);
- NonZeroUsize::new(number).map(ThreadId)
+ NonZero::new(number).map(ThreadId)
}
#[allow(unsafe_code)]
pub fn swap(&self, value: Option<ThreadId>, ordering: Ordering) -> Option<ThreadId> {
let number = value.map(|id| id.0.get()).unwrap_or(0);
let number = self.0.swap(number, ordering);
- NonZeroUsize::new(number).map(ThreadId)
+ NonZero::new(number).map(ThreadId)
}
}
diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs
index 7b45d9688f1..0216ca84543 100644
--- a/components/script_layout_interface/lib.rs
+++ b/components/script_layout_interface/lib.rs
@@ -45,10 +45,9 @@ use canvas_traits::canvas::CanvasMsg;
use ipc_channel::ipc::IpcSender;
use libc::c_void;
use net_traits::image_cache::PendingImageId;
-use nonzero::NonZeroUsize;
+use nonzero::NonZero;
use script_traits::UntrustedNodeAddress;
use servo_url::ServoUrl;
-use std::marker::PhantomData;
use std::sync::atomic::AtomicIsize;
use style::data::ElementData;
@@ -78,8 +77,7 @@ pub struct OpaqueStyleAndLayoutData {
// NB: We really store a `StyleAndLayoutData` here, so be careful!
#[ignore_heap_size_of = "TODO(#6910) Box value that should be counted but \
the type lives in layout"]
- pub ptr: NonZeroUsize,
- pub phantom: PhantomData<*mut StyleData>,
+ pub ptr: NonZero<*mut StyleData>,
}
#[allow(unsafe_code)]