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