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_GPR_COUNT 7
27
28 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
29 const nsXPTMethodInfo* info = nullptr;
30 uint8_t paramCount;
31 uint8_t i;
32
33 NS_ASSERTION(self,"no self");
34
35 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
36 NS_ASSERTION(info,"no method info");
37
38 paramCount = info->GetParamCount();
39
40 const uint8_t indexOfJSContext = info->IndexOfJSContext();
41
42 uint32_t* ap = args;
43 uint32_t iCount = 0;
44 uint32_t fpCount = 0;
45 for(i = 0; i < paramCount; i++)
46 {
47 const nsXPTParamInfo& param = info->GetParam(i);
48 const nsXPTType& type = param.GetType();
49 nsXPTCMiniVariant* dp = ¶mBuffer[i];
50
51 if (i == indexOfJSContext) {
52 if (iCount < PARAM_GPR_COUNT)
53 iCount++;
54 else
55 ap++;
56 }
57
58 if(param.IsOut() || !type.IsArithmetic())
59 {
60 if (iCount < PARAM_GPR_COUNT)
61 dp->val.p = (void*) gprData[iCount++];
62 else
63 dp->val.p = (void*) *ap++;
64 continue;
65 }
66 // else
67 switch(type)
68 {
69 case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
70 dp->val.i8 = (int8_t) gprData[iCount++];
71 else
72 dp->val.i8 = (int8_t) *ap++;
73 break;
74 case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
75 dp->val.i16 = (int16_t) gprData[iCount++];
76 else
77 dp->val.i16 = (int16_t) *ap++;
78 break;
79 case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
80 dp->val.i32 = (int32_t) gprData[iCount++];
81 else
82 dp->val.i32 = (int32_t) *ap++;
83 break;
84 case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
85 ((DU *)dp)->hi = (int32_t) gprData[iCount++];
86 else
87 ((DU *)dp)->hi = (int32_t) *ap++;
88 if (iCount < PARAM_GPR_COUNT)
89 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
90 else
91 ((DU *)dp)->lo = (uint32_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 ((DU *)dp)->hi = (uint32_t) gprData[iCount++];
110 else
111 ((DU *)dp)->hi = (uint32_t) *ap++;
112 if (iCount < PARAM_GPR_COUNT)
113 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
114 else
115 ((DU *)dp)->lo = (uint32_t) *ap++;
116 break;
117 case nsXPTType::T_FLOAT : if (fpCount < 13) {
118 dp->val.f = (float) fprData[fpCount++];
119 if (iCount < PARAM_GPR_COUNT)
120 ++iCount;
121 else
122 ++ap;
123 }
124 else
125 dp->val.f = *((float*) ap++);
126 break;
127 case nsXPTType::T_DOUBLE : if (fpCount < 13) {
128 dp->val.d = (double) fprData[fpCount++];
129 if (iCount < PARAM_GPR_COUNT)
130 ++iCount;
131 else
132 ++ap;
133 if (iCount < PARAM_GPR_COUNT)
134 ++iCount;
135 else
136 ++ap;
137 }
138 else {
139 dp->val.f = *((double*) ap);
140 ap += 2;
141 }
142 break;
143 case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
144 dp->val.b = (bool) gprData[iCount++];
145 else
146 dp->val.b = (bool) *ap++;
147 break;
148 case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
149 dp->val.c = (char) gprData[iCount++];
150 else
151 dp->val.c = (char) *ap++;
152 break;
153 case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
154 dp->val.wc = (wchar_t) gprData[iCount++];
155 else
156 dp->val.wc = (wchar_t) *ap++;
157 break;
158 default:
159 NS_ERROR("bad type");
160 break;
161 }
162 }
163
164 nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
165 paramBuffer);
166
167 return result;
168 }
169
170 #define STUB_ENTRY(n)
171
172 #define SENTINEL_ENTRY(n) \
173 nsresult nsXPTCStubBase::Sentinel##n() \
174 { \
175 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
176 return NS_ERROR_NOT_IMPLEMENTED; \
177 }
178
179 #include "xptcstubsdef.inc"
180
181 #endif /* AIX */
182