1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* C++ types corresponding to Servo and Gecko types used across bindings,
8 with some annotations to indicate ownership expectations */
10 // This file defines a number of C++ types used to represent strong, and owning
11 // references to Servo and Gecko objects that might be used across bindings and
14 // By convention, the types defined here are named "RawServo{Type}" and
15 // "RawGecko{Type}". The {Type} should be something close to the real Rust or
16 // C++ name of the type, but need not be. The "Raw" is really just used to
17 // avoid clashing with other names.
19 // For Servo types, each "RawServo{ServoTypeName}" is generated as an opaque,
20 // declared but not defined struct.
22 // For Gecko types, each "RawGecko{GeckoTypeName}" is a typedef that aliases
23 // the actual C++ type.
25 // Each of these types can have a number of different typedefs generated for
26 // them, representing different notions of ownership when passing or receiving
27 // these values across bindings and FFI:
29 // RawServo{Type}Strong
30 // strong reference to an Arc-managed value
32 // All of these strong, and owned types are generated by adding
33 // entries to one of these files:
36 // generates the Strong type
39 // The strong, and owned reference types should be used in FFI function
40 // signatures where possible, to help indicate the ownership properties that
41 // both sides of the function call must adhere to.
43 // There are some special cases defined at the bottom of this file that don't
44 // fit neatly into these three categories.
47 // Using these types in C++ ========================
49 // The Strong types are a C++ struct that wraps a raw pointer. When receiving a
50 // Strong value from a Servo_* FFI function, you must call Consume() on it to
51 // convert it into an already_AddRefed<RawServo{Type}>, otherwise it will leak.
53 // We don't currently have any cases where we pass a Strong value to Servo; this
54 // could be done by creating a RawServo{Type}Strong struct value whose mPtr is
55 // initialized to the result of calling `.forget().take()` on a
56 // RefPtr<RawServo{Type}>, but it's probably easier just to pass a raw pointer
57 // and let the Rust code turn it into an Arc.
59 // TODO(heycam): We should perhaps have a similar struct for Owned types with a
60 // Consume() method to convert them into a UniquePtr. The struct for Strong
61 // types at least have [[nodiscard]] on them.
64 // Using these types in Rust =========================
66 // The FFI type names are available in Rust in the gecko_bindings::bindings mod,
67 // which is generated by servo/components/style/build_gecko.rs.
69 // Borrowed types in rust are represented by &T, Option<&T>, &mut T, and
72 // In C++ you should write them as const pointers (for &T and Option<&T>) or
73 // non-const pointers (for &mut T and Option<&mut T>).
75 // The Strong types are defined as gecko_bindings::sugar::ownership::Strong<T>.
77 // This is an FFI safe type that represents the value with a strong reference
78 // already added to it. Dropping a Strong<T> will leak the strong reference.
80 // A RawServoFooStrong received from FFI can be converted into a
81 // `RawOffsetArc<Foo>` by calling `into_arc()` or `into_arc_opt()` on it.
82 // To pass a RawServoFooStrong back to Gecko, call `into_strong()` on the
85 // The Owned types are defined as gecko_bindings::sugar::ownership::Owned<T>
86 // (or OwnedOrNull<T>).
88 // This is another FFI safe type that represents the owning reference to the
89 // value. Dropping an Owned<T> will leak the value.
91 // An Owned<RawServoFoo> received from FFI can be converted into a `Box<Foo>`
92 // by calling `into_box()`. To pass an Owned<RawServoFoo> back to Gecko, call
93 // `HasBoxFFI::into_ffi()` passing in the `Box<Foo>` value.
95 // Reading through servo/components/style/gecko_bindings/sugar/ownership.rs
96 // is also instructive in understanding all this.
98 #ifndef mozilla_ServoBindingTypes_h
99 #define mozilla_ServoBindingTypes_h
101 #include "mozilla/RefPtr.h"
102 #include "mozilla/ServoTypes.h"
103 #include "mozilla/UniquePtr.h"
104 #include "mozilla/gfx/Types.h"
105 #include "nsCSSPropertyID.h"
106 #include "nsStyleAutoArray.h"
107 #include "nsTArray.h"
109 // Forward declarations.
111 #define SERVO_ARC_TYPE(name_, type_) struct type_;
112 #include "mozilla/ServoArcTypeList.h"
113 #undef SERVO_ARC_TYPE
115 class nsCSSPropertyIDSet
;
119 struct nsFontFaceRuleContainer
;
120 struct nsTimingFunction
;
124 class ServoElementSnapshot
;
125 struct AnimationPropertySegment
;
126 struct ComputedTiming
;
128 struct PropertyStyleAnimationValuePair
;
129 struct PropertyValuePair
;
130 struct StyleAnimation
;
132 using ComputedKeyframeValues
= nsTArray
<PropertyStyleAnimationValuePair
>;
133 using GfxMatrix4x4
= mozilla::gfx::Float
[16];
136 class StyleChildrenIterator
;
141 } // namespace mozilla
143 #define SERVO_ARC_TYPE(name_, type_) \
145 void Servo_##name_##_AddRef(const type_*); \
146 void Servo_##name_##_Release(const type_*); \
148 namespace mozilla { \
150 struct RefPtrTraits<type_> { \
151 static void AddRef(type_* aPtr) { Servo_##name_##_AddRef(aPtr); } \
152 static void Release(type_* aPtr) { Servo_##name_##_Release(aPtr); } \
155 #include "mozilla/ServoArcTypeList.h"
156 SERVO_ARC_TYPE(ComputedStyle
, mozilla::ComputedStyle
)
157 #undef SERVO_ARC_TYPE
159 #define SERVO_BOXED_TYPE(name_, type_) \
161 extern "C" void Servo_##name_##_Drop(type_*); \
162 namespace mozilla { \
164 class DefaultDelete<type_> { \
166 void operator()(type_* aPtr) const { Servo_##name_##_Drop(aPtr); } \
169 #include "mozilla/ServoBoxedTypeList.h"
170 #undef SERVO_BOXED_TYPE
172 // Other special cases.
174 struct RawServoAnimationValueTable
;
176 #endif // mozilla_ServoBindingTypes_h