What is <tt>xptcall</tt>?
<tt>xptcall</tt> is a small low level xpcom method call library. It is implemented using platform specific C/C and assembly language code. It is used to facilitate cross language and cross thread method calls. Porting this code is required in order to make mozilla run on any given platfrom.
Why does <tt>xptcall</tt> exist?
<tt>xptcall</tt> exists for two reasons:
- To support invoking arbitrary methods on xpcom interfaces.
- To support dynamically impersonating any xpcom interface.
The <tt>xptcall</tt> approach was chosen over an approach that would have required generating stub code for calling and implementing all interfaces. Though the chosen approach requires some core platform specific code, it has minimal footprint and is extendable to work with any valid XPCOM interface without requiring additional per platform compiled code to be distributed.
What does <tt>xptcall</tt> really do?
The core invoke function has the declaration:
XPTC_PUBLIC_API(nsresult) XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex, PRUint32 paramCount, nsXPTCVariant* params);
<tt>nsXPTCVariant</tt> is a discriminated union of the types that can be passed as parameters to the target function (including <tt>void*</tt> to represent arbitrary pointer types).
The stubs (or impersonation) facility of <tt>xptcall</tt> allows for implementing a class which can, at runtime, pretend to be any XPCOM interface. This is done by providing a vtbl full of generic function stubs in <tt>xptcall</tt>. These stubs forward calls to a shared function whose job it is to use the typelib information to extract the params from the platform specific calling convention to build an array of variants to hold the params and then call an inherited method which can then do whatever it wants with the call. This code also does the platform specific cleanup as the call returns.
This all works and is being used in mozilla today on numerous platforms.
Why can't <tt>xptcall</tt> just be implemented in C or C++?
Neither of these two facilities can be done in a fully cross platform way. Nor can they generally be done fully in C or C . Let's take them one at a time to see why.
The invoke facility requires code that can build and invoke an arbitrary call frame. The C compiler builds such call frames all the time. But the compiler builds frames customized at compile time for the specific signature of the callee. <tt>xptcall</tt> needs to be able to call any valid XPCOM method signature and it needs to specify this at runtime.
The stubs facility needs to impersonate the full vtbl full of methods for any given valid XPCOM interface (including ancestor methods). There are a few ways to do this. We could run the compiler at runtime and dynamically build and load stubs. Or, we could write a bunch of platform specific code to build interface specific vtbls and method stubs. The method I choose was to use a single large vtbl with a lot of small generic stubs. This minimizes the platform specific code as much as possible. Again, you just can't write code in C to do all this. The varargs stuff goes part way, but is just not enough.
If anyone has credible ideas about how to get the required functionality in a cross platform way and/or without resorting to assembly code I'd love to hear about it.
Is <tt>xptcall</tt> a platform requirement for mozilla?
Yes. Mozilla will not run properly without a functioning port of <tt>xptcall</tt>. Non-functional stub code exists to allow building <tt>xptcall</tt> on non-supported platforms. But any browser feature that relies on <tt>xpconnect</tt> will fail. Any platform that does not do <tt>xptcall</tt> is in trouble. We need to get moving on getting <tt>xptcall</tt> working everywhere!
What platforms are supported?
The growing list:
Where can I find other resources?
The code is at: http://lxr.mozilla.org/seamonkey/source/xpcom/reflect/xptcall
A new porting guide is at: http://lxr.mozilla.org/seamonkey/source/xpcom/reflect/xptcall/porting.html
Original Document Information
- Author(s): John Bandhauer <firstname.lastname@example.org>
- Originally Published: 02 September 1999