fune/xpcom/components/StaticComponents.h
Narcis Beleuzu 7eae8c1064 Backed out 16 changesets (bug 1770944) as req by asuth.
Backed out changeset 61af32f40777 (bug 1770944)
Backed out changeset 4ff0c45db93b (bug 1770944)
Backed out changeset 8a217eff7bcd (bug 1770944)
Backed out changeset 6435f48c96bf (bug 1770944)
Backed out changeset 0d2432765ca0 (bug 1770944)
Backed out changeset 58e02566db85 (bug 1770944)
Backed out changeset 0a8c4c2460ee (bug 1770944)
Backed out changeset 9416bafd9982 (bug 1770944)
Backed out changeset 79de4f83fe2e (bug 1770944)
Backed out changeset 63ac518aceb0 (bug 1770944)
Backed out changeset 14952f872b77 (bug 1770944)
Backed out changeset f65e0967ad75 (bug 1770944)
Backed out changeset bd53c42038f7 (bug 1770944)
Backed out changeset 36c378ba8212 (bug 1770944)
Backed out changeset 9ba54ab06348 (bug 1770944)
Backed out changeset fb5a54b3cbe9 (bug 1770944)
2024-02-23 21:11:08 +02:00

284 lines
7.8 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef StaticComponents_h
#define StaticComponents_h
#include "mozilla/AlreadyAddRefed.h"
#include "mozilla/Module.h"
#include "mozilla/Span.h"
#include "nsID.h"
#include "nsStringFwd.h"
#include "nscore.h"
#include "mozilla/Components.h"
#include "StaticComponentData.h"
class nsIFactory;
class nsIUTF8StringEnumerator;
class nsISupports;
template <typename T, size_t N>
class AutoTArray;
namespace mozilla {
namespace xpcom {
struct ContractEntry;
struct StaticModule;
struct StaticCategoryEntry;
struct StaticCategory;
struct StaticProtocolHandler;
extern const StaticModule gStaticModules[kStaticModuleCount];
extern const ContractEntry gContractEntries[kContractCount];
extern uint8_t gInvalidContracts[kContractCount / 8 + 1];
extern const StaticCategory gStaticCategories[kStaticCategoryCount];
extern const StaticCategoryEntry gStaticCategoryEntries[];
extern const StaticProtocolHandler
gStaticProtocolHandlers[kStaticProtocolHandlerCount];
template <size_t N>
static inline bool GetBit(const uint8_t (&aBits)[N], size_t aBit) {
static constexpr size_t width = sizeof(aBits[0]) * 8;
size_t idx = aBit / width;
MOZ_ASSERT(idx < N);
return aBits[idx] & (1 << (aBit % width));
}
template <size_t N>
static inline void SetBit(uint8_t (&aBits)[N], size_t aBit,
bool aValue = true) {
static constexpr size_t width = sizeof(aBits[0]) * 8;
size_t idx = aBit / width;
MOZ_ASSERT(idx < N);
if (aValue) {
aBits[idx] |= 1 << (aBit % width);
} else {
aBits[idx] &= ~(1 << (aBit % width));
}
}
/**
* Represents a string entry in the static string table. Can be converted to a
* nsCString using GetString() in StaticComponents.cpp.
*
* This is a struct rather than a pure offset primarily for the purposes of type
* safety, but also so that it can easily be extended to include a static length
* in the future, if efficiency concerns warrant it.
*/
struct StringOffset final {
uint32_t mOffset;
};
/**
* Represents an offset into the interfaces table.
*/
struct InterfaceOffset final {
uint16_t mOffset;
};
/**
* Represents a static component entry defined in a `Classes` list in an XPCOM
* manifest. Handles creating instances of and caching service instances for
* that class.
*/
struct StaticModule {
nsID mCID;
StringOffset mContractID;
Module::ProcessSelector mProcessSelector;
const nsID& CID() const { return mCID; }
ModuleID ID() const { return ModuleID(this - gStaticModules); }
/**
* Returns this entry's index in the gStaticModules array.
*/
size_t Idx() const { return size_t(ID()); }
/**
* Returns true if this component's corresponding contract ID is expected to
* be overridden at runtime. If so, it should always be looked up by its
* ContractID() when retrieving its service instance.
*/
bool Overridable() const;
/**
* If this entry is overridable, returns its associated contract ID string.
* The component should always be looked up by this contract ID when
* retrieving its service instance.
*
* Note: This may *only* be called if Overridable() returns true.
*/
nsCString ContractID() const;
/**
* Returns true if this entry is active. Typically this will only return false
* if the entry's process selector does not match this process.
*/
bool Active() const;
already_AddRefed<nsIFactory> GetFactory() const;
nsresult CreateInstance(const nsIID& aIID, void** aResult) const;
GetServiceHelper GetService() const;
GetServiceHelper GetService(nsresult*) const;
nsISupports* ServiceInstance() const;
void SetServiceInstance(already_AddRefed<nsISupports> aInst) const;
};
/**
* Represents a static mapping between a contract ID string and a StaticModule
* entry.
*/
struct ContractEntry final {
StringOffset mContractID;
ModuleID mModuleID;
size_t Idx() const { return this - gContractEntries; }
nsCString ContractID() const;
const StaticModule& Module() const {
return gStaticModules[size_t(mModuleID)];
}
/**
* Returns true if this entry's underlying module is active, and its contract
* ID matches the given contract ID string. This is used by the PerfectHash
* function to determine whether to return a result for this entry.
*/
bool Matches(const nsACString& aContractID) const;
/**
* Returns true if this entry has been invalidated, and should be ignored.
*
* Contract IDs may be overwritten at runtime. When that happens for a static
* contract ID, we mark its entry invalid, and ignore it thereafter.
*/
bool Invalid() const { return GetBit(gInvalidContracts, Idx()); }
/**
* Marks this entry invalid (or unsets the invalid bit if aInvalid is false),
* after which it will be ignored in contract ID lookup attempts. See
* `Invalid()` above.
*/
void SetInvalid(bool aInvalid = true) const {
return SetBit(gInvalidContracts, Idx(), aInvalid);
}
};
/**
* Represents a declared category manager entry declared in an XPCOM manifest.
*
* The entire set of static category entries is read at startup and loaded into
* the category manager's dynamic hash tables, so there is memory and
* initialization overhead for each entry in these tables. This may be further
* optimized in the future to reduce some of that overhead.
*/
struct StaticCategoryEntry final {
StringOffset mEntry;
StringOffset mValue;
Module::BackgroundTasksSelector mBackgroundTasksSelector;
Module::ProcessSelector mProcessSelector;
nsCString Entry() const;
nsCString Value() const;
bool Active() const;
};
struct StaticCategory final {
StringOffset mName;
uint16_t mStart;
uint16_t mCount;
nsCString Name() const;
const StaticCategoryEntry* begin() const {
return &gStaticCategoryEntries[mStart];
}
const StaticCategoryEntry* end() const {
return &gStaticCategoryEntries[mStart + mCount];
}
};
struct JSServiceEntry final {
using InterfaceList = AutoTArray<const nsIID*, 4>;
static const JSServiceEntry* Lookup(const nsACString& aName);
StringOffset mName;
ModuleID mModuleID;
InterfaceOffset mInterfaceOffset;
uint8_t mInterfaceCount;
nsCString Name() const;
const StaticModule& Module() const {
return gStaticModules[size_t(mModuleID)];
}
InterfaceList Interfaces() const;
};
struct StaticProtocolHandler final {
static const StaticProtocolHandler* Lookup(const nsACString& aScheme);
static const StaticProtocolHandler& Default() {
return gStaticProtocolHandlers[kDefaultProtocolHandlerIndex];
}
StringOffset mScheme;
uint32_t mProtocolFlags;
int32_t mDefaultPort;
ModuleID mModuleID;
bool mHasDynamicFlags;
nsCString Scheme() const;
const StaticModule& Module() const {
return gStaticModules[size_t(mModuleID)];
}
};
class StaticComponents final {
public:
static const StaticModule* LookupByCID(const nsID& aCID);
static const StaticModule* LookupByContractID(const nsACString& aContractID);
/**
* Marks a static contract ID entry invalid (or unsets the invalid bit if
* aInvalid is false). See `CategoryEntry::Invalid()`.
*/
static bool InvalidateContractID(const nsACString& aContractID,
bool aInvalid = true);
static already_AddRefed<nsIUTF8StringEnumerator> GetComponentJSMs();
static already_AddRefed<nsIUTF8StringEnumerator> GetComponentESModules();
static Span<const JSServiceEntry> GetJSServices();
/**
* Calls any module unload from manifests whose components have been loaded.
*/
static void Shutdown();
};
} // namespace xpcom
} // namespace mozilla
#endif // defined StaticComponents_h