diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2017-10-14 12:27:26 +0200 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2017-10-16 20:19:19 +0200 |
commit | 9e4865b6c89267e987b2b638295ad6d872f260ca (patch) | |
tree | 7aab36dc182ee185caf56be6b54498a11fadfde9 | |
parent | 4ee1b26b6cf315b6f026f7e96a36877285f79573 (diff) | |
download | servo-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.rs | 6 | ||||
-rw-r--r-- | components/compositing/compositor.rs | 4 | ||||
-rw-r--r-- | components/layout_thread/dom_wrapper.rs | 5 | ||||
-rw-r--r-- | components/msg/constellation_msg.rs | 14 | ||||
-rw-r--r-- | components/nonzero/lib.rs | 135 | ||||
-rw-r--r-- | components/remutex/lib.rs | 10 | ||||
-rw-r--r-- | components/script_layout_interface/lib.rs | 6 |
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)] |