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