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,
}
#[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,

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`.
#[derive(Debug, Serialize)]
#[repr(C)]
pub struct FlexFlow {
/// Data common to all block flows.
block_flow: BlockFlow,

View file

@ -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,7 +459,7 @@ pub trait Flow: fmt::Debug + Sync + Send + 'static {
#[inline(always)]
#[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 = ptr as *const BaseFlow;
unsafe { &*ptr }
@ -464,7 +472,7 @@ 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 {
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 }

View file

@ -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,

View file

@ -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,

View file

@ -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,
}

View file

@ -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,

View file

@ -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,
}

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,