Backed out 3 changesets (bug 1854934) for causing build bustages on widget/windows...
[gecko.git] / xpcom / components / StaticComponents.h
blobac4095f2f35e85e367b0a455453e8b84db3ee09a
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"
13 #include "nsID.h"
14 #include "nsStringFwd.h"
15 #include "nscore.h"
17 #include "mozilla/Components.h"
18 #include "StaticComponentData.h"
20 class nsIFactory;
21 class nsIUTF8StringEnumerator;
22 class nsISupports;
23 template <typename T, size_t N>
24 class AutoTArray;
26 namespace mozilla {
27 namespace xpcom {
29 struct ContractEntry;
30 struct StaticModule;
32 struct StaticCategoryEntry;
33 struct StaticCategory;
35 struct StaticProtocolHandler;
37 extern const StaticModule gStaticModules[kStaticModuleCount];
39 extern const ContractEntry gContractEntries[kContractCount];
40 extern uint8_t gInvalidContracts[kContractCount / 8 + 1];
42 extern const StaticCategory gStaticCategories[kStaticCategoryCount];
43 extern const StaticCategoryEntry gStaticCategoryEntries[];
45 extern const StaticProtocolHandler
46 gStaticProtocolHandlers[kStaticProtocolHandlerCount];
48 template <size_t N>
49 static inline bool GetBit(const uint8_t (&aBits)[N], size_t aBit) {
50 static constexpr size_t width = sizeof(aBits[0]) * 8;
52 size_t idx = aBit / width;
53 MOZ_ASSERT(idx < N);
54 return aBits[idx] & (1 << (aBit % width));
57 template <size_t N>
58 static inline void SetBit(uint8_t (&aBits)[N], size_t aBit,
59 bool aValue = true) {
60 static constexpr size_t width = sizeof(aBits[0]) * 8;
62 size_t idx = aBit / width;
63 MOZ_ASSERT(idx < N);
64 if (aValue) {
65 aBits[idx] |= 1 << (aBit % width);
66 } else {
67 aBits[idx] &= ~(1 << (aBit % width));
71 /**
72 * Represents a string entry in the static string table. Can be converted to a
73 * nsCString using GetString() in StaticComponents.cpp.
75 * This is a struct rather than a pure offset primarily for the purposes of type
76 * safety, but also so that it can easily be extended to include a static length
77 * in the future, if efficiency concerns warrant it.
79 struct StringOffset final {
80 uint32_t mOffset;
83 /**
84 * Represents an offset into the interfaces table.
86 struct InterfaceOffset final {
87 uint16_t mOffset;
90 /**
91 * Represents a static component entry defined in a `Classes` list in an XPCOM
92 * manifest. Handles creating instances of and caching service instances for
93 * that class.
95 struct StaticModule {
96 nsID mCID;
97 StringOffset mContractID;
98 Module::ProcessSelector mProcessSelector;
100 const nsID& CID() const { return mCID; }
102 ModuleID ID() const { return ModuleID(this - gStaticModules); }
105 * Returns this entry's index in the gStaticModules array.
107 size_t Idx() const { return size_t(ID()); }
110 * Returns true if this component's corresponding contract ID is expected to
111 * be overridden at runtime. If so, it should always be looked up by its
112 * ContractID() when retrieving its service instance.
114 bool Overridable() const;
117 * If this entry is overridable, returns its associated contract ID string.
118 * The component should always be looked up by this contract ID when
119 * retrieving its service instance.
121 * Note: This may *only* be called if Overridable() returns true.
123 nsCString ContractID() const;
126 * Returns true if this entry is active. Typically this will only return false
127 * if the entry's process selector does not match this process.
129 bool Active() const;
131 already_AddRefed<nsIFactory> GetFactory() const;
133 nsresult CreateInstance(const nsIID& aIID, void** aResult) const;
135 GetServiceHelper GetService() const;
136 GetServiceHelper GetService(nsresult*) const;
138 nsISupports* ServiceInstance() const;
139 void SetServiceInstance(already_AddRefed<nsISupports> aInst) const;
143 * Represents a static mapping between a contract ID string and a StaticModule
144 * entry.
146 struct ContractEntry final {
147 StringOffset mContractID;
148 ModuleID mModuleID;
150 size_t Idx() const { return this - gContractEntries; }
152 nsCString ContractID() const;
154 const StaticModule& Module() const {
155 return gStaticModules[size_t(mModuleID)];
159 * Returns true if this entry's underlying module is active, and its contract
160 * ID matches the given contract ID string. This is used by the PerfectHash
161 * function to determine whether to return a result for this entry.
163 bool Matches(const nsACString& aContractID) const;
166 * Returns true if this entry has been invalidated, and should be ignored.
168 * Contract IDs may be overwritten at runtime. When that happens for a static
169 * contract ID, we mark its entry invalid, and ignore it thereafter.
171 bool Invalid() const { return GetBit(gInvalidContracts, Idx()); }
174 * Marks this entry invalid (or unsets the invalid bit if aInvalid is false),
175 * after which it will be ignored in contract ID lookup attempts. See
176 * `Invalid()` above.
178 void SetInvalid(bool aInvalid = true) const {
179 return SetBit(gInvalidContracts, Idx(), aInvalid);
184 * Represents a declared category manager entry declared in an XPCOM manifest.
186 * The entire set of static category entries is read at startup and loaded into
187 * the category manager's dynamic hash tables, so there is memory and
188 * initialization overhead for each entry in these tables. This may be further
189 * optimized in the future to reduce some of that overhead.
191 struct StaticCategoryEntry final {
192 StringOffset mEntry;
193 StringOffset mValue;
194 Module::BackgroundTasksSelector mBackgroundTasksSelector;
195 Module::ProcessSelector mProcessSelector;
197 nsCString Entry() const;
198 nsCString Value() const;
199 bool Active() const;
202 struct StaticCategory final {
203 StringOffset mName;
204 uint16_t mStart;
205 uint16_t mCount;
207 nsCString Name() const;
209 const StaticCategoryEntry* begin() const {
210 return &gStaticCategoryEntries[mStart];
212 const StaticCategoryEntry* end() const {
213 return &gStaticCategoryEntries[mStart + mCount];
217 struct JSServiceEntry final {
218 using InterfaceList = AutoTArray<const nsIID*, 4>;
220 static const JSServiceEntry* Lookup(const nsACString& aName);
222 StringOffset mName;
223 ModuleID mModuleID;
225 InterfaceOffset mInterfaceOffset;
227 uint8_t mInterfaceCount;
229 nsCString Name() const;
231 const StaticModule& Module() const {
232 return gStaticModules[size_t(mModuleID)];
235 InterfaceList Interfaces() const;
238 struct StaticProtocolHandler final {
239 static const StaticProtocolHandler* Lookup(const nsACString& aScheme);
240 static const StaticProtocolHandler& Default() {
241 return gStaticProtocolHandlers[kDefaultProtocolHandlerIndex];
244 StringOffset mScheme;
245 uint32_t mProtocolFlags;
246 int32_t mDefaultPort;
247 ModuleID mModuleID;
248 bool mHasDynamicFlags;
250 nsCString Scheme() const;
252 const StaticModule& Module() const {
253 return gStaticModules[size_t(mModuleID)];
257 class StaticComponents final {
258 public:
259 static const StaticModule* LookupByCID(const nsID& aCID);
261 static const StaticModule* LookupByContractID(const nsACString& aContractID);
264 * Marks a static contract ID entry invalid (or unsets the invalid bit if
265 * aInvalid is false). See `CategoryEntry::Invalid()`.
267 static bool InvalidateContractID(const nsACString& aContractID,
268 bool aInvalid = true);
270 static already_AddRefed<nsIUTF8StringEnumerator> GetComponentJSMs();
271 static already_AddRefed<nsIUTF8StringEnumerator> GetComponentESModules();
273 static Span<const JSServiceEntry> GetJSServices();
276 * Calls any module unload from manifests whose components have been loaded.
278 static void Shutdown();
281 } // namespace xpcom
282 } // namespace mozilla
284 #endif // defined StaticComponents_h