|
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/. */ |
|
5 |
|
6 // Platform specific code to invoke XPCOM methods on native objects |
|
7 |
|
8 // The purpose of NS_InvokeByIndex() is to map a platform |
|
9 // independent call to the platform ABI. To do that, |
|
10 // NS_InvokeByIndex() has to determine the method to call via vtable |
|
11 // access. The parameters for the method are read from the |
|
12 // nsXPTCVariant* and prepared for the native ABI. |
|
13 |
|
14 // The PowerPC64 platform ABI can be found here: |
|
15 // http://www.freestandards.org/spec/ELF/ppc64/ |
|
16 // and in particular: |
|
17 // http://www.freestandards.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#FUNC-CALL |
|
18 |
|
19 #include <stdio.h> |
|
20 #include "xptcprivate.h" |
|
21 |
|
22 // 8 integral parameters are passed in registers, not including 'that' |
|
23 #define GPR_COUNT 7 |
|
24 |
|
25 // 8 floating point parameters are passed in registers, floats are |
|
26 // promoted to doubles when passed in registers |
|
27 #define FPR_COUNT 13 |
|
28 |
|
29 extern "C" uint32_t |
|
30 invoke_count_words(uint32_t paramCount, nsXPTCVariant* s) |
|
31 { |
|
32 return uint32_t(((paramCount * 2) + 3) & ~3); |
|
33 } |
|
34 |
|
35 extern "C" void |
|
36 invoke_copy_to_stack(uint64_t* gpregs, |
|
37 double* fpregs, |
|
38 uint32_t paramCount, |
|
39 nsXPTCVariant* s, |
|
40 uint64_t* d) |
|
41 { |
|
42 uint64_t tempu64; |
|
43 |
|
44 for(uint32_t i = 0; i < paramCount; i++, s++) { |
|
45 if(s->IsPtrData()) |
|
46 tempu64 = (uint64_t) s->ptr; |
|
47 else { |
|
48 switch(s->type) { |
|
49 case nsXPTType::T_FLOAT: break; |
|
50 case nsXPTType::T_DOUBLE: break; |
|
51 case nsXPTType::T_I8: tempu64 = s->val.i8; break; |
|
52 case nsXPTType::T_I16: tempu64 = s->val.i16; break; |
|
53 case nsXPTType::T_I32: tempu64 = s->val.i32; break; |
|
54 case nsXPTType::T_I64: tempu64 = s->val.i64; break; |
|
55 case nsXPTType::T_U8: tempu64 = s->val.u8; break; |
|
56 case nsXPTType::T_U16: tempu64 = s->val.u16; break; |
|
57 case nsXPTType::T_U32: tempu64 = s->val.u32; break; |
|
58 case nsXPTType::T_U64: tempu64 = s->val.u64; break; |
|
59 case nsXPTType::T_BOOL: tempu64 = s->val.b; break; |
|
60 case nsXPTType::T_CHAR: tempu64 = s->val.c; break; |
|
61 case nsXPTType::T_WCHAR: tempu64 = s->val.wc; break; |
|
62 default: tempu64 = (uint64_t) s->val.p; break; |
|
63 } |
|
64 } |
|
65 |
|
66 if (!s->IsPtrData() && s->type == nsXPTType::T_DOUBLE) { |
|
67 if (i < FPR_COUNT) |
|
68 fpregs[i] = s->val.d; |
|
69 else |
|
70 *(double *)d = s->val.d; |
|
71 } |
|
72 else if (!s->IsPtrData() && s->type == nsXPTType::T_FLOAT) { |
|
73 if (i < FPR_COUNT) { |
|
74 fpregs[i] = s->val.f; // if passed in registers, floats are promoted to doubles |
|
75 } else { |
|
76 float *p = (float *)d; |
|
77 #ifndef __LITTLE_ENDIAN__ |
|
78 p++; |
|
79 #endif |
|
80 *p = s->val.f; |
|
81 } |
|
82 } |
|
83 else { |
|
84 if (i < GPR_COUNT) |
|
85 gpregs[i] = tempu64; |
|
86 else |
|
87 *d = tempu64; |
|
88 } |
|
89 if (i >= 7) |
|
90 d++; |
|
91 } |
|
92 } |
|
93 |
|
94 EXPORT_XPCOM_API(nsresult) |
|
95 NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
|
96 uint32_t paramCount, nsXPTCVariant* params); |
|
97 |