diff options
Diffstat (limited to 'components/layout/flow.rs')
-rw-r--r-- | components/layout/flow.rs | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/components/layout/flow.rs b/components/layout/flow.rs index fbcf7866931..990e29e0238 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -44,7 +44,7 @@ use multicol::MulticolFlow; use parallel::FlowParallelInfo; use serde::ser::{Serialize, SerializeStruct, Serializer}; use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect, max_rect}; -use std::{fmt, mem}; +use std::fmt; use std::iter::Zip; use std::slice::IterMut; use std::sync::Arc; @@ -65,11 +65,19 @@ use table_rowgroup::TableRowGroupFlow; use table_wrapper::TableWrapperFlow; use webrender_api::ClipAndScrollInfo; +/// This marker trait indicates that a type is a struct with `#[repr(C)]` whose first field +/// is of type `BaseFlow` or some type that also implements this trait. +/// +/// In other words, the memory representation of `BaseFlow` must be a prefix +/// of the memory representation of types implementing `HasBaseFlow`. +#[allow(unsafe_code)] +pub unsafe trait HasBaseFlow {} + /// Virtual methods that make up a float context. /// /// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding /// methods to `ImmutableFlowUtils` or `MutableFlowUtils` before adding more methods here. -pub trait Flow: fmt::Debug + Sync + Send + 'static { +pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static { // RTTI // // TODO(pcwalton): Use Rust's RTTI, once that works. @@ -451,11 +459,10 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static { #[inline(always)] #[allow(unsafe_code)] -pub fn base<T: ?Sized + Flow>(this: &T) -> &BaseFlow { - unsafe { - let obj = mem::transmute::<&&T, &::TraitObject>(&this); - mem::transmute::<*mut (), &BaseFlow>(obj.data) - } +pub fn base<T: ?Sized + HasBaseFlow>(this: &T) -> &BaseFlow { + let ptr: *const T = this; + let ptr = ptr as *const BaseFlow; + unsafe { &*ptr } } /// Iterates over the children of this immutable flow. @@ -465,11 +472,10 @@ pub fn child_iter<'a>(flow: &'a Flow) -> FlowListIterator { #[inline(always)] #[allow(unsafe_code)] -pub fn mut_base<T: ?Sized + Flow>(this: &mut T) -> &mut BaseFlow { - unsafe { - let obj = mem::transmute::<&&mut T, &::TraitObject>(&this); - mem::transmute::<*mut (), &mut BaseFlow>(obj.data) - } +pub fn mut_base<T: ?Sized + HasBaseFlow>(this: &mut T) -> &mut BaseFlow { + let ptr: *mut T = this; + let ptr = ptr as *mut BaseFlow; + unsafe { &mut *ptr } } /// Iterates over the children of this flow. @@ -1419,11 +1425,9 @@ impl ContainingBlockLink { pub struct OpaqueFlow(pub usize); impl OpaqueFlow { - #[allow(unsafe_code)] pub fn from_flow(flow: &Flow) -> OpaqueFlow { - unsafe { - let object = mem::transmute::<&Flow, ::TraitObject>(flow); - OpaqueFlow(object.data as usize) - } + let object_ptr: *const Flow = flow; + let data_ptr = object_ptr as *const (); + OpaqueFlow(data_ptr as usize) } } |