mozilla/gecko-dev
XPCOM and the component framework
XPCOM ("Cross-Platform Component Object Model") is the C++ component framework Gecko was built on top of. It provides reference counting, interface-based polymorphism, a service registry, threading primitives, string types, observers, file I/O, and pretty much every utility that doesn't live in mfbt/. Source: xpcom/.
Why it exists
Originally designed in 1998 to mirror Microsoft's COM but be portable, XPCOM provides a stable ABI for components, an IDL toolchain (XPIDL), and a reflection layer that lets JavaScript call into C++ and vice versa. Most modern code uses smaller subsets — refcounting, services, threading — but the legacy interfaces (nsI*) remain pervasive.
Directory layout
xpcom/
├── base/ # Refcounting, cycle collector, observer service, console service
├── build/ # Initialization, process types, version info
├── components/ # Component manager, services, contracts
├── ds/ # Data structures: nsTArray, nsHashtable, nsCOMArray
├── glue/ # Helpers shipped to consumers
├── idl-parser/ # The xpidl compiler (Python)
├── io/ # nsIFile, streams, IPC pipes, local file
├── reflect/ # Type reflection (e.g., for IDL ↔ JS bridges)
├── string/ # nsAString, nsCString, friends
├── tests/
├── threads/ # nsThread, nsIRunnable, scheduling, MozPromise
└── xpidl/ # Public XPIDL headers (typelib format)Key abstractions
| Type | File | Role |
|---|---|---|
nsCOMPtr<T> |
xpcom/base/nsCOMPtr.h |
Smart pointer for XPCOM interface pointers |
RefPtr<T> |
mfbt/RefPtr.h |
Generic refcounted smart pointer |
nsIRunnable / nsThread |
xpcom/threads/ |
Task/thread abstraction |
mozilla::MozPromise |
xpcom/threads/MozPromise.h |
Promise/future-like async type |
nsCycleCollector |
xpcom/base/nsCycleCollector.cpp |
Cycle collector |
nsIObserverService |
xpcom/base/nsIObserverService.idl |
Pub/sub by topic string |
nsIFile |
xpcom/io/nsIFile.idl |
Cross-platform file path |
nsIServiceManager / Services |
xpcom/components/ |
Component / service registry |
nsString, nsCString, nsTArray<>, nsTHashMap<> |
xpcom/string/, xpcom/ds/ |
Core containers |
Refcounting
Every nsISupports-derived type has AddRef / Release. Conventions:
class MyClass : public nsISupports {
public:
NS_DECL_ISUPPORTS
// ...
};
NS_IMPL_ISUPPORTS(MyClass, nsISupports)For new C++ types not exposed via XPIDL, prefer mozilla::RefPtr plus NS_INLINE_DECL_REFCOUNTING(...) (single-threaded) or NS_INLINE_DECL_THREADSAFE_REFCOUNTING(...).
Cycle collection
When refcount cycles can form (very common in DOM trees), classes participate in the cycle collector: they declare which fields are traversable, the CC runs periodically and breaks cycles. Macros: NS_DECL_CYCLE_COLLECTION_CLASS, NS_IMPL_CYCLE_COLLECTION. See xpcom/base/nsCycleCollector.cpp.
Threading
Gecko's threading primitives:
nsIThread/nsIThreadManager.nsCOMPtr<nsIRunnable>— a unit of work; subclass and overrideRun().NS_DispatchToMainThread(runnable)posts work to the main loop.nsISerialEventTarget— stable identifier for "this thread or thread-pool slot".mozilla::TaskController— the modern scheduler, replacing the oldnsThread::Dispatch.MozPromise<T>— chainable async results.- Static analysis annotations (
MOZ_CAN_RUN_SCRIPT,MOZ_KNOWN_LIVE) protect against re-entrancy bugs.
Component / service registry
Components are declared in *.toml manifest files (the modern pattern, e.g., browser/components/components.conf) which generate static registrations at build time. Older code uses XPCOMUtils.defineLazyServiceGetter(...) from JS to fetch services lazily.
The Services global in JS provides convenient accessors:
Services.prefs.getBoolPref("browser.foo");
Services.obs.notifyObservers(...);
Services.io.newURI("https://example.com");Static prefs
modules/libpref/init/StaticPrefList.yaml declares prefs that have generated C++ accessors (mozilla::StaticPrefs::dom_foo_enabled()). Avoids touching the pref service every read. See modules/libpref/.
Related
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.