Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* Invoke tests xptcall. */
8 #include <stdio.h>
9 #include "xptcall.h"
10 #include "prinrval.h"
11 #include "nsMemory.h"
13 // Allows us to mark unused functions as known-unused
14 #ifdef __GNUC__
15 #define UNUSED __attribute__ ((unused))
16 #else
17 #define UNUSED
18 #endif
20 // forward declration
21 static void DoMultipleInheritenceTest();
22 static void DoMultipleInheritenceTest2();
23 static void UNUSED DoSpeedTest();
25 // {AAC1FB90-E099-11d2-984E-006008962422}
26 #define INVOKETESTTARGET_IID \
27 { 0xaac1fb90, 0xe099, 0x11d2, \
28 { 0x98, 0x4e, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
31 class InvokeTestTargetInterface : public nsISupports
32 {
33 public:
34 NS_DECLARE_STATIC_IID_ACCESSOR(INVOKETESTTARGET_IID)
35 NS_IMETHOD AddTwoInts(int32_t p1, int32_t p2, int32_t* retval) = 0;
36 NS_IMETHOD MultTwoInts(int32_t p1, int32_t p2, int32_t* retval) = 0;
37 NS_IMETHOD AddTwoLLs(int64_t p1, int64_t p2, int64_t* retval) = 0;
38 NS_IMETHOD MultTwoLLs(int64_t p1, int64_t p2, int64_t* retval) = 0;
40 NS_IMETHOD AddManyInts(int32_t p1, int32_t p2, int32_t p3, int32_t p4,
41 int32_t p5, int32_t p6, int32_t p7, int32_t p8,
42 int32_t p9, int32_t p10, int32_t* retval) = 0;
44 NS_IMETHOD AddTwoFloats(float p1, float p2, float* retval) = 0;
46 NS_IMETHOD AddManyDoubles(double p1, double p2, double p3, double p4,
47 double p5, double p6, double p7, double p8,
48 double p9, double p10, double* retval) = 0;
50 NS_IMETHOD AddManyFloats(float p1, float p2, float p3, float p4,
51 float p5, float p6, float p7, float p8,
52 float p9, float p10, float* retval) = 0;
54 NS_IMETHOD AddManyManyFloats(float p1, float p2, float p3, float p4,
55 float p5, float p6, float p7, float p8,
56 float p9, float p10, float p11, float p12,
57 float p13, float p14, float p15, float p16,
58 float p17, float p18, float p19, float p20,
59 float *retval) = 0;
61 NS_IMETHOD AddMixedInts(int64_t p1, int32_t p2, int64_t p3, int32_t p4,
62 int32_t p5, int64_t p6, int32_t p7, int32_t p8,
63 int64_t p9, int32_t p10, int64_t* retval) = 0;
65 NS_IMETHOD AddMixedInts2(int32_t p1, int64_t p2, int32_t p3, int64_t p4,
66 int64_t p5, int32_t p6, int64_t p7, int64_t p8,
67 int32_t p9, int64_t p10, int64_t* retval) = 0;
69 NS_IMETHOD AddMixedFloats(float p1, float p2, double p3, double p4,
70 float p5, float p6, double p7, double p8,
71 float p9, double p10, float p11,
72 double *retval) = 0;
74 NS_IMETHOD PassTwoStrings(const char* s1, const char* s2, char** retval) = 0;
76 NS_IMETHOD AddMixedInts3(int64_t p1, int64_t p2, int32_t p3, int64_t p4,
77 int32_t p5, int32_t p6, int64_t p7, int64_t p8,
78 int32_t p9, int64_t p10, int64_t* retval) = 0;
79 NS_IMETHOD ShouldFail(int32_t p) = 0;
80 };
82 NS_DEFINE_STATIC_IID_ACCESSOR(InvokeTestTargetInterface, INVOKETESTTARGET_IID)
84 class InvokeTestTarget : public InvokeTestTargetInterface
85 {
86 public:
87 NS_DECL_ISUPPORTS
88 NS_IMETHOD AddTwoInts(int32_t p1, int32_t p2, int32_t* retval);
89 NS_IMETHOD MultTwoInts(int32_t p1, int32_t p2, int32_t* retval);
90 NS_IMETHOD AddTwoLLs(int64_t p1, int64_t p2, int64_t* retval);
91 NS_IMETHOD MultTwoLLs(int64_t p1, int64_t p2, int64_t* retval);
93 NS_IMETHOD AddManyInts(int32_t p1, int32_t p2, int32_t p3, int32_t p4,
94 int32_t p5, int32_t p6, int32_t p7, int32_t p8,
95 int32_t p9, int32_t p10, int32_t* retval);
97 NS_IMETHOD AddTwoFloats(float p1, float p2, float* retval);
99 NS_IMETHOD AddManyDoubles(double p1, double p2, double p3, double p4,
100 double p5, double p6, double p7, double p8,
101 double p9, double p10, double* retval);
103 NS_IMETHOD AddManyFloats(float p1, float p2, float p3, float p4,
104 float p5, float p6, float p7, float p8,
105 float p9, float p10, float* retval);
107 NS_IMETHOD AddMixedInts(int64_t p1, int32_t p2, int64_t p3, int32_t p4,
108 int32_t p5, int64_t p6, int32_t p7, int32_t p8,
109 int64_t p9, int32_t p10, int64_t* retval);
111 NS_IMETHOD AddMixedInts2(int32_t p1, int64_t p2, int32_t p3, int64_t p4,
112 int64_t p5, int32_t p6, int64_t p7, int64_t p8,
113 int32_t p9, int64_t p10, int64_t* retval);
115 NS_IMETHOD AddMixedFloats(float p1, float p2, double p3, double p4,
116 float p5, float p6, double p7, double p8,
117 float p9, double p10, float p11,
118 double *retval);
120 NS_IMETHOD AddManyManyFloats(float p1, float p2, float p3, float p4,
121 float p5, float p6, float p7, float p8,
122 float p9, float p10, float p11, float p12,
123 float p13, float p14, float p15, float p16,
124 float p17, float p18, float p19, float p20,
125 float *retval);
127 NS_IMETHOD PassTwoStrings(const char* s1, const char* s2, char** retval);
129 InvokeTestTarget();
131 NS_IMETHOD AddMixedInts3(int64_t p1, int64_t p2, int32_t p3, int64_t p4,
132 int32_t p5, int32_t p6, int64_t p7, int64_t p8,
133 int32_t p9, int64_t p10, int64_t* retval);
134 NS_IMETHOD ShouldFail(int32_t p);
135 };
137 NS_IMPL_ISUPPORTS(InvokeTestTarget, InvokeTestTargetInterface)
139 InvokeTestTarget::InvokeTestTarget()
140 {
141 NS_ADDREF_THIS();
142 }
144 NS_IMETHODIMP
145 InvokeTestTarget::ShouldFail(int32_t p) {
146 return NS_ERROR_NULL_POINTER;
147 }
148 NS_IMETHODIMP
149 InvokeTestTarget::AddTwoInts(int32_t p1, int32_t p2, int32_t* retval)
150 {
151 *retval = p1 + p2;
152 return NS_OK;
153 }
155 NS_IMETHODIMP
156 InvokeTestTarget::MultTwoInts(int32_t p1, int32_t p2, int32_t* retval)
157 {
158 *retval = p1 * p2;
159 return NS_OK;
160 }
162 NS_IMETHODIMP
163 InvokeTestTarget::AddTwoLLs(int64_t p1, int64_t p2, int64_t* retval)
164 {
165 *retval = p1 + p2;
166 return NS_OK;
167 }
169 NS_IMETHODIMP
170 InvokeTestTarget::MultTwoLLs(int64_t p1, int64_t p2, int64_t* retval)
171 {
172 *retval = p1 * p2;
173 return NS_OK;
174 }
176 NS_IMETHODIMP
177 InvokeTestTarget::AddManyInts(int32_t p1, int32_t p2, int32_t p3, int32_t p4,
178 int32_t p5, int32_t p6, int32_t p7, int32_t p8,
179 int32_t p9, int32_t p10, int32_t* retval)
180 {
181 #ifdef DEBUG_TESTINVOKE
182 printf("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
183 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
184 #endif
185 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
186 return NS_OK;
187 }
189 NS_IMETHODIMP
190 InvokeTestTarget::AddTwoFloats(float p1, float p2, float *retval)
191 {
192 #ifdef DEBUG_TESTINVOKE
193 printf("%f, %f\n", p1, p2);
194 #endif
195 *retval = p1 + p2;
196 return NS_OK;
197 }
199 NS_IMETHODIMP
200 InvokeTestTarget::AddManyDoubles(double p1, double p2, double p3, double p4,
201 double p5, double p6, double p7, double p8,
202 double p9, double p10, double* retval)
203 {
204 #ifdef DEBUG_TESTINVOKE
205 printf("%lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf, %lf\n",
206 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
207 #endif
208 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
209 return NS_OK;
210 }
212 NS_IMETHODIMP
213 InvokeTestTarget::AddManyFloats(float p1, float p2, float p3, float p4,
214 float p5, float p6, float p7, float p8,
215 float p9, float p10, float* retval)
216 {
217 #ifdef DEBUG_TESTINVOKE
218 printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n",
219 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
220 #endif
221 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
222 return NS_OK;
223 }
225 NS_IMETHODIMP
226 InvokeTestTarget::AddMixedFloats(float p1, float p2, double p3, double p4,
227 float p5, float p6, double p7, double p8,
228 float p9, double p10, float p11,
229 double *retval)
230 {
231 #ifdef DEBUG_TESTINVOKE
232 printf("%f, %f, %lf, %lf, %f, %f, %lf, %lf, %f, %lf, %f\n",
233 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
234 #endif
235 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 + p11;
236 return NS_OK;
237 }
239 NS_IMETHODIMP
240 InvokeTestTarget::AddManyManyFloats(float p1, float p2, float p3, float p4,
241 float p5, float p6, float p7, float p8,
242 float p9, float p10, float p11, float p12,
243 float p13, float p14, float p15, float p16,
244 float p17, float p18, float p19, float p20,
245 float *retval)
246 {
247 #ifdef DEBUG_TESTINVOKE
248 printf("%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, "
249 "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f\n",
250 p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
251 p11, p12, p13, p14, p15, p16, p17, p18, p19, p20);
252 #endif
253 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10 +
254 p11 + p12 + p13 + p14 + p15 + p16 + p17 + p18 + p19 + p20;
255 return NS_OK;
256 }
258 NS_IMETHODIMP
259 InvokeTestTarget::AddMixedInts(int64_t p1, int32_t p2, int64_t p3, int32_t p4,
260 int32_t p5, int64_t p6, int32_t p7, int32_t p8,
261 int64_t p9, int32_t p10, int64_t* retval)
262 {
263 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
264 return NS_OK;
265 }
267 NS_IMETHODIMP
268 InvokeTestTarget::AddMixedInts2(int32_t p1, int64_t p2, int32_t p3, int64_t p4,
269 int64_t p5, int32_t p6, int64_t p7, int64_t p8,
270 int32_t p9, int64_t p10, int64_t* retval)
271 {
272 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
273 return NS_OK;
274 }
276 NS_IMETHODIMP
277 InvokeTestTarget::AddMixedInts3(int64_t p1, int64_t p2, int32_t p3, int64_t p4,
278 int32_t p5, int32_t p6, int64_t p7, int64_t p8,
279 int32_t p9, int64_t p10, int64_t* retval)
280 {
281 printf("P1 : %lld\n", p1);
282 printf("P2 : %lld\n", p2);
283 printf("P3 : %d\n", p3);
284 printf("P4 : %lld\n", p4);
285 printf("P5 : %d\n", p5);
286 printf("P6 : %d\n", p6);
287 printf("P7 : %lld\n", p7);
288 printf("P8 : %lld\n", p8);
289 printf("P9 : %d\n", p9);
290 printf("P10: %lld\n", p10);
291 printf("ret: %p\n", static_cast<void*>(retval));
292 *retval = p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9 + p10;
293 return NS_OK;
294 }
296 NS_IMETHODIMP
297 InvokeTestTarget::PassTwoStrings(const char* s1, const char* s2, char** retval)
298 {
299 const char milk[] = "milk";
300 char *ret = (char*)nsMemory::Alloc(sizeof(milk));
301 if (!ret)
302 return NS_ERROR_OUT_OF_MEMORY;
303 strncpy(ret, milk, sizeof(milk));
304 printf("\t%s %s", s1, s2);
305 *retval = ret;
306 return NS_OK;
307 }
309 int main()
310 {
311 InvokeTestTarget *test = new InvokeTestTarget();
313 /* here we make the global 'check for alloc failure' checker happy */
314 if(!test)
315 return 1;
317 int32_t out, tmp32 = 0;
318 int64_t out64;
319 nsresult failed_rv;
320 printf("calling direct:\n");
321 if(NS_SUCCEEDED(test->AddTwoInts(1,1,&out)))
322 printf("\t1 + 1 = %d\n", out);
323 else
324 printf("\tFAILED");
325 int64_t one = 1, two = 2;
326 if(NS_SUCCEEDED(test->AddTwoLLs(one,one,&out64)))
327 {
328 tmp32 = (int)out64;
329 printf("\t1L + 1L = %d\n", tmp32);
330 }
331 else
332 printf("\tFAILED");
333 if(NS_SUCCEEDED(test->MultTwoInts(2,2,&out)))
334 printf("\t2 * 2 = %d\n", out);
335 else
336 printf("\tFAILED");
337 if(NS_SUCCEEDED(test->MultTwoLLs(two,two,&out64)))
338 {
339 tmp32 = (int)out64;
340 printf("\t2L * 2L = %d\n", tmp32);
341 }
342 else
343 printf("\tFAILED");
345 double outD;
346 float outF;
347 int32_t outI;
348 char *outS;
350 if(NS_SUCCEEDED(test->AddManyInts(1,2,3,4,5,6,7,8,9,10,&outI)))
351 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", outI);
352 else
353 printf("\tFAILED");
355 if(NS_SUCCEEDED(test->AddTwoFloats(1,2,&outF)))
356 printf("\t1 + 2 = %ff\n", (double)outF);
357 else
358 printf("\tFAILED");
360 if(NS_SUCCEEDED(test->AddManyDoubles(1,2,3,4,5,6,7,8,9,10,&outD)))
361 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n", outD);
362 else
363 printf("\tFAILED");
365 if(NS_SUCCEEDED(test->AddManyFloats(1,2,3,4,5,6,7,8,9,10,&outF)))
366 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n", (double)outF);
367 else
368 printf("\tFAILED");
370 if(NS_SUCCEEDED(test->AddManyManyFloats(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,&outF)))
371 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 +1 15 + 16 + 17 + 18 + 19 + 20 = %ff\n", (double)outF);
372 else
373 printf("\tFAILED");
375 if(NS_SUCCEEDED(test->AddMixedInts(1,2,3,4,5,6,7,8,9,10,&out64)))
376 {
377 tmp32 = (int)out64;
378 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", tmp32);
379 }
380 else
381 printf("\tFAILED");
383 if(NS_SUCCEEDED(test->AddMixedInts2(1,2,3,4,5,6,7,8,9,10,&out64)))
384 {
385 tmp32 = (int)out64;
386 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n", tmp32);
387 }
388 else
389 printf("\tFAILED");
391 if(NS_SUCCEEDED(test->AddMixedInts3(3,5,7,11,13,17,19,23,29,31,&out64)))
392 {
393 tmp32 = (int)out64;
394 printf("\t3 + 5 + 7 + 11 + 13 + 17 + 19 + 23 + 29 + 31 = %d\n", tmp32);
395 }
396 else
397 printf("\tFAILED");
399 if(NS_SUCCEEDED(test->AddMixedFloats(1,2,3,4,5,6,7,8,9,10,11,&outD)))
400 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n", (double)outD);
401 else
402 printf("\tFAILED");
404 if (NS_SUCCEEDED(test->PassTwoStrings("moo","cow",&outS))) {
405 printf(" = %s\n", outS);
406 nsMemory::Free(outS);
407 } else
408 printf("\tFAILED");
410 failed_rv = test->ShouldFail(5);
411 printf("should fail %s, returned %x\n", failed_rv == NS_ERROR_NULL_POINTER ? "failed" :"passed", failed_rv);
413 printf("calling via invoke:\n");
415 nsXPTCVariant var[21];
417 var[0].val.i32 = 1;
418 var[0].type = nsXPTType::T_I32;
419 var[0].flags = 0;
421 var[1].val.i32 = 1;
422 var[1].type = nsXPTType::T_I32;
423 var[1].flags = 0;
425 var[2].val.i32 = 0;
426 var[2].type = nsXPTType::T_I32;
427 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
428 var[2].ptr = &var[2].val.i32;
430 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 3, 3, var)))
431 printf("\t1 + 1 = %d\n", var[2].val.i32);
432 else
433 printf("\tFAILED");
435 var[0].val.i64 = 1;
436 var[0].type = nsXPTType::T_I64;
437 var[0].flags = 0;
439 var[1].val.i64 = 1;
440 var[1].type = nsXPTType::T_I64;
441 var[1].flags = 0;
443 var[2].val.i64 = 0;
444 var[2].type = nsXPTType::T_I64;
445 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
446 var[2].ptr = &var[2].val.i64;
448 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 5, 3, var)))
449 printf("\t1L + 1L = %d\n", (int)var[2].val.i64);
450 else
451 printf("\tFAILED");
453 var[0].val.i32 = 2;
454 var[0].type = nsXPTType::T_I32;
455 var[0].flags = 0;
457 var[1].val.i32 = 2;
458 var[1].type = nsXPTType::T_I32;
459 var[1].flags = 0;
461 var[2].val.i32 = 0;
462 var[2].type = nsXPTType::T_I32;
463 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
464 var[2].ptr = &var[2].val.i32;
466 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 4, 3, var)))
467 printf("\t2 * 2 = %d\n", var[2].val.i32);
468 else
469 printf("\tFAILED");
471 var[0].val.i64 = 2;
472 var[0].type = nsXPTType::T_I64;
473 var[0].flags = 0;
475 var[1].val.i64 = 2;
476 var[1].type = nsXPTType::T_I64;
477 var[1].flags = 0;
479 var[2].val.i64 = 0;
480 var[2].type = nsXPTType::T_I64;
481 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
482 var[2].ptr = &var[2].val.i64;
484 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 6, 3, var)))
485 printf("\t2L * 2L = %d\n", (int)var[2].val.i64);
486 else
487 printf("\tFAILED");
489 var[0].val.i32 = 1;
490 var[0].type = nsXPTType::T_I32;
491 var[0].flags = 0;
493 var[1].val.i32 = 2;
494 var[1].type = nsXPTType::T_I32;
495 var[1].flags = 0;
497 var[2].val.i32 = 3;
498 var[2].type = nsXPTType::T_I32;
499 var[2].flags = 0;
501 var[3].val.i32 = 4;
502 var[3].type = nsXPTType::T_I32;
503 var[3].flags = 0;
505 var[4].val.i32 = 5;
506 var[4].type = nsXPTType::T_I32;
507 var[4].flags = 0;
509 var[5].val.i32 = 6;
510 var[5].type = nsXPTType::T_I32;
511 var[5].flags = 0;
513 var[6].val.i32 = 7;
514 var[6].type = nsXPTType::T_I32;
515 var[6].flags = 0;
517 var[7].val.i32 = 8;
518 var[7].type = nsXPTType::T_I32;
519 var[7].flags = 0;
521 var[8].val.i32 = 9;
522 var[8].type = nsXPTType::T_I32;
523 var[8].flags = 0;
525 var[9].val.i32 = 10;
526 var[9].type = nsXPTType::T_I32;
527 var[9].flags = 0;
529 var[10].val.i32 = 0;
530 var[10].type = nsXPTType::T_I32;
531 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
532 var[10].ptr = &var[10].val.i32;
534 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 7, 11, var)))
535 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
536 var[10].val.i32);
538 var[0].val.f = 1.0f;
539 var[0].type = nsXPTType::T_FLOAT;
540 var[0].flags = 0;
542 var[1].val.f = 2.0f;
543 var[1].type = nsXPTType::T_FLOAT;
544 var[1].flags = 0;
546 var[2].val.f = 0.0f;
547 var[2].type = nsXPTType::T_FLOAT;
548 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
549 var[2].ptr = &var[2].val.f;
551 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 8, 3, var)))
552 printf("\t1 + 2 = %ff\n",
553 (double) var[2].val.f);
556 var[0].val.d = 1.0;
557 var[0].type = nsXPTType::T_DOUBLE;
558 var[0].flags = 0;
560 var[1].val.d = 2.0;
561 var[1].type = nsXPTType::T_DOUBLE;
562 var[1].flags = 0;
564 var[2].val.d = 3.0;
565 var[2].type = nsXPTType::T_DOUBLE;
566 var[2].flags = 0;
568 var[3].val.d = 4.0;
569 var[3].type = nsXPTType::T_DOUBLE;
570 var[3].flags = 0;
572 var[4].val.d = 5.0;
573 var[4].type = nsXPTType::T_DOUBLE;
574 var[4].flags = 0;
576 var[5].val.d = 6.0;
577 var[5].type = nsXPTType::T_DOUBLE;
578 var[5].flags = 0;
580 var[6].val.d = 7.0;
581 var[6].type = nsXPTType::T_DOUBLE;
582 var[6].flags = 0;
584 var[7].val.d = 8.0;
585 var[7].type = nsXPTType::T_DOUBLE;
586 var[7].flags = 0;
588 var[8].val.d = 9.0;
589 var[8].type = nsXPTType::T_DOUBLE;
590 var[8].flags = 0;
592 var[9].val.d = 10.0;
593 var[9].type = nsXPTType::T_DOUBLE;
594 var[9].flags = 0;
596 var[10].val.d = 0.0;
597 var[10].type = nsXPTType::T_DOUBLE;
598 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
599 var[10].ptr = &var[10].val.d;
601 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 9, 11, var)))
602 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %f\n",
603 var[10].val.d);
604 else
605 printf("\tFAILED");
607 var[0].val.f = 1.0f;
608 var[0].type = nsXPTType::T_FLOAT;
609 var[0].flags = 0;
611 var[1].val.f = 2.0f;
612 var[1].type = nsXPTType::T_FLOAT;
613 var[1].flags = 0;
615 var[2].val.f = 3.0f;
616 var[2].type = nsXPTType::T_FLOAT;
617 var[2].flags = 0;
619 var[3].val.f = 4.0f;
620 var[3].type = nsXPTType::T_FLOAT;
621 var[3].flags = 0;
623 var[4].val.f = 5.0f;
624 var[4].type = nsXPTType::T_FLOAT;
625 var[4].flags = 0;
627 var[5].val.f = 6.0f;
628 var[5].type = nsXPTType::T_FLOAT;
629 var[5].flags = 0;
631 var[6].val.f = 7.0f;
632 var[6].type = nsXPTType::T_FLOAT;
633 var[6].flags = 0;
635 var[7].val.f = 8.0f;
636 var[7].type = nsXPTType::T_FLOAT;
637 var[7].flags = 0;
639 var[8].val.f = 9.0f;
640 var[8].type = nsXPTType::T_FLOAT;
641 var[8].flags = 0;
643 var[9].val.f = 10.0f;
644 var[9].type = nsXPTType::T_FLOAT;
645 var[9].flags = 0;
647 var[10].val.f = 0.0f;
648 var[10].type = nsXPTType::T_FLOAT;
649 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
650 var[10].ptr = &var[10].val.f;
652 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 10, 11, var)))
653 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %ff\n",
654 (double) var[10].val.f);
655 else
656 printf("\tFAILED");
658 var[0].val.f = 1.0f;
659 var[0].type = nsXPTType::T_FLOAT;
660 var[0].flags = 0;
662 var[1].val.f = 2.0f;
663 var[1].type = nsXPTType::T_FLOAT;
664 var[1].flags = 0;
666 var[2].val.f = 3.0f;
667 var[2].type = nsXPTType::T_FLOAT;
668 var[2].flags = 0;
670 var[3].val.f = 4.0f;
671 var[3].type = nsXPTType::T_FLOAT;
672 var[3].flags = 0;
674 var[4].val.f = 5.0f;
675 var[4].type = nsXPTType::T_FLOAT;
676 var[4].flags = 0;
678 var[5].val.f = 6.0f;
679 var[5].type = nsXPTType::T_FLOAT;
680 var[5].flags = 0;
682 var[6].val.f = 7.0f;
683 var[6].type = nsXPTType::T_FLOAT;
684 var[6].flags = 0;
686 var[7].val.f = 8.0f;
687 var[7].type = nsXPTType::T_FLOAT;
688 var[7].flags = 0;
690 var[8].val.f = 9.0f;
691 var[8].type = nsXPTType::T_FLOAT;
692 var[8].flags = 0;
694 var[9].val.f = 10.0f;
695 var[9].type = nsXPTType::T_FLOAT;
696 var[9].flags = 0;
698 var[10].val.f = 11.0f;
699 var[10].type = nsXPTType::T_FLOAT;
700 var[10].flags = 0;
702 var[11].val.f = 12.0f;
703 var[11].type = nsXPTType::T_FLOAT;
704 var[11].flags = 0;
706 var[12].val.f = 13.0f;
707 var[12].type = nsXPTType::T_FLOAT;
708 var[12].flags = 0;
710 var[13].val.f = 14.0f;
711 var[13].type = nsXPTType::T_FLOAT;
712 var[13].flags = 0;
714 var[14].val.f = 15.0f;
715 var[14].type = nsXPTType::T_FLOAT;
716 var[14].flags = 0;
718 var[15].val.f = 16.0f;
719 var[15].type = nsXPTType::T_FLOAT;
720 var[15].flags = 0;
722 var[16].val.f = 17.0f;
723 var[16].type = nsXPTType::T_FLOAT;
724 var[16].flags = 0;
726 var[17].val.f = 18.0f;
727 var[17].type = nsXPTType::T_FLOAT;
728 var[17].flags = 0;
730 var[18].val.f = 19.0f;
731 var[18].type = nsXPTType::T_FLOAT;
732 var[18].flags = 0;
734 var[19].val.f = 20.0f;
735 var[19].type = nsXPTType::T_FLOAT;
736 var[19].flags = 0;
738 var[20].val.f = 0.0f;
739 var[20].type = nsXPTType::T_FLOAT;
740 var[20].flags = nsXPTCVariant::PTR_IS_DATA;
741 var[20].ptr = &var[20].val.f;
743 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 11, 21, var)))
744 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 = %ff\n",
745 (double) var[20].val.f);
747 var[0].val.i64 = 1;
748 var[0].type = nsXPTType::T_I64;
749 var[0].flags = 0;
751 var[1].val.i32 = 2;
752 var[1].type = nsXPTType::T_I32;
753 var[1].flags = 0;
755 var[2].val.i64 = 3;
756 var[2].type = nsXPTType::T_I64;
757 var[2].flags = 0;
759 var[3].val.i32 = 4;
760 var[3].type = nsXPTType::T_I32;
761 var[3].flags = 0;
763 var[4].val.i32 = 5;
764 var[4].type = nsXPTType::T_I32;
765 var[4].flags = 0;
767 var[5].val.i64 = 6;
768 var[5].type = nsXPTType::T_I64;
769 var[5].flags = 0;
771 var[6].val.i32 = 7;
772 var[6].type = nsXPTType::T_I32;
773 var[6].flags = 0;
775 var[7].val.i32 = 8;
776 var[7].type = nsXPTType::T_I32;
777 var[7].flags = 0;
779 var[8].val.i64 = 9;
780 var[8].type = nsXPTType::T_I64;
781 var[8].flags = 0;
783 var[9].val.i32 = 10;
784 var[9].type = nsXPTType::T_I32;
785 var[9].flags = 0;
787 var[10].val.i64 = 0;
788 var[10].type = nsXPTType::T_I64;
789 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
790 var[10].ptr = &var[10].val.i64;
792 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 12, 11, var)))
793 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
794 (int)var[10].val.i64);
795 else
796 printf("\tFAILED");
798 var[0].val.i32 = 1;
799 var[0].type = nsXPTType::T_I32;
800 var[0].flags = 0;
802 var[1].val.i64 = 2;
803 var[1].type = nsXPTType::T_I64;
804 var[1].flags = 0;
806 var[2].val.i32 = 3;
807 var[2].type = nsXPTType::T_I32;
808 var[2].flags = 0;
810 var[3].val.i64 = 4;
811 var[3].type = nsXPTType::T_I64;
812 var[3].flags = 0;
814 var[4].val.i64 = 5;
815 var[4].type = nsXPTType::T_I64;
816 var[4].flags = 0;
818 var[5].val.i32 = 6;
819 var[5].type = nsXPTType::T_I32;
820 var[5].flags = 0;
822 var[6].val.i64 = 7;
823 var[6].type = nsXPTType::T_I64;
824 var[6].flags = 0;
826 var[7].val.i64 = 8;
827 var[7].type = nsXPTType::T_I64;
828 var[7].flags = 0;
830 var[8].val.i32 = 9;
831 var[8].type = nsXPTType::T_I32;
832 var[8].flags = 0;
834 var[9].val.i64 = 10;
835 var[9].type = nsXPTType::T_I64;
836 var[9].flags = 0;
838 var[10].val.i64 = 0;
839 var[10].type = nsXPTType::T_I64;
840 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
841 var[10].ptr = &var[10].val.i64;
843 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 13, 11, var)))
844 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = %d\n",
845 (int)var[10].val.i64);
846 else
847 printf("\tFAILED");
849 var[0].val.f = 1.0f;
850 var[0].type = nsXPTType::T_FLOAT;
851 var[0].flags = 0;
853 var[1].val.f = 2.0f;
854 var[1].type = nsXPTType::T_FLOAT;
855 var[1].flags = 0;
857 var[2].val.d = 3.0;
858 var[2].type = nsXPTType::T_DOUBLE;
859 var[2].flags = 0;
861 var[3].val.d = 4.0;
862 var[3].type = nsXPTType::T_DOUBLE;
863 var[3].flags = 0;
865 var[4].val.f = 5.0f;
866 var[4].type = nsXPTType::T_FLOAT;
867 var[4].flags = 0;
869 var[5].val.f = 6.0f;
870 var[5].type = nsXPTType::T_FLOAT;
871 var[5].flags = 0;
873 var[6].val.d = 7.0;
874 var[6].type = nsXPTType::T_DOUBLE;
875 var[6].flags = 0;
877 var[7].val.d = 8.0;
878 var[7].type = nsXPTType::T_DOUBLE;
879 var[7].flags = 0;
881 var[8].val.f = 9.0f;
882 var[8].type = nsXPTType::T_FLOAT;
883 var[8].flags = 0;
885 var[9].val.d = 10.0;
886 var[9].type = nsXPTType::T_DOUBLE;
887 var[9].flags = 0;
889 var[10].val.f = 11.0f;
890 var[10].type = nsXPTType::T_FLOAT;
891 var[10].flags = 0;
893 var[11].val.d = 0.0;
894 var[11].type = nsXPTType::T_DOUBLE;
895 var[11].flags = nsXPTCVariant::PTR_IS_DATA;
896 var[11].ptr = &var[11].val.d;
898 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 14, 12, var)))
899 printf("\t1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 = %f\n",
900 var[11].val.d);
901 else
902 printf("\tFAILED");
904 var[0].val.p = (void*)"moo";
905 var[0].type = nsXPTType::T_CHAR_STR;
906 var[0].flags = 0;
908 var[1].val.p = (void*)"cow";
909 var[1].type = nsXPTType::T_CHAR_STR;
910 var[1].flags = 0;
912 var[2].val.p = 0;
913 var[2].type = nsXPTType::T_CHAR_STR;
914 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
915 var[2].ptr = &var[2].val.p;
917 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 15, 3, var)))
918 printf(" = %s\n", static_cast<char*>(var[2].val.p));
919 else
920 printf("\tFAILED");
922 var[0].val.i32 = 5;
923 var[0].type = nsXPTType::T_I32;
924 var[0].flags = 0;
926 failed_rv = NS_InvokeByIndex(test, 17, 1, var);
927 printf("should fail %s, returned %x\n", failed_rv == NS_ERROR_NULL_POINTER ? "failed" :"passed", failed_rv);
929 var[0].val.i64 = 3;
930 var[0].type = nsXPTType::T_I64;
931 var[0].flags = 0;
933 var[1].val.i64 = 5;
934 var[1].type = nsXPTType::T_I64;
935 var[1].flags = 0;
937 var[2].val.i32 = 7;
938 var[2].type = nsXPTType::T_I32;
939 var[2].flags = 0;
941 var[3].val.i64 = 11;
942 var[3].type = nsXPTType::T_I64;
943 var[3].flags = 0;
945 var[4].val.i32 = 13;
946 var[4].type = nsXPTType::T_I32;
947 var[4].flags = 0;
949 var[5].val.i32 = 17;
950 var[5].type = nsXPTType::T_I32;
951 var[5].flags = 0;
953 var[6].val.i64 = 19;
954 var[6].type = nsXPTType::T_I64;
955 var[6].flags = 0;
957 var[7].val.i64 = 23;
958 var[7].type = nsXPTType::T_I64;
959 var[7].flags = 0;
961 var[8].val.i32 = 29;
962 var[8].type = nsXPTType::T_I32;
963 var[8].flags = 0;
965 var[9].val.i64 = 31;
966 var[9].type = nsXPTType::T_I64;
967 var[9].flags = 0;
969 var[10].val.i64 = 0;
970 var[10].type = nsXPTType::T_I64;
971 var[10].flags = nsXPTCVariant::PTR_IS_DATA;
972 var[10].ptr = &var[10].val.i64;
974 if(NS_SUCCEEDED(NS_InvokeByIndex(test, 16, 11, var)))
975 printf("\t3 + 5 + 7 + 11 + 13 + 17 + 19 + 23 + 29+ 31 = %d\n",
976 (int)var[10].val.i64);
977 else
978 printf("\tFAILED");
980 DoMultipleInheritenceTest();
981 DoMultipleInheritenceTest2();
982 // Disabled by default - takes too much time on slow machines
983 //DoSpeedTest();
985 return 0;
986 }
988 /***************************************************************************/
989 /***************************************************************************/
990 /***************************************************************************/
992 // {491C65A0-3317-11d3-9885-006008962422}
993 #define FOO_IID \
994 { 0x491c65a0, 0x3317, 0x11d3, \
995 { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
997 // {491C65A1-3317-11d3-9885-006008962422}
998 #define BAR_IID \
999 { 0x491c65a1, 0x3317, 0x11d3, \
1000 { 0x98, 0x85, 0x0, 0x60, 0x8, 0x96, 0x24, 0x22 } }
1002 /***************************/
1004 class nsIFoo : public nsISupports
1005 {
1006 public:
1007 NS_DECLARE_STATIC_IID_ACCESSOR(FOO_IID)
1008 NS_IMETHOD FooMethod1(int32_t i) = 0;
1009 NS_IMETHOD FooMethod2(int32_t i) = 0;
1010 };
1012 NS_DEFINE_STATIC_IID_ACCESSOR(nsIFoo, FOO_IID)
1014 class nsIBar : public nsISupports
1015 {
1016 public:
1017 NS_DECLARE_STATIC_IID_ACCESSOR(BAR_IID)
1018 NS_IMETHOD BarMethod1(int32_t i) = 0;
1019 NS_IMETHOD BarMethod2(int32_t i) = 0;
1020 };
1022 NS_DEFINE_STATIC_IID_ACCESSOR(nsIBar, BAR_IID)
1024 /***************************/
1026 class FooImpl : public nsIFoo
1027 {
1028 public:
1029 NS_IMETHOD FooMethod1(int32_t i);
1030 NS_IMETHOD FooMethod2(int32_t i);
1032 FooImpl();
1034 protected:
1035 ~FooImpl() {}
1037 public:
1038 virtual const char* ImplName() = 0;
1040 int SomeData1;
1041 int SomeData2;
1042 const char* Name;
1043 };
1045 class BarImpl : public nsIBar
1046 {
1047 public:
1048 NS_IMETHOD BarMethod1(int32_t i);
1049 NS_IMETHOD BarMethod2(int32_t i);
1051 BarImpl();
1053 protected:
1054 ~BarImpl() {}
1056 public:
1057 virtual const char * ImplName() = 0;
1059 int SomeData1;
1060 int SomeData2;
1061 const char* Name;
1062 };
1064 /***************************/
1066 FooImpl::FooImpl() : Name("FooImpl")
1067 {
1068 }
1070 NS_IMETHODIMP FooImpl::FooMethod1(int32_t i)
1071 {
1072 printf("\tFooImpl::FooMethod1 called with i == %d, %s part of a %s\n",
1073 i, Name, ImplName());
1074 return NS_OK;
1075 }
1077 NS_IMETHODIMP FooImpl::FooMethod2(int32_t i)
1078 {
1079 printf("\tFooImpl::FooMethod2 called with i == %d, %s part of a %s\n",
1080 i, Name, ImplName());
1081 return NS_OK;
1082 }
1084 /***************************/
1086 BarImpl::BarImpl() : Name("BarImpl")
1087 {
1088 }
1090 NS_IMETHODIMP BarImpl::BarMethod1(int32_t i)
1091 {
1092 printf("\tBarImpl::BarMethod1 called with i == %d, %s part of a %s\n",
1093 i, Name, ImplName());
1094 return NS_OK;
1095 }
1097 NS_IMETHODIMP BarImpl::BarMethod2(int32_t i)
1098 {
1099 printf("\tBarImpl::BarMethod2 called with i == %d, %s part of a %s\n",
1100 i, Name, ImplName());
1101 return NS_OK;
1102 }
1104 /***************************/
1106 class FooBarImpl : public FooImpl, public BarImpl
1107 {
1108 public:
1109 NS_DECL_ISUPPORTS
1111 const char* ImplName();
1113 FooBarImpl();
1115 private:
1116 ~FooBarImpl() {}
1118 public:
1119 const char* MyName;
1120 };
1122 FooBarImpl::FooBarImpl() : MyName("FooBarImpl")
1123 {
1124 NS_ADDREF_THIS();
1125 }
1127 const char* FooBarImpl::ImplName()
1128 {
1129 return MyName;
1130 }
1132 NS_IMETHODIMP
1133 FooBarImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
1134 {
1135 if (nullptr == aInstancePtr) {
1136 return NS_ERROR_NULL_POINTER;
1137 }
1139 *aInstancePtr = nullptr;
1142 if (aIID.Equals(NS_GET_IID(nsIFoo))) {
1143 *aInstancePtr = (void*) static_cast<nsIFoo*>(this);
1144 NS_ADDREF_THIS();
1145 return NS_OK;
1146 }
1147 if (aIID.Equals(NS_GET_IID(nsIBar))) {
1148 *aInstancePtr = (void*) static_cast<nsIBar*>(this);
1149 NS_ADDREF_THIS();
1150 return NS_OK;
1151 }
1153 if (aIID.Equals(NS_GET_IID(nsISupports))) {
1154 *aInstancePtr = (void*) static_cast<nsISupports*>
1155 (static_cast<nsIFoo*>(this));
1156 NS_ADDREF_THIS();
1157 return NS_OK;
1158 }
1159 return NS_NOINTERFACE;
1160 }
1162 NS_IMPL_ADDREF(FooBarImpl)
1163 NS_IMPL_RELEASE(FooBarImpl)
1166 static void DoMultipleInheritenceTest()
1167 {
1168 FooBarImpl* impl = new FooBarImpl();
1169 if(!impl)
1170 return;
1172 nsIFoo* foo;
1173 nsIBar* bar;
1175 nsXPTCVariant var[1];
1177 printf("\n");
1178 if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) &&
1179 NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar)))
1180 {
1181 printf("impl == %p\n", static_cast<void*>(impl));
1182 printf("foo == %p\n", static_cast<void*>(foo));
1183 printf("bar == %p\n", static_cast<void*>(bar));
1185 printf("Calling Foo...\n");
1186 printf("direct calls:\n");
1187 foo->FooMethod1(1);
1188 foo->FooMethod2(2);
1190 printf("invoke calls:\n");
1191 var[0].val.i32 = 1;
1192 var[0].type = nsXPTType::T_I32;
1193 var[0].flags = 0;
1194 NS_InvokeByIndex(foo, 3, 1, var);
1196 var[0].val.i32 = 2;
1197 var[0].type = nsXPTType::T_I32;
1198 var[0].flags = 0;
1199 NS_InvokeByIndex(foo, 4, 1, var);
1201 printf("\n");
1203 printf("Calling Bar...\n");
1204 printf("direct calls:\n");
1205 bar->BarMethod1(1);
1206 bar->BarMethod2(2);
1208 printf("invoke calls:\n");
1209 var[0].val.i32 = 1;
1210 var[0].type = nsXPTType::T_I32;
1211 var[0].flags = 0;
1212 NS_InvokeByIndex(bar, 3, 1, var);
1214 var[0].val.i32 = 2;
1215 var[0].type = nsXPTType::T_I32;
1216 var[0].flags = 0;
1217 NS_InvokeByIndex(bar, 4, 1, var);
1219 printf("\n");
1221 NS_RELEASE(foo);
1222 NS_RELEASE(bar);
1223 }
1224 NS_RELEASE(impl);
1225 }
1226 /***************************************************************************/
1227 /***************************************************************************/
1228 /***************************************************************************/
1229 /* This is a variation on the theme submitted by duncan@be.com (Duncan Wilcox).
1230 * He was seeing the other test work and this test not work. They should both
1231 * Work on any given platform
1232 */
1234 class nsIFoo2 : public nsISupports
1235 {
1236 public:
1237 NS_IMETHOD FooMethod1(int32_t i) = 0;
1238 NS_IMETHOD FooMethod2(int32_t i) = 0;
1239 };
1241 class nsIBar2 : public nsISupports
1242 {
1243 public:
1244 NS_IMETHOD BarMethod1(int32_t i) = 0;
1245 NS_IMETHOD BarMethod2(int32_t i) = 0;
1246 };
1248 class FooBarImpl2 : public nsIFoo2, public nsIBar2
1249 {
1250 public:
1251 // Foo interface
1252 NS_IMETHOD FooMethod1(int32_t i);
1253 NS_IMETHOD FooMethod2(int32_t i);
1255 // Bar interface
1256 NS_IMETHOD BarMethod1(int32_t i);
1257 NS_IMETHOD BarMethod2(int32_t i);
1259 NS_DECL_ISUPPORTS
1261 FooBarImpl2();
1263 private:
1264 ~FooBarImpl2() {}
1266 public:
1267 int32_t value;
1268 };
1270 FooBarImpl2::FooBarImpl2() : value(0x12345678)
1271 {
1272 NS_ADDREF_THIS();
1273 }
1275 NS_IMETHODIMP FooBarImpl2::FooMethod1(int32_t i)
1276 {
1277 printf("\tFooBarImpl2::FooMethod1 called with i == %d, local value = %x\n",
1278 i, value);
1279 return NS_OK;
1280 }
1282 NS_IMETHODIMP FooBarImpl2::FooMethod2(int32_t i)
1283 {
1284 printf("\tFooBarImpl2::FooMethod2 called with i == %d, local value = %x\n",
1285 i, value);
1286 return NS_OK;
1287 }
1289 NS_IMETHODIMP FooBarImpl2::BarMethod1(int32_t i)
1290 {
1291 printf("\tFooBarImpl2::BarMethod1 called with i == %d, local value = %x\n",
1292 i, value);
1293 return NS_OK;
1294 }
1296 NS_IMETHODIMP FooBarImpl2::BarMethod2(int32_t i)
1297 {
1298 printf("\tFooBarImpl2::BarMethod2 called with i == %d, local value = %x\n",
1299 i, value);
1300 return NS_OK;
1301 }
1303 NS_IMETHODIMP
1304 FooBarImpl2::QueryInterface(REFNSIID aIID, void** aInstancePtr)
1305 {
1306 if (nullptr == aInstancePtr) {
1307 return NS_ERROR_NULL_POINTER;
1308 }
1310 *aInstancePtr = nullptr;
1313 if (aIID.Equals(NS_GET_IID(nsIFoo))) {
1314 *aInstancePtr = (void*) static_cast<nsIFoo2*>(this);
1315 NS_ADDREF_THIS();
1316 return NS_OK;
1317 }
1318 if (aIID.Equals(NS_GET_IID(nsIBar))) {
1319 *aInstancePtr = (void*) static_cast<nsIBar2*>(this);
1320 NS_ADDREF_THIS();
1321 return NS_OK;
1322 }
1324 if (aIID.Equals(NS_GET_IID(nsISupports))) {
1325 *aInstancePtr = (void*) static_cast<nsISupports*>
1326 (static_cast<nsIFoo2*>(this));
1327 NS_ADDREF_THIS();
1328 return NS_OK;
1329 }
1330 return NS_NOINTERFACE;
1331 }
1333 NS_IMPL_ADDREF(FooBarImpl2)
1334 NS_IMPL_RELEASE(FooBarImpl2)
1336 static void DoMultipleInheritenceTest2()
1337 {
1338 FooBarImpl2* impl = new FooBarImpl2();
1339 if(!impl)
1340 return;
1342 nsIFoo2* foo;
1343 nsIBar2* bar;
1345 nsXPTCVariant var[1];
1347 printf("\n");
1348 if(NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIFoo), (void**)&foo)) &&
1349 NS_SUCCEEDED(impl->QueryInterface(NS_GET_IID(nsIBar), (void**)&bar)))
1350 {
1351 printf("impl == %p\n", static_cast<void*>(impl));
1352 printf("foo == %p\n", static_cast<void*>(foo));
1353 printf("bar == %p\n", static_cast<void*>(bar));
1355 printf("Calling Foo...\n");
1356 printf("direct calls:\n");
1357 foo->FooMethod1(1);
1358 foo->FooMethod2(2);
1360 printf("invoke calls:\n");
1361 var[0].val.i32 = 1;
1362 var[0].type = nsXPTType::T_I32;
1363 var[0].flags = 0;
1364 NS_InvokeByIndex(foo, 3, 1, var);
1366 var[0].val.i32 = 2;
1367 var[0].type = nsXPTType::T_I32;
1368 var[0].flags = 0;
1369 NS_InvokeByIndex(foo, 4, 1, var);
1371 printf("\n");
1373 printf("Calling Bar...\n");
1374 printf("direct calls:\n");
1375 bar->BarMethod1(1);
1376 bar->BarMethod2(2);
1378 printf("invoke calls:\n");
1379 var[0].val.i32 = 1;
1380 var[0].type = nsXPTType::T_I32;
1381 var[0].flags = 0;
1382 NS_InvokeByIndex(bar, 3, 1, var);
1384 var[0].val.i32 = 2;
1385 var[0].type = nsXPTType::T_I32;
1386 var[0].flags = 0;
1387 NS_InvokeByIndex(bar, 4, 1, var);
1389 printf("\n");
1391 NS_RELEASE(foo);
1392 NS_RELEASE(bar);
1393 }
1394 NS_RELEASE(impl);
1395 }
1397 static void DoSpeedTest()
1398 {
1399 InvokeTestTarget *test = new InvokeTestTarget();
1401 nsXPTCVariant var[3];
1403 var[0].val.i32 = 1;
1404 var[0].type = nsXPTType::T_I32;
1405 var[0].flags = 0;
1407 var[1].val.i32 = 1;
1408 var[1].type = nsXPTType::T_I32;
1409 var[1].flags = 0;
1411 var[2].val.i32 = 0;
1412 var[2].type = nsXPTType::T_I32;
1413 var[2].flags = nsXPTCVariant::PTR_IS_DATA;
1414 var[2].ptr = &var[2].val.i32;
1416 int32_t in1 = 1;
1417 int32_t in2 = 1;
1418 int32_t out;
1420 // Crank this number down if your platform is slow :)
1421 static const int count = 100000000;
1422 int i;
1423 PRIntervalTime start;
1424 PRIntervalTime interval_direct;
1425 PRIntervalTime interval_invoke;
1427 printf("Speed test...\n\n");
1428 printf("Doing %d direct call iterations...\n", count);
1429 start = PR_IntervalNow();
1430 for(i = count; i; i--)
1431 (void)test->AddTwoInts(in1, in2, &out);
1432 interval_direct = PR_IntervalNow() - start;
1434 printf("Doing %d invoked call iterations...\n", count);
1435 start = PR_IntervalNow();
1436 for(i = count; i; i--)
1437 (void)NS_InvokeByIndex(test, 3, 3, var);
1438 interval_invoke = PR_IntervalNow() - start;
1440 printf(" direct took %0.2f seconds\n",
1441 (double)interval_direct/(double)PR_TicksPerSecond());
1442 printf(" invoke took %0.2f seconds\n",
1443 (double)interval_invoke/(double)PR_TicksPerSecond());
1444 printf(" So, invoke overhead was ~ %0.2f seconds (~ %0.0f%%)\n",
1445 (double)(interval_invoke-interval_direct)/(double)PR_TicksPerSecond(),
1446 (double)(interval_invoke-interval_direct)/(double)interval_invoke*100);
1447 }