Bug 1372061 - Change StyleChildrenIterator FFI functions to use placement new/delete. r=bholley
MozReview-Commit-ID: BEWvJcaJxA
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -259,18 +259,21 @@ private:
* At present, this is identical to AllChildrenIterator with
* (eAllChildren | eSkipDocumentLevelNativeAnonymousContent). We used to have
* detect and skip any native anonymous children that are used to implement some
* special magic in here that went away, but we keep the separate class so
* we can reintroduce special magic back if needed.
*
* Note: it assumes that no mutation of the DOM or frame tree takes place during
* iteration, and will break horribly if that is not true.
+ *
+ * We require this to be memmovable since Rust code can create and move
+ * StyleChildrenIterators.
*/
-class StyleChildrenIterator : private AllChildrenIterator
+class MOZ_NEEDS_MEMMOVABLE_MEMBERS StyleChildrenIterator : private AllChildrenIterator
{
public:
explicit StyleChildrenIterator(const nsIContent* aContent)
: AllChildrenIterator(aContent,
nsIContent::eAllChildren |
nsIContent::eSkipDocumentLevelNativeAnonymousContent)
{
MOZ_COUNT_CTOR(StyleChildrenIterator);
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -63,16 +63,17 @@ typedef nsTArray<mozilla::Keyframe> RawG
typedef nsTArray<mozilla::ComputedKeyframeValues> RawGeckoComputedKeyframeValuesList;
typedef nsStyleAutoArray<mozilla::StyleAnimation> RawGeckoStyleAnimationList;
typedef nsTArray<nsFontFaceRuleContainer> RawGeckoFontFaceRuleList;
typedef mozilla::AnimationPropertySegment RawGeckoAnimationPropertySegment;
typedef mozilla::ComputedTiming RawGeckoComputedTiming;
typedef nsTArray<const RawServoStyleRule*> RawGeckoServoStyleRuleList;
typedef nsTArray<nsCSSPropertyID> RawGeckoCSSPropertyIDList;
typedef mozilla::gfx::Float RawGeckoGfxMatrix4x4[16];
+typedef mozilla::dom::StyleChildrenIterator RawGeckoStyleChildrenIterator;
// We have these helper types so that we can directly generate
// things like &T or Borrowed<T> on the Rust side in the function, providing
// additional safety benefits.
//
// FFI has a problem with templated types, so we just use raw pointers here.
//
// The "Borrowed" types generate &T or Borrowed<T> in the nullable case.
@@ -151,16 +152,17 @@ DECL_BORROWED_MUT_REF_TYPE_FOR(nsTimingF
DECL_BORROWED_REF_TYPE_FOR(nsTimingFunction)
DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoFontFaceRuleList)
DECL_BORROWED_REF_TYPE_FOR(RawGeckoAnimationPropertySegment)
DECL_BORROWED_REF_TYPE_FOR(RawGeckoComputedTiming)
DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoServoStyleRuleList)
DECL_BORROWED_MUT_REF_TYPE_FOR(nsCSSPropertyIDSet)
DECL_BORROWED_REF_TYPE_FOR(RawGeckoCSSPropertyIDList)
DECL_BORROWED_REF_TYPE_FOR(nsXBLBinding)
+DECL_BORROWED_MUT_REF_TYPE_FOR(RawGeckoStyleChildrenIterator)
#undef DECL_ARC_REF_TYPE_FOR
#undef DECL_OWNED_REF_TYPE_FOR
#undef DECL_NULLABLE_OWNED_REF_TYPE_FOR
#undef DECL_BORROWED_REF_TYPE_FOR
#undef DECL_NULLABLE_BORROWED_REF_TYPE_FOR
#undef DECL_BORROWED_MUT_REF_TYPE_FOR
#undef DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -200,48 +200,48 @@ Gecko_GetAnonymousContentForElement(RawG
void
Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
{
MOZ_ASSERT(aAnonContent);
delete aAnonContent;
}
-StyleChildrenIteratorOwnedOrNull
-Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed aNode)
+void
+Gecko_ConstructStyleChildrenIterator(
+ RawGeckoElementBorrowed aElement,
+ RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
{
- if (!aNode->IsElement()) {
- return nullptr;
- }
-
- const Element* el = aNode->AsElement();
- return StyleChildrenIterator::IsNeeded(el) ? new StyleChildrenIterator(el)
- : nullptr;
+ MOZ_ASSERT(aElement);
+ MOZ_ASSERT(aIterator);
+ new (aIterator) StyleChildrenIterator(aElement);
}
void
-Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned aIterator)
+Gecko_DestroyStyleChildrenIterator(
+ RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
{
MOZ_ASSERT(aIterator);
- delete aIterator;
+
+ aIterator->~StyleChildrenIterator();
}
nsIContent*
Gecko_ElementBindingAnonymousContent(RawGeckoElementBorrowed aElement)
{
MOZ_ASSERT(aElement->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR));
nsBindingManager* manager = aElement->OwnerDoc()->BindingManager();
if (nsXBLBinding* binding = manager->GetBindingWithContent(aElement)) {
return binding->GetAnonymousContent();
}
return nullptr;
}
RawGeckoNodeBorrowed
-Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowedMut aIterator)
+Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
{
MOZ_ASSERT(aIterator);
return aIterator->GetNextChild();
}
EventStates::ServoType
Gecko_ElementState(RawGeckoElementBorrowed aElement)
{
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -131,22 +131,21 @@ RawGeckoNodeBorrowedOrNull Gecko_GetLast
RawGeckoNodeBorrowedOrNull Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed node);
RawGeckoElementBorrowedOrNull Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed element, bool is_before);
nsTArray<nsIContent*>* Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed element);
void Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* anon_content);
// By default, Servo walks the DOM by traversing the siblings of the DOM-view
// first child. This generally works, but misses anonymous children, which we
// want to traverse during styling. To support these cases, we create an
-// optional heap-allocated iterator for nodes that need it. If the creation
-// method returns null, Servo falls back to the aforementioned simpler (and
-// faster) sibling traversal.
-StyleChildrenIteratorOwnedOrNull Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed node);
-void Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned it);
-RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowedMut it);
+// optional stack-allocated iterator in aIterator for nodes that need it.
+void Gecko_ConstructStyleChildrenIterator(RawGeckoElementBorrowed aElement,
+ RawGeckoStyleChildrenIteratorBorrowedMut aIterator);
+void Gecko_DestroyStyleChildrenIterator(RawGeckoStyleChildrenIteratorBorrowedMut aIterator);
+RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut it);
void Gecko_LoadStyleSheet(mozilla::css::Loader* loader,
mozilla::ServoStyleSheet* parent,
mozilla::css::LoaderReusableStyleSheets* reusable_sheets,
RawServoStyleSheetBorrowed child_sheet,
RawGeckoURLExtraData* base_url_data,
const uint8_t* url_bytes,
uint32_t url_length,
--- a/layout/style/ServoBindings.toml
+++ b/layout/style/ServoBindings.toml
@@ -52,16 +52,17 @@ headers = [
"mozilla/dom/KeyframeEffectBinding.h",
"mozilla/AnimationPropertySegment.h",
"mozilla/ComputedTiming.h",
"mozilla/ComputedTimingFunction.h",
"mozilla/Keyframe.h",
"mozilla/ServoElementSnapshot.h",
"mozilla/ServoElementSnapshotTable.h",
"mozilla/dom/Element.h",
+ "mozilla/dom/ChildIterator.h",
"mozilla/dom/NameSpaceConstants.h",
"mozilla/LookAndFeel.h",
"mozilla/ServoBindings.h",
"nsCSSCounterStyleRule.h",
"nsCSSFontFaceRule.h",
"nsMediaFeatures.h",
"nsMediaList.h",
"nsXBLBinding.h",
@@ -118,16 +119,17 @@ whitelist-types = [
"mozilla::ComputedTimingFunction",
"mozilla::ComputedTimingFunction::BeforeFlag",
"mozilla::ServoStyleSheet",
"mozilla::ServoElementSnapshot.*",
"mozilla::CSSPseudoClassType",
"mozilla::css::SheetParsingMode",
"mozilla::css::URLMatchingFunction",
"mozilla::dom::IterationCompositeOperation",
+ "mozilla::dom::StyleChildrenIterator",
"mozilla::HalfCorner",
"mozilla::PropertyStyleAnimationValuePair",
"mozilla::TraversalRestyleBehavior",
"mozilla::TraversalRootBehavior",
"mozilla::StyleShapeRadius",
"mozilla::StyleGrid.*",
"mozilla::UpdateAnimationsTasks",
"mozilla::LookAndFeel",
@@ -341,16 +343,17 @@ structs-types = [
"RawGeckoNode",
"RawServoAnimationValue",
"RawGeckoServoAnimationValueList",
"RawServoDeclarationBlock",
"RawServoStyleRule",
"RawGeckoPresContext",
"RawGeckoPresContextOwned",
"RawGeckoStyleAnimationList",
+ "RawGeckoStyleChildrenIteratorBorrowedMut",
"RawGeckoServoStyleRuleList",
"RawGeckoURLExtraData",
"RawGeckoXBLBinding",
"RefPtr",
"CSSPseudoClassType",
"CSSPseudoElementType",
"TraversalRestyleBehavior",
"TraversalRootBehavior",
@@ -446,17 +449,16 @@ structs-types = [
"nsStyleTransformMatrix::MatrixTransformOperator",
"RawGeckoGfxMatrix4x4",
]
array-types = [
{ cpp-type = "uintptr_t", rust-type = "usize" },
]
servo-owned-types = [
{ name = "RawServoStyleSet", opaque = true },
- { name = "StyleChildrenIterator", opaque = true },
{ name = "ServoElementSnapshot", opaque = false },
{ name = "RawServoAnimationValueMap", opaque = true },
]
servo-immutable-borrow-types = [
"RawGeckoNode",
"RawGeckoElement",
"RawGeckoDocument",
"RawServoDeclarationBlockStrong",