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