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 /* Implement shared vtbl methods. */
6
7 #include "xptcprivate.h"
8 #include "xptiprivate.h"
9
10 #if defined(AIX)
11
12 /*
13 For PPC (AIX & MAC), the first 8 integral and the first 13 f.p. parameters
14 arrive in a separate chunk of data that has been loaded from the registers.
15 The args pointer has been set to the start of the parameters BEYOND the ones
16 arriving in registers
17 */
18 extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase * self,uint64_t methodIndex,uint64_t * args,uint64_t * gprData,double * fprData)19 PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args, uint64_t *gprData, double *fprData)
20 {
21
22 #define PARAM_BUFFER_COUNT 16
23 #define PARAM_GPR_COUNT 7
24
25 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
26 nsXPTCMiniVariant* dispatchParams = nullptr;
27 const nsXPTMethodInfo* info = nullptr;
28 uint8_t paramCount;
29 uint8_t i;
30 nsresult result = NS_ERROR_FAILURE;
31
32 NS_ASSERTION(self,"no self");
33
34 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
35 NS_ASSERTION(info,"no method info");
36
37 paramCount = info->GetParamCount();
38
39 // setup variant array pointer
40 if(paramCount > PARAM_BUFFER_COUNT)
41 dispatchParams = new nsXPTCMiniVariant[paramCount];
42 else
43 dispatchParams = paramBuffer;
44 NS_ASSERTION(dispatchParams,"no place for params");
45
46 uint64_t* ap = args;
47 uint32_t iCount = 0;
48 uint32_t fpCount = 0;
49 for(i = 0; i < paramCount; i++)
50 {
51 const nsXPTParamInfo& param = info->GetParam(i);
52 const nsXPTType& type = param.GetType();
53 nsXPTCMiniVariant* dp = &dispatchParams[i];
54
55 if(param.IsOut() || !type.IsArithmetic())
56 {
57 if (iCount < PARAM_GPR_COUNT)
58 dp->val.p = (void*) gprData[iCount++];
59 else
60 dp->val.p = (void*) *ap++;
61 continue;
62 }
63 // else
64 switch(type)
65 {
66 case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
67 dp->val.i8 = (int8_t) gprData[iCount++];
68 else
69 dp->val.i8 = (int8_t) *ap++;
70 break;
71 case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
72 dp->val.i16 = (int16_t) gprData[iCount++];
73 else
74 dp->val.i16 = (int16_t) *ap++;
75 break;
76 case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
77 dp->val.i32 = (int32_t) gprData[iCount++];
78 else
79 dp->val.i32 = (int32_t) *ap++;
80 break;
81 case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
82 dp->val.i64 = (int64_t) gprData[iCount++];
83 else
84 dp->val.i64 = (int64_t) *ap++;
85 break;
86 case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT)
87 dp->val.u8 = (uint8_t) gprData[iCount++];
88 else
89 dp->val.u8 = (uint8_t) *ap++;
90 break;
91 case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT)
92 dp->val.u16 = (uint16_t) gprData[iCount++];
93 else
94 dp->val.u16 = (uint16_t) *ap++;
95 break;
96 case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT)
97 dp->val.u32 = (uint32_t) gprData[iCount++];
98 else
99 dp->val.u32 = (uint32_t) *ap++;
100 break;
101 case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT)
102 dp->val.u64 = (uint64_t) gprData[iCount++];
103 else
104 dp->val.u64 = (uint64_t) *ap++;
105 break;
106 case nsXPTType::T_FLOAT : if (fpCount < 13) {
107 dp->val.f = (float) fprData[fpCount++];
108 if (iCount < PARAM_GPR_COUNT)
109 ++iCount;
110 else
111 ++ap;
112 }
113 else
114 dp->val.f = *((float*) ap++);
115 break;
116 case nsXPTType::T_DOUBLE : if (fpCount < 13) {
117 dp->val.d = (double) fprData[fpCount++];
118 if (iCount < PARAM_GPR_COUNT)
119 ++iCount;
120 else
121 ++ap;
122 if (iCount < PARAM_GPR_COUNT)
123 ++iCount;
124 else
125 ++ap;
126 }
127 else {
128 dp->val.f = *((double*) ap);
129 ap += 2;
130 }
131 break;
132 case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
133 dp->val.b = (bool) gprData[iCount++];
134 else
135 dp->val.b = (bool) *ap++;
136 break;
137 case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
138 dp->val.c = (char) gprData[iCount++];
139 else
140 dp->val.c = (char) *ap++;
141 break;
142 case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
143 dp->val.wc = (wchar_t) gprData[iCount++];
144 else
145 dp->val.wc = (wchar_t) *ap++;
146 break;
147 default:
148 NS_ERROR("bad type");
149 break;
150 }
151 }
152
153 result = self->mOuter->CallMethod((uint16_t)methodIndex,info,dispatchParams);
154
155 if(dispatchParams != paramBuffer)
156 delete [] dispatchParams;
157
158 return result;
159 }
160
161 #define STUB_ENTRY(n)
162
163 #define SENTINEL_ENTRY(n) \
164 nsresult nsXPTCStubBase::Sentinel##n() \
165 { \
166 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
167 return NS_ERROR_NOT_IMPLEMENTED; \
168 }
169
170 #include "xptcstubsdef.inc"
171
172 #endif /* AIX */
173