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