xptcall FAQ
Why does xptcall exist?
xptcall exists for two reasons:
- To support invoking arbitrary methods on xpcom interfaces.
- To support dynamically impersonating any xpcom interface.
Both of these facilities are required by XPConnect. The
invoke facility will also be used in a system warren is working on for
simplifying working with RDF datasources.
The xptcall 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 xptcall really do?
The core invoke function has the declaration:
XPTC_PUBLIC_API(nsresult)
XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
PRUint32 paramCount, nsXPTCVariant* params);
nsXPTCVariant is a discriminated union of the types that can be
passed as parameters to the target function (including void* to
represent arbitrary pointer types).
Given the correct set of params, this function can call any method on any XPCOM
interface. XPConnect uses information from typelib files to
reflect arbitrary XPCOM interfaces into JavaScript and to make calls from
JavaScript to XPCOM using XPTC_InvokeByIndex. The information in
the typelibs allows XPConnect to convert function params and build the
nsXPTCVariant array required to make this call.
The stubs (or impersonation) facility of xptcall 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
xptcall. 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 test programs
Why can't xptcall 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. xptcall 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 xptcall a platform requirement for mozilla?
Yes. While the mozilla browser does not require xptcall
functionality today, it will soon. Non-functional stub code exists to
allow building xptcall on non-supported platforms. But as soon as
the browser starts using xpconnect, any platform that does not do
xptcall will be in trouble. We need to get moving on getting
xptcall working everywhere!
What platforms are supported?
The growing list:
Porting Status
Where can I find other resources?
The code is at:
http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall
A new porting guide is at:
http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/porting.html
Pre-implementation proposals are
here and
here.
Author: John Bandhauer <jband@netscape.com>
Last modified: 30 April 1999
|