aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs4
-rw-r--r--components/layout/flex.rs4
-rw-r--r--components/layout/flow.rs38
-rw-r--r--components/layout/inline.rs4
-rw-r--r--components/layout/lib.rs9
-rw-r--r--components/layout/list_item.rs4
-rw-r--r--components/layout/multicol.rs8
-rw-r--r--components/layout/table.rs4
-rw-r--r--components/layout/table_caption.rs4
-rw-r--r--components/layout/table_cell.rs4
-rw-r--r--components/layout/table_colgroup.rs4
-rw-r--r--components/layout/table_row.rs4
-rw-r--r--components/layout/table_rowgroup.rs4
-rw-r--r--components/layout/table_wrapper.rs4
-rw-r--r--components/script/dom/element.rs3
-rw-r--r--tests/unit/layout/lib.rs29
16 files changed, 74 insertions, 57 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index c7f675293d3..bffcbef0e67 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -492,8 +492,12 @@ pub enum FormattingContextType {
Other,
}
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for BlockFlow {}
+
// A block formatting context.
#[derive(Serialize)]
+#[repr(C)]
pub struct BlockFlow {
/// Data common to all flows.
pub base: BaseFlow,
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 063add9e1d5..6d969ef8643 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -328,8 +328,12 @@ impl FlexLine {
}
}
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for FlexFlow {}
+
/// A block with the CSS `display` property equal to `flex`.
#[derive(Debug, Serialize)]
+#[repr(C)]
pub struct FlexFlow {
/// Data common to all block flows.
block_flow: BlockFlow,
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)
}
}
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index e04ede22470..e6f23afae8f 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -861,8 +861,12 @@ impl InlineFragments {
}
}
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for InlineFlow {}
+
/// Flows for inline layout.
#[derive(Serialize)]
+#[repr(C)]
pub struct InlineFlow {
/// Data common to all flows.
pub base: BaseFlow,
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index 1e48a2b5a6d..f9c3cbeda2b 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -90,12 +90,3 @@ pub use self::data::LayoutData;
// We can't use servo_arc for everything in layout, because the Flow stuff uses
// weak references.
use servo_arc::Arc as ServoArc;
-
-/// Stable copy of std::raw::TraitObject
-/// test/unit/layout/lib.rs asserts that the memory layout matches.
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct TraitObject {
- pub data: *mut (),
- pub vtable: *mut (),
-}
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 969d82b7fd7..270d15b3771 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -24,8 +24,12 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for ListItemFlow {}
+
/// A block with the CSS `display` property equal to `list-item`.
#[derive(Debug)]
+#[repr(C)]
pub struct ListItemFlow {
/// Data common to all block flows.
pub block_flow: BlockFlow,
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
index 2cb181f1f97..7b811e38772 100644
--- a/components/layout/multicol.rs
+++ b/components/layout/multicol.rs
@@ -24,6 +24,10 @@ use style::properties::ComputedValues;
use style::values::Either;
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for MulticolFlow {}
+
+#[repr(C)]
pub struct MulticolFlow {
pub block_flow: BlockFlow,
@@ -32,6 +36,10 @@ pub struct MulticolFlow {
pub column_pitch: Au,
}
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for MulticolColumnFlow {}
+
+#[repr(C)]
pub struct MulticolColumnFlow {
pub block_flow: BlockFlow,
}
diff --git a/components/layout/table.rs b/components/layout/table.rs
index a0c7c69ce85..7009e4ec60b 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -34,10 +34,14 @@ use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderP
use table_row::TableRowFlow;
use table_wrapper::TableLayout;
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableFlow {}
+
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
/// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
/// not table fragment per CSS 2.1 § 10.5.
#[derive(Serialize)]
+#[repr(C)]
pub struct TableFlow {
pub block_flow: BlockFlow,
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index ecdd52784ee..c6425e93b4e 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -19,7 +19,11 @@ use std::fmt;
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableCaptionFlow {}
+
/// A table formatting context.
+#[repr(C)]
pub struct TableCaptionFlow {
pub block_flow: BlockFlow,
}
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 1c04b327904..c6c438204cf 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -28,8 +28,12 @@ use style::values::generics::box_::VerticalAlign;
use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance};
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableCellFlow {}
+
/// A table formatting context.
#[derive(Serialize)]
+#[repr(C)]
pub struct TableCellFlow {
/// Data common to all block flows.
pub block_flow: BlockFlow,
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 4d54afbe386..4b6af989e25 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -19,7 +19,11 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::values::computed::LengthOrPercentageOrAuto;
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableColGroupFlow {}
+
/// A table formatting context.
+#[repr(C)]
pub struct TableColGroupFlow {
/// Data common to all flows.
pub base: BaseFlow,
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 5a835d0ded2..761a363881a 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -31,7 +31,11 @@ use style::values::computed::{Color, LengthOrPercentageOrAuto};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableRowFlow {}
+
/// A single row of a table.
+#[repr(C)]
pub struct TableRowFlow {
/// Fields common to all block flows.
pub block_flow: BlockFlow,
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index 6877ba8b781..0639f02dbf5 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -24,7 +24,11 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use table::{ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableRowGroupFlow {}
+
/// A table formatting context.
+#[repr(C)]
pub struct TableRowGroupFlow {
/// Fields common to all block flows.
pub block_flow: BlockFlow,
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index 972f5299094..866916b9ad5 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -43,8 +43,12 @@ pub enum TableLayout {
Auto
}
+#[allow(unsafe_code)]
+unsafe impl ::flow::HasBaseFlow for TableWrapperFlow {}
+
/// A table wrapper flow based on a block formatting context.
#[derive(Serialize)]
+#[repr(C)]
pub struct TableWrapperFlow {
pub block_flow: BlockFlow,
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index ee5682b561a..f6e5357df10 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -89,9 +89,8 @@ use script_layout_interface::message::ReflowGoal;
use script_thread::ScriptThread;
use selectors::Element as SelectorsElement;
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
-use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode};
+use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, RelevantLinkStatus};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
-use selectors::matching::{RelevantLinkStatus, matches_selector_list};
use selectors::sink::Push;
use servo_arc::Arc;
use servo_atoms::Atom;
diff --git a/tests/unit/layout/lib.rs b/tests/unit/layout/lib.rs
index bc1d9dfd464..a763135260a 100644
--- a/tests/unit/layout/lib.rs
+++ b/tests/unit/layout/lib.rs
@@ -2,36 +2,7 @@
* 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(raw)]
-
extern crate layout;
#[macro_use] extern crate size_of_test;
#[cfg(all(test, target_pointer_width = "64"))] mod size_of;
-
-use std::mem;
-use std::ptr;
-use std::raw;
-
-#[test]
-fn test_trait_object_layout() {
- assert_eq!(mem::size_of::<raw::TraitObject>(), mem::size_of::<layout::TraitObject>());
- let null: *mut () = ptr::null_mut();
- let a = raw::TraitObject {
- data: null,
- vtable: null,
- };
- let b = layout::TraitObject {
- data: null,
- vtable: null,
- };
-
- fn offset<T, U>(struct_: &T, field: &U) -> usize {
- let addr_struct = struct_ as *const T as usize;
- let addr_field = field as *const U as usize;
- addr_field - addr_struct
- }
-
- assert_eq!(offset(&a, &a.data), offset(&b, &b.data));
- assert_eq!(offset(&a, &a.vtable), offset(&b, &b.vtable));
-}