1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/reflect/xptcall/porting.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,216 @@ 1.4 +<!-- This Source Code Form is subject to the terms of the Mozilla Public 1.5 + - License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> 1.7 + 1.8 +<html> 1.9 +<head> 1.10 +<title>xptcall Porting Guide</title> 1.11 +</head> 1.12 +<body bgcolor = "white"> 1.13 +<h2><center>xptcall Porting Guide</center></h2> 1.14 + 1.15 +<h3>Overview</h3> 1.16 + 1.17 +<blockquote> 1.18 + 1.19 +<a href="http://www.mozilla.org/scriptable/xptcall-faq.html"> xptcall</a> is a 1.20 +library that supports both invoking methods on arbitrary xpcom objects and 1.21 +implementing classes whose objects can impersonate any xpcom interface. It does 1.22 +this using platform specific assembly language code. This code needs to be 1.23 +ported to all platforms that want to support xptcall (and thus mozilla). 1.24 + 1.25 +</blockquote> 1.26 + 1.27 +<h3>The tree</h3> 1.28 + 1.29 +<blockquote> 1.30 +<pre> 1.31 +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall">mozilla/xpcom/reflect/xptcall</a> 1.32 + +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public">public</a> // exported headers 1.33 + +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src">src</a> // core source 1.34 + | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md">md</a> // platform specific parts 1.35 + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a> // mac ppc 1.36 + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> // all unix 1.37 + | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a> // win32 1.38 + | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">test</a> // simple tests to get started 1.39 + \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">tests</a> // full tests via api 1.40 +</pre> 1.41 + 1.42 +Porters are free to create subdirectories under the base <code>md</code> 1.43 +directory for their given platforms and to integrate into the build system as 1.44 +appropriate for their platform. 1.45 + 1.46 +</blockquote> 1.47 + 1.48 +<h3>Theory of operation</h3> 1.49 + 1.50 +<blockquote> 1.51 + 1.52 +There are really two pieces of functionality: <i>invoke</i> and <i>stubs</i>... 1.53 + 1.54 +<p> 1.55 + 1.56 +The <b><i>invoke</i></b> functionality requires the implementation of the 1.57 +following on each platform (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>): 1.58 + 1.59 +<pre> 1.60 +XPTC_PUBLIC_API(nsresult) 1.61 +NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, 1.62 + uint32_t paramCount, nsXPTCVariant* params); 1.63 +</pre> 1.64 + 1.65 +Calling code is expected to supply an array of <code>nsXPTCVariant</code> 1.66 +structs. These are discriminated unions describing the type and value of each 1.67 +parameter of the target function. The platform specific code then builds a call 1.68 +frame and invokes the method indicated by the index <code>methodIndex</code> on 1.69 +the xpcom interface <code>that</code>. 1.70 + 1.71 +<p> 1.72 + 1.73 +Here are examples of this implementation for 1.74 +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp">Win32</a> 1.75 +and 1.76 +<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>. 1.77 + 1.78 +Both of these implementations use the basic strategy of: figure out how much 1.79 +stack space is needed for the params, make the space in a new frame, copy the 1.80 +params to that space, invoke the method, cleanup and return. C++ is used where 1.81 +appropriate, Assembly language is used where necessary. Inline assembly language is used here, 1.82 +but it is equally valid to use separate assembly language source files. Porters 1.83 +can decide how best to do this for their platforms. 1.84 + 1.85 +<p> 1.86 + 1.87 +The <b><i>stubs</i></b> functionality is more complex. The goal here is a class 1.88 +whose vtbl can look like the vtbl of any arbitrary xpcom interface. Objects of 1.89 +this class can then be built to impersonate any xpcom object. The base interface 1.90 +for this is (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>): 1.91 + 1.92 +<pre> 1.93 +class nsXPTCStubBase : public nsISupports 1.94 +{ 1.95 +public: 1.96 + // Include generated vtbl stub declarations. 1.97 + // These are virtual and *also* implemented by this class.. 1.98 +#include "xptcstubsdecl.inc" 1.99 + 1.100 + // The following methods must be provided by inheritor of this class. 1.101 + 1.102 + // return a refcounted pointer to the InterfaceInfo for this object 1.103 + // NOTE: on some platforms this MUST not fail or we crash! 1.104 + NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0; 1.105 + 1.106 + // call this method and return result 1.107 + NS_IMETHOD CallMethod(uint16_t methodIndex, 1.108 + const nsXPTMethodInfo* info, 1.109 + nsXPTCMiniVariant* params) = 0; 1.110 +}; 1.111 +</pre> 1.112 + 1.113 +Code that wishes to make use of this <i>stubs</i> functionality (such as 1.114 +<a href="http://www.mozilla.org/scriptable/">XPConnect</a>) implement a class 1.115 +which inherits from <code>nsXPTCStubBase</code> and implements the 1.116 +<code>GetInterfaceInfo</code> and <code>CallMethod</code> to let the 1.117 +platform specific code know how to get interface information and how to dispatch methods 1.118 +once their parameters have been pulled out of the platform specific calling 1.119 +frame. 1.120 + 1.121 +<p> 1.122 + 1.123 +Porters of this functionality implement the platform specific code for the 1.124 +<i>stub</i> methods that fill the vtbl for this class. The idea here is that the 1.125 +class has a vtbl full of a large number of generic stubs. All instances of this 1.126 +class share that vtbl and the same stubs. The stubs forward calls to a platform 1.127 +specific method that uses the interface information supplied by 1.128 +the overridden <code>GetInterfaceInfo</code> to extract the parameters and build 1.129 +an array of platform independent <code>nsXPTCMiniVariant</code> structs which 1.130 +are in turn passed on to the overridden <code>CallMethod</code>. The 1.131 +platform dependent code is responsible for doing any cleanup and returning. 1.132 + 1.133 +<p> 1.134 + 1.135 +The stub methods are declared in <a 1.136 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdecl.inc">xptcall/public/xptcstubsdecl.inc</a>. 1.137 +These are '#included' into the declaration of <code>nsXPTCStubBase</code>. A 1.138 +similar include file (<a 1.139 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdef.inc">xptcall/public/xptcstubsdef.inc</a>) 1.140 +is expanded using platform specific macros to define the stub functions. These 1.141 +'.inc' files are checked into cvs. However, they can be regenerated as necessary 1.142 +(i.e. to change the number of stubs or to change their specific declaration) 1.143 +using the Perl script <a 1.144 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/genstubs.pl">xptcall/public/genstubs.pl</a>. 1.145 + 1.146 +<p> 1.147 + 1.148 +Here are examples of this implementation for <a 1.149 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp">Win32</a> 1.150 +and <a 1.151 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>. 1.152 +Both of these examples use inline assembly language. That is just how I 1.153 +decided to do it. You can do it as you choose. 1.154 + 1.155 +<p> 1.156 + 1.157 +The Win32 version is somewhat tighter because the __declspec(naked) feature 1.158 +allows for very small stubs. However, the __stdcall requires the callee to clean 1.159 +up the stack, so it is imperative that the interface information scheme allow 1.160 +the code to determine the correct stack pointer fixup for return without fail, 1.161 +else the process will crash. 1.162 + 1.163 +<p> 1.164 + 1.165 +I opted to use inline assembler for the gcc Linux x86 port. I ended up with 1.166 +larger stubs than I would have preferred rather than battle the compiler over 1.167 +what would happen to the stack before my asm code began running. 1.168 + 1.169 +<p> 1.170 + 1.171 +I believe that the non-assembly parts of these files can be copied and reused 1.172 +with minimal (but not zero) platform specific tweaks. Feel free to copy and 1.173 +paste as necessary. Please remember that safety and reliability are more 1.174 +important than speed optimizations. This code is primarily used to connect XPCOM 1.175 +components with JavaScript; function call overhead is a <b>tiny</b> part of the 1.176 +time involved. 1.177 + 1.178 +<p> 1.179 + 1.180 +I put together 1.181 +<a 1.182 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">xptcall/src/md/test 1.183 +</a> as a place to evolve the basic functionality as a port is coming together. 1.184 +Not all of the functionality is exercised, but it is a place to get started. 1.185 +<a 1.186 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">xptcall/tests 1.187 +</a> has an api level test for <code>NS_InvokeByIndex</code>, but no tests for 1.188 +the <i>stubs</i> functionality. Such a test ought to be written, but this has not 1.189 +yet been done. 1.190 + 1.191 +<p> 1.192 + 1.193 +A full 'test' at this point requires building the client and running the 1.194 +XPConnect test called <i>TestXPC</i> in 1.195 +<a 1.196 +href="http://lxr.mozilla.org/mozilla/source/js/xpconnect/tests">mozilla/js/xpconnect/tests 1.197 +</a>. 1.198 + 1.199 +<p> 1.200 + 1.201 +Getting these ports done is very important. Please let <a 1.202 +href="mailto:jband@netscape.com">me</a> know if you are interested in doing one. 1.203 +I'll answer any questions as I get them. 1.204 + 1.205 +<p> 1.206 + 1.207 +<a 1.208 +href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/status.html"> 1.209 +Porting Status 1.210 +</a> 1.211 + 1.212 +</blockquote> 1.213 + 1.214 +<hr> 1.215 +<b>Author:</b> <a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a><br> 1.216 +<b>Last modified:</b> 31 May 1999 1.217 + 1.218 +</body> 1.219 +</html>