From cb05c969c89baee2a09a5f9be397a2dad9810fc5 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 20 Jul 2016 13:11:08 +0530 Subject: [PATCH 1/3] Resync bindings --- ports/geckolib/gecko_bindings/bindings.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 550d5c8cc8e..76e96a0ac06 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -293,7 +293,7 @@ extern "C" { pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool; pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet; pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet); - pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u8, + pub fn Servo_ParseStyleAttribute(bytes: *const u8, length: u32, cache: *mut nsHTMLCSSStyleSheet) -> *mut ServoDeclarationBlock; pub fn Servo_DropDeclarationBlock(declarations: @@ -305,7 +305,7 @@ extern "C" { *mut ServoDeclarationBlock); pub fn Servo_ClearDeclarationBlockCachePointer(declarations: *mut ServoDeclarationBlock); - pub fn Servo_CSSSupports(property: *const u8, property_length: u32, + pub fn Servo_CSSSupports(name: *const u8, name_length: u32, value: *const u8, value_length: u32) -> bool; pub fn Servo_GetComputedValues(node: *mut RawGeckoNode) -> *mut ServoComputedValues; From 6e9a68a0dbd3fb97321bb99d8219c4bf1c909937 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 20 Jul 2016 16:32:21 +0530 Subject: [PATCH 2/3] Introduce safer layer of sugar for nsStyleUnion --- components/style/gecko_values.rs | 280 ++++-------------- components/style/properties/gecko.mako.rs | 173 ++++++----- ports/geckolib/gecko_bindings/sugar/mod.rs | 2 +- .../gecko_bindings/sugar/ns_style_coord.rs | 251 ++++++++++++++-- 4 files changed, 365 insertions(+), 341 deletions(-) diff --git a/components/style/gecko_values.rs b/components/style/gecko_values.rs index 19d242b352e..1fef6e4c496 100644 --- a/components/style/gecko_values.rs +++ b/components/style/gecko_values.rs @@ -6,291 +6,123 @@ use app_units::Au; use cssparser::RGBA; -use gecko_bindings::structs::{nsStyleCoord, nsStyleUnion, nsStyleUnit}; +use gecko_bindings::structs::nsStyleCoord; +use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataValues}; 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(&mut self, val: T); - - fn set_auto(&mut self); - fn is_auto(&self) -> bool; - - fn set_normal(&mut self); - fn is_normal(&self) -> bool; - - fn set_coord(&mut self, val: Au); - fn is_coord(&self) -> bool; - fn get_coord(&self) -> Au; - - fn set_int(&mut self, val: i32); - fn is_int(&self) -> bool; - fn get_int(&self) -> i32; - - fn set_enum(&mut self, val: i32); - fn is_enum(&self) -> bool; - fn get_enum(&self) -> i32; - - fn set_percent(&mut self, val: f32); - fn is_percent(&self) -> bool; - fn get_percent(&self) -> f32; - - fn set_factor(&mut self, val: f32); - fn is_factor(&self) -> bool; - fn get_factor(&self) -> f32; } impl StyleCoordHelpers for nsStyleCoord { #[inline] fn copy_from(&mut self, other: &Self) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = other.mUnit; - self.mValue = other.mValue; - unsafe { self.addref_if_calc(); } + self.data().copy_from(&other.data()) } #[inline] fn set(&mut self, val: T) { - val.to_gecko_style_coord(&mut self.mUnit, &mut self.mValue); - } - - #[inline] - fn set_auto(&mut self) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Auto; - unsafe { *self.mValue.mInt.as_mut() = 0; } - } - #[inline] - fn is_auto(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Auto - } - - #[inline] - fn set_normal(&mut self) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Normal; - unsafe { *self.mValue.mInt.as_mut() = 0; } - } - #[inline] - fn is_normal(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Normal - } - - #[inline] - fn set_coord(&mut self, val: Au) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Coord; - unsafe { *self.mValue.mInt.as_mut() = val.0; } - } - #[inline] - fn is_coord(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Coord - } - #[inline] - fn get_coord(&self) -> Au { - debug_assert!(self.is_coord()); - Au(unsafe { *self.mValue.mInt.as_ref() }) - } - - #[inline] - fn set_int(&mut self, val: i32) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Integer; - unsafe { *self.mValue.mInt.as_mut() = val; } - } - #[inline] - fn is_int(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Integer - } - #[inline] - fn get_int(&self) -> i32 { - debug_assert!(self.is_int()); - unsafe { *self.mValue.mInt.as_ref() } - } - - #[inline] - fn set_enum(&mut self, val: i32) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Enumerated; - unsafe { *self.mValue.mInt.as_mut() = val; } - } - #[inline] - fn is_enum(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Enumerated - } - #[inline] - fn get_enum(&self) -> i32 { - debug_assert!(self.is_enum()); - unsafe { *self.mValue.mInt.as_ref() } - } - - #[inline] - fn set_percent(&mut self, val: f32) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Percent; - unsafe { *self.mValue.mFloat.as_mut() = val; } - } - #[inline] - fn is_percent(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Percent - } - #[inline] - fn get_percent(&self) -> f32 { - debug_assert!(self.is_percent()); - unsafe { *self.mValue.mFloat.as_ref() } - } - - #[inline] - fn set_factor(&mut self, val: f32) { - unsafe { self.mValue.reset(&mut self.mUnit) }; - self.mUnit = nsStyleUnit::eStyleUnit_Factor; - unsafe { *self.mValue.mFloat.as_mut() = val; } - } - #[inline] - fn is_factor(&self) -> bool { - self.mUnit == nsStyleUnit::eStyleUnit_Factor - } - #[inline] - fn get_factor(&self) -> f32 { - debug_assert!(self.is_factor()); - unsafe { *self.mValue.mFloat.as_ref() } + val.to_gecko_style_coord(&mut self.data()); } } + pub trait GeckoStyleCoordConvertible : Sized { - fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion); - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option; + fn to_gecko_style_coord(&self, coord: &mut CoordData); + fn from_gecko_style_coord(coord: &CoordData) -> Option; } impl GeckoStyleCoordConvertible for LengthOrPercentage { - fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) { - unsafe { union.reset(unit) }; - match *self { - LengthOrPercentage::Length(au) => { - *unit = nsStyleUnit::eStyleUnit_Coord; - unsafe { *union.mInt.as_mut() = au.0; } - }, - LengthOrPercentage::Percentage(p) => { - *unit = nsStyleUnit::eStyleUnit_Percent; - unsafe { *union.mFloat.as_mut() = p; } - }, - LengthOrPercentage::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) }, + fn to_gecko_style_coord(&self, coord: &mut CoordData) { + let value = match *self { + LengthOrPercentage::Length(au) => CoordDataValues::Coord(au.0), + LengthOrPercentage::Percentage(p) => CoordDataValues::Percent(p), + LengthOrPercentage::Calc(calc) => CoordDataValues::Calc(calc.into()), }; + coord.set_enum(value); } - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option { - match *unit { - nsStyleUnit::eStyleUnit_Coord - => Some(LengthOrPercentage::Length(Au(unsafe { *union.mInt.as_ref() }))), - nsStyleUnit::eStyleUnit_Percent - => Some(LengthOrPercentage::Percentage(unsafe { *union.mFloat.as_ref() })), - nsStyleUnit::eStyleUnit_Calc - => Some(LengthOrPercentage::Calc(unsafe { union.get_calc().into() })), + fn from_gecko_style_coord(coord: &CoordData) -> Option { + 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())), _ => None, } } } impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { - fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) { - unsafe { union.reset(unit) }; - match *self { - LengthOrPercentageOrAuto::Length(au) => { - *unit = nsStyleUnit::eStyleUnit_Coord; - unsafe { *union.mInt.as_mut() = au.0; } - }, - LengthOrPercentageOrAuto::Percentage(p) => { - *unit = nsStyleUnit::eStyleUnit_Percent; - unsafe { *union.mFloat.as_mut() = p; } - }, - LengthOrPercentageOrAuto::Auto => { - *unit = nsStyleUnit::eStyleUnit_Auto; - unsafe { *union.mInt.as_mut() = 0; } - }, - LengthOrPercentageOrAuto::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) }, + fn to_gecko_style_coord(&self, coord: &mut CoordData) { + 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()), }; + coord.set_enum(value); } - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option { - match *unit { - nsStyleUnit::eStyleUnit_Auto - => Some(LengthOrPercentageOrAuto::Auto), - nsStyleUnit::eStyleUnit_Coord - => Some(LengthOrPercentageOrAuto::Length(Au(unsafe { *union.mInt.as_ref() }))), - nsStyleUnit::eStyleUnit_Percent - => Some(LengthOrPercentageOrAuto::Percentage(unsafe { *union.mFloat.as_ref() })), - nsStyleUnit::eStyleUnit_Calc - => Some(LengthOrPercentageOrAuto::Calc(unsafe { union.get_calc().into() })), + fn from_gecko_style_coord(coord: &CoordData) -> Option { + 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())), _ => None, } } } impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone { - fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) { - unsafe { union.reset(unit) }; - match *self { - LengthOrPercentageOrNone::Length(au) => { - *unit = nsStyleUnit::eStyleUnit_Coord; - unsafe { *union.mInt.as_mut() = au.0; } - }, - LengthOrPercentageOrNone::Percentage(p) => { - *unit = nsStyleUnit::eStyleUnit_Percent; - unsafe { *union.mFloat.as_mut() = p; } - }, - LengthOrPercentageOrNone::None => { - *unit = nsStyleUnit::eStyleUnit_None; - unsafe { *union.mInt.as_mut() = 0; } - }, - LengthOrPercentageOrNone::Calc(calc) => unsafe { union.set_calc_value(unit, calc.into()) }, + fn to_gecko_style_coord(&self, coord: &mut CoordData) { + 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()), }; + coord.set_enum(value); } - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option { - match *unit { - nsStyleUnit::eStyleUnit_None - => Some(LengthOrPercentageOrNone::None), - nsStyleUnit::eStyleUnit_Coord - => Some(LengthOrPercentageOrNone::Length(Au(unsafe { *union.mInt.as_ref() }))), - nsStyleUnit::eStyleUnit_Percent - => Some(LengthOrPercentageOrNone::Percentage(unsafe { *union.mFloat.as_ref() })), - nsStyleUnit::eStyleUnit_Calc - => Some(LengthOrPercentageOrNone::Calc(unsafe { union.get_calc().into() })), + fn from_gecko_style_coord(coord: &CoordData) -> Option { + 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())), _ => None, } } } impl GeckoStyleCoordConvertible for Option { - fn to_gecko_style_coord(&self, unit: &mut nsStyleUnit, union: &mut nsStyleUnion) { - unsafe { union.reset(unit) }; + fn to_gecko_style_coord(&self, coord: &mut CoordData) { if let Some(ref me) = *self { - me.to_gecko_style_coord(unit, union); + me.to_gecko_style_coord(coord); } else { - *unit = nsStyleUnit::eStyleUnit_None; - unsafe { *union.mInt.as_mut() = 0; } + coord.set_enum(CoordDataValues::None); } } - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option { - Some(T::from_gecko_style_coord(unit, union)) + fn from_gecko_style_coord(coord: &CoordData) -> Option { + Some(T::from_gecko_style_coord(coord)) } } impl GeckoStyleCoordConvertible for Angle { - fn to_gecko_style_coord(&self, - unit: &mut nsStyleUnit, - union: &mut nsStyleUnion) { - unsafe { union.reset(unit) }; - *unit = nsStyleUnit::eStyleUnit_Radian; - unsafe { *union.mFloat.as_mut() = self.radians() }; + fn to_gecko_style_coord(&self, coord: &mut CoordData) { + coord.set_enum(CoordDataValues::Radian(self.radians())) } - fn from_gecko_style_coord(unit: &nsStyleUnit, union: &nsStyleUnion) -> Option { - if *unit == nsStyleUnit::eStyleUnit_Radian { - Some(Angle::from_radians(unsafe { *union.mFloat.as_ref() })) + fn from_gecko_style_coord(coord: &CoordData) -> Option { + if let CoordDataValues::Radian(r) = coord.as_enum() { + Some(Angle::from_radians(r)) + // XXXManishearth should this handle Degree too? } else { None } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 6cc7592de81..264fef07cd5 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -26,6 +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_glue::ArcHelpers; use gecko_values::{StyleCoordHelpers, GeckoStyleCoordConvertible, convert_nscolor_to_rgba}; use gecko_values::convert_rgba_to_nscolor; @@ -325,67 +326,65 @@ def set_gecko_property(ffi_name, expr): % endif -<%def name="impl_split_style_coord(ident, unit_ffi_name, union_ffi_name, need_clone=False)"> +<%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.${unit_ffi_name}, - &mut self.gecko.${union_ffi_name}); + v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data_at(${index})); } #[allow(non_snake_case)] pub fn copy_${ident}_from(&mut self, other: &Self) { - unsafe { self.gecko.${union_ffi_name}.reset(&mut self.gecko.${unit_ffi_name}) }; - self.gecko.${unit_ffi_name} = other.gecko.${unit_ffi_name}; - self.gecko.${union_ffi_name} = other.gecko.${union_ffi_name}; - unsafe { self.gecko.${union_ffi_name}.addref_if_calc(&self.gecko.${unit_ffi_name}) }; + self.gecko.${gecko_ffi_name}.data_at(${index}).copy_from(&other.gecko.${gecko_ffi_name}.data_at(${index})); } % 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.${unit_ffi_name}, - &self.gecko.${union_ffi_name}) + T::from_gecko_style_coord(&self.gecko.${gecko_ffi_name}.data_at(${index})) .expect("clone for ${ident} failed") } % endif <%def name="impl_style_coord(ident, gecko_ffi_name, need_clone=False)"> -${impl_split_style_coord(ident, - "%s.mUnit" % gecko_ffi_name, - "%s.mValue" % gecko_ffi_name, - need_clone=need_clone)} - - -<%def name="impl_corner_style_coord(ident, x_unit_ffi_name, x_union_ffi_name, \ - y_unit_ffi_name, y_union_ffi_name, 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.${x_unit_ffi_name}, - &mut self.gecko.${x_union_ffi_name}); - v.0.height.to_gecko_style_coord(&mut self.gecko.${y_unit_ffi_name}, - &mut self.gecko.${y_union_ffi_name}); + v.to_gecko_style_coord(&mut self.gecko.${gecko_ffi_name}.data()); } #[allow(non_snake_case)] pub fn copy_${ident}_from(&mut self, other: &Self) { - unsafe { self.gecko.${x_union_ffi_name}.reset(&mut self.gecko.${x_unit_ffi_name}) }; - unsafe { self.gecko.${y_union_ffi_name}.reset(&mut self.gecko.${y_unit_ffi_name}) }; - self.gecko.${x_unit_ffi_name} = other.gecko.${x_unit_ffi_name}; - self.gecko.${x_union_ffi_name} = other.gecko.${x_union_ffi_name}; - self.gecko.${y_unit_ffi_name} = other.gecko.${y_unit_ffi_name}; - self.gecko.${y_union_ffi_name} = other.gecko.${y_union_ffi_name}; - unsafe { self.gecko.${x_union_ffi_name}.addref_if_calc(&self.gecko.${x_unit_ffi_name}) }; - unsafe { self.gecko.${y_union_ffi_name}.addref_if_calc(&self.gecko.${y_unit_ffi_name}) }; + self.gecko.${gecko_ffi_name}.data().copy_from(&other.gecko.${gecko_ffi_name}.data()); + } + % 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()) + .expect("clone for ${ident} failed") + } + % endif + + +<%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})); + } + #[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})); } % if need_clone: #[allow(non_snake_case)] pub fn clone_${ident}(&self) -> longhands::${ident}::computed_value::T { use properties::longhands::${ident}::computed_value::T; use euclid::Size2D; - let width = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${x_unit_ffi_name}, - &self.gecko.${x_union_ffi_name}) + let width = GeckoStyleCoordConvertible::from_gecko_style_coord( + &self.gecko.${gecko_ffi_name}.data_at(${x_index})) .expect("Failed to clone ${ident}"); - let height = GeckoStyleCoordConvertible::from_gecko_style_coord(&self.gecko.${y_unit_ffi_name}, - &self.gecko.${y_union_ffi_name}) + let height = GeckoStyleCoordConvertible::from_gecko_style_coord( + &self.gecko.${gecko_ffi_name}.data_at(${y_index})) .expect("Failed to clone ${ident}"); T(Size2D::new(width, height)) } @@ -602,10 +601,9 @@ fn static_assert() { % for corner in CORNERS: <% impl_corner_style_coord("border_%s_radius" % corner.ident, - "mBorderRadius.mUnits[%s]" % corner.x_index, - "mBorderRadius.mValues[%s]" % corner.x_index, - "mBorderRadius.mUnits[%s]" % corner.y_index, - "mBorderRadius.mValues[%s]" % corner.y_index, + "mBorderRadius", + corner.x_index, + corner.y_index, need_clone=True) %> % endfor @@ -616,8 +614,8 @@ fn static_assert() { % for side in SIDES: <% impl_split_style_coord("margin_%s" % side.ident, - "mMargin.mUnits[%s]" % side.index, - "mMargin.mValues[%s]" % side.index, + "mMargin", + side.index, need_clone=True) %> % endfor @@ -628,8 +626,8 @@ fn static_assert() { % for side in SIDES: <% impl_split_style_coord("padding_%s" % side.ident, - "mPadding.mUnits[%s]" % side.index, - "mPadding.mValues[%s]" % side.index, + "mPadding", + side.index, need_clone=True) %> % endfor @@ -640,16 +638,16 @@ fn static_assert() { % for side in SIDES: <% impl_split_style_coord("%s" % side.ident, - "mOffset.mUnits[%s]" % side.index, - "mOffset.mValues[%s]" % side.index, + "mOffset", + side.index, need_clone=True) %> % endfor 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.set_auto(), - T::Number(n) => self.gecko.mZIndex.set_int(n), + T::Auto => self.gecko.mZIndex.data().set_enum(CoordDataValues::Auto), + T::Number(n) => self.gecko.mZIndex.data().set_enum(CoordDataValues::Integer(n)), } } @@ -664,13 +662,14 @@ fn static_assert() { pub fn clone_z_index(&self) -> longhands::z_index::computed_value::T { use properties::longhands::z_index::computed_value::T; - - if self.gecko.mZIndex.is_auto() { - return T::Auto; + return match self.gecko.mZIndex.data().as_enum() { + CoordDataValues::Auto => T::Auto, + CoordDataValues::Integer(n) => T::Number(n), + _ => { + debug_assert!(false); + T::Number(0) + } } - - debug_assert!(self.gecko.mZIndex.is_int()); - T::Number(self.gecko.mZIndex.get_int()) } pub fn set_box_sizing(&mut self, v: longhands::box_sizing::computed_value::T) { @@ -702,10 +701,9 @@ fn static_assert() { % for corner in CORNERS: <% impl_corner_style_coord("_moz_outline_radius_%s" % corner.ident.replace("_", ""), - "mOutlineRadius.mUnits[%s]" % corner.x_index, - "mOutlineRadius.mValues[%s]" % corner.x_index, - "mOutlineRadius.mUnits[%s]" % corner.y_index, - "mOutlineRadius.mValues[%s]" % corner.y_index) %> + "mOutlineRadius", + corner.x_index, + corner.y_index) %> % endfor pub fn outline_has_nonzero_width(&self) -> bool { @@ -826,7 +824,8 @@ fn static_assert() { match v { % for value in keyword.values_for('gecko'): T::${to_rust_ident(value)} => - self.gecko.mVerticalAlign.set_enum(structs::${keyword.gecko_constant(value)} as i32), + self.gecko.mVerticalAlign.data().set_enum( + CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)})), % endfor T::LengthOrPercentage(v) => self.gecko.mVerticalAlign.set(v), } @@ -836,19 +835,17 @@ fn static_assert() { use properties::longhands::vertical_align::computed_value::T; use values::computed::LengthOrPercentage; - if self.gecko.mVerticalAlign.is_enum() { - match self.gecko.mVerticalAlign.get_enum() as u32 { - % for value in keyword.values_for('gecko'): - structs::${keyword.gecko_constant(value)} - => T::${to_rust_ident(value)}, - % endfor - _ => panic!("Unexpected enum variant for vertical-align"), - } - } else { - let v = LengthOrPercentage::from_gecko_style_coord(&self.gecko.mVerticalAlign.mUnit, - &self.gecko.mVerticalAlign.mValue) - .expect("Expected length or percentage for vertical-align"); - T::LengthOrPercentage(v) + let data = self.gecko.mVerticalAlign.data(); + match data.as_enum() { + % for value in keyword.values_for('gecko'): + CoordDataValues::Enumerated(structs::${keyword.gecko_constant(value)}) => T::${to_rust_ident(value)}, + % endfor + CoordDataValues::Enumerated(_) => panic!("Unexpected enum variant for vertical-align"), + _ => { + let v = LengthOrPercentage::from_gecko_style_coord(&data) + .expect("Expected length or percentage for vertical-align"); + T::LengthOrPercentage(v) + } } } @@ -1132,29 +1129,29 @@ fn static_assert() { pub fn set_line_height(&mut self, v: longhands::line_height::computed_value::T) { use properties::longhands::line_height::computed_value::T; // FIXME: Align binary representations and ditch |match| for cast + static_asserts - match v { - T::Normal => self.gecko.mLineHeight.set_normal(), - T::Length(val) => self.gecko.mLineHeight.set_coord(val), - T::Number(val) => self.gecko.mLineHeight.set_factor(val), + let en = match v { + T::Normal => CoordDataValues::Normal, + T::Length(val) => CoordDataValues::Coord(val.0), + T::Number(val) => CoordDataValues::Factor(val), T::MozBlockHeight => - self.gecko.mLineHeight.set_enum(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32), - } + CoordDataValues::Enumerated(structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT), + }; + self.gecko.mLineHeight.data().set_enum(en); } pub fn clone_line_height(&self) -> longhands::line_height::computed_value::T { use properties::longhands::line_height::computed_value::T; - if self.gecko.mLineHeight.is_normal() { - return T::Normal; + 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 => + T::MozBlockHeight, + _ => { + debug_assert!(false); + T::MozBlockHeight + } } - if self.gecko.mLineHeight.is_coord() { - return T::Length(self.gecko.mLineHeight.get_coord()); - } - if self.gecko.mLineHeight.is_factor() { - return T::Number(self.gecko.mLineHeight.get_factor()); - } - - debug_assert!(self.gecko.mLineHeight.get_enum() == structs::NS_STYLE_LINE_HEIGHT_BLOCK_HEIGHT as i32); - T::MozBlockHeight } <%call expr="impl_coord_copy('line_height', 'mLineHeight')"> @@ -1283,8 +1280,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.set_coord(au), - None => self.gecko.mColumnWidth.set_auto(), + Some(au) => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Coord(au.0)), + None => self.gecko.mColumnWidth.data().set_enum(CoordDataValues::Auto), } } diff --git a/ports/geckolib/gecko_bindings/sugar/mod.rs b/ports/geckolib/gecko_bindings/sugar/mod.rs index fa995c3f963..1cdd8b0c96a 100644 --- a/ports/geckolib/gecko_bindings/sugar/mod.rs +++ b/ports/geckolib/gecko_bindings/sugar/mod.rs @@ -3,5 +3,5 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ mod ns_style_auto_array; -mod ns_style_coord; +pub mod ns_style_coord; mod ns_t_array; diff --git a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs index ef03f4d7b41..e17570039fb 100644 --- a/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs +++ b/ports/geckolib/gecko_bindings/sugar/ns_style_coord.rs @@ -4,51 +4,246 @@ use bindings::{Gecko_ResetStyleCoord, Gecko_SetStyleCoordCalcValue, Gecko_AddRefCalcArbitraryThread}; use std::mem::transmute; -use structs::{nsStyleCoord_CalcValue, nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord}; +use std::marker::PhantomData; +use structs::{nsStyleCoord_Calc, nsStyleUnit, nsStyleUnion, nsStyleCoord, nsStyleSides, nsStyleCorners}; +use structs::{nsStyleCoord_CalcValue, nscoord}; -// Functions here are unsafe because it is possible to use the wrong nsStyleUnit -// FIXME we should be pairing up nsStyleUnion and nsStyleUnit somehow -// nsStyleCoord is one way to do it, but there are other structs using pairs -// of union and unit too +impl nsStyleCoord { + #[inline] + pub unsafe fn addref_if_calc(&mut self) { + self.data().addref_if_calc(); + } -impl nsStyleUnion { - /// Clean up any resources used by an nsStyleUnit + #[inline] + pub fn data(&self) -> CoordData { + CoordData { + union: &self.mValue as *const _ as *mut _, + unit: &self.mUnit as *const _ as *mut _, + _marker: PhantomData, + } + } +} + +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, + } + } +} + +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, + } + } +} + +#[derive(Copy, Clone)] +/// 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 { + Null, + Normal, + Auto, + None, + Percent(f32), + Factor(f32), + Degree(f32), + Grad(f32), + Radian(f32), + Turn(f32), + FlexFraction(f32), + Coord(nscoord), + Integer(i32), + Enumerated(u32), + 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> { + /// Clean up any resources used by the union /// Currently, this only happens if the nsStyleUnit /// is a Calc - pub unsafe fn reset(&mut self, unit: &mut nsStyleUnit) { - if *unit == nsStyleUnit::eStyleUnit_Calc { - Gecko_ResetStyleCoord(unit, self); + #[inline] + pub fn reset(&mut self) { + unsafe { + if *self.unit == nsStyleUnit::eStyleUnit_Calc { + Gecko_ResetStyleCoord(self.unit, self.union); + } } } - /// Set internal value to a calc() value - /// reset() the union before calling this - pub unsafe fn set_calc_value(&mut self, unit: &mut nsStyleUnit, v: nsStyleCoord_CalcValue) { - // Calc should have been cleaned up - debug_assert!(*unit != nsStyleUnit::eStyleUnit_Calc); - Gecko_SetStyleCoordCalcValue(unit, self, v); + #[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::*; + 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()), + } + } + } + + #[inline(always)] + pub fn set_enum(&mut self, value: CoordDataValues) { + use self::CoordDataValues::*; + use structs::nsStyleUnit::*; + self.reset(); + unsafe { + match value { + Null => { + *self.unit = eStyleUnit_Null; + *(*self.union).mInt.as_mut() = 0; + } + Normal => { + *self.unit = eStyleUnit_Normal; + *(*self.union).mInt.as_mut() = 0; + } + Auto => { + *self.unit = eStyleUnit_Auto; + *(*self.union).mInt.as_mut() = 0; + } + None => { + *self.unit = eStyleUnit_None; + *(*self.union).mInt.as_mut() = 0; + } + Percent(f) => { + *self.unit = eStyleUnit_Percent; + *(*self.union).mFloat.as_mut() = f; + } + Factor(f) => { + *self.unit = eStyleUnit_Factor; + *(*self.union).mFloat.as_mut() = f; + } + Degree(f) => { + *self.unit = eStyleUnit_Degree; + *(*self.union).mFloat.as_mut() = f; + } + Grad(f) => { + *self.unit = eStyleUnit_Grad; + *(*self.union).mFloat.as_mut() = f; + } + Radian(f) => { + *self.unit = eStyleUnit_Radian; + *(*self.union).mFloat.as_mut() = f; + } + Turn(f) => { + *self.unit = eStyleUnit_Turn; + *(*self.union).mFloat.as_mut() = f; + } + FlexFraction(f) => { + *self.unit = eStyleUnit_FlexFraction; + *(*self.union).mFloat.as_mut() = f; + } + Coord(coord) => { + *self.unit = eStyleUnit_Coord; + *(*self.union).mInt.as_mut() = coord; + } + Integer(i) => { + *self.unit = eStyleUnit_Integer; + *(*self.union).mInt.as_mut() = i; + } + Enumerated(i) => { + *self.unit = eStyleUnit_Enumerated; + *(*self.union).mInt.as_mut() = i as i32; + } + Calc(calc) => { + *self.unit = eStyleUnit_Calc; + self.set_calc_value(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() } + } + + #[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() } + } + + #[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 } - pub unsafe fn addref_if_calc(&mut self, unit: &nsStyleUnit) { - if *unit == nsStyleUnit::eStyleUnit_Calc { - Gecko_AddRefCalcArbitraryThread(self.as_calc_mut()); + /// Set internal value to a calc() value + /// reset() the union before calling this + #[inline] + pub fn set_calc_value(&mut self, v: nsStyleCoord_CalcValue) { + unsafe { + // Calc should have been cleaned up + debug_assert!(*self.unit != nsStyleUnit::eStyleUnit_Calc); + Gecko_SetStyleCoordCalcValue(self.unit, self.union, v); } } - unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc { - transmute(*self.mPointer.as_mut() as *mut nsStyleCoord_Calc) + #[inline] + pub fn addref_if_calc(&mut self) { + unsafe { + if *self.unit == nsStyleUnit::eStyleUnit_Calc { + Gecko_AddRefCalcArbitraryThread(self.as_calc_mut()); + } + } } - unsafe fn as_calc(&self) -> &nsStyleCoord_Calc { - transmute(*self.mPointer.as_ref() as *const nsStyleCoord_Calc) - } -} -impl nsStyleCoord { - pub unsafe fn addref_if_calc(&mut self) { - self.mValue.addref_if_calc(&self.mUnit); + #[inline] + unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc { + transmute(*(*self.union).mPointer.as_mut() as *mut nsStyleCoord_Calc) + } + + #[inline] + unsafe fn as_calc(&self) -> &nsStyleCoord_Calc { + transmute(*(*self.union).mPointer.as_ref() as *const nsStyleCoord_Calc) } } From 73d7db0d5eda75bdbf38f55ed9b40405cb2fd364 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 20 Jul 2016 19:08:31 +0530 Subject: [PATCH 3/3] Make nsStyleUnion sugar use traits --- components/style/gecko_values.rs | 96 ++--- components/style/properties/gecko.mako.rs | 69 +-- .../gecko_bindings/sugar/ns_style_coord.rs | 392 +++++++++++------- ports/geckolib/gecko_bindings/tools/regen.py | 10 +- 4 files changed, 326 insertions(+), 241 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(&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(&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; + fn to_gecko_style_coord(&self, coord: &mut T); + fn from_gecko_style_coord(coord: &T) -> Option; } impl GeckoStyleCoordConvertible for LengthOrPercentage { - fn to_gecko_style_coord(&self, coord: &mut CoordData) { + fn to_gecko_style_coord(&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 { - 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(coord: &T) -> Option { + 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(&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 { - 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(coord: &T) -> Option { + 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(&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 { - 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(coord: &T) -> Option { + 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 GeckoStyleCoordConvertible for Option { - fn to_gecko_style_coord(&self, coord: &mut CoordData) { + fn to_gecko_style_coord(&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 { + fn from_gecko_style_coord(coord: &U) -> Option { 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(&self, coord: &mut T) { + coord.set_value(CoordDataValue::Radian(self.radians())) } - fn from_gecko_style_coord(coord: &CoordData) -> Option { - if let CoordDataValues::Radian(r) = coord.as_enum() { + fn from_gecko_style_coord(coord: &T) -> Option { + 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,40 +146,137 @@ 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(); + fn copy_from(&mut self, other: &T) { + unsafe { + self.reset(); + { + let (unit, union) = self.values_mut(); + *unit = other.unit(); + *union = other.union(); + } + self.addref_if_calc(); + } } #[inline(always)] - pub fn as_enum(&self) -> 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 => { + *unit = eStyleUnit_Null; + *union.mInt.as_mut() = 0; + } + Normal => { + *unit = eStyleUnit_Normal; + *union.mInt.as_mut() = 0; + } + Auto => { + *unit = eStyleUnit_Auto; + *union.mInt.as_mut() = 0; + } + None => { + *unit = eStyleUnit_None; + *union.mInt.as_mut() = 0; + } + Percent(f) => { + *unit = eStyleUnit_Percent; + *union.mFloat.as_mut() = f; + } + Factor(f) => { + *unit = eStyleUnit_Factor; + *union.mFloat.as_mut() = f; + } + Degree(f) => { + *unit = eStyleUnit_Degree; + *union.mFloat.as_mut() = f; + } + Grad(f) => { + *unit = eStyleUnit_Grad; + *union.mFloat.as_mut() = f; + } + Radian(f) => { + *unit = eStyleUnit_Radian; + *union.mFloat.as_mut() = f; + } + Turn(f) => { + *unit = eStyleUnit_Turn; + *union.mFloat.as_mut() = f; + } + FlexFraction(f) => { + *unit = eStyleUnit_FlexFraction; + *union.mFloat.as_mut() = f; + } + Coord(coord) => { + *unit = eStyleUnit_Coord; + *union.mInt.as_mut() = coord; + } + Integer(i) => { + *unit = eStyleUnit_Integer; + *union.mInt.as_mut() = i; + } + Enumerated(i) => { + *unit = eStyleUnit_Enumerated; + *union.mInt.as_mut() = i as i32; + } + Calc(calc) => { + // Gecko_SetStyleCoordCalcValue changes the unit internally + Gecko_SetStyleCoordCalcValue(unit, union, calc); + } + } + } + } + + #[inline] + 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] + 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(always)] + fn as_value(&self) -> CoordDataValue { + use self::CoordDataValue::*; use structs::nsStyleUnit::*; unsafe { - match *self.unit { + match self.unit() { eStyleUnit_Null => Null, eStyleUnit_Normal => Normal, eStyleUnit_Auto => Auto, @@ -116,134 +291,43 @@ impl<'a> CoordData<'a> { 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()), + eStyleUnit_Calc => Calc(self.get_calc_value()), } } } - #[inline(always)] - pub fn set_enum(&mut self, value: CoordDataValues) { - use self::CoordDataValues::*; + #[inline] + /// Pretend inner value is a float; obtain it. + unsafe fn get_float(&self) -> f32 { use structs::nsStyleUnit::*; - self.reset(); - unsafe { - match value { - Null => { - *self.unit = eStyleUnit_Null; - *(*self.union).mInt.as_mut() = 0; - } - Normal => { - *self.unit = eStyleUnit_Normal; - *(*self.union).mInt.as_mut() = 0; - } - Auto => { - *self.unit = eStyleUnit_Auto; - *(*self.union).mInt.as_mut() = 0; - } - None => { - *self.unit = eStyleUnit_None; - *(*self.union).mInt.as_mut() = 0; - } - Percent(f) => { - *self.unit = eStyleUnit_Percent; - *(*self.union).mFloat.as_mut() = f; - } - Factor(f) => { - *self.unit = eStyleUnit_Factor; - *(*self.union).mFloat.as_mut() = f; - } - Degree(f) => { - *self.unit = eStyleUnit_Degree; - *(*self.union).mFloat.as_mut() = f; - } - Grad(f) => { - *self.unit = eStyleUnit_Grad; - *(*self.union).mFloat.as_mut() = f; - } - Radian(f) => { - *self.unit = eStyleUnit_Radian; - *(*self.union).mFloat.as_mut() = f; - } - Turn(f) => { - *self.unit = eStyleUnit_Turn; - *(*self.union).mFloat.as_mut() = f; - } - FlexFraction(f) => { - *self.unit = eStyleUnit_FlexFraction; - *(*self.union).mFloat.as_mut() = f; - } - Coord(coord) => { - *self.unit = eStyleUnit_Coord; - *(*self.union).mInt.as_mut() = coord; - } - Integer(i) => { - *self.unit = eStyleUnit_Integer; - *(*self.union).mInt.as_mut() = i; - } - Enumerated(i) => { - *self.unit = eStyleUnit_Enumerated; - *(*self.union).mInt.as_mut() = i as i32; - } - Calc(calc) => { - *self.unit = eStyleUnit_Calc; - self.set_calc_value(calc); - } - } - } + 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] - /// 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() } + /// 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 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() } - } - - #[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 { + /// 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 } - /// Set internal value to a calc() value - /// reset() the union before calling this - #[inline] - pub fn set_calc_value(&mut self, v: nsStyleCoord_CalcValue) { - unsafe { - // Calc should have been cleaned up - debug_assert!(*self.unit != nsStyleUnit::eStyleUnit_Calc); - Gecko_SetStyleCoordCalcValue(self.unit, self.union, v); - } - } - - #[inline] - pub fn addref_if_calc(&mut self) { - unsafe { - if *self.unit == nsStyleUnit::eStyleUnit_Calc { - Gecko_AddRefCalcArbitraryThread(self.as_calc_mut()); - } - } - } - - #[inline] - unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc { - transmute(*(*self.union).mPointer.as_mut() as *mut nsStyleCoord_Calc) - } #[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")