diff --git a/components/style/author_styles.rs b/components/style/author_styles.rs index 101c2e17349..37eb68ff4f7 100644 --- a/components/style/author_styles.rs +++ b/components/style/author_styles.rs @@ -77,7 +77,7 @@ where #[cfg(feature = "gecko")] unsafe impl HasFFI for AuthorStyles { - type FFIType = crate::gecko_bindings::bindings::RawServoAuthorStyles; + type FFIType = crate::gecko_bindings::structs::RawServoAuthorStyles; } #[cfg(feature = "gecko")] unsafe impl HasSimpleFFI for AuthorStyles {} diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 734d09569f5..52dc5f51e24 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -128,9 +128,6 @@ mod bindings { trait BuilderExt { fn get_initial_builder() -> Builder; fn include>(self, file: T) -> Builder; - fn zero_size_type(self, ty: &str, structs_list: &HashSet<&str>) -> Builder; - fn borrowed_type(self, ty: &str) -> Builder; - fn mutable_borrowed_type(self, ty: &str) -> Builder; } impl BuilderExt for Builder { @@ -181,42 +178,6 @@ mod bindings { fn include>(self, file: T) -> Builder { self.clang_arg("-include").clang_arg(file) } - // This makes an FFI-safe void type that can't be matched on - // &VoidType is UB to have, because you can match on it - // to produce a reachable unreachable. If it's wrapped in - // a struct as a private field it becomes okay again - // - // Not 100% sure of how safe this is, but it's what we're using - // in the XPCOM ffi too - // https://github.com/nikomatsakis/rust-memory-model/issues/2 - fn zero_size_type(self, ty: &str, structs_list: &HashSet<&str>) -> Builder { - if !structs_list.contains(ty) { - self.blacklist_type(ty) - .raw_line(format!("enum {}Void {{ }}", ty)) - .raw_line(format!("pub struct {0}({0}Void);", ty)) - } else { - self - } - } - fn borrowed_type(self, ty: &str) -> Builder { - self.blacklist_type(format!("{}Borrowed", ty)) - .raw_line(format!("pub type {0}Borrowed<'a> = &'a {0};", ty)) - .blacklist_type(format!("{}BorrowedOrNull", ty)) - .raw_line(format!( - "pub type {0}BorrowedOrNull<'a> = Option<&'a {0}>;", - ty - )) - } - fn mutable_borrowed_type(self, ty: &str) -> Builder { - self.borrowed_type(ty) - .blacklist_type(format!("{}BorrowedMut", ty)) - .raw_line(format!("pub type {0}BorrowedMut<'a> = &'a mut {0};", ty)) - .blacklist_type(format!("{}BorrowedMutOrNull", ty)) - .raw_line(format!( - "pub type {0}BorrowedMutOrNull<'a> = Option<&'a mut {0}>;", - ty - )) - } } struct Fixup { @@ -290,13 +251,6 @@ mod bindings { .collect() } - fn get_borrowed_types() -> Vec<(bool, String)> { - get_types("BorrowedTypeList.h", "GECKO_BORROWED_TYPE(?:_MUT)?") - .into_iter() - .map(|(macro_name, type_name)| (macro_name.ends_with("MUT"), type_name)) - .collect() - } - fn get_arc_types() -> Vec { get_types("ServoArcTypeList.h", "SERVO_ARC_TYPE") .into_iter() @@ -480,67 +434,24 @@ mod bindings { } } + // FIXME(emilio): Avoid this altogether. fn generate_bindings() { let builder = Builder::get_initial_builder() .disable_name_namespacing() .with_codegen_config(CodegenConfig::FUNCTIONS); let config = CONFIG["bindings"].as_table().unwrap(); - let mut structs_types = HashSet::new(); let mut fixups = vec![]; let mut builder = BuilderWithConfig::new(builder, config) .handle_common(&mut fixups) .handle_str_items("whitelist-functions", |b, item| b.whitelist_function(item)) - .handle_str_items("structs-types", |mut builder, ty| { - builder = builder - .blacklist_type(ty) - .raw_line(format!("use gecko_bindings::structs::{};", ty)); - structs_types.insert(ty); - // TODO this is hacky, figure out a better way to do it without - // hardcoding everything... - if ty.starts_with("nsStyle") { - builder = builder - .raw_line(format!("unsafe impl Send for {} {{}}", ty)) - .raw_line(format!("unsafe impl Sync for {} {{}}", ty)); - } - builder - }) - // TODO This was added due to servo/rust-bindgen#75, but - // that has been fixed in clang 4.0+. When we switch people - // to libclang 4.0, we can remove this. - .handle_table_items("array-types", |builder, item| { - let cpp_type = item["cpp-type"].as_str().unwrap(); - let rust_type = item["rust-type"].as_str().unwrap(); - builder.raw_line(format!( - concat!( - "pub type nsTArrayBorrowed_{}<'a> = ", - "&'a mut ::gecko_bindings::structs::nsTArray<{}>;" - ), - cpp_type, rust_type - )) - }) - .handle_str_items("servo-immutable-borrow-types", |b, ty| b.borrowed_type(ty)) - // Right now the only immutable borrow types are ones which we import - // from the |structs| module. As such, we don't need to create an opaque - // type with zero_size_type. If we ever introduce immutable borrow types - // which _do_ need to be opaque, we'll need a separate mode. - .handle_str_items("servo-borrow-types", |b, ty| b.mutable_borrowed_type(ty)) .get_builder(); - for (is_mut, ty) in get_borrowed_types().iter() { - if *is_mut { - builder = builder.mutable_borrowed_type(ty); - } else { - builder = builder.borrowed_type(ty); - } - } for ty in get_arc_types().iter() { builder = builder .blacklist_type(format!("{}Strong", ty)) .raw_line(format!( "pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;", ty - )) - .borrowed_type(ty) - .zero_size_type(ty, &structs_types); + )); } for ty in get_boxed_types().iter() { builder = builder @@ -556,9 +467,7 @@ mod bindings { "::gecko_bindings::sugar::ownership::OwnedOrNull<{0}>;" ), ty - )) - .mutable_borrowed_type(ty) - .zero_size_type(ty, &structs_types); + )); } write_binding_file(builder, BINDINGS_FILE, &fixups); } diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index 95a37f0d905..145670c776f 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -9,19 +9,19 @@ #![allow(non_snake_case, missing_docs)] use crate::gecko::url::CssUrlData; -use crate::gecko_bindings::bindings::RawServoCounterStyleRule; -use crate::gecko_bindings::bindings::RawServoFontFeatureValuesRule; -use crate::gecko_bindings::bindings::RawServoImportRule; -use crate::gecko_bindings::bindings::RawServoKeyframe; -use crate::gecko_bindings::bindings::RawServoKeyframesRule; -use crate::gecko_bindings::bindings::RawServoMediaRule; -use crate::gecko_bindings::bindings::RawServoMozDocumentRule; -use crate::gecko_bindings::bindings::RawServoNamespaceRule; -use crate::gecko_bindings::bindings::RawServoPageRule; -use crate::gecko_bindings::bindings::RawServoRuleNode; -use crate::gecko_bindings::bindings::RawServoRuleNodeStrong; -use crate::gecko_bindings::bindings::RawServoSupportsRule; -use crate::gecko_bindings::bindings::ServoCssRules; +use crate::gecko_bindings::structs::RawServoCounterStyleRule; +use crate::gecko_bindings::structs::RawServoFontFeatureValuesRule; +use crate::gecko_bindings::structs::RawServoImportRule; +use crate::gecko_bindings::structs::RawServoKeyframe; +use crate::gecko_bindings::structs::RawServoKeyframesRule; +use crate::gecko_bindings::structs::RawServoMediaRule; +use crate::gecko_bindings::structs::RawServoMozDocumentRule; +use crate::gecko_bindings::structs::RawServoNamespaceRule; +use crate::gecko_bindings::structs::RawServoPageRule; +use crate::gecko_bindings::structs::RawServoRuleNode; +use crate::gecko_bindings::structs::RawServoRuleNodeStrong; +use crate::gecko_bindings::structs::RawServoSupportsRule; +use crate::gecko_bindings::structs::ServoCssRules; use crate::gecko_bindings::structs::RawServoAnimationValue; use crate::gecko_bindings::structs::RawServoCssUrlData; use crate::gecko_bindings::structs::RawServoDeclarationBlock; diff --git a/components/style/gecko/conversions.rs b/components/style/gecko/conversions.rs index 64f0726b21e..4d667681938 100644 --- a/components/style/gecko/conversions.rs +++ b/components/style/gecko/conversions.rs @@ -12,8 +12,7 @@ use crate::gecko::values::GeckoStyleCoordConvertible; use crate::gecko_bindings::bindings; -use crate::gecko_bindings::structs::RawGeckoGfxMatrix4x4; -use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue}; +use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue, Matrix4x4Components}; use crate::gecko_bindings::structs::{nsStyleImage, nsresult, SheetType}; use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use crate::stylesheets::{Origin, RulesMutateError}; @@ -986,8 +985,8 @@ pub unsafe fn string_from_chars_pointer(p: *const u16) -> String { String::from_utf16_lossy(char_vec) } -impl<'a> From<&'a RawGeckoGfxMatrix4x4> for Matrix3D { - fn from(m: &'a RawGeckoGfxMatrix4x4) -> Matrix3D { +impl<'a> From<&'a Matrix4x4Components> for Matrix3D { + fn from(m: &'a Matrix4x4Components) -> Matrix3D { Matrix3D { m11: m[0], m12: m[1], @@ -1009,12 +1008,13 @@ impl<'a> From<&'a RawGeckoGfxMatrix4x4> for Matrix3D { } } -impl From for RawGeckoGfxMatrix4x4 { - fn from(matrix: Matrix3D) -> RawGeckoGfxMatrix4x4 { +impl From for Matrix4x4Components { + fn from(matrix: Matrix3D) -> Self { [ - matrix.m11, matrix.m12, matrix.m13, matrix.m14, matrix.m21, matrix.m22, matrix.m23, - matrix.m24, matrix.m31, matrix.m32, matrix.m33, matrix.m34, matrix.m41, matrix.m42, - matrix.m43, matrix.m44, + matrix.m11, matrix.m12, matrix.m13, matrix.m14, matrix.m21, + matrix.m22, matrix.m23, matrix.m24, matrix.m31, matrix.m32, + matrix.m33, matrix.m34, matrix.m41, matrix.m42, matrix.m43, + matrix.m44, ] } } diff --git a/components/style/gecko/data.rs b/components/style/gecko/data.rs index b70f376d7e6..ead7d88502b 100644 --- a/components/style/gecko/data.rs +++ b/components/style/gecko/data.rs @@ -6,8 +6,8 @@ use crate::context::QuirksMode; use crate::dom::TElement; -use crate::gecko_bindings::bindings::{self, RawServoStyleSet}; -use crate::gecko_bindings::structs::{self, ServoStyleSetSizes}; +use crate::gecko_bindings::bindings; +use crate::gecko_bindings::structs::{self, RawServoStyleSet, ServoStyleSetSizes}; use crate::gecko_bindings::structs::{StyleSheet as DomStyleSheet, StyleSheetInfo}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; use crate::invalidation::media_queries::{MediaListKey, ToMediaListKey}; diff --git a/components/style/gecko/restyle_damage.rs b/components/style/gecko/restyle_damage.rs index 9c9d07b7112..a97098363cb 100644 --- a/components/style/gecko/restyle_damage.rs +++ b/components/style/gecko/restyle_damage.rs @@ -51,8 +51,8 @@ impl GeckoRestyleDamage { let mut reset_only = false; let hint = unsafe { bindings::Gecko_CalcStyleDifference( - old_style, - new_style, + old_style.as_gecko_computed_style(), + new_style.as_gecko_computed_style(), &mut any_style_changed, &mut reset_only, ) diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index ee3dcced3e4..93d3290c191 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -53,7 +53,7 @@ use crate::gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT; use crate::gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES; use crate::gecko_bindings::structs::NODE_NEEDS_FRAME; use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; -use crate::gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding}; +use crate::gecko_bindings::structs::{Element as RawGeckoElement, nsINode as RawGeckoNode, nsXBLBinding as RawGeckoXBLBinding}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; use crate::global_style_data::GLOBAL_STYLE_DATA; use crate::hash::FxHashMap; @@ -168,11 +168,7 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { where Self: 'a, { - let author_styles = unsafe { - (self.0.mServoStyles.mPtr as *const structs::RawServoAuthorStyles - as *const bindings::RawServoAuthorStyles) - .as_ref()? - }; + let author_styles = unsafe { self.0.mServoStyles.mPtr.as_ref()? }; let author_styles = AuthorStyles::::from_ffi(author_styles); @@ -325,7 +321,7 @@ impl<'ln> GeckoNode<'ln> { // `flattened_tree_parent`. if self.flattened_tree_parent_is_parent() { debug_assert_eq!( - unsafe { bindings::Gecko_GetFlattenedTreeParentNode(self.0).map(GeckoNode) }, + unsafe { bindings::Gecko_GetFlattenedTreeParentNode(self.0).as_ref().map(GeckoNode) }, self.parent_node(), "Fast path stopped holding!" ); @@ -335,7 +331,7 @@ impl<'ln> GeckoNode<'ln> { // NOTE(emilio): If this call is too expensive, we could manually // inline more aggressively. - unsafe { bindings::Gecko_GetFlattenedTreeParentNode(self.0).map(GeckoNode) } + unsafe { bindings::Gecko_GetFlattenedTreeParentNode(self.0).as_ref().map(GeckoNode) } } #[inline] @@ -380,12 +376,12 @@ impl<'ln> TNode for GeckoNode<'ln> { #[inline] fn last_child(&self) -> Option { - unsafe { bindings::Gecko_GetLastChild(self.0).map(GeckoNode) } + unsafe { bindings::Gecko_GetLastChild(self.0).as_ref().map(GeckoNode) } } #[inline] fn prev_sibling(&self) -> Option { - unsafe { bindings::Gecko_GetPreviousSibling(self.0).map(GeckoNode) } + unsafe { bindings::Gecko_GetPreviousSibling(self.0).as_ref().map(GeckoNode) } } #[inline] @@ -502,7 +498,7 @@ impl<'a> Iterator for GeckoChildrenIterator<'a> { // however we can't express this easily with bindgen, and it would // introduce functions with two input lifetimes into bindgen, // which would be out of scope for elision. - bindings::Gecko_GetNextStyleChild(&mut *(it as *mut _)).map(GeckoNode) + bindings::Gecko_GetNextStyleChild(&mut *(it as *mut _)).as_ref().map(GeckoNode) }, } } @@ -548,7 +544,7 @@ impl<'lb> GeckoXBLBinding<'lb> { base.each_xbl_cascade_data(f); } - let data = unsafe { bindings::Gecko_XBLBinding_GetRawServoStyles(self.0) }; + let data = unsafe { bindings::Gecko_XBLBinding_GetRawServoStyles(self.0).as_ref() }; if let Some(data) = data { let data: &'lb _ = AuthorStyles::::from_ffi(data); @@ -709,7 +705,7 @@ impl<'le> GeckoElement<'le> { // FIXME(heycam): Having trouble with bindgen on nsXULElement, // where the binding parent is stored in a member variable // rather than in slots. So just get it through FFI for now. - unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } + unsafe { bindings::Gecko_GetBindingParent(self.0).as_ref().map(GeckoElement) } } else { let binding_parent = unsafe { self.non_xul_xbl_binding_parent_raw_content().as_ref() } .map(GeckoNode::from_content) @@ -717,7 +713,7 @@ impl<'le> GeckoElement<'le> { debug_assert!( binding_parent == - unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } + unsafe { bindings::Gecko_GetBindingParent(self.0).as_ref().map(GeckoElement) } ); binding_parent } @@ -777,7 +773,7 @@ impl<'le> GeckoElement<'le> { return None; } - unsafe { bindings::Gecko_GetBeforeOrAfterPseudo(self.0, is_before).map(GeckoElement) } + unsafe { bindings::Gecko_GetBeforeOrAfterPseudo(self.0, is_before).as_ref().map(GeckoElement) } } #[inline] @@ -887,7 +883,7 @@ impl<'le> GeckoElement<'le> { let mut map = FxHashMap::with_capacity_and_hasher(collection_length, Default::default()); for i in 0..collection_length { - let raw_end_value = unsafe { Gecko_ElementTransitions_EndValueAt(self.0, i) }; + let raw_end_value = unsafe { Gecko_ElementTransitions_EndValueAt(self.0, i).as_ref() }; let end_value = AnimationValue::arc_from_borrowed(&raw_end_value) .expect("AnimationValue not found in ElementTransitions"); @@ -1270,7 +1266,7 @@ impl<'le> TElement for GeckoElement<'le> { return None; } - let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; + let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0).as_ref() }; let declarations: Option<&RawOffsetArc>> = declarations.and_then(|s| s.as_arc_opt()); declarations.map(|s| s.borrow_arc()) @@ -1551,8 +1547,10 @@ impl<'le> TElement for GeckoElement<'le> { // should destroy all CSS animations in display:none subtree. let computed_data = self.borrow_data(); let computed_values = computed_data.as_ref().map(|d| d.styles.primary()); - let before_change_values = before_change_style.as_ref().map(|x| &**x); - let computed_values_opt = computed_values.as_ref().map(|x| &***x); + let before_change_values = + before_change_style.as_ref().map_or(ptr::null(), |x| x.as_gecko_computed_style()); + let computed_values_opt = + computed_values.as_ref().map_or(ptr::null(), |x| x.as_gecko_computed_style()); unsafe { Gecko_UpdateAnimations( self.0, @@ -1828,7 +1826,7 @@ impl<'le> TElement for GeckoElement<'le> { hints.push(SVG_TEXT_DISABLE_ZOOM_RULE.clone()); } } - let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0) }; + let declarations = unsafe { Gecko_GetHTMLPresentationAttrDeclarationBlock(self.0).as_ref() }; let declarations: Option<&RawOffsetArc>> = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { @@ -1837,7 +1835,7 @@ impl<'le> TElement for GeckoElement<'le> { ServoCascadeLevel::PresHints, )); } - let declarations = unsafe { Gecko_GetExtraContentStyleDeclarations(self.0) }; + let declarations = unsafe { Gecko_GetExtraContentStyleDeclarations(self.0).as_ref() }; let declarations: Option<&RawOffsetArc>> = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { @@ -1859,10 +1857,10 @@ impl<'le> TElement for GeckoElement<'le> { ); }, VisitedHandlingMode::AllLinksUnvisited => unsafe { - Gecko_GetUnvisitedLinkAttrDeclarationBlock(self.0) + Gecko_GetUnvisitedLinkAttrDeclarationBlock(self.0).as_ref() }, VisitedHandlingMode::RelevantLinkVisited => unsafe { - Gecko_GetVisitedLinkAttrDeclarationBlock(self.0) + Gecko_GetVisitedLinkAttrDeclarationBlock(self.0).as_ref() }, }; let declarations: Option<&RawOffsetArc>> = @@ -1878,7 +1876,7 @@ impl<'le> TElement for GeckoElement<'le> { .state() .intersects(NonTSPseudoClass::Active.state_flag()); if active { - let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0) }; + let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0).as_ref() }; let declarations: Option<&RawOffsetArc>> = declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index b289e2e21ec..1ad71afa6bc 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -285,7 +285,7 @@ macro_rules! impl_threadsafe_refcount { } impl_threadsafe_refcount!( - structs::RawGeckoURLExtraData, + structs::mozilla::URLExtraData, bindings::Gecko_AddRefURLExtraDataArbitraryThread, bindings::Gecko_ReleaseURLExtraDataArbitraryThread ); diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 331ffb5c34f..0879e5846c3 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -66,16 +66,25 @@ use crate::values::generics::url::UrlOrNone; pub mod style_structs { % for style_struct in data.style_structs: pub use super::${style_struct.gecko_struct_name} as ${style_struct.name}; + + unsafe impl Send for ${style_struct.name} {} + unsafe impl Sync for ${style_struct.name} {} % endfor + } /// FIXME(emilio): This is completely duplicated with the other properties code. -pub type ComputedValuesInner = crate::gecko_bindings::structs::ServoComputedData; +pub type ComputedValuesInner = structs::ServoComputedData; #[repr(C)] -pub struct ComputedValues(crate::gecko_bindings::structs::mozilla::ComputedStyle); +pub struct ComputedValues(structs::mozilla::ComputedStyle); impl ComputedValues { + #[inline] + pub (crate) fn as_gecko_computed_style(&self) -> &structs::ComputedStyle { + &self.0 + } + pub fn new( pseudo: Option<<&PseudoElement>, custom_properties: Option>, @@ -929,7 +938,7 @@ transform_functions = [ debug_assert!(!${item}${index + 1}.0.is_empty()); % endif ${css_value_setters[item] % ( - "bindings::Gecko_CSSValue_GetArrayItem(gecko_value, %d)" % (index + 1), + "(&mut *bindings::Gecko_CSSValue_GetArrayItem(gecko_value, %d))" % (index + 1), item + str(index + 1) )}; % endfor @@ -980,7 +989,7 @@ transform_functions = [ % endif <% getter = css_value_getters[item] % ( - "bindings::Gecko_CSSValue_GetArrayItemConst(gecko_value, %d)" % (index + 1) + "(&*bindings::Gecko_CSSValue_GetArrayItemConst(gecko_value, %d))" % (index + 1) ) %> ${getter}, @@ -989,6 +998,7 @@ transform_functions = [ }, +#[allow(unused_parens)] fn set_single_transform_function( servo_value: &values::computed::TransformOperation, gecko_value: &mut structs::nsCSSValue /* output */ @@ -1031,6 +1041,7 @@ pub fn convert_transform( output.set_move(list); } +#[allow(unused_parens)] fn clone_single_transform_function( gecko_value: &structs::nsCSSValue ) -> values::computed::TransformOperation {