xpcom/reflect/xptcall/porting.html

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:9f38d24a14b2
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 &lt;jband@netscape.com&gt;</a><br>
213 <b>Last modified:</b> 31 May 1999
214
215 </body>
216 </html>

mercurial