1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 /* Implement shared vtbl methods. */
7
8 #include "xptcprivate.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,uint32_t methodIndex,uint32_t * args,uint32_t * gprData,double * fprData)19 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args, uint32_t *gprData, double *fprData)
20 {
21 typedef struct {
22 uint32_t hi;
23 uint32_t lo; // have to move 64 bit entities as 32 bit halves since
24 } DU; // stack slots are not guaranteed 16 byte aligned
25
26 #define PARAM_BUFFER_COUNT 16
27 #define PARAM_GPR_COUNT 7
28
29 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
30 nsXPTCMiniVariant* dispatchParams = nullptr;
31 const nsXPTMethodInfo* info = nullptr;
32 uint8_t paramCount;
33 uint8_t i;
34
35 NS_ASSERTION(self,"no self");
36
37 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
38 NS_ASSERTION(info,"no method info");
39
40 paramCount = info->GetParamCount();
41
42 // setup variant array pointer
43 if(paramCount > PARAM_BUFFER_COUNT)
44 dispatchParams = new nsXPTCMiniVariant[paramCount];
45 else
46 dispatchParams = paramBuffer;
47 NS_ASSERTION(dispatchParams,"no place for params");
48
49 const uint8_t indexOfJSContext = info->IndexOfJSContext();
50
51 uint32_t* ap = args;
52 uint32_t iCount = 0;
53 uint32_t fpCount = 0;
54 for(i = 0; i < paramCount; i++)
55 {
56 const nsXPTParamInfo& param = info->GetParam(i);
57 const nsXPTType& type = param.GetType();
58 nsXPTCMiniVariant* dp = &dispatchParams[i];
59
60 if (i == indexOfJSContext) {
61 if (iCount < PARAM_GPR_COUNT)
62 iCount++;
63 else
64 ap++;
65 }
66
67 if(param.IsOut() || !type.IsArithmetic())
68 {
69 if (iCount < PARAM_GPR_COUNT)
70 dp->val.p = (void*) gprData[iCount++];
71 else
72 dp->val.p = (void*) *ap++;
73 continue;
74 }
75 // else
76 switch(type)
77 {
78 case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
79 dp->val.i8 = (int8_t) gprData[iCount++];
80 else
81 dp->val.i8 = (int8_t) *ap++;
82 break;
83 case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
84 dp->val.i16 = (int16_t) gprData[iCount++];
85 else
86 dp->val.i16 = (int16_t) *ap++;
87 break;
88 case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
89 dp->val.i32 = (int32_t) gprData[iCount++];
90 else
91 dp->val.i32 = (int32_t) *ap++;
92 break;
93 case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
94 ((DU *)dp)->hi = (int32_t) gprData[iCount++];
95 else
96 ((DU *)dp)->hi = (int32_t) *ap++;
97 if (iCount < PARAM_GPR_COUNT)
98 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
99 else
100 ((DU *)dp)->lo = (uint32_t) *ap++;
101 break;
102 case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT)
103 dp->val.u8 = (uint8_t) gprData[iCount++];
104 else
105 dp->val.u8 = (uint8_t) *ap++;
106 break;
107 case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT)
108 dp->val.u16 = (uint16_t) gprData[iCount++];
109 else
110 dp->val.u16 = (uint16_t) *ap++;
111 break;
112 case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT)
113 dp->val.u32 = (uint32_t) gprData[iCount++];
114 else
115 dp->val.u32 = (uint32_t) *ap++;
116 break;
117 case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT)
118 ((DU *)dp)->hi = (uint32_t) gprData[iCount++];
119 else
120 ((DU *)dp)->hi = (uint32_t) *ap++;
121 if (iCount < PARAM_GPR_COUNT)
122 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
123 else
124 ((DU *)dp)->lo = (uint32_t) *ap++;
125 break;
126 case nsXPTType::T_FLOAT : if (fpCount < 13) {
127 dp->val.f = (float) fprData[fpCount++];
128 if (iCount < PARAM_GPR_COUNT)
129 ++iCount;
130 else
131 ++ap;
132 }
133 else
134 dp->val.f = *((float*) ap++);
135 break;
136 case nsXPTType::T_DOUBLE : if (fpCount < 13) {
137 dp->val.d = (double) fprData[fpCount++];
138 if (iCount < PARAM_GPR_COUNT)
139 ++iCount;
140 else
141 ++ap;
142 if (iCount < PARAM_GPR_COUNT)
143 ++iCount;
144 else
145 ++ap;
146 }
147 else {
148 dp->val.f = *((double*) ap);
149 ap += 2;
150 }
151 break;
152 case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
153 dp->val.b = (bool) gprData[iCount++];
154 else
155 dp->val.b = (bool) *ap++;
156 break;
157 case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
158 dp->val.c = (char) gprData[iCount++];
159 else
160 dp->val.c = (char) *ap++;
161 break;
162 case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
163 dp->val.wc = (wchar_t) gprData[iCount++];
164 else
165 dp->val.wc = (wchar_t) *ap++;
166 break;
167 default:
168 NS_ERROR("bad type");
169 break;
170 }
171 }
172
173 nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
174 dispatchParams);
175
176 if(dispatchParams != paramBuffer)
177 delete [] dispatchParams;
178
179 return result;
180 }
181
182 #define STUB_ENTRY(n)
183
184 #define SENTINEL_ENTRY(n) \
185 nsresult nsXPTCStubBase::Sentinel##n() \
186 { \
187 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
188 return NS_ERROR_NOT_IMPLEMENTED; \
189 }
190
191 #include "xptcstubsdef.inc"
192
193 #endif /* AIX */
194