1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase * self,uint32_t methodIndex,uint32_t * args)11 PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint32_t* args)
12 {
13
14 nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
15 const nsXPTInterfaceInfo* iface_info = nullptr;
16 const nsXPTMethodInfo* info;
17 uint8_t paramCount;
18 uint8_t i;
19
20 NS_ASSERTION(self,"no self");
21
22 self->GetInterfaceInfo(&iface_info);
23 NS_ASSERTION(iface_info,"no interface info");
24
25 iface_info->GetMethodInfo(uint16_t(methodIndex), &info);
26 NS_ASSERTION(info,"no interface info");
27
28 paramCount = info->GetParamCount();
29
30 uint32_t* ap = args;
31 for(i = 0; i < paramCount; i++, ap++)
32 {
33 const nsXPTParamInfo& param = info->GetParam(i);
34 const nsXPTType& type = param.GetType();
35 nsXPTCMiniVariant* dp = ¶mBuffer[i];
36
37 if(param.IsOut() || !type.IsArithmetic())
38 {
39 dp->val.p = (void*) *ap;
40 continue;
41 }
42 // else
43 switch(type)
44 {
45 case nsXPTType::T_I8 : dp->val.i8 = *((int8_t*) ap); break;
46 case nsXPTType::T_I16 : dp->val.i16 = *((int16_t*) ap); break;
47 case nsXPTType::T_I32 : dp->val.i32 = *((int32_t*) ap); break;
48 case nsXPTType::T_I64 : dp->val.i64 = *((int64_t*) ap); ap++; break;
49 case nsXPTType::T_U8 : dp->val.u8 = *((uint8_t*) ap); break;
50 case nsXPTType::T_U16 : dp->val.u16 = *((uint16_t*)ap); break;
51 case nsXPTType::T_U32 : dp->val.u32 = *((uint32_t*)ap); break;
52 case nsXPTType::T_U64 : dp->val.u64 = *((uint64_t*)ap); ap++; break;
53 case nsXPTType::T_FLOAT : dp->val.f = *((float*) ap); break;
54 case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break;
55 case nsXPTType::T_BOOL : dp->val.b = *((bool*) ap); break;
56 case nsXPTType::T_CHAR : dp->val.c = *((char*) ap); break;
57 case nsXPTType::T_WCHAR : dp->val.wc = *((wchar_t*) ap); break;
58 default:
59 NS_ERROR("bad type");
60 break;
61 }
62 }
63
64 nsresult result = self->CallMethod((uint16_t)methodIndex, info,
65 paramBuffer);
66
67 return result;
68 }
69
70 /*
71 * These stubs move just move the values passed in registers onto the stack,
72 * so they are contiguous with values passed on the stack, and then calls
73 * PrepareAndDispatch() to do the dirty work.
74 */
75
76 #define STUB_ENTRY(n) \
77 __asm__( \
78 ".global _Stub"#n"__14nsXPTCStubBase\n\t" \
79 "_Stub"#n"__14nsXPTCStubBase:\n\t" \
80 "stmfd sp!, {r1, r2, r3} \n\t" \
81 "mov ip, sp \n\t" \
82 "stmfd sp!, {fp, ip, lr, pc} \n\t" \
83 "sub fp, ip, #4 \n\t" \
84 "mov r1, #"#n" \n\t" /* = methodIndex */ \
85 "add r2, sp, #16 \n\t" \
86 "bl _PrepareAndDispatch__FP14nsXPTCStubBaseUiPUi \n\t" \
87 "ldmea fp, {fp, sp, lr} \n\t" \
88 "add sp, sp, #12 \n\t" \
89 "mov pc, lr \n\t" \
90 );
91
92 #define SENTINEL_ENTRY(n) \
93 nsresult nsXPTCStubBase::Sentinel##n() \
94 { \
95 NS_ERROR("nsXPTCStubBase::Sentinel called"); \
96 return NS_ERROR_NOT_IMPLEMENTED; \
97 }
98
99 #include "xptcstubsdef.inc"
100