1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 /* Implement shared vtbl methods. */
8
9 #include "xptcprivate.h"
10
11 static nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase * self,uint32_t methodIndex,uint32_t * a_gpr,uint64_t * a_fpr,uint32_t * a_ov)12 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex,
13 uint32_t* a_gpr, uint64_t *a_fpr, uint32_t *a_ov)
14 {
15 #define PARAM_BUFFER_COUNT 16
16
17 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
18 nsXPTCMiniVariant* dispatchParams = nullptr;
19 const nsXPTMethodInfo* info;
20 uint8_t paramCount;
21 uint8_t i;
22
23 NS_ASSERTION(self,"no self");
24
25 self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
26 NS_ASSERTION(info,"no info");
27
28 paramCount = info->GetParamCount();
29
30 // setup variant array pointer
31 if(paramCount > PARAM_BUFFER_COUNT)
32 dispatchParams = new nsXPTCMiniVariant[paramCount];
33 else
34 dispatchParams = paramBuffer;
35 NS_ASSERTION(dispatchParams,"no place for params");
36
37 const uint8_t indexOfJSContext = info->IndexOfJSContext();
38
39 uint32_t gpr = 1, fpr = 0;
40
41 for(i = 0; i < paramCount; i++)
42 {
43 const nsXPTParamInfo& param = info->GetParam(i);
44 const nsXPTType& type = param.GetType();
45 nsXPTCMiniVariant* dp = &dispatchParams[i];
46
47 if (i == indexOfJSContext) {
48 if (gpr < 5)
49 a_gpr++, gpr++;
50 else
51 a_ov++;
52 }
53
54 if(param.IsOut() || !type.IsArithmetic())
55 {
56 if (gpr < 5)
57 dp->val.p = (void*) *a_gpr++, gpr++;
58 else
59 dp->val.p = (void*) *a_ov++;
60 continue;
61 }
62 // else
63 switch(type)
64 {
65 case nsXPTType::T_I8 :
66 if (gpr < 5)
67 dp->val.i8 = *((int32_t*) a_gpr), a_gpr++, gpr++;
68 else
69 dp->val.i8 = *((int32_t*) a_ov ), a_ov++;
70 break;
71 case nsXPTType::T_I16 :
72 if (gpr < 5)
73 dp->val.i16 = *((int32_t*) a_gpr), a_gpr++, gpr++;
74 else
75 dp->val.i16 = *((int32_t*) a_ov ), a_ov++;
76 break;
77 case nsXPTType::T_I32 :
78 if (gpr < 5)
79 dp->val.i32 = *((int32_t*) a_gpr), a_gpr++, gpr++;
80 else
81 dp->val.i32 = *((int32_t*) a_ov ), a_ov++;
82 break;
83 case nsXPTType::T_I64 :
84 if (gpr < 4)
85 dp->val.i64 = *((int64_t*) a_gpr), a_gpr+=2, gpr+=2;
86 else
87 dp->val.i64 = *((int64_t*) a_ov ), a_ov+=2, gpr=5;
88 break;
89 case nsXPTType::T_U8 :
90 if (gpr < 5)
91 dp->val.u8 = *((uint32_t*)a_gpr), a_gpr++, gpr++;
92 else
93 dp->val.u8 = *((uint32_t*)a_ov ), a_ov++;
94 break;
95 case nsXPTType::T_U16 :
96 if (gpr < 5)
97 dp->val.u16 = *((uint32_t*)a_gpr), a_gpr++, gpr++;
98 else
99 dp->val.u16 = *((uint32_t*)a_ov ), a_ov++;
100 break;
101 case nsXPTType::T_U32 :
102 if (gpr < 5)
103 dp->val.u32 = *((uint32_t*)a_gpr), a_gpr++, gpr++;
104 else
105 dp->val.u32 = *((uint32_t*)a_ov ), a_ov++;
106 break;
107 case nsXPTType::T_U64 :
108 if (gpr < 4)
109 dp->val.u64 = *((uint64_t*)a_gpr), a_gpr+=2, gpr+=2;
110 else
111 dp->val.u64 = *((uint64_t*)a_ov ), a_ov+=2, gpr=5;
112 break;
113 case nsXPTType::T_FLOAT :
114 if (fpr < 2)
115 dp->val.f = *((float*) a_fpr), a_fpr++, fpr++;
116 else
117 dp->val.f = *((float*) a_ov ), a_ov++;
118 break;
119 case nsXPTType::T_DOUBLE :
120 if (fpr < 2)
121 dp->val.d = *((double*) a_fpr), a_fpr++, fpr++;
122 else
123 dp->val.d = *((double*) a_ov ), a_ov+=2;
124 break;
125 case nsXPTType::T_BOOL :
126 if (gpr < 5)
127 dp->val.b = *((uint32_t*)a_gpr), a_gpr++, gpr++;
128 else
129 dp->val.b = *((uint32_t*)a_ov ), a_ov++;
130 break;
131 case nsXPTType::T_CHAR :
132 if (gpr < 5)
133 dp->val.c = *((uint32_t*)a_gpr), a_gpr++, gpr++;
134 else
135 dp->val.c = *((uint32_t*)a_ov ), a_ov++;
136 break;
137 case nsXPTType::T_WCHAR :
138 if (gpr < 5)
139 dp->val.wc = *((uint32_t*)a_gpr), a_gpr++, gpr++;
140 else
141 dp->val.wc = *((uint32_t*)a_ov ), a_ov++;
142 break;
143 default:
144 NS_ERROR("bad type");
145 break;
146 }
147 }
148
149 nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
150 dispatchParams);
151
152 if(dispatchParams != paramBuffer)
153 delete [] dispatchParams;
154
155 return result;
156 }
157
158 #define STUB_ENTRY(n) \
159 nsresult nsXPTCStubBase::Stub##n() \
160 { \
161 uint32_t a_gpr[4]; \
162 uint64_t a_fpr[2]; \
163 uint32_t *a_ov; \
164 \
165 __asm__ __volatile__ \
166 ( \
167 "l %0,0(15)\n\t" \
168 "ahi %0,96\n\t" \
169 "stm 3,6,0(%3)\n\t" \
170 "std 0,%1\n\t" \
171 "std 2,%2\n\t" \
172 : "=&a" (a_ov), \
173 "=m" (a_fpr[0]), \
174 "=m" (a_fpr[1]) \
175 : "a" (a_gpr) \
176 : "memory", "cc", \
177 "3", "4", "5", "6" \
178 ); \
179 \
180 return PrepareAndDispatch(this, n, a_gpr, a_fpr, a_ov); \
181 }
182
183 #define SENTINEL_ENTRY(n) \
184 nsresult nsXPTCStubBase::Sentinel##n() \
185 { \
186 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
187 return NS_ERROR_NOT_IMPLEMENTED; \
188 }
189
190 #include "xptcstubsdef.inc"
191