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 #ifndef StaticComponents_h
8 #define StaticComponents_h
10 #include "mozilla/AlreadyAddRefed.h"
11 #include "mozilla/Module.h"
12 #include "mozilla/Span.h"
14 #include "nsStringFwd.h"
17 #include "mozilla/Components.h"
18 #include "StaticComponentData.h"
21 class nsIUTF8StringEnumerator
;
23 template <typename T
, size_t N
>
32 struct StaticCategoryEntry
;
33 struct StaticCategory
;
35 extern const StaticModule gStaticModules
[kStaticModuleCount
];
37 extern const ContractEntry gContractEntries
[kContractCount
];
38 extern uint8_t gInvalidContracts
[kContractCount
/ 8 + 1];
40 extern const StaticCategory gStaticCategories
[kStaticCategoryCount
];
41 extern const StaticCategoryEntry gStaticCategoryEntries
[];
44 static inline bool GetBit(const uint8_t (&aBits
)[N
], size_t aBit
) {
45 static constexpr size_t width
= sizeof(aBits
[0]) * 8;
47 size_t idx
= aBit
/ width
;
49 return aBits
[idx
] & (1 << (aBit
% width
));
53 static inline void SetBit(uint8_t (&aBits
)[N
], size_t aBit
,
55 static constexpr size_t width
= sizeof(aBits
[0]) * 8;
57 size_t idx
= aBit
/ width
;
60 aBits
[idx
] |= 1 << (aBit
% width
);
62 aBits
[idx
] &= ~(1 << (aBit
% width
));
67 * Represents a string entry in the static string table. Can be converted to a
68 * nsCString using GetString() in StaticComponents.cpp.
70 * This is a struct rather than a pure offset primarily for the purposes of type
71 * safety, but also so that it can easily be extended to include a static length
72 * in the future, if efficiency concerns warrant it.
74 struct StringOffset final
{
79 * Represents an offset into the interfaces table.
81 struct InterfaceOffset final
{
86 * Represents a static component entry defined in a `Classes` list in an XPCOM
87 * manifest. Handles creating instances of and caching service instances for
92 StringOffset mContractID
;
93 Module::ProcessSelector mProcessSelector
;
95 const nsID
& CID() const { return mCID
; }
97 ModuleID
ID() const { return ModuleID(this - gStaticModules
); }
100 * Returns this entry's index in the gStaticModules array.
102 size_t Idx() const { return size_t(ID()); }
105 * Returns true if this component's corresponding contract ID is expected to
106 * be overridden at runtime. If so, it should always be looked up by its
107 * ContractID() when retrieving its service instance.
109 bool Overridable() const;
112 * If this entry is overridable, returns its associated contract ID string.
113 * The component should always be looked up by this contract ID when
114 * retrieving its service instance.
116 * Note: This may *only* be called if Overridable() returns true.
118 nsCString
ContractID() const;
121 * Returns true if this entry is active. Typically this will only return false
122 * if the entry's process selector does not match this process.
126 already_AddRefed
<nsIFactory
> GetFactory() const;
128 nsresult
CreateInstance(const nsIID
& aIID
, void** aResult
) const;
130 GetServiceHelper
GetService() const;
131 GetServiceHelper
GetService(nsresult
*) const;
133 nsISupports
* ServiceInstance() const;
134 void SetServiceInstance(already_AddRefed
<nsISupports
> aInst
) const;
138 * Represents a static mapping between a contract ID string and a StaticModule
141 struct ContractEntry final
{
142 StringOffset mContractID
;
145 size_t Idx() const { return this - gContractEntries
; }
147 nsCString
ContractID() const;
149 const StaticModule
& Module() const {
150 return gStaticModules
[size_t(mModuleID
)];
154 * Returns true if this entry's underlying module is active, and its contract
155 * ID matches the given contract ID string. This is used by the PerfectHash
156 * function to determine whether to return a result for this entry.
158 bool Matches(const nsACString
& aContractID
) const;
161 * Returns true if this entry has been invalidated, and should be ignored.
163 * Contract IDs may be overwritten at runtime. When that happens for a static
164 * contract ID, we mark its entry invalid, and ignore it thereafter.
166 bool Invalid() const { return GetBit(gInvalidContracts
, Idx()); }
169 * Marks this entry invalid (or unsets the invalid bit if aInvalid is false),
170 * after which it will be ignored in contract ID lookup attempts. See
173 void SetInvalid(bool aInvalid
= true) const {
174 return SetBit(gInvalidContracts
, Idx(), aInvalid
);
179 * Represents a declared category manager entry declared in an XPCOM manifest.
181 * The entire set of static category entries is read at startup and loaded into
182 * the category manager's dynamic hash tables, so there is memory and
183 * initialization overhead for each entry in these tables. This may be further
184 * optimized in the future to reduce some of that overhead.
186 struct StaticCategoryEntry final
{
189 Module::BackgroundTasksSelector mBackgroundTasksSelector
;
190 Module::ProcessSelector mProcessSelector
;
192 nsCString
Entry() const;
193 nsCString
Value() const;
197 struct StaticCategory final
{
202 nsCString
Name() const;
204 const StaticCategoryEntry
* begin() const {
205 return &gStaticCategoryEntries
[mStart
];
207 const StaticCategoryEntry
* end() const {
208 return &gStaticCategoryEntries
[mStart
+ mCount
];
212 struct JSServiceEntry final
{
213 using InterfaceList
= AutoTArray
<const nsIID
*, 4>;
215 static const JSServiceEntry
* Lookup(const nsACString
& aName
);
220 InterfaceOffset mInterfaceOffset
;
221 uint8_t mInterfaceCount
;
223 nsCString
Name() const;
225 const StaticModule
& Module() const {
226 return gStaticModules
[size_t(mModuleID
)];
229 InterfaceList
Interfaces() const;
232 class StaticComponents final
{
234 static const StaticModule
* LookupByCID(const nsID
& aCID
);
236 static const StaticModule
* LookupByContractID(const nsACString
& aContractID
);
239 * Marks a static contract ID entry invalid (or unsets the invalid bit if
240 * aInvalid is false). See `CategoryEntry::Invalid()`.
242 static bool InvalidateContractID(const nsACString
& aContractID
,
243 bool aInvalid
= true);
245 static already_AddRefed
<nsIUTF8StringEnumerator
> GetComponentJSMs();
247 static Span
<const JSServiceEntry
> GetJSServices();
250 * Calls any module unload from manifests whose components have been loaded.
252 static void Shutdown();
256 } // namespace mozilla
258 #endif // defined StaticComponents_h