--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -14,42 +14,42 @@
* and the parameter list of the function.
*
* Users of this list should define a macro
* SERVO_BINDING_FUNC(name_, return_, ...)
* before including this file.
*/
// Node data
-SERVO_BINDING_FUNC(Servo_NodeData_Drop, void, ServoNodeData* data)
+SERVO_BINDING_FUNC(Servo_NodeData_Drop, void, ServoNodeDataOwned data)
// Styleset and Stylesheet management
SERVO_BINDING_FUNC(Servo_StyleSheet_FromUTF8Bytes, RawServoStyleSheetStrong,
const uint8_t* bytes, uint32_t length,
mozilla::css::SheetParsingMode parsing_mode,
const uint8_t* base_bytes, uint32_t base_length,
ThreadSafeURIHolder* base,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal)
SERVO_BINDING_FUNC(Servo_StyleSheet_AddRef, void,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_Release, void,
RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
RawServoStyleSheetBorrowed sheet)
-SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSet*)
-SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSet* set)
+SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned)
+SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSetOwned set)
SERVO_BINDING_FUNC(Servo_StyleSet_AppendStyleSheet, void,
- RawServoStyleSet* set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
- RawServoStyleSet* set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
- RawServoStyleSet* set, RawServoStyleSheetBorrowed sheet)
+ RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
- RawServoStyleSet* set, RawServoStyleSheetBorrowed sheet,
+ RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet,
RawServoStyleSheetBorrowed reference)
// Style attribute
SERVO_BINDING_FUNC(Servo_ParseStyleAttribute, ServoDeclarationBlockStrong,
const uint8_t* bytes, uint32_t length,
nsHTMLCSSStyleSheet* cache)
SERVO_BINDING_FUNC(Servo_DeclarationBlock_AddRef, void,
ServoDeclarationBlockBorrowed declarations)
@@ -64,48 +64,48 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
// CSS supports()
SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
const uint8_t* name, uint32_t name_length,
const uint8_t* value, uint32_t value_length)
// Computed style data
SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
- RawGeckoNode* node)
+ RawGeckoNodeBorrowed node)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
ServoComputedValuesStrong,
- ServoComputedValuesBorrowed parent_style_or_null,
- nsIAtom* pseudoTag, RawServoStyleSet* set)
+ ServoComputedValuesBorrowedOrNull parent_style_or_null,
+ nsIAtom* pseudoTag, RawServoStyleSetBorrowedMut set)
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForPseudoElement,
ServoComputedValuesStrong,
ServoComputedValuesBorrowed parent_style,
- RawGeckoElement* match_element, nsIAtom* pseudo_tag,
- RawServoStyleSet* set, bool is_probe)
+ RawGeckoElementBorrowed match_element, nsIAtom* pseudo_tag,
+ RawServoStyleSetBorrowedMut set, bool is_probe)
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
- ServoComputedValuesBorrowed parent_style)
+ ServoComputedValuesBorrowedOrNull parent_style)
SERVO_BINDING_FUNC(Servo_ComputedValues_AddRef, void,
ServoComputedValuesBorrowed computed_values)
SERVO_BINDING_FUNC(Servo_ComputedValues_Release, void,
ServoComputedValuesBorrowed computed_values)
// Initialize Servo components. Should be called exactly once at startup.
SERVO_BINDING_FUNC(Servo_Initialize, void)
// Shut down Servo components. Should be called exactly once at shutdown.
SERVO_BINDING_FUNC(Servo_Shutdown, void)
// Restyle hints
SERVO_BINDING_FUNC(Servo_ComputeRestyleHint, nsRestyleHint,
RawGeckoElement* element, ServoElementSnapshot* snapshot,
- RawServoStyleSet* set)
+ RawServoStyleSetBorrowed set)
// Restyle the given document or subtree
SERVO_BINDING_FUNC(Servo_RestyleDocument, void,
- RawGeckoDocument* doc, RawServoStyleSet* set)
+ RawGeckoDocumentBorrowed doc, RawServoStyleSetBorrowedMut set)
SERVO_BINDING_FUNC(Servo_RestyleSubtree, void,
- RawGeckoNode* node, RawServoStyleSet* set)
+ RawGeckoNodeBorrowed node, RawServoStyleSetBorrowedMut set)
// Style-struct management.
#define STYLE_STRUCT(name, checkdata_cb) \
struct nsStyle##name; \
SERVO_BINDING_FUNC(Servo_GetStyle##name, const nsStyle##name*, \
ServoComputedValuesBorrowed computed_values)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -44,202 +44,202 @@ using namespace mozilla::dom;
IMPL_STRONG_REF_TYPE_FOR(ServoComputedValues)
IMPL_STRONG_REF_TYPE_FOR(RawServoStyleSheet)
IMPL_STRONG_REF_TYPE_FOR(ServoDeclarationBlock)
#undef IMPL_STRONG_REF_TYPE_FOR
uint32_t
-Gecko_ChildrenCount(RawGeckoNode* aNode)
+Gecko_ChildrenCount(RawGeckoNodeBorrowed aNode)
{
return aNode->GetChildCount();
}
bool
-Gecko_NodeIsElement(RawGeckoNode* aNode)
+Gecko_NodeIsElement(RawGeckoNodeBorrowed aNode)
{
return aNode->IsElement();
}
-RawGeckoNode*
-Gecko_GetParentNode(RawGeckoNode* aNode)
+RawGeckoNodeBorrowedOrNull
+Gecko_GetParentNode(RawGeckoNodeBorrowed aNode)
{
return aNode->GetFlattenedTreeParentNode();
}
-RawGeckoNode*
-Gecko_GetFirstChild(RawGeckoNode* aNode)
+RawGeckoNodeBorrowedOrNull
+Gecko_GetFirstChild(RawGeckoNodeBorrowed aNode)
{
return aNode->GetFirstChild();
}
-RawGeckoNode*
-Gecko_GetLastChild(RawGeckoNode* aNode)
+RawGeckoNodeBorrowedOrNull
+Gecko_GetLastChild(RawGeckoNodeBorrowed aNode)
{
return aNode->GetLastChild();
}
-RawGeckoNode*
-Gecko_GetPrevSibling(RawGeckoNode* aNode)
+RawGeckoNodeBorrowedOrNull
+Gecko_GetPrevSibling(RawGeckoNodeBorrowed aNode)
{
return aNode->GetPreviousSibling();
}
-RawGeckoNode*
-Gecko_GetNextSibling(RawGeckoNode* aNode)
+RawGeckoNodeBorrowedOrNull
+Gecko_GetNextSibling(RawGeckoNodeBorrowed aNode)
{
return aNode->GetNextSibling();
}
-RawGeckoElement*
-Gecko_GetParentElement(RawGeckoElement* aElement)
+RawGeckoElementBorrowedOrNull
+Gecko_GetParentElement(RawGeckoElementBorrowed aElement)
{
nsINode* parentNode = aElement->GetFlattenedTreeParentNode();
return parentNode->IsElement() ? parentNode->AsElement() : nullptr;
}
-RawGeckoElement*
-Gecko_GetFirstChildElement(RawGeckoElement* aElement)
+RawGeckoElementBorrowedOrNull
+Gecko_GetFirstChildElement(RawGeckoElementBorrowed aElement)
{
return aElement->GetFirstElementChild();
}
-RawGeckoElement* Gecko_GetLastChildElement(RawGeckoElement* aElement)
+RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed aElement)
{
return aElement->GetLastElementChild();
}
-RawGeckoElement*
-Gecko_GetPrevSiblingElement(RawGeckoElement* aElement)
+RawGeckoElementBorrowedOrNull
+Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed aElement)
{
return aElement->GetPreviousElementSibling();
}
-RawGeckoElement*
-Gecko_GetNextSiblingElement(RawGeckoElement* aElement)
+RawGeckoElementBorrowedOrNull
+Gecko_GetNextSiblingElement(RawGeckoElementBorrowed aElement)
{
return aElement->GetNextElementSibling();
}
-RawGeckoElement*
-Gecko_GetDocumentElement(RawGeckoDocument* aDoc)
+RawGeckoElementBorrowedOrNull
+Gecko_GetDocumentElement(RawGeckoDocumentBorrowed aDoc)
{
return aDoc->GetDocumentElement();
}
-StyleChildrenIterator*
-Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNode* aNode)
+StyleChildrenIteratorOwnedOrNull
+Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed aNode)
{
if (!aNode->IsElement()) {
return nullptr;
}
Element* el = aNode->AsElement();
return StyleChildrenIterator::IsNeeded(el) ? new StyleChildrenIterator(el)
: nullptr;
}
void
-Gecko_DropStyleChildrenIterator(StyleChildrenIterator* aIterator)
+Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned aIterator)
{
MOZ_ASSERT(aIterator);
delete aIterator;
}
-RawGeckoNode*
-Gecko_GetNextStyleChild(StyleChildrenIterator* aIterator)
+RawGeckoNodeBorrowed
+Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowed aIterator)
{
MOZ_ASSERT(aIterator);
return aIterator->GetNextChild();
}
EventStates::ServoType
-Gecko_ElementState(RawGeckoElement* aElement)
+Gecko_ElementState(RawGeckoElementBorrowed aElement)
{
return aElement->StyleState().ServoValue();
}
bool
-Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* aElement)
+Gecko_IsHTMLElementInHTMLDocument(RawGeckoElementBorrowed aElement)
{
return aElement->IsHTMLElement() && aElement->OwnerDoc()->IsHTMLDocument();
}
bool
-Gecko_IsLink(RawGeckoElement* aElement)
+Gecko_IsLink(RawGeckoElementBorrowed aElement)
{
return nsCSSRuleProcessor::IsLink(aElement);
}
bool
-Gecko_IsTextNode(RawGeckoNode* aNode)
+Gecko_IsTextNode(RawGeckoNodeBorrowed aNode)
{
return aNode->NodeInfo()->NodeType() == nsIDOMNode::TEXT_NODE;
}
bool
-Gecko_IsVisitedLink(RawGeckoElement* aElement)
+Gecko_IsVisitedLink(RawGeckoElementBorrowed aElement)
{
return aElement->StyleState().HasState(NS_EVENT_STATE_VISITED);
}
bool
-Gecko_IsUnvisitedLink(RawGeckoElement* aElement)
+Gecko_IsUnvisitedLink(RawGeckoElementBorrowed aElement)
{
return aElement->StyleState().HasState(NS_EVENT_STATE_UNVISITED);
}
bool
-Gecko_IsRootElement(RawGeckoElement* aElement)
+Gecko_IsRootElement(RawGeckoElementBorrowed aElement)
{
return aElement->OwnerDoc()->GetRootElement() == aElement;
}
nsIAtom*
-Gecko_LocalName(RawGeckoElement* aElement)
+Gecko_LocalName(RawGeckoElementBorrowed aElement)
{
return aElement->NodeInfo()->NameAtom();
}
nsIAtom*
-Gecko_Namespace(RawGeckoElement* aElement)
+Gecko_Namespace(RawGeckoElementBorrowed aElement)
{
int32_t id = aElement->NodeInfo()->NamespaceID();
return nsContentUtils::NameSpaceManager()->NameSpaceURIAtomForServo(id);
}
nsIAtom*
-Gecko_GetElementId(RawGeckoElement* aElement)
+Gecko_GetElementId(RawGeckoElementBorrowed aElement)
{
const nsAttrValue* attr = aElement->GetParsedAttr(nsGkAtoms::id);
return attr ? attr->GetAtomValue() : nullptr;
}
// Dirtiness tracking.
uint32_t
-Gecko_GetNodeFlags(RawGeckoNode* aNode)
+Gecko_GetNodeFlags(RawGeckoNodeBorrowed aNode)
{
return aNode->GetFlags();
}
void
-Gecko_SetNodeFlags(RawGeckoNode* aNode, uint32_t aFlags)
+Gecko_SetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
{
aNode->SetFlags(aFlags);
}
void
-Gecko_UnsetNodeFlags(RawGeckoNode* aNode, uint32_t aFlags)
+Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
{
aNode->UnsetFlags(aFlags);
}
nsStyleContext*
-Gecko_GetStyleContext(RawGeckoNode* aNode, nsIAtom* aPseudoTagOrNull)
+Gecko_GetStyleContext(RawGeckoNodeBorrowed aNode, nsIAtom* aPseudoTagOrNull)
{
MOZ_ASSERT(aNode->IsContent());
nsIFrame* relevantFrame =
ServoRestyleManager::FrameForPseudoElement(aNode->AsContent(),
aPseudoTagOrNull);
if (!relevantFrame) {
return nullptr;
}
@@ -267,17 +267,17 @@ Gecko_CalcStyleDifference(nsStyleContext
forDescendants,
&equalStructs,
&samePointerStructs);
return result;
}
void
-Gecko_StoreStyleDifference(RawGeckoNode* aNode, nsChangeHint aChangeHintToStore)
+Gecko_StoreStyleDifference(RawGeckoNodeBorrowed aNode, nsChangeHint aChangeHintToStore)
{
#ifdef MOZ_STYLO
MOZ_ASSERT(aNode->IsContent());
MOZ_ASSERT(aNode->IsDirtyForServo(),
"Change hint stored in a not-dirty node");
// For elements, we need to store the change hint in the proper style context.
// For text nodes, we want to store the change hint in the parent element,
@@ -310,17 +310,17 @@ Gecko_StoreStyleDifference(RawGeckoNode*
primaryFrame->StyleContext()->StoreChangeHint(aChangeHintToStore);
#else
MOZ_CRASH("stylo: Shouldn't call Gecko_StoreStyleDifference in "
"non-stylo build");
#endif
}
ServoDeclarationBlock*
-Gecko_GetServoDeclarationBlock(RawGeckoElement* aElement)
+Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed aElement)
{
const nsAttrValue* attr = aElement->GetParsedAttr(nsGkAtoms::style);
if (!attr || attr->Type() != nsAttrValue::eServoCSSDeclaration) {
return nullptr;
}
return attr->GetServoCSSDeclarationValue();
}
@@ -511,73 +511,73 @@ ClassOrClassList(Implementor* aElement,
nsCOMPtr<nsIAtom>* elements = atomArray->Elements();
nsIAtom** rawElements = reinterpret_cast<nsIAtom**>(elements);
*aClassList = rawElements;
return atomArray->Length();
}
#define SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
- nsIAtom* prefix_##AtomAttrValue(implementor_* aElement, nsIAtom* aName) \
+ nsIAtom* prefix_##AtomAttrValue(implementor_ aElement, nsIAtom* aName) \
{ \
return AtomAttrValue(aElement, aName); \
} \
- bool prefix_##HasAttr(implementor_* aElement, nsIAtom* aNS, nsIAtom* aName) \
+ bool prefix_##HasAttr(implementor_ aElement, nsIAtom* aNS, nsIAtom* aName) \
{ \
return HasAttr(aElement, aNS, aName); \
} \
- bool prefix_##AttrEquals(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrEquals(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase) \
{ \
return AttrEquals(aElement, aNS, aName, aStr, aIgnoreCase); \
} \
- bool prefix_##AttrDashEquals(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrDashEquals(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr) \
{ \
return AttrDashEquals(aElement, aNS, aName, aStr); \
} \
- bool prefix_##AttrIncludes(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrIncludes(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr) \
{ \
return AttrIncludes(aElement, aNS, aName, aStr); \
} \
- bool prefix_##AttrHasSubstring(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrHasSubstring(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr) \
{ \
return AttrHasSubstring(aElement, aNS, aName, aStr); \
} \
- bool prefix_##AttrHasPrefix(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrHasPrefix(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr) \
{ \
return AttrHasPrefix(aElement, aNS, aName, aStr); \
} \
- bool prefix_##AttrHasSuffix(implementor_* aElement, nsIAtom* aNS, \
+ bool prefix_##AttrHasSuffix(implementor_ aElement, nsIAtom* aNS, \
nsIAtom* aName, nsIAtom* aStr) \
{ \
return AttrHasSuffix(aElement, aNS, aName, aStr); \
} \
- uint32_t prefix_##ClassOrClassList(implementor_* aElement, nsIAtom** aClass, \
+ uint32_t prefix_##ClassOrClassList(implementor_ aElement, nsIAtom** aClass, \
nsIAtom*** aClassList) \
{ \
return ClassOrClassList(aElement, aClass, aClassList); \
}
-SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElement)
-SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, ServoElementSnapshot)
+SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
+SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, ServoElementSnapshot*)
#undef SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS
-ServoNodeData*
-Gecko_GetNodeData(RawGeckoNode* aNode)
+ServoNodeDataBorrowedOrNull
+Gecko_GetNodeData(RawGeckoNodeBorrowed aNode)
{
return aNode->ServoData().get();
}
void
-Gecko_SetNodeData(RawGeckoNode* aNode, ServoNodeData* aData)
+Gecko_SetNodeData(RawGeckoNodeBorrowed aNode, ServoNodeDataOwned aData)
{
MOZ_ASSERT(!aNode->ServoData());
aNode->ServoData().reset(aData);
}
nsIAtom*
Gecko_Atomize(const char* aString, uint32_t aLength)
{
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -56,29 +56,88 @@ struct nsStyleDisplay;
struct ServoDeclarationBlock;
namespace mozilla {
namespace dom {
class StyleChildrenIterator;
}
}
-#define DECL_REF_TYPE_FOR(type_) \
- typedef type_* type_##Borrowed; \
- struct MOZ_MUST_USE_TYPE type_##Strong \
- { \
- type_* mPtr; \
- already_AddRefed<type_> Consume(); \
+using mozilla::dom::StyleChildrenIterator;
+
+// 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.
+//
+// The "Owned" types generate Owned<T> or OwnedOrNull<T>. Some of these
+// are Servo-managed and can be converted to Box<ServoType> on the
+// Servo side.
+//
+// The "Arc" types are Servo-managed Arc<ServoType>s, which are passed
+// over FFI as Strong<T> (which is nullable).
+// Note that T != ServoType, rather T is ArcInner<ServoType>
+#define DECL_BORROWED_REF_TYPE_FOR(type_) typedef type_* type_##Borrowed;
+#define DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedOrNull;
+#define DECL_BORROWED_MUT_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedMut;
+#define DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_) typedef type_* type_##BorrowedMutOrNull;
+
+#define DECL_ARC_REF_TYPE_FOR(type_) \
+ DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
+ DECL_BORROWED_REF_TYPE_FOR(type_) \
+ struct MOZ_MUST_USE_TYPE type_##Strong \
+ { \
+ type_* mPtr; \
+ already_AddRefed<type_> Consume(); \
};
-DECL_REF_TYPE_FOR(ServoComputedValues)
-DECL_REF_TYPE_FOR(RawServoStyleSheet)
-DECL_REF_TYPE_FOR(ServoDeclarationBlock)
+#define DECL_OWNED_REF_TYPE_FOR(type_) \
+ typedef type_* type_##Owned; \
+ DECL_BORROWED_REF_TYPE_FOR(type_) \
+ DECL_BORROWED_MUT_REF_TYPE_FOR(type_)
+
+#define DECL_NULLABLE_OWNED_REF_TYPE_FOR(type_) \
+ typedef type_* type_##OwnedOrNull; \
+ DECL_NULLABLE_BORROWED_REF_TYPE_FOR(type_) \
+ DECL_NULLABLE_BORROWED_MUT_REF_TYPE_FOR(type_)
+
+DECL_ARC_REF_TYPE_FOR(ServoComputedValues)
+DECL_ARC_REF_TYPE_FOR(RawServoStyleSheet)
+DECL_ARC_REF_TYPE_FOR(ServoDeclarationBlock)
+
+DECL_OWNED_REF_TYPE_FOR(RawServoStyleSet)
+DECL_NULLABLE_OWNED_REF_TYPE_FOR(ServoNodeData)
+DECL_OWNED_REF_TYPE_FOR(ServoNodeData)
+DECL_NULLABLE_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
+DECL_OWNED_REF_TYPE_FOR(StyleChildrenIterator)
-#undef DECL_REF_TYPE_FOR
+// We don't use BorrowedMut because the nodes may alias
+// Servo itself doesn't directly read or mutate these;
+// it only asks Gecko to do so. In case we wish to in
+// the future, we should ensure that things being mutated
+// are protected from noalias violations by a cell type
+DECL_BORROWED_REF_TYPE_FOR(RawGeckoNode)
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoNode)
+DECL_BORROWED_REF_TYPE_FOR(RawGeckoElement)
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoElement)
+DECL_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
+DECL_NULLABLE_BORROWED_REF_TYPE_FOR(RawGeckoDocument)
+DECL_BORROWED_MUT_REF_TYPE_FOR(StyleChildrenIterator)
+
+#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
+
#define NS_DECL_THREADSAFE_FFI_REFCOUNTING(class_, name_) \
void Gecko_AddRef##name_##ArbitraryThread(class_* aPtr); \
void Gecko_Release##name_##ArbitraryThread(class_* aPtr);
#define NS_IMPL_THREADSAFE_FFI_REFCOUNTING(class_, name_) \
static_assert(class_::HasThreadSafeRefCnt::value, \
"NS_DECL_THREADSAFE_FFI_REFCOUNTING can only be used with " \
"classes that have thread-safe refcounting"); \
@@ -95,83 +154,83 @@ DECL_REF_TYPE_FOR(ServoDeclarationBlock)
void Gecko_AddRef##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \
{ NS_ADDREF(aPtr); } \
void Gecko_Release##name_##ArbitraryThread(ThreadSafe##name_##Holder* aPtr) \
{ NS_RELEASE(aPtr); } \
extern "C" {
// DOM Traversal.
-uint32_t Gecko_ChildrenCount(RawGeckoNode* node);
-bool Gecko_NodeIsElement(RawGeckoNode* node);
-RawGeckoNode* Gecko_GetParentNode(RawGeckoNode* node);
-RawGeckoNode* Gecko_GetFirstChild(RawGeckoNode* node);
-RawGeckoNode* Gecko_GetLastChild(RawGeckoNode* node);
-RawGeckoNode* Gecko_GetPrevSibling(RawGeckoNode* node);
-RawGeckoNode* Gecko_GetNextSibling(RawGeckoNode* node);
-RawGeckoElement* Gecko_GetParentElement(RawGeckoElement* element);
-RawGeckoElement* Gecko_GetFirstChildElement(RawGeckoElement* element);
-RawGeckoElement* Gecko_GetLastChildElement(RawGeckoElement* element);
-RawGeckoElement* Gecko_GetPrevSiblingElement(RawGeckoElement* element);
-RawGeckoElement* Gecko_GetNextSiblingElement(RawGeckoElement* element);
-RawGeckoElement* Gecko_GetDocumentElement(RawGeckoDocument* document);
+uint32_t Gecko_ChildrenCount(RawGeckoNodeBorrowed node);
+bool Gecko_NodeIsElement(RawGeckoNodeBorrowed node);
+RawGeckoNodeBorrowedOrNull Gecko_GetParentNode(RawGeckoNodeBorrowed node);
+RawGeckoNodeBorrowedOrNull Gecko_GetFirstChild(RawGeckoNodeBorrowed node);
+RawGeckoNodeBorrowedOrNull Gecko_GetLastChild(RawGeckoNodeBorrowed node);
+RawGeckoNodeBorrowedOrNull Gecko_GetPrevSibling(RawGeckoNodeBorrowed node);
+RawGeckoNodeBorrowedOrNull Gecko_GetNextSibling(RawGeckoNodeBorrowed node);
+RawGeckoElementBorrowedOrNull Gecko_GetParentElement(RawGeckoElementBorrowed element);
+RawGeckoElementBorrowedOrNull Gecko_GetFirstChildElement(RawGeckoElementBorrowed element);
+RawGeckoElementBorrowedOrNull Gecko_GetLastChildElement(RawGeckoElementBorrowed element);
+RawGeckoElementBorrowedOrNull Gecko_GetPrevSiblingElement(RawGeckoElementBorrowed element);
+RawGeckoElementBorrowedOrNull Gecko_GetNextSiblingElement(RawGeckoElementBorrowed element);
+RawGeckoElementBorrowedOrNull Gecko_GetDocumentElement(RawGeckoDocumentBorrowed document);
// 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.
-mozilla::dom::StyleChildrenIterator* Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNode* node);
-void Gecko_DropStyleChildrenIterator(mozilla::dom::StyleChildrenIterator* it);
-RawGeckoNode* Gecko_GetNextStyleChild(mozilla::dom::StyleChildrenIterator* it);
+StyleChildrenIteratorOwnedOrNull Gecko_MaybeCreateStyleChildrenIterator(RawGeckoNodeBorrowed node);
+void Gecko_DropStyleChildrenIterator(StyleChildrenIteratorOwned it);
+RawGeckoNodeBorrowedOrNull Gecko_GetNextStyleChild(StyleChildrenIteratorBorrowed it);
// Selector Matching.
-uint8_t Gecko_ElementState(RawGeckoElement* element);
-bool Gecko_IsHTMLElementInHTMLDocument(RawGeckoElement* element);
-bool Gecko_IsLink(RawGeckoElement* element);
-bool Gecko_IsTextNode(RawGeckoNode* node);
-bool Gecko_IsVisitedLink(RawGeckoElement* element);
-bool Gecko_IsUnvisitedLink(RawGeckoElement* element);
-bool Gecko_IsRootElement(RawGeckoElement* element);
-nsIAtom* Gecko_LocalName(RawGeckoElement* element);
-nsIAtom* Gecko_Namespace(RawGeckoElement* element);
-nsIAtom* Gecko_GetElementId(RawGeckoElement* element);
+uint8_t Gecko_ElementState(RawGeckoElementBorrowed element);
+bool Gecko_IsHTMLElementInHTMLDocument(RawGeckoElementBorrowed element);
+bool Gecko_IsLink(RawGeckoElementBorrowed element);
+bool Gecko_IsTextNode(RawGeckoNodeBorrowed node);
+bool Gecko_IsVisitedLink(RawGeckoElementBorrowed element);
+bool Gecko_IsUnvisitedLink(RawGeckoElementBorrowed element);
+bool Gecko_IsRootElement(RawGeckoElementBorrowed element);
+nsIAtom* Gecko_LocalName(RawGeckoElementBorrowed element);
+nsIAtom* Gecko_Namespace(RawGeckoElementBorrowed element);
+nsIAtom* Gecko_GetElementId(RawGeckoElementBorrowed element);
// Attributes.
-#define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
- nsIAtom* prefix_##AtomAttrValue(implementor_* element, nsIAtom* attribute); \
- bool prefix_##HasAttr(implementor_* element, nsIAtom* ns, nsIAtom* name); \
- bool prefix_##AttrEquals(implementor_* element, nsIAtom* ns, nsIAtom* name, \
- nsIAtom* str, bool ignoreCase); \
- bool prefix_##AttrDashEquals(implementor_* element, nsIAtom* ns, \
- nsIAtom* name, nsIAtom* str); \
- bool prefix_##AttrIncludes(implementor_* element, nsIAtom* ns, \
- nsIAtom* name, nsIAtom* str); \
- bool prefix_##AttrHasSubstring(implementor_* element, nsIAtom* ns, \
- nsIAtom* name, nsIAtom* str); \
- bool prefix_##AttrHasPrefix(implementor_* element, nsIAtom* ns, \
- nsIAtom* name, nsIAtom* str); \
- bool prefix_##AttrHasSuffix(implementor_* element, nsIAtom* ns, \
- nsIAtom* name, nsIAtom* str); \
- uint32_t prefix_##ClassOrClassList(implementor_* element, nsIAtom** class_, \
+#define SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
+ nsIAtom* prefix_##AtomAttrValue(implementor_ element, nsIAtom* attribute); \
+ bool prefix_##HasAttr(implementor_ element, nsIAtom* ns, nsIAtom* name); \
+ bool prefix_##AttrEquals(implementor_ element, nsIAtom* ns, nsIAtom* name, \
+ nsIAtom* str, bool ignoreCase); \
+ bool prefix_##AttrDashEquals(implementor_ element, nsIAtom* ns, \
+ nsIAtom* name, nsIAtom* str); \
+ bool prefix_##AttrIncludes(implementor_ element, nsIAtom* ns, \
+ nsIAtom* name, nsIAtom* str); \
+ bool prefix_##AttrHasSubstring(implementor_ element, nsIAtom* ns, \
+ nsIAtom* name, nsIAtom* str); \
+ bool prefix_##AttrHasPrefix(implementor_ element, nsIAtom* ns, \
+ nsIAtom* name, nsIAtom* str); \
+ bool prefix_##AttrHasSuffix(implementor_ element, nsIAtom* ns, \
+ nsIAtom* name, nsIAtom* str); \
+ uint32_t prefix_##ClassOrClassList(implementor_ element, nsIAtom** class_, \
nsIAtom*** classList);
-SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElement)
+SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot,
- ServoElementSnapshot)
+ ServoElementSnapshot*)
#undef SERVO_DECLARE_ELEMENT_ATTR_MATCHING_FUNCTIONS
// Style attributes.
-ServoDeclarationBlockBorrowed Gecko_GetServoDeclarationBlock(RawGeckoElement* element);
+ServoDeclarationBlockBorrowedOrNull Gecko_GetServoDeclarationBlock(RawGeckoElementBorrowed element);
// Node data.
-ServoNodeData* Gecko_GetNodeData(RawGeckoNode* node);
-void Gecko_SetNodeData(RawGeckoNode* node, ServoNodeData* data);
+ServoNodeDataBorrowedOrNull Gecko_GetNodeData(RawGeckoNodeBorrowed node);
+void Gecko_SetNodeData(RawGeckoNodeBorrowed node, ServoNodeDataOwned data);
// Atoms.
nsIAtom* Gecko_Atomize(const char* aString, uint32_t aLength);
void Gecko_AddRefAtom(nsIAtom* aAtom);
void Gecko_ReleaseAtom(nsIAtom* aAtom);
const uint16_t* Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength);
bool Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength);
bool Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength);
@@ -206,32 +265,32 @@ NS_DECL_HOLDER_FFI_REFCOUNTING(nsIURI, U
void Gecko_SetMozBinding(nsStyleDisplay* style_struct,
const uint8_t* string_bytes, uint32_t string_length,
ThreadSafeURIHolder* base_uri,
ThreadSafeURIHolder* referrer,
ThreadSafePrincipalHolder* principal);
void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src);
// Dirtiness tracking.
-uint32_t Gecko_GetNodeFlags(RawGeckoNode* node);
-void Gecko_SetNodeFlags(RawGeckoNode* node, uint32_t flags);
-void Gecko_UnsetNodeFlags(RawGeckoNode* node, uint32_t flags);
+uint32_t Gecko_GetNodeFlags(RawGeckoNodeBorrowed node);
+void Gecko_SetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
+void Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed node, uint32_t flags);
// Incremental restyle.
// TODO: We would avoid a few ffi calls if we decide to make an API like the
// former CalcAndStoreStyleDifference, but that would effectively mean breaking
// some safety guarantees in the servo side.
//
// Also, we might want a ComputedValues to ComputedValues API for animations?
// Not if we do them in Gecko...
-nsStyleContext* Gecko_GetStyleContext(RawGeckoNode* node,
+nsStyleContext* Gecko_GetStyleContext(RawGeckoNodeBorrowed node,
nsIAtom* aPseudoTagOrNull);
nsChangeHint Gecko_CalcStyleDifference(nsStyleContext* oldstyle,
ServoComputedValuesBorrowed newstyle);
-void Gecko_StoreStyleDifference(RawGeckoNode* node, nsChangeHint change);
+void Gecko_StoreStyleDifference(RawGeckoNodeBorrowed node, nsChangeHint change);
// `array` must be an nsTArray
// If changing this signature, please update the
// friend function declaration in nsTArray.h
void Gecko_EnsureTArrayCapacity(void* array, size_t capacity, size_t elem_size);
// Same here, `array` must be an nsTArray<T>, for some T.
//