Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
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/. */
6 /* Implement shared vtbl methods. */
8 #include "xptcprivate.h"
9 #include "xptiprivate.h"
11 #if defined(AIX)
13 /*
14 For PPC (AIX & MAC), the first 8 integral and the first 13 f.p. parameters
15 arrive in a separate chunk of data that has been loaded from the registers.
16 The args pointer has been set to the start of the parameters BEYOND the ones
17 arriving in registers
18 */
19 extern "C" nsresult ATTRIBUTE_USED
20 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args, uint32_t *gprData, double *fprData)
21 {
22 typedef struct {
23 uint32_t hi;
24 uint32_t lo; // have to move 64 bit entities as 32 bit halves since
25 } DU; // stack slots are not guaranteed 16 byte aligned
27 #define PARAM_BUFFER_COUNT 16
28 #define PARAM_GPR_COUNT 7
30 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
31 nsXPTCMiniVariant* dispatchParams = nullptr;
32 const nsXPTMethodInfo* info = nullptr;
33 uint8_t paramCount;
34 uint8_t i;
35 nsresult result = NS_ERROR_FAILURE;
37 NS_ASSERTION(self,"no self");
39 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
40 NS_ASSERTION(info,"no method info");
42 paramCount = info->GetParamCount();
44 // setup variant array pointer
45 if(paramCount > PARAM_BUFFER_COUNT)
46 dispatchParams = new nsXPTCMiniVariant[paramCount];
47 else
48 dispatchParams = paramBuffer;
49 NS_ASSERTION(dispatchParams,"no place for params");
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];
60 if(param.IsOut() || !type.IsArithmetic())
61 {
62 if (iCount < PARAM_GPR_COUNT)
63 dp->val.p = (void*) gprData[iCount++];
64 else
65 dp->val.p = (void*) *ap++;
66 continue;
67 }
68 // else
69 switch(type)
70 {
71 case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
72 dp->val.i8 = (int8_t) gprData[iCount++];
73 else
74 dp->val.i8 = (int8_t) *ap++;
75 break;
76 case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
77 dp->val.i16 = (int16_t) gprData[iCount++];
78 else
79 dp->val.i16 = (int16_t) *ap++;
80 break;
81 case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
82 dp->val.i32 = (int32_t) gprData[iCount++];
83 else
84 dp->val.i32 = (int32_t) *ap++;
85 break;
86 case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
87 ((DU *)dp)->hi = (int32_t) gprData[iCount++];
88 else
89 ((DU *)dp)->hi = (int32_t) *ap++;
90 if (iCount < PARAM_GPR_COUNT)
91 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
92 else
93 ((DU *)dp)->lo = (uint32_t) *ap++;
94 break;
95 case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT)
96 dp->val.u8 = (uint8_t) gprData[iCount++];
97 else
98 dp->val.u8 = (uint8_t) *ap++;
99 break;
100 case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT)
101 dp->val.u16 = (uint16_t) gprData[iCount++];
102 else
103 dp->val.u16 = (uint16_t) *ap++;
104 break;
105 case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT)
106 dp->val.u32 = (uint32_t) gprData[iCount++];
107 else
108 dp->val.u32 = (uint32_t) *ap++;
109 break;
110 case nsXPTType::T_U64 : if (iCount < PARAM_GPR_COUNT)
111 ((DU *)dp)->hi = (uint32_t) gprData[iCount++];
112 else
113 ((DU *)dp)->hi = (uint32_t) *ap++;
114 if (iCount < PARAM_GPR_COUNT)
115 ((DU *)dp)->lo = (uint32_t) gprData[iCount++];
116 else
117 ((DU *)dp)->lo = (uint32_t) *ap++;
118 break;
119 case nsXPTType::T_FLOAT : if (fpCount < 13) {
120 dp->val.f = (float) fprData[fpCount++];
121 if (iCount < PARAM_GPR_COUNT)
122 ++iCount;
123 else
124 ++ap;
125 }
126 else
127 dp->val.f = *((float*) ap++);
128 break;
129 case nsXPTType::T_DOUBLE : if (fpCount < 13) {
130 dp->val.d = (double) fprData[fpCount++];
131 if (iCount < PARAM_GPR_COUNT)
132 ++iCount;
133 else
134 ++ap;
135 if (iCount < PARAM_GPR_COUNT)
136 ++iCount;
137 else
138 ++ap;
139 }
140 else {
141 dp->val.f = *((double*) ap);
142 ap += 2;
143 }
144 break;
145 case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
146 dp->val.b = (bool) gprData[iCount++];
147 else
148 dp->val.b = (bool) *ap++;
149 break;
150 case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
151 dp->val.c = (char) gprData[iCount++];
152 else
153 dp->val.c = (char) *ap++;
154 break;
155 case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
156 dp->val.wc = (wchar_t) gprData[iCount++];
157 else
158 dp->val.wc = (wchar_t) *ap++;
159 break;
160 default:
161 NS_ERROR("bad type");
162 break;
163 }
164 }
166 result = self->mOuter->CallMethod((uint16_t)methodIndex,info,dispatchParams);
168 if(dispatchParams != paramBuffer)
169 delete [] dispatchParams;
171 return result;
172 }
174 #define STUB_ENTRY(n)
176 #define SENTINEL_ENTRY(n) \
177 nsresult nsXPTCStubBase::Sentinel##n() \
178 { \
179 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
180 return NS_ERROR_NOT_IMPLEMENTED; \
181 }
183 #include "xptcstubsdef.inc"
185 #endif /* AIX */