From eda6a4fc4f3025dc850c1e87e81dee9854006f0e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 22 Feb 2017 17:19:04 -0800 Subject: [PATCH] stylo: Pass parser URL data in Servo_DeclarationBlock_SetProperty* MozReview-Commit-ID: EVk4aEoyiXv --- components/style/build_gecko.rs | 2 + components/style/gecko_bindings/bindings.rs | 21 +++++--- .../style/gecko_bindings/structs_debug.rs | 34 +++++++++++++ .../style/gecko_bindings/structs_release.rs | 34 +++++++++++++ components/style/parser.rs | 16 ++++++ ports/geckolib/glue.rs | 50 ++++++++++++------- 6 files changed, 132 insertions(+), 25 deletions(-) diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index 7b13ff0e1fd..e29d111723e 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -317,6 +317,7 @@ mod bindings { "FontFamilyType", "FragmentOrURL", "FrameRequestCallback", + "GeckoParserExtraData", "gfxAlternateValue", "gfxFontFeature", "gfxFontVariation", @@ -538,6 +539,7 @@ mod bindings { "RawServoDeclarationBlock", "RawGeckoPresContext", "RawGeckoPresContextOwned", + "GeckoParserExtraData", "RefPtr", "ThreadSafeURIHolder", "ThreadSafePrincipalHolder", diff --git a/components/style/gecko_bindings/bindings.rs b/components/style/gecko_bindings/bindings.rs index 763ad94e219..13617160f9a 100644 --- a/components/style/gecko_bindings/bindings.rs +++ b/components/style/gecko_bindings/bindings.rs @@ -14,6 +14,7 @@ use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoDeclarationBlock; use gecko_bindings::structs::RawGeckoPresContext; use gecko_bindings::structs::RawGeckoPresContextOwned; +use gecko_bindings::structs::GeckoParserExtraData; use gecko_bindings::structs::RefPtr; use gecko_bindings::structs::ThreadSafeURIHolder; use gecko_bindings::structs::ThreadSafePrincipalHolder; @@ -1339,10 +1340,8 @@ extern "C" { extern "C" { pub fn Servo_ParseProperty(property: *const nsACString_internal, value: *const nsACString_internal, - base_url: *const nsACString_internal, - base: *mut ThreadSafeURIHolder, - referrer: *mut ThreadSafeURIHolder, - principal: *mut ThreadSafePrincipalHolder) + base: *const nsACString_internal, + data: *const GeckoParserExtraData) -> RawServoDeclarationBlockStrong; } extern "C" { @@ -1466,7 +1465,12 @@ extern "C" { *const nsACString_internal, value: *const nsACString_internal, - is_important: bool) -> bool; + is_important: bool, + base: + *const nsACString_internal, + data: + *const GeckoParserExtraData) + -> bool; } extern "C" { pub fn Servo_DeclarationBlock_SetPropertyById(declarations: @@ -1474,7 +1478,12 @@ extern "C" { property: nsCSSPropertyID, value: *const nsACString_internal, - is_important: bool) -> bool; + is_important: bool, + base: + *const nsACString_internal, + data: + *const GeckoParserExtraData) + -> bool; } extern "C" { pub fn Servo_DeclarationBlock_RemoveProperty(declarations: diff --git a/components/style/gecko_bindings/structs_debug.rs b/components/style/gecko_bindings/structs_debug.rs index f26967f17d6..d8c822f842d 100644 --- a/components/style/gecko_bindings/structs_debug.rs +++ b/components/style/gecko_bindings/structs_debug.rs @@ -25749,6 +25749,40 @@ pub mod root { impl Clone for ServoBundledURI { fn clone(&self) -> Self { *self } } + #[repr(C)] + #[derive(Debug)] + pub struct GeckoParserExtraData { + pub mBaseURI: root::RefPtr>, + pub mReferrer: root::RefPtr>, + pub mPrincipal: root::RefPtr>, + } + #[test] + fn bindgen_test_layout_GeckoParserExtraData() { + assert_eq!(::std::mem::size_of::() , 24usize , + concat ! ( + "Size of: " , stringify ! ( GeckoParserExtraData ) )); + assert_eq! (::std::mem::align_of::() , 8usize , + concat ! ( + "Alignment of " , stringify ! ( GeckoParserExtraData ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mBaseURI + as * const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mBaseURI ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mReferrer + as * const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mReferrer ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mPrincipal + as * const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mPrincipal ) + )); + } pub type nsMediaFeatureValueGetter = ::std::option::Option Self { *self } } + #[repr(C)] + #[derive(Debug)] + pub struct GeckoParserExtraData { + pub mBaseURI: root::RefPtr>, + pub mReferrer: root::RefPtr>, + pub mPrincipal: root::RefPtr>, + } + #[test] + fn bindgen_test_layout_GeckoParserExtraData() { + assert_eq!(::std::mem::size_of::() , 24usize , + concat ! ( + "Size of: " , stringify ! ( GeckoParserExtraData ) )); + assert_eq! (::std::mem::align_of::() , 8usize , + concat ! ( + "Alignment of " , stringify ! ( GeckoParserExtraData ) )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mBaseURI + as * const _ as usize } , 0usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mBaseURI ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mReferrer + as * const _ as usize } , 8usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mReferrer ) + )); + assert_eq! (unsafe { + & ( * ( 0 as * const GeckoParserExtraData ) ) . mPrincipal + as * const _ as usize } , 16usize , concat ! ( + "Alignment of field: " , stringify ! ( + GeckoParserExtraData ) , "::" , stringify ! ( mPrincipal ) + )); + } pub type nsMediaFeatureValueGetter = ::std::option::Option Self { + // the to_safe calls are safe since we trust that we have references to + // real Gecko refptrs. The dereferencing of data is safe because this function + // is expected to be called with a `data` living longer than this function. + unsafe { ParserContextExtraData { + base: Some((*data).mBaseURI.to_safe()), + referrer: Some((*data).mReferrer.to_safe()), + principal: Some((*data).mPrincipal.to_safe()), + }} + } +} /// The data that the parser needs from outside in order to parse a stylesheet. pub struct ParserContext<'a> { /// The `Origin` of the stylesheet, whether it's a user, author or diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index aab286b9ba8..15ca0c5a52f 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -681,11 +681,21 @@ pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () { let _ = data.into_box::(); } +// Must be a macro since we need to store the base_url on the stack somewhere +/// Initializes the data needed for constructing a ParserContext from +/// Gecko-side values +macro_rules! make_context { + (($base:ident, $data:ident) => ($base_url:ident, $extra_data:ident)) => { + let base_str = unsafe { $base.as_ref().unwrap().as_str_unchecked() }; + let $base_url = ServoUrl::parse(base_str).unwrap(); + let $extra_data = unsafe { ParserContextExtraData::new($data) }; + } +} + #[no_mangle] pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const nsACString, - base_url: *const nsACString, base: *mut ThreadSafeURIHolder, - referrer: *mut ThreadSafeURIHolder, - principal: *mut ThreadSafePrincipalHolder) + base: *const nsACString, + data: *const structs::GeckoParserExtraData) -> RawServoDeclarationBlockStrong { let name = unsafe { property.as_ref().unwrap().as_str_unchecked() }; let id = if let Ok(id) = PropertyId::parse(name.into()) { @@ -694,15 +704,11 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const return RawServoDeclarationBlockStrong::null() }; let value = unsafe { value.as_ref().unwrap().as_str_unchecked() }; - let base_str = unsafe { base_url.as_ref().unwrap().as_str_unchecked() }; - let base_url = ServoUrl::parse(base_str).unwrap(); - let extra_data = unsafe { ParserContextExtraData { - base: Some(GeckoArcURI::new(base)), - referrer: Some(GeckoArcURI::new(referrer)), - principal: Some(GeckoArcPrincipal::new(principal)), - }}; - let context = ParserContext::new_with_extra_data(Origin::Author, &base_url, + make_context!((base, data) => (base_url, extra_data)); + + let context = ParserContext::new_with_extra_data(Origin::Author, + &base_url, Box::new(StdoutErrorReporter), extra_data); @@ -819,11 +825,11 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: Ra } fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId, - value: *const nsACString, is_important: bool) -> bool { + value: *const nsACString, is_important: bool, + base: *const nsACString, data: *const structs::GeckoParserExtraData) -> bool { let value = unsafe { value.as_ref().unwrap().as_str_unchecked() }; - // FIXME Needs real URL and ParserContextExtraData. - let base_url = &*DUMMY_BASE_URL; - let extra_data = ParserContextExtraData::default(); + + make_context!((base, data) => (base_url, extra_data)); if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url, Box::new(StdoutErrorReporter), extra_data) { let mut declarations = RwLock::::as_arc(&declarations).write(); @@ -841,15 +847,21 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_SetProperty(declarations: RawServoDeclarationBlockBorrowed, property: *const nsACString, value: *const nsACString, - is_important: bool) -> bool { - set_property(declarations, get_property_id_from_property!(property, false), value, is_important) + is_important: bool, + base: *const nsACString, + data: *const structs::GeckoParserExtraData) -> bool { + set_property(declarations, get_property_id_from_property!(property, false), + value, is_important, base, data) } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoDeclarationBlockBorrowed, property: nsCSSPropertyID, value: *const nsACString, - is_important: bool) -> bool { - set_property(declarations, get_property_id_from_nscsspropertyid!(property, false), value, is_important) + is_important: bool, + base: *const nsACString, + data: *const structs::GeckoParserExtraData) -> bool { + set_property(declarations, get_property_id_from_nscsspropertyid!(property, false), + value, is_important, base, data) } fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) {