Improving XPCOM for Mozilla 2
XPCOM technology, based on Microsoft COM, is fundamentally structured around the concept of binary object layouts and stylized calling conventions. XPCOM was a good technique for introducing modularity and extensibility to the Mozilla codebase, but it is showing its age. One of the interesting things about Mozilla 2 is that we can breaking API and binary compatibility.
There are several ways we should improve XPCOM:
- Improve reference-counting (this could include universal support for cycle collection, or even allocating all XPCOM objects using MMgc; Graydon and I talked about this some at the Summit, and I’m sure he’ll take the lead determining what this means in practice.
- Allow throwing complicated (object-type) exceptions from any XPCOM method, and reduce the verbosity and inefficiencies of nsresult return codes. C++ exceptions, as much as I dislike them, provide the shortest path to this goal. Taras has been working with oink to provide an automated way to convert method calls automatically.
- Reduce the complexity and verbosity of using XPCOM. I’ve been spending a fair amount of time working in Python recently, and I’m very impressed with its use of module objects. Using XPCOM could be a lot easier from script with some very simple changes. I’ll blog about this soon!
In order to achieve these objectives, I’m convinced that Mozilla must break XPCOM binary compatibility, and should stop using XPCOM as the binary embedding solution:
- We may want the flexibility of making GCRoot or another abstract non-interface class the root type (nsISupports) for all XPCOM objects. We at least ought to add interfacerequestor and classinfo functionality to the root object type, and perhaps weak-reference support as well.
- C++ exceptions are very compiler dependent (and compiler-version dependent) and are not good candidates for binary freezing.
The implications of a change like this are considerable:
- It will no longer be possible (or desirable) to write binary XPCOM components in C++ that don’t live in the monolithic platform binary (libxul). At first this seemed like a significant challenge: Firefox and Thunderbird use binary components to do OS integration (profile migration and OS integration). Various extension also use binary components to integrate with external libraries. But most of these use-cases can be solved with a good foreign-function-interface library available from script. I’ll blog about this separately; I’ve been very impressed with the expressiveness and flexibility of the python ctypes library and I think it could be ported to SpiderMonkey rather easily.
- Binary embedders (e.g. gtkmozembed clients) will no longer be able to access DOM objects via their XPCOM interfaces.
The simplest way to solve this problem is to extend the scriptable NPAPI object model to be accessible by binary embedders. This will give embedders access to the DOM that is straightforward and relatively complete.
Brainstorming Example
class nsISupports : virtual public RCObject { inline void AddRef() { IncrementRef(); return 2; } inline void Release() { DecrementRef(); return 1; } virtual nsISupports* QueryInterface(REFNSIID aIID, PRBool aAddRef) = 0; /** * For ease of conversion, provide an old-style QI wrapper. */ inline nsresult QueryInterface(REFNSIID aIID, void **aResult) { *aResult = QueryInterface(aIID, PR_TRUE); return (*aResult) ? NS_OK : NS_NOINTERFACE; } virtual nsISupports* GetInterface(REFNSIID aIID, PRBool aAddRef) = 0; virtual nsIClassInfo* GetClassInfo() = 0; };
The virtual inheritance of RCObject could be a problem for xptcall. There are ways around that. I’m also a little concerned that objects won’t be storing pointers to the “root” GCObject, but rather vtables within that object. I hope that doesn’t mess up MMgc.
December 22nd, 2006 at 1:35 pm
Is there anything which needs to be done to make creating language bindings easier? I’d really like to use lua or C# or ocaml, but the bindings aren’t there. Is this because its difficult to create the bindings, or just because there’s no interest?
December 22nd, 2006 at 6:10 pm
Why would we want GCRoot to be a base class for all XPCOM objects?
> I’m also a little concerned that objects won’t be storing pointers to the “rootâ€
> GCObject, but rather vtables within that object
You mean “subobjects within that object”, right? Not the vtable itself
If we’re only going to be using XPCOM within libxul, and JS bindings are going to be redone to not use XPCOM, then why we do we need it at all?
April 13th, 2007 at 5:42 am
>Firefox and Thunderbird use binary components to do OS integration.
More obviously, Thunderbird has this rather large binary component called mail, which is going to take some work just to port to frozen linkage…
July 11th, 2007 at 10:59 am
> I’m also a little concerned that objects won’t be storing pointers to the “rootâ€
> GCObject, but rather vtables within that object. I hope that doesn’t mess up MMgc.
You’re right, this is a problem. This would mess up MMgc as it stands. There’s some code in GC::MarkItem() that checks that the (possible) pointer points to the start of the allocated region. If it points into the middle of an allocated region, MMgc skips that pointer.
It can be fixed, at the cost of more often misinterpreting numbers as pointers.
February 12th, 2008 at 1:07 pm
[…] about goals for XPCOM in Mozilla 2 to the Wiki and Newsgroup. See Benjamin’s older post on XPCOM changes too. I encourage any extension, embedders and XUL application developers who use binary code to go […]