aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/style/gecko_values.rs96
-rw-r--r--components/style/properties/gecko.mako.rs69
-rw-r--r--ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs338
-rwxr-xr-xports/geckolib/gecko_bindings/tools/regen.py10
4 files changed, 299 insertions, 214 deletions
diff --git a/components/style/gecko_values.rs b/components/style/gecko_values.rs
index 1fef6e4c496..efbcb7db93e 100644
--- a/components/style/gecko_values.rs
+++ b/components/style/gecko_values.rs
@@ -7,120 +7,114 @@
use app_units::Au;
use cssparser::RGBA;
use gecko_bindings::structs::nsStyleCoord;
-use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataValues};
+use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use std::cmp::max;
use values::computed::Angle;
use values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
pub trait StyleCoordHelpers {
- fn copy_from(&mut self, other: &Self);
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T);
}
impl StyleCoordHelpers for nsStyleCoord {
#[inline]
- fn copy_from(&mut self, other: &Self) {
- self.data().copy_from(&other.data())
- }
-
- #[inline]
fn set<T: GeckoStyleCoordConvertible>(&mut self, val: T) {
- val.to_gecko_style_coord(&mut self.data());
+ val.to_gecko_style_coord(self);
}
}
pub trait GeckoStyleCoordConvertible : Sized {
- fn to_gecko_style_coord(&self, coord: &mut CoordData);
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self>;
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T);
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>;
}
impl GeckoStyleCoordConvertible for LengthOrPercentage {
- fn to_gecko_style_coord(&self, coord: &mut CoordData) {
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
- LengthOrPercentage::Length(au) => CoordDataValues::Coord(au.0),
- LengthOrPercentage::Percentage(p) => CoordDataValues::Percent(p),
- LengthOrPercentage::Calc(calc) => CoordDataValues::Calc(calc.into()),
+ LengthOrPercentage::Length(au) => CoordDataValue::Coord(au.0),
+ LengthOrPercentage::Percentage(p) => CoordDataValue::Percent(p),
+ LengthOrPercentage::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
- coord.set_enum(value);
+ coord.set_value(value);
}
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
- match coord.as_enum() {
- CoordDataValues::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
- CoordDataValues::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
- CoordDataValues::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ match coord.as_value() {
+ CoordDataValue::Coord(coord) => Some(LengthOrPercentage::Length(Au(coord))),
+ CoordDataValue::Percent(p) => Some(LengthOrPercentage::Percentage(p)),
+ CoordDataValue::Calc(calc) => Some(LengthOrPercentage::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto {
- fn to_gecko_style_coord(&self, coord: &mut CoordData) {
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
- LengthOrPercentageOrAuto::Length(au) => CoordDataValues::Coord(au.0),
- LengthOrPercentageOrAuto::Percentage(p) => CoordDataValues::Percent(p),
- LengthOrPercentageOrAuto::Auto => CoordDataValues::Auto,
- LengthOrPercentageOrAuto::Calc(calc) => CoordDataValues::Calc(calc.into()),
+ LengthOrPercentageOrAuto::Length(au) => CoordDataValue::Coord(au.0),
+ LengthOrPercentageOrAuto::Percentage(p) => CoordDataValue::Percent(p),
+ LengthOrPercentageOrAuto::Auto => CoordDataValue::Auto,
+ LengthOrPercentageOrAuto::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
- coord.set_enum(value);
+ coord.set_value(value);
}
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
- match coord.as_enum() {
- CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
- CoordDataValues::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
- CoordDataValues::Auto => Some(LengthOrPercentageOrAuto::Auto),
- CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ match coord.as_value() {
+ CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrAuto::Length(Au(coord))),
+ CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(p)),
+ CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto),
+ CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())),
_ => None,
}
}
}
impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone {
- fn to_gecko_style_coord(&self, coord: &mut CoordData) {
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
let value = match *self {
- LengthOrPercentageOrNone::Length(au) => CoordDataValues::Coord(au.0),
- LengthOrPercentageOrNone::Percentage(p) => CoordDataValues::Percent(p),
- LengthOrPercentageOrNone::None => CoordDataValues::None,
- LengthOrPercentageOrNone::Calc(calc) => CoordDataValues::Calc(calc.into()),
+ LengthOrPercentageOrNone::Length(au) => CoordDataValue::Coord(au.0),
+ LengthOrPercentageOrNone::Percentage(p) => CoordDataValue::Percent(p),
+ LengthOrPercentageOrNone::None => CoordDataValue::None,
+ LengthOrPercentageOrNone::Calc(calc) => CoordDataValue::Calc(calc.into()),
};
- coord.set_enum(value);
+ coord.set_value(value);
}
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
- match coord.as_enum() {
- CoordDataValues::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
- CoordDataValues::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
- CoordDataValues::None => Some(LengthOrPercentageOrNone::None),
- CoordDataValues::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ match coord.as_value() {
+ CoordDataValue::Coord(coord) => Some(LengthOrPercentageOrNone::Length(Au(coord))),
+ CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(p)),
+ CoordDataValue::None => Some(LengthOrPercentageOrNone::None),
+ CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())),
_ => None,
}
}
}
impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> {
- fn to_gecko_style_coord(&self, coord: &mut CoordData) {
+ fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) {
if let Some(ref me) = *self {
me.to_gecko_style_coord(coord);
} else {
- coord.set_enum(CoordDataValues::None);
+ coord.set_value(CoordDataValue::None);
}
}
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
+ fn from_gecko_style_coord<U: CoordData>(coord: &U) -> Option<Self> {
Some(T::from_gecko_style_coord(coord))
}
}
impl GeckoStyleCoordConvertible for Angle {
- fn to_gecko_style_coord(&self, coord: &mut CoordData) {
- coord.set_enum(CoordDataValues::Radian(self.radians()))
+ fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) {
+ coord.set_value(CoordDataValue::Radian(self.radians()))
}
- fn from_gecko_style_coord(coord: &CoordData) -> Option<Self> {
- if let CoordDataValues::Radian(r) = coord.as_enum() {
+ fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> {
+ if let CoordDataValue::Radian(r) = coord.as_value() {
Some(Angle::from_radians(r))
// XXXManishearth should this handle Degree too?
} else {
diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs
index 264fef07cd5..2209651b18b 100644
--- a/components/style/properties/gecko.mako.rs
+++ b/components/style/properties/gecko.mako.rs
@@ -26,7 +26,7 @@ use gecko_bindings::bindings::{Gecko_FontFamilyList_AppendGeneric, Gecko_FontFam
use gecko_bindings::bindings::{Gecko_FontFamilyList_Clear, Gecko_InitializeImageLayer};
use gecko_bindings::bindings;
use gecko_bindings::structs;
-use gecko_bindings::sugar::ns_style_coord::CoordDataValues;
+use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use gecko_glue::ArcHelpers;
use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba};
use gecko_values::convert_rgba_to_nscolor;
@@ -329,11 +329,11 @@ def set_gecko_property(ffi_name, expr):
<%def name="impl_split_style_coord(ident, gecko_ffi_name, index, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
- v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${index}));
+ v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${index}));
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
- self.gecko.${gecko_ffi_name}.data_at(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
+ self.gecko.${gecko_ffi_name}.data_at_mut(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index}));
}
% if need_clone:
#[allow(non_snake_case)]
@@ -348,17 +348,17 @@ def set_gecko_property(ffi_name, expr):
<%def name="impl_style_coord(ident, gecko_ffi_name, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
- v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data());
+ v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name});
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
- self.gecko.${gecko_ffi_name}.data().copy_from(&other.gecko.${gecko_ffi_name}.data());
+ self.gecko.${gecko_ffi_name}.copy_from(&other.gecko.${gecko_ffi_name});
}
% if need_clone:
#[allow(non_snake_case)]
pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T {
use properties::longhands::${ident}::computed_value::T;
- T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data())
+ T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name})
.expect("clone for ${ident} failed")
}
% endif
@@ -367,13 +367,15 @@ def set_gecko_property(ffi_name, expr):
<%def name="impl_corner_style_coord(ident, gecko_ffi_name, x_index, y_index, need_clone=False)">
#[allow(non_snake_case)]
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
- v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${x_index}));
- v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${y_index}));
+ v.0.width.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${x_index}));
+ v.0.height.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at_mut(${y_index}));
}
#[allow(non_snake_case)]
pub fn copy_${ident}_from(&mut self, other: &Self) {
- self.gecko.${gecko_ffi_name}.data_at(${x_index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${x_index}));
- self.gecko.${gecko_ffi_name}.data_at(${x_index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${y_index}));
+ self.gecko.${gecko_ffi_name}.data_at_mut(${x_index})
+ .copy_from(&other.gecko.${gecko_ffi_name}.data_at(${x_index}));
+ self.gecko.${gecko_ffi_name}.data_at_mut(${y_index})
+ .copy_from(&other.gecko.${gecko_ffi_name}.data_at(${y_index}));
}
% if need_clone:
#[allow(non_snake_case)]
@@ -646,8 +648,8 @@ fn static_assert() {
pub fn set_z_index(&mut self, v: longhands::z_index::computed_value::T) {
use properties::longhands::z_index::computed_value::T;
match v {
- T::Auto => self.gecko.mZIndex.data().set_enum(CoordDataValues::Auto),
- T::Number(n) => self.gecko.mZIndex.data().set_enum(CoordDataValues::Integer(n)),
+ T::Auto => self.gecko.mZIndex.set_value(CoordDataValue::Auto),
+ T::Number(n) => self.gecko.mZIndex.set_value(CoordDataValue::Integer(n)),
}
}
@@ -662,9 +664,9 @@ fn static_assert() {
pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T {
use properties::longhands::z_index::computed_value::T;
- return match self.gecko.mZIndex.data().as_enum() {
- CoordDataValues::Auto => T::Auto,
- CoordDataValues::Integer(n) => T::Number(n),
+ return match self.gecko.mZIndex.as_value() {
+ CoordDataValue::Auto => T::Auto,
+ CoordDataValue::Integer(n) => T::Number(n),
_ => {
debug_assert!(false);
T::Number(0)
@@ -824,8 +826,8 @@ fn static_assert() {
match v {
% for value in keyword.values_for('gecko'):
T::${to_rust_ident(value)} =>
- self.gecko.mVerticalAlign.data().set_enum(
- CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)})),
+ self.gecko.mVerticalAlign.set_value(
+ CoordDataValue::Enumerated(structs::${keyword.gecko_constant(value)})),
% endfor
T::LengthOrPercentage(v) => self.gecko.mVerticalAlign.set(v),
}
@@ -835,14 +837,13 @@ fn static_assert() {
use properties::longhands::vertical_align::computed_value::T;
use values::computed::LengthOrPercentage;
- let data = self.gecko.mVerticalAlign.data();
- match data.as_enum() {
+ match self.gecko.mVerticalAlign.as_value() {
% for value in keyword.values_for('gecko'):
- CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)},
+ CoordDataValue::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)},
% endfor
- CoordDataValues::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"),
+ CoordDataValue::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"),
_ => {
- let v = LengthOrPercentage::from_gecko_style_coord(&data)
+ let v = LengthOrPercentage::from_gecko_style_coord(&self.gecko.mVerticalAlign)
.expect("Expected length or percentage for vertical-align");
T::LengthOrPercentage(v)
}
@@ -1130,22 +1131,22 @@ fn static_assert() {
use properties::longhands::line_height::computed_value::T;
// FIXME: Align binary representations and ditch |match| for cast + static_asserts
let en = match v {
- T::Normal => CoordDataValues::Normal,
- T::Length(val) => CoordDataValues::Coord(val.0),
- T::Number(val) => CoordDataValues::Factor(val),
+ T::Normal => CoordDataValue::Normal,
+ T::Length(val) => CoordDataValue::Coord(val.0),
+ T::Number(val) => CoordDataValue::Factor(val),
T::MozBlockHeight =>
- CoordDataValues::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
+ CoordDataValue::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT),
};
- self.gecko.mLineHeight.data().set_enum(en);
+ self.gecko.mLineHeight.set_value(en);
}
pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T {
use properties::longhands::line_height::computed_value::T;
- return match self.gecko.mLineHeight.data().as_enum() {
- CoordDataValues::Normal => T::Normal,
- CoordDataValues::Coord(coord) => T::Length(Au(coord)),
- CoordDataValues::Factor(n) => T::Number(n),
- CoordDataValues::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
+ return match self.gecko.mLineHeight.as_value() {
+ CoordDataValue::Normal => T::Normal,
+ CoordDataValue::Coord(coord) => T::Length(Au(coord)),
+ CoordDataValue::Factor(n) => T::Number(n),
+ CoordDataValue::Enumerated(val) if val == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT =>
T::MozBlockHeight,
_ => {
debug_assert!(false);
@@ -1280,8 +1281,8 @@ fn static_assert() {
pub fn set_column_width(&mut self, v: longhands::column_width::computed_value::T) {
match v.0 {
- Some(au) => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Coord(au.0)),
- None => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Auto),
+ Some(au) => self.gecko.mColumnWidth.set_value(CoordDataValue::Coord(au.0)),
+ None => self.gecko.mColumnWidth.set_value(CoordDataValue::Auto),
}
}
diff --git a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
index e17570039fb..33dff1a705d 100644
--- a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
+++ b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs
@@ -4,53 +4,131 @@
use bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread};
use std::mem::transmute;
-use std::marker::PhantomData;
use structs::{nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord, nsStyleSides, nsStyleCorners};
use structs::{nsStyleCoord_CalcValue, nscoord};
-impl nsStyleCoord {
+impl CoordData for nsStyleCoord {
#[inline]
- pub unsafe fn addref_if_calc(&mut self) {
- self.data().addref_if_calc();
+ fn unit(&self) -> nsStyleUnit {
+ self.mUnit
}
-
#[inline]
- pub fn data(&self) -> CoordData {
- CoordData {
- union: &self.mValue as *const _ as *mut _,
- unit: &self.mUnit as *const _ as *mut _,
- _marker: PhantomData,
- }
+ fn union(&self) -> nsStyleUnion {
+ self.mValue
+ }
+}
+
+impl CoordDataMut for nsStyleCoord {
+ unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
+ (&mut self.mUnit, &mut self.mValue)
}
}
impl nsStyleSides {
#[inline]
- pub fn data_at(&self, index: usize) -> CoordData {
- CoordData {
- union: &self.mValues[index] as *const _ as *mut _,
- unit: &self.mUnits[index] as *const _ as *mut _,
- _marker: PhantomData,
+ pub fn data_at(&self, index: usize) -> SidesData {
+ SidesData {
+ sides: self,
+ index: index,
}
}
+ #[inline]
+ pub fn data_at_mut(&mut self, index: usize) -> SidesDataMut {
+ SidesDataMut {
+ sides: self,
+ index: index,
+ }
+ }
+}
+
+pub struct SidesData<'a> {
+ sides: &'a nsStyleSides,
+ index: usize,
+}
+pub struct SidesDataMut<'a> {
+ sides: &'a mut nsStyleSides,
+ index: usize,
+}
+
+impl<'a> CoordData for SidesData<'a> {
+ #[inline]
+ fn unit(&self) -> nsStyleUnit {
+ self.sides.mUnits[self.index]
+ }
+ #[inline]
+ fn union(&self) -> nsStyleUnion {
+ self.sides.mValues[self.index]
+ }
+}
+impl<'a> CoordData for SidesDataMut<'a> {
+ #[inline]
+ fn unit(&self) -> nsStyleUnit {
+ self.sides.mUnits[self.index]
+ }
+ #[inline]
+ fn union(&self) -> nsStyleUnion {
+ self.sides.mValues[self.index]
+ }
+}
+impl<'a> CoordDataMut for SidesDataMut<'a> {
+ unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
+ (&mut self.sides.mUnits[self.index], &mut self.sides.mValues[self.index])
+ }
}
impl nsStyleCorners {
#[inline]
- pub fn data_at(&self, index: usize) -> CoordData {
- CoordData {
- union: &self.mValues[index] as *const _ as *mut _,
- unit: &self.mUnits[index] as *const _ as *mut _,
- _marker: PhantomData,
+ pub fn data_at(&self, index: usize) -> CornersData {
+ CornersData {
+ corners: self,
+ index: index,
+ }
+ }
+ #[inline]
+ pub fn data_at_mut(&mut self, index: usize) -> CornersDataMut {
+ CornersDataMut {
+ corners: self,
+ index: index,
}
}
}
+pub struct CornersData<'a> {
+ corners: &'a nsStyleCorners,
+ index: usize,
+}
+pub struct CornersDataMut<'a> {
+ corners: &'a mut nsStyleCorners,
+ index: usize,
+}
+
+impl<'a> CoordData for CornersData<'a> {
+ fn unit(&self) -> nsStyleUnit {
+ self.corners.mUnits[self.index]
+ }
+ fn union(&self) -> nsStyleUnion {
+ self.corners.mValues[self.index]
+ }
+}
+impl<'a> CoordData for CornersDataMut<'a> {
+ fn unit(&self) -> nsStyleUnit {
+ self.corners.mUnits[self.index]
+ }
+ fn union(&self) -> nsStyleUnion {
+ self.corners.mValues[self.index]
+ }
+}
+impl<'a> CoordDataMut for CornersDataMut<'a> {
+ unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion) {
+ (&mut self.corners.mUnits[self.index], &mut self.corners.mValues[self.index])
+ }
+}
+
#[derive(Copy, Clone)]
-/// Enum representing the tagged union that is CoordData
+/// Enum representing the tagged union that is CoordData.
/// In release mode this should never actually exist in the code,
-/// and will be optimized out by threading matches and inlining
-pub enum CoordDataValues {
+/// and will be optimized out by threading matches and inlining.
+pub enum CoordDataValue {
Null,
Normal,
Auto,
@@ -68,182 +146,188 @@ pub enum CoordDataValues {
Calc(nsStyleCoord_CalcValue),
}
-/// XXXManishearth should this be using Cell/UnsafeCell?
-pub struct CoordData<'a> {
- union: *mut nsStyleUnion,
- unit: *mut nsStyleUnit,
- _marker: PhantomData<&'a mut ()>,
-}
-impl<'a> CoordData<'a> {
+pub trait CoordDataMut : CoordData {
+ // This can't be two methods since we can't mutably borrow twice
+ /// This is unsafe since it's possible to modify
+ /// the unit without changing the union
+ unsafe fn values_mut(&mut self) -> (&mut nsStyleUnit, &mut nsStyleUnion);
+
/// Clean up any resources used by the union
/// Currently, this only happens if the nsStyleUnit
/// is a Calc
#[inline]
- pub fn reset(&mut self) {
+ fn reset(&mut self) {
unsafe {
- if *self.unit == nsStyleUnit::eStyleUnit_Calc {
- Gecko_ResetStyleCoord(self.unit, self.union);
+ if self.unit() == nsStyleUnit::eStyleUnit_Calc {
+ let (unit, union) = self.values_mut();
+ Gecko_ResetStyleCoord(unit, union);
}
}
}
#[inline]
- pub fn copy_from(&mut self, other: &CoordData) {
- self.reset();
- self.unit = other.unit;
- self.union = other.union;
- self.addref_if_calc();
- }
-
- #[inline(always)]
- pub fn as_enum(&self) -> CoordDataValues {
- use self::CoordDataValues::*;
- use structs::nsStyleUnit::*;
+ fn copy_from<T: CoordData>(&mut self, other: &T) {
unsafe {
- match *self.unit {
- eStyleUnit_Null => Null,
- eStyleUnit_Normal => Normal,
- eStyleUnit_Auto => Auto,
- eStyleUnit_None => None,
- eStyleUnit_Percent => Percent(self.get_float()),
- eStyleUnit_Factor => Factor(self.get_float()),
- eStyleUnit_Degree => Degree(self.get_float()),
- eStyleUnit_Grad => Grad(self.get_float()),
- eStyleUnit_Radian => Radian(self.get_float()),
- eStyleUnit_Turn => Turn(self.get_float()),
- eStyleUnit_FlexFraction => FlexFraction(self.get_float()),
- eStyleUnit_Coord => Coord(self.get_integer()),
- eStyleUnit_Integer => Integer(self.get_integer()),
- eStyleUnit_Enumerated => Enumerated(self.get_integer() as u32),
- eStyleUnit_Calc => Calc(self.get_calc()),
+ self.reset();
+ {
+ let (unit, union) = self.values_mut();
+ *unit = other.unit();
+ *union = other.union();
}
+ self.addref_if_calc();
}
}
#[inline(always)]
- pub fn set_enum(&mut self, value: CoordDataValues) {
- use self::CoordDataValues::*;
+ fn set_value(&mut self, value: CoordDataValue) {
+ use self::CoordDataValue::*;
use structs::nsStyleUnit::*;
self.reset();
unsafe {
+ let (unit, union) = self.values_mut();
match value {
Null => {
- *self.unit = eStyleUnit_Null;
- *(*self.union).mInt.as_mut() = 0;
+ *unit = eStyleUnit_Null;
+ *union.mInt.as_mut() = 0;
}
Normal => {
- *self.unit = eStyleUnit_Normal;
- *(*self.union).mInt.as_mut() = 0;
+ *unit = eStyleUnit_Normal;
+ *union.mInt.as_mut() = 0;
}
Auto => {
- *self.unit = eStyleUnit_Auto;
- *(*self.union).mInt.as_mut() = 0;
+ *unit = eStyleUnit_Auto;
+ *union.mInt.as_mut() = 0;
}
None => {
- *self.unit = eStyleUnit_None;
- *(*self.union).mInt.as_mut() = 0;
+ *unit = eStyleUnit_None;
+ *union.mInt.as_mut() = 0;
}
Percent(f) => {
- *self.unit = eStyleUnit_Percent;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Percent;
+ *union.mFloat.as_mut() = f;
}
Factor(f) => {
- *self.unit = eStyleUnit_Factor;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Factor;
+ *union.mFloat.as_mut() = f;
}
Degree(f) => {
- *self.unit = eStyleUnit_Degree;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Degree;
+ *union.mFloat.as_mut() = f;
}
Grad(f) => {
- *self.unit = eStyleUnit_Grad;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Grad;
+ *union.mFloat.as_mut() = f;
}
Radian(f) => {
- *self.unit = eStyleUnit_Radian;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Radian;
+ *union.mFloat.as_mut() = f;
}
Turn(f) => {
- *self.unit = eStyleUnit_Turn;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_Turn;
+ *union.mFloat.as_mut() = f;
}
FlexFraction(f) => {
- *self.unit = eStyleUnit_FlexFraction;
- *(*self.union).mFloat.as_mut() = f;
+ *unit = eStyleUnit_FlexFraction;
+ *union.mFloat.as_mut() = f;
}
Coord(coord) => {
- *self.unit = eStyleUnit_Coord;
- *(*self.union).mInt.as_mut() = coord;
+ *unit = eStyleUnit_Coord;
+ *union.mInt.as_mut() = coord;
}
Integer(i) => {
- *self.unit = eStyleUnit_Integer;
- *(*self.union).mInt.as_mut() = i;
+ *unit = eStyleUnit_Integer;
+ *union.mInt.as_mut() = i;
}
Enumerated(i) => {
- *self.unit = eStyleUnit_Enumerated;
- *(*self.union).mInt.as_mut() = i as i32;
+ *unit = eStyleUnit_Enumerated;
+ *union.mInt.as_mut() = i as i32;
}
Calc(calc) => {
- *self.unit = eStyleUnit_Calc;
- self.set_calc_value(calc);
+ // Gecko_SetStyleCoordCalcValue changes the unit internally
+ Gecko_SetStyleCoordCalcValue(unit, union, calc);
}
}
}
}
#[inline]
- /// Pretend inner value is a float; obtain it
- /// While this should usually be called with the unit checked,
- /// it is not an intrinsically unsafe operation to call this function
- /// with the wrong unit
- pub fn get_float(&self) -> f32 {
- unsafe { *(*self.union).mFloat.as_ref() }
+ unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
+ debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
+ transmute(*self.union().mPointer.as_mut() as *mut nsStyleCoord_Calc)
}
#[inline]
- /// Pretend inner value is an int; obtain it
- /// While this should usually be called with the unit checked,
- /// it is not an intrinsically unsafe operation to call this function
- /// with the wrong unit
- pub fn get_integer(&self) -> i32 {
- unsafe { *(*self.union).mInt.as_ref() }
+ fn addref_if_calc(&mut self) {
+ unsafe {
+ if self.unit() == nsStyleUnit::eStyleUnit_Calc {
+ Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
+ }
+ }
}
+}
+pub trait CoordData {
+ fn unit(&self) -> nsStyleUnit;
+ fn union(&self) -> nsStyleUnion;
- #[inline]
- /// Pretend inner value is a calc; obtain it
- /// Ensure that the unit is Calc before calling this
- pub unsafe fn get_calc(&self) -> nsStyleCoord_CalcValue {
- (*self.as_calc())._base
- }
- /// Set internal value to a calc() value
- /// reset() the union before calling this
- #[inline]
- pub fn set_calc_value(&mut self, v: nsStyleCoord_CalcValue) {
+ #[inline(always)]
+ fn as_value(&self) -> CoordDataValue {
+ use self::CoordDataValue::*;
+ use structs::nsStyleUnit::*;
unsafe {
- // Calc should have been cleaned up
- debug_assert!(*self.unit != nsStyleUnit::eStyleUnit_Calc);
- Gecko_SetStyleCoordCalcValue(self.unit, self.union, v);
+ match self.unit() {
+ eStyleUnit_Null => Null,
+ eStyleUnit_Normal => Normal,
+ eStyleUnit_Auto => Auto,
+ eStyleUnit_None => None,
+ eStyleUnit_Percent => Percent(self.get_float()),
+ eStyleUnit_Factor => Factor(self.get_float()),
+ eStyleUnit_Degree => Degree(self.get_float()),
+ eStyleUnit_Grad => Grad(self.get_float()),
+ eStyleUnit_Radian => Radian(self.get_float()),
+ eStyleUnit_Turn => Turn(self.get_float()),
+ eStyleUnit_FlexFraction => FlexFraction(self.get_float()),
+ eStyleUnit_Coord => Coord(self.get_integer()),
+ eStyleUnit_Integer => Integer(self.get_integer()),
+ eStyleUnit_Enumerated => Enumerated(self.get_integer() as u32),
+ eStyleUnit_Calc => Calc(self.get_calc_value()),
+ }
}
}
#[inline]
- pub fn addref_if_calc(&mut self) {
- unsafe {
- if *self.unit == nsStyleUnit::eStyleUnit_Calc {
- Gecko_AddRefCalcArbitraryThread(self.as_calc_mut());
- }
- }
+ /// Pretend inner value is a float; obtain it.
+ unsafe fn get_float(&self) -> f32 {
+ use structs::nsStyleUnit::*;
+ debug_assert!(self.unit() == eStyleUnit_Percent || self.unit() == eStyleUnit_Factor
+ || self.unit() == eStyleUnit_Degree || self.unit() == eStyleUnit_Grad
+ || self.unit() == eStyleUnit_Radian || self.unit() == eStyleUnit_Turn
+ || self.unit() == eStyleUnit_FlexFraction);
+ *self.union().mFloat.as_ref()
}
#[inline]
- unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc {
- transmute(*(*self.union).mPointer.as_mut() as *mut nsStyleCoord_Calc)
+ /// Pretend inner value is an int; obtain it.
+ unsafe fn get_integer(&self) -> i32 {
+ use structs::nsStyleUnit::*;
+ debug_assert!(self.unit() == eStyleUnit_Coord || self.unit() == eStyleUnit_Integer
+ || self.unit() == eStyleUnit_Enumerated);
+ *self.union().mInt.as_ref()
+ }
+
+ #[inline]
+ /// Pretend inner value is a calc; obtain it.
+ /// Ensure that the unit is Calc before calling this.
+ unsafe fn get_calc_value(&self) -> nsStyleCoord_CalcValue {
+ debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
+ (*self.as_calc())._base
}
+
#[inline]
unsafe fn as_calc(&self) -> &nsStyleCoord_Calc {
- transmute(*(*self.union).mPointer.as_ref() as *const nsStyleCoord_Calc)
+ debug_assert!(self.unit() == nsStyleUnit::eStyleUnit_Calc);
+ transmute(*self.union().mPointer.as_ref() as *const nsStyleCoord_Calc)
}
}
diff --git a/ports/geckolib/gecko_bindings/tools/regen.py b/ports/geckolib/gecko_bindings/tools/regen.py
index 4c3d4e5ac9c..c7fd5819b88 100755
--- a/ports/geckolib/gecko_bindings/tools/regen.py
+++ b/ports/geckolib/gecko_bindings/tools/regen.py
@@ -94,7 +94,8 @@ COMPILATION_TARGETS = {
"imgRequestProxy", "imgRequestProxyStatic", "CounterStyleManager",
"ImageValue", "URLValue", "URLValueData", "nsIPrincipal",
"nsDataHashtable", "imgIRequest"
- ]
+ ],
+ "unsafe_field_types": ["nsStyleUnion", "nsStyleUnit"],
},
# Generation of the ffi bindings.
"bindings": {
@@ -130,7 +131,7 @@ COMPILATION_TARGETS = {
],
"void_types": [
"nsINode", "nsIDocument", "nsIPrincipal", "nsIURI",
- ]
+ ],
}
}
@@ -253,6 +254,11 @@ def build(objdir, target_name, kind_name=None,
flags.append("-match")
flags.append(header.format(objdir))
+ if "unsafe_field_types" in current_target:
+ for ty in current_target["unsafe_field_types"]:
+ flags.append("-unsafe-field-type")
+ flags.append(ty.format(objdir))
+
if "blacklist" in current_target:
for ty in current_target["blacklist"]:
flags.append("-blacklist-type")