xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_rhapsody.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:dab1835b4ef0
1 /* -*- Mode: C -*- */
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 #include "xptcprivate.h"
7 #include "xptiprivate.h"
8
9 /* Under the Mac OS X PowerPC ABI, the first 8 integer and 13 floating point
10 * parameters are delivered in registers and are not on the stack, although
11 * stack space is allocated for them. The integer parameters are delivered
12 * in GPRs r3 through r10. The first 8 words of the parameter area on the
13 * stack shadow these registers. A word will either be in a register or on
14 * the stack, but not in both. Although the first floating point parameters
15 * are passed in floating point registers, GPR space and stack space is
16 * reserved for them as well.
17 *
18 * SharedStub has passed pointers to the parameter section of the stack
19 * and saved copies of the GPRs and FPRs used for parameter passing. We
20 * don't care about the first parameter (which is delivered here as the self
21 * pointer), so SharedStub pointed us past that. argsGPR thus points to GPR
22 * r4 (corresponding to the first argument after the self pointer) and
23 * argsStack points to the parameter section of the caller's stack frame
24 * reserved for the same argument. This way, it is possible to reference
25 * either argsGPR or argsStack with the same index.
26 *
27 * Contrary to the assumption made by the previous implementation, the
28 * Mac OS X PowerPC ABI doesn't impose any special alignment restrictions on
29 * parameter sections of stacks. Values that are 64 bits wide appear on the
30 * stack without any special padding.
31 *
32 * See also xptcstubs_asm_ppc_darwin.s.m4:_SharedStub.
33 *
34 * ABI reference:
35 * http://developer.apple.com/documentation/DeveloperTools/Conceptual/
36 * MachORuntime/PowerPCConventions/chapter_3_section_1.html */
37
38 extern "C" nsresult ATTRIBUTE_USED
39 PrepareAndDispatch(
40 nsXPTCStubBase *self,
41 uint32_t methodIndex,
42 uint32_t *argsStack,
43 uint32_t *argsGPR,
44 double *argsFPR) {
45 #define PARAM_BUFFER_COUNT 16
46 #define PARAM_FPR_COUNT 13
47 #define PARAM_GPR_COUNT 7
48
49 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
50 nsXPTCMiniVariant *dispatchParams = nullptr;
51 const nsXPTMethodInfo *methodInfo;
52 uint8_t paramCount;
53 uint8_t i;
54 nsresult result = NS_ERROR_FAILURE;
55 uint32_t argIndex = 0;
56 uint32_t fprIndex = 0;
57
58 typedef struct {
59 uint32_t hi;
60 uint32_t lo;
61 } DU;
62
63 NS_ASSERTION(self, "no self");
64
65 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &methodInfo);
66 NS_ASSERTION(methodInfo, "no method info");
67
68 paramCount = methodInfo->GetParamCount();
69
70 if(paramCount > PARAM_BUFFER_COUNT) {
71 dispatchParams = new nsXPTCMiniVariant[paramCount];
72 }
73 else {
74 dispatchParams = paramBuffer;
75 }
76 NS_ASSERTION(dispatchParams,"no place for params");
77
78 for(i = 0; i < paramCount; i++, argIndex++) {
79 const nsXPTParamInfo &param = methodInfo->GetParam(i);
80 const nsXPTType &type = param.GetType();
81 nsXPTCMiniVariant *dp = &dispatchParams[i];
82 uint32_t theParam;
83
84 if(argIndex < PARAM_GPR_COUNT)
85 theParam = argsGPR[argIndex];
86 else
87 theParam = argsStack[argIndex];
88
89 if(param.IsOut() || !type.IsArithmetic())
90 dp->val.p = (void *) theParam;
91 else {
92 switch(type) {
93 case nsXPTType::T_I8:
94 dp->val.i8 = (int8_t) theParam;
95 break;
96 case nsXPTType::T_I16:
97 dp->val.i16 = (int16_t) theParam;
98 break;
99 case nsXPTType::T_I32:
100 dp->val.i32 = (int32_t) theParam;
101 break;
102 case nsXPTType::T_U8:
103 dp->val.u8 = (uint8_t) theParam;
104 break;
105 case nsXPTType::T_U16:
106 dp->val.u16 = (uint16_t) theParam;
107 break;
108 case nsXPTType::T_U32:
109 dp->val.u32 = (uint32_t) theParam;
110 break;
111 case nsXPTType::T_I64:
112 case nsXPTType::T_U64:
113 ((DU *)dp)->hi = (uint32_t) theParam;
114 if(++argIndex < PARAM_GPR_COUNT)
115 ((DU *)dp)->lo = (uint32_t) argsGPR[argIndex];
116 else
117 ((DU *)dp)->lo = (uint32_t) argsStack[argIndex];
118 break;
119 case nsXPTType::T_BOOL:
120 dp->val.b = (bool) theParam;
121 break;
122 case nsXPTType::T_CHAR:
123 dp->val.c = (char) theParam;
124 break;
125 case nsXPTType::T_WCHAR:
126 dp->val.wc = (wchar_t) theParam;
127 break;
128 case nsXPTType::T_FLOAT:
129 if(fprIndex < PARAM_FPR_COUNT)
130 dp->val.f = (float) argsFPR[fprIndex++];
131 else
132 dp->val.f = *(float *) &argsStack[argIndex];
133 break;
134 case nsXPTType::T_DOUBLE:
135 if(fprIndex < PARAM_FPR_COUNT)
136 dp->val.d = argsFPR[fprIndex++];
137 else
138 dp->val.d = *(double *) &argsStack[argIndex];
139 argIndex++;
140 break;
141 default:
142 NS_ERROR("bad type");
143 break;
144 }
145 }
146 }
147
148 result = self->mOuter->
149 CallMethod((uint16_t)methodIndex, methodInfo, dispatchParams);
150
151 if(dispatchParams != paramBuffer)
152 delete [] dispatchParams;
153
154 return result;
155 }
156
157 #define STUB_ENTRY(n)
158 #define SENTINEL_ENTRY(n) \
159 nsresult nsXPTCStubBase::Sentinel##n() \
160 { \
161 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
162 return NS_ERROR_NOT_IMPLEMENTED; \
163 }
164
165 #include "xptcstubsdef.inc"

mercurial