|
1 <!-- This Source Code Form is subject to the terms of the Mozilla Public |
|
2 - License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> |
|
4 |
|
5 <html> |
|
6 <head> |
|
7 <title>xptcall Porting Guide</title> |
|
8 </head> |
|
9 <body bgcolor = "white"> |
|
10 <h2><center>xptcall Porting Guide</center></h2> |
|
11 |
|
12 <h3>Overview</h3> |
|
13 |
|
14 <blockquote> |
|
15 |
|
16 <a href="http://www.mozilla.org/scriptable/xptcall-faq.html"> xptcall</a> is a |
|
17 library that supports both invoking methods on arbitrary xpcom objects and |
|
18 implementing classes whose objects can impersonate any xpcom interface. It does |
|
19 this using platform specific assembly language code. This code needs to be |
|
20 ported to all platforms that want to support xptcall (and thus mozilla). |
|
21 |
|
22 </blockquote> |
|
23 |
|
24 <h3>The tree</h3> |
|
25 |
|
26 <blockquote> |
|
27 <pre> |
|
28 <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall">mozilla/xpcom/reflect/xptcall</a> |
|
29 +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public">public</a> // exported headers |
|
30 +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src">src</a> // core source |
|
31 | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md">md</a> // platform specific parts |
|
32 | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/mac">mac</a> // mac ppc |
|
33 | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix">unix</a> // all unix |
|
34 | \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32">win32</a> // win32 |
|
35 | +--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">test</a> // simple tests to get started |
|
36 \--<a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">tests</a> // full tests via api |
|
37 </pre> |
|
38 |
|
39 Porters are free to create subdirectories under the base <code>md</code> |
|
40 directory for their given platforms and to integrate into the build system as |
|
41 appropriate for their platform. |
|
42 |
|
43 </blockquote> |
|
44 |
|
45 <h3>Theory of operation</h3> |
|
46 |
|
47 <blockquote> |
|
48 |
|
49 There are really two pieces of functionality: <i>invoke</i> and <i>stubs</i>... |
|
50 |
|
51 <p> |
|
52 |
|
53 The <b><i>invoke</i></b> functionality requires the implementation of the |
|
54 following on each platform (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>): |
|
55 |
|
56 <pre> |
|
57 XPTC_PUBLIC_API(nsresult) |
|
58 NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
|
59 uint32_t paramCount, nsXPTCVariant* params); |
|
60 </pre> |
|
61 |
|
62 Calling code is expected to supply an array of <code>nsXPTCVariant</code> |
|
63 structs. These are discriminated unions describing the type and value of each |
|
64 parameter of the target function. The platform specific code then builds a call |
|
65 frame and invokes the method indicated by the index <code>methodIndex</code> on |
|
66 the xpcom interface <code>that</code>. |
|
67 |
|
68 <p> |
|
69 |
|
70 Here are examples of this implementation for |
|
71 <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcinvoke.cpp">Win32</a> |
|
72 and |
|
73 <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>. |
|
74 |
|
75 Both of these implementations use the basic strategy of: figure out how much |
|
76 stack space is needed for the params, make the space in a new frame, copy the |
|
77 params to that space, invoke the method, cleanup and return. C++ is used where |
|
78 appropriate, Assembly language is used where necessary. Inline assembly language is used here, |
|
79 but it is equally valid to use separate assembly language source files. Porters |
|
80 can decide how best to do this for their platforms. |
|
81 |
|
82 <p> |
|
83 |
|
84 The <b><i>stubs</i></b> functionality is more complex. The goal here is a class |
|
85 whose vtbl can look like the vtbl of any arbitrary xpcom interface. Objects of |
|
86 this class can then be built to impersonate any xpcom object. The base interface |
|
87 for this is (from <a href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcall.h">xptcall/public/xptcall.h</a>): |
|
88 |
|
89 <pre> |
|
90 class nsXPTCStubBase : public nsISupports |
|
91 { |
|
92 public: |
|
93 // Include generated vtbl stub declarations. |
|
94 // These are virtual and *also* implemented by this class.. |
|
95 #include "xptcstubsdecl.inc" |
|
96 |
|
97 // The following methods must be provided by inheritor of this class. |
|
98 |
|
99 // return a refcounted pointer to the InterfaceInfo for this object |
|
100 // NOTE: on some platforms this MUST not fail or we crash! |
|
101 NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info) = 0; |
|
102 |
|
103 // call this method and return result |
|
104 NS_IMETHOD CallMethod(uint16_t methodIndex, |
|
105 const nsXPTMethodInfo* info, |
|
106 nsXPTCMiniVariant* params) = 0; |
|
107 }; |
|
108 </pre> |
|
109 |
|
110 Code that wishes to make use of this <i>stubs</i> functionality (such as |
|
111 <a href="http://www.mozilla.org/scriptable/">XPConnect</a>) implement a class |
|
112 which inherits from <code>nsXPTCStubBase</code> and implements the |
|
113 <code>GetInterfaceInfo</code> and <code>CallMethod</code> to let the |
|
114 platform specific code know how to get interface information and how to dispatch methods |
|
115 once their parameters have been pulled out of the platform specific calling |
|
116 frame. |
|
117 |
|
118 <p> |
|
119 |
|
120 Porters of this functionality implement the platform specific code for the |
|
121 <i>stub</i> methods that fill the vtbl for this class. The idea here is that the |
|
122 class has a vtbl full of a large number of generic stubs. All instances of this |
|
123 class share that vtbl and the same stubs. The stubs forward calls to a platform |
|
124 specific method that uses the interface information supplied by |
|
125 the overridden <code>GetInterfaceInfo</code> to extract the parameters and build |
|
126 an array of platform independent <code>nsXPTCMiniVariant</code> structs which |
|
127 are in turn passed on to the overridden <code>CallMethod</code>. The |
|
128 platform dependent code is responsible for doing any cleanup and returning. |
|
129 |
|
130 <p> |
|
131 |
|
132 The stub methods are declared in <a |
|
133 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdecl.inc">xptcall/public/xptcstubsdecl.inc</a>. |
|
134 These are '#included' into the declaration of <code>nsXPTCStubBase</code>. A |
|
135 similar include file (<a |
|
136 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/xptcstubsdef.inc">xptcall/public/xptcstubsdef.inc</a>) |
|
137 is expanded using platform specific macros to define the stub functions. These |
|
138 '.inc' files are checked into cvs. However, they can be regenerated as necessary |
|
139 (i.e. to change the number of stubs or to change their specific declaration) |
|
140 using the Perl script <a |
|
141 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/public/genstubs.pl">xptcall/public/genstubs.pl</a>. |
|
142 |
|
143 <p> |
|
144 |
|
145 Here are examples of this implementation for <a |
|
146 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp">Win32</a> |
|
147 and <a |
|
148 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/unix/xptcstubs_unixish_x86.cpp">Linux x86, NetBSD x86, and FreeBSD</a>. |
|
149 Both of these examples use inline assembly language. That is just how I |
|
150 decided to do it. You can do it as you choose. |
|
151 |
|
152 <p> |
|
153 |
|
154 The Win32 version is somewhat tighter because the __declspec(naked) feature |
|
155 allows for very small stubs. However, the __stdcall requires the callee to clean |
|
156 up the stack, so it is imperative that the interface information scheme allow |
|
157 the code to determine the correct stack pointer fixup for return without fail, |
|
158 else the process will crash. |
|
159 |
|
160 <p> |
|
161 |
|
162 I opted to use inline assembler for the gcc Linux x86 port. I ended up with |
|
163 larger stubs than I would have preferred rather than battle the compiler over |
|
164 what would happen to the stack before my asm code began running. |
|
165 |
|
166 <p> |
|
167 |
|
168 I believe that the non-assembly parts of these files can be copied and reused |
|
169 with minimal (but not zero) platform specific tweaks. Feel free to copy and |
|
170 paste as necessary. Please remember that safety and reliability are more |
|
171 important than speed optimizations. This code is primarily used to connect XPCOM |
|
172 components with JavaScript; function call overhead is a <b>tiny</b> part of the |
|
173 time involved. |
|
174 |
|
175 <p> |
|
176 |
|
177 I put together |
|
178 <a |
|
179 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/src/md/test">xptcall/src/md/test |
|
180 </a> as a place to evolve the basic functionality as a port is coming together. |
|
181 Not all of the functionality is exercised, but it is a place to get started. |
|
182 <a |
|
183 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/tests">xptcall/tests |
|
184 </a> has an api level test for <code>NS_InvokeByIndex</code>, but no tests for |
|
185 the <i>stubs</i> functionality. Such a test ought to be written, but this has not |
|
186 yet been done. |
|
187 |
|
188 <p> |
|
189 |
|
190 A full 'test' at this point requires building the client and running the |
|
191 XPConnect test called <i>TestXPC</i> in |
|
192 <a |
|
193 href="http://lxr.mozilla.org/mozilla/source/js/xpconnect/tests">mozilla/js/xpconnect/tests |
|
194 </a>. |
|
195 |
|
196 <p> |
|
197 |
|
198 Getting these ports done is very important. Please let <a |
|
199 href="mailto:jband@netscape.com">me</a> know if you are interested in doing one. |
|
200 I'll answer any questions as I get them. |
|
201 |
|
202 <p> |
|
203 |
|
204 <a |
|
205 href="http://lxr.mozilla.org/mozilla/source/xpcom/reflect/xptcall/status.html"> |
|
206 Porting Status |
|
207 </a> |
|
208 |
|
209 </blockquote> |
|
210 |
|
211 <hr> |
|
212 <b>Author:</b> <a href="mailto:jband@netscape.com">John Bandhauer <jband@netscape.com></a><br> |
|
213 <b>Last modified:</b> 31 May 1999 |
|
214 |
|
215 </body> |
|
216 </html> |