Introduce an unsafe HasBaseFlow trait for base()/base_mut() casts.

This commit is contained in:
Simon Sapin 2017-10-14 00:03:57 +02:00
parent 4c5d6fd834
commit b505c9e948
13 changed files with 63 additions and 3 deletions

View file

@ -492,8 +492,12 @@ pub enum FormattingContextType {
Other, Other,
} }
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for BlockFlow {}
// A block formatting context. // A block formatting context.
#[derive(Serialize)] #[derive(Serialize)]
#[repr(C)]
pub struct BlockFlow { pub struct BlockFlow {
/// Data common to all flows. /// Data common to all flows.
pub base: BaseFlow, pub base: BaseFlow,

View file

@ -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`. /// A block with the CSS `display` property equal to `flex`.
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[repr(C)]
pub struct FlexFlow { pub struct FlexFlow {
/// Data common to all block flows. /// Data common to all block flows.
block_flow: BlockFlow, block_flow: BlockFlow,

View file

@ -65,11 +65,19 @@ use table_rowgroup::TableRowGroupFlow;
use table_wrapper::TableWrapperFlow; use table_wrapper::TableWrapperFlow;
use webrender_api::ClipAndScrollInfo; 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. /// Virtual methods that make up a float context.
/// ///
/// Note that virtual methods have a cost; we should not overuse them in Servo. Consider adding /// 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. /// 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 // RTTI
// //
// TODO(pcwalton): Use Rust's RTTI, once that works. // TODO(pcwalton): Use Rust's RTTI, once that works.
@ -451,7 +459,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
#[inline(always)] #[inline(always)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn base<T: ?Sized + Flow>(this: &T) -> &BaseFlow { pub fn base<T: ?Sized + HasBaseFlow>(this: &T) -> &BaseFlow {
let ptr: *const T = this; let ptr: *const T = this;
let ptr = ptr as *const BaseFlow; let ptr = ptr as *const BaseFlow;
unsafe { &*ptr } unsafe { &*ptr }
@ -464,7 +472,7 @@ pub fn child_iter<'a>(flow: &'a Flow) -> FlowListIterator {
#[inline(always)] #[inline(always)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub fn mut_base<T: ?Sized + Flow>(this: &mut T) -> &mut BaseFlow { pub fn mut_base<T: ?Sized + HasBaseFlow>(this: &mut T) -> &mut BaseFlow {
let ptr: *mut T = this; let ptr: *mut T = this;
let ptr = ptr as *mut BaseFlow; let ptr = ptr as *mut BaseFlow;
unsafe { &mut *ptr } unsafe { &mut *ptr }

View file

@ -861,8 +861,12 @@ impl InlineFragments {
} }
} }
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for InlineFlow {}
/// Flows for inline layout. /// Flows for inline layout.
#[derive(Serialize)] #[derive(Serialize)]
#[repr(C)]
pub struct InlineFlow { pub struct InlineFlow {
/// Data common to all flows. /// Data common to all flows.
pub base: BaseFlow, pub base: BaseFlow,

View file

@ -24,8 +24,12 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT; 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`. /// A block with the CSS `display` property equal to `list-item`.
#[derive(Debug)] #[derive(Debug)]
#[repr(C)]
pub struct ListItemFlow { pub struct ListItemFlow {
/// Data common to all block flows. /// Data common to all block flows.
pub block_flow: BlockFlow, pub block_flow: BlockFlow,

View file

@ -24,6 +24,10 @@ use style::properties::ComputedValues;
use style::values::Either; use style::values::Either;
use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone}; use style::values::computed::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for MulticolFlow {}
#[repr(C)]
pub struct MulticolFlow { pub struct MulticolFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,
@ -32,6 +36,10 @@ pub struct MulticolFlow {
pub column_pitch: Au, pub column_pitch: Au,
} }
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for MulticolColumnFlow {}
#[repr(C)]
pub struct MulticolColumnFlow { pub struct MulticolColumnFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,
} }

View file

@ -34,10 +34,14 @@ use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderP
use table_row::TableRowFlow; use table_row::TableRowFlow;
use table_wrapper::TableLayout; 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. /// 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, /// The properties `position`, `float`, and `margin-*` are used on the table wrapper fragment,
/// not table fragment per CSS 2.1 § 10.5. /// not table fragment per CSS 2.1 § 10.5.
#[derive(Serialize)] #[derive(Serialize)]
#[repr(C)]
pub struct TableFlow { pub struct TableFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,

View file

@ -19,7 +19,11 @@ use std::fmt;
use style::logical_geometry::LogicalSize; use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableCaptionFlow {}
/// A table formatting context. /// A table formatting context.
#[repr(C)]
pub struct TableCaptionFlow { pub struct TableCaptionFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,
} }

View file

@ -28,8 +28,12 @@ use style::values::generics::box_::VerticalAlign;
use table::InternalTable; use table::InternalTable;
use table_row::{CollapsedBorder, CollapsedBorderProvenance}; use table_row::{CollapsedBorder, CollapsedBorderProvenance};
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableCellFlow {}
/// A table formatting context. /// A table formatting context.
#[derive(Serialize)] #[derive(Serialize)]
#[repr(C)]
pub struct TableCellFlow { pub struct TableCellFlow {
/// Data common to all block flows. /// Data common to all block flows.
pub block_flow: BlockFlow, pub block_flow: BlockFlow,

View file

@ -19,7 +19,11 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::LengthOrPercentageOrAuto; use style::values::computed::LengthOrPercentageOrAuto;
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableColGroupFlow {}
/// A table formatting context. /// A table formatting context.
#[repr(C)]
pub struct TableColGroupFlow { pub struct TableColGroupFlow {
/// Data common to all flows. /// Data common to all flows.
pub base: BaseFlow, pub base: BaseFlow,

View file

@ -31,7 +31,11 @@ use style::values::computed::{Color, LengthOrPercentageOrAuto};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt}; use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow}; use table_cell::{CollapsedBordersForCell, TableCellFlow};
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableRowFlow {}
/// A single row of a table. /// A single row of a table.
#[repr(C)]
pub struct TableRowFlow { pub struct TableRowFlow {
/// Fields common to all block flows. /// Fields common to all block flows.
pub block_flow: BlockFlow, pub block_flow: BlockFlow,

View file

@ -24,7 +24,11 @@ use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use table::{ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow}; use table::{ColumnIntrinsicInlineSize, InternalTable, TableLikeFlow};
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableRowGroupFlow {}
/// A table formatting context. /// A table formatting context.
#[repr(C)]
pub struct TableRowGroupFlow { pub struct TableRowGroupFlow {
/// Fields common to all block flows. /// Fields common to all block flows.
pub block_flow: BlockFlow, pub block_flow: BlockFlow,

View file

@ -43,8 +43,12 @@ pub enum TableLayout {
Auto Auto
} }
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for TableWrapperFlow {}
/// A table wrapper flow based on a block formatting context. /// A table wrapper flow based on a block formatting context.
#[derive(Serialize)] #[derive(Serialize)]
#[repr(C)]
pub struct TableWrapperFlow { pub struct TableWrapperFlow {
pub block_flow: BlockFlow, pub block_flow: BlockFlow,