diff -r 000000000000 -r 6474c204b198 xpcom/reflect/xptcall/porting.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xpcom/reflect/xptcall/porting.html Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,216 @@ + + + +
++ + xptcall is a +library that supports both invoking methods on arbitrary xpcom objects and +implementing classes whose objects can impersonate any xpcom interface. It does +this using platform specific assembly language code. This code needs to be +ported to all platforms that want to support xptcall (and thus mozilla). + ++ +
++ ++mozilla/xpcom/reflect/xptcall + +--public // exported headers + +--src // core source + | \--md // platform specific parts + | +--mac // mac ppc + | +--unix // all unix + | \--win32 // win32 + | +--test // simple tests to get started + \--tests // full tests via api ++ +Porters are free to create subdirectories under the basemd
+directory for their given platforms and to integrate into the build system as +appropriate for their platform. + +
+ +There are really two pieces of functionality: invoke and stubs... + ++ ++ +The invoke functionality requires the implementation of the +following on each platform (from xptcall/public/xptcall.h): + +
+XPTC_PUBLIC_API(nsresult) +NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, + uint32_t paramCount, nsXPTCVariant* params); ++ +Calling code is expected to supply an array ofnsXPTCVariant
+structs. These are discriminated unions describing the type and value of each +parameter of the target function. The platform specific code then builds a call +frame and invokes the method indicated by the indexmethodIndex
on +the xpcom interfacethat
. + ++ +Here are examples of this implementation for +Win32 +and +Linux x86, NetBSD x86, and FreeBSD. + +Both of these implementations use the basic strategy of: figure out how much +stack space is needed for the params, make the space in a new frame, copy the +params to that space, invoke the method, cleanup and return. C++ is used where +appropriate, Assembly language is used where necessary. Inline assembly language is used here, +but it is equally valid to use separate assembly language source files. Porters +can decide how best to do this for their platforms. + +
+ +The stubs functionality is more complex. The goal here is a class +whose vtbl can look like the vtbl of any arbitrary xpcom interface. Objects of +this class can then be built to impersonate any xpcom object. The base interface +for this is (from xptcall/public/xptcall.h): + +
+class nsXPTCStubBase : public nsISupports +{ +public: + // Include generated vtbl stub declarations. + // These are virtual and *also* implemented by this class.. +#include "xptcstubsdecl.inc" + + // The following methods must be provided by inheritor of this class. + + // return a refcounted pointer to the InterfaceInfo for this object + // NOTE: on some platforms this MUST not fail or we crash! + NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0; + + // call this method and return result + NS_IMETHOD CallMethod(uint16_t methodIndex, + const nsXPTMethodInfo* info, + nsXPTCMiniVariant* params) = 0; +}; ++ +Code that wishes to make use of this stubs functionality (such as +XPConnect) implement a class +which inherits fromnsXPTCStubBase
and implements the +GetInterfaceInfo
andCallMethod
to let the +platform specific code know how to get interface information and how to dispatch methods +once their parameters have been pulled out of the platform specific calling +frame. + ++ +Porters of this functionality implement the platform specific code for the +stub methods that fill the vtbl for this class. The idea here is that the +class has a vtbl full of a large number of generic stubs. All instances of this +class share that vtbl and the same stubs. The stubs forward calls to a platform +specific method that uses the interface information supplied by +the overridden
GetInterfaceInfo
to extract the parameters and build +an array of platform independentnsXPTCMiniVariant
structs which +are in turn passed on to the overriddenCallMethod
. The +platform dependent code is responsible for doing any cleanup and returning. + ++ +The stub methods are declared in xptcall/public/xptcstubsdecl.inc. +These are '#included' into the declaration of
nsXPTCStubBase
. A +similar include file (xptcall/public/xptcstubsdef.inc) +is expanded using platform specific macros to define the stub functions. These +'.inc' files are checked into cvs. However, they can be regenerated as necessary +(i.e. to change the number of stubs or to change their specific declaration) +using the Perl script xptcall/public/genstubs.pl. + ++ +Here are examples of this implementation for Win32 +and Linux x86, NetBSD x86, and FreeBSD. +Both of these examples use inline assembly language. That is just how I +decided to do it. You can do it as you choose. + +
+ +The Win32 version is somewhat tighter because the __declspec(naked) feature +allows for very small stubs. However, the __stdcall requires the callee to clean +up the stack, so it is imperative that the interface information scheme allow +the code to determine the correct stack pointer fixup for return without fail, +else the process will crash. + +
+ +I opted to use inline assembler for the gcc Linux x86 port. I ended up with +larger stubs than I would have preferred rather than battle the compiler over +what would happen to the stack before my asm code began running. + +
+ +I believe that the non-assembly parts of these files can be copied and reused +with minimal (but not zero) platform specific tweaks. Feel free to copy and +paste as necessary. Please remember that safety and reliability are more +important than speed optimizations. This code is primarily used to connect XPCOM +components with JavaScript; function call overhead is a tiny part of the +time involved. + +
+ +I put together +xptcall/src/md/test + as a place to evolve the basic functionality as a port is coming together. +Not all of the functionality is exercised, but it is a place to get started. +xptcall/tests + has an api level test for
NS_InvokeByIndex
, but no tests for +the stubs functionality. Such a test ought to be written, but this has not +yet been done. + ++ +A full 'test' at this point requires building the client and running the +XPConnect test called TestXPC in +mozilla/js/xpconnect/tests +. + +
+ +Getting these ports done is very important. Please let me know if you are interested in doing one. +I'll answer any questions as I get them. + +
+ + +Porting Status + + +