1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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 #include "xptiprivate.h"
11 
12 #if defined(sparc) || defined(__sparc__)
13 
14 extern "C" nsresult ATTRIBUTE_USED
PrepareAndDispatch(nsXPTCStubBase * self,uint64_t methodIndex,uint64_t * args)15 PrepareAndDispatch(nsXPTCStubBase* self, uint64_t methodIndex, uint64_t* args)
16 {
17 
18 #define PARAM_BUFFER_COUNT     16
19 
20     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
21     nsXPTCMiniVariant* dispatchParams = nullptr;
22     const nsXPTMethodInfo* info;
23     uint8_t paramCount;
24     uint8_t i;
25     nsresult result = NS_ERROR_FAILURE;
26 
27     NS_ASSERTION(self,"no self");
28 
29     self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
30     NS_ASSERTION(info,"no interface info");
31 
32     paramCount = info->GetParamCount();
33 
34     // setup variant array pointer
35     if(paramCount > PARAM_BUFFER_COUNT)
36         dispatchParams = new nsXPTCMiniVariant[paramCount];
37     else
38         dispatchParams = paramBuffer;
39 
40     NS_ASSERTION(dispatchParams,"no place for params");
41     if (!dispatchParams)
42         return NS_ERROR_OUT_OF_MEMORY;
43 
44     uint64_t* ap = args;
45     for(i = 0; i < paramCount; i++, ap++)
46     {
47         const nsXPTParamInfo& param = info->GetParam(i);
48         const nsXPTType& type = param.GetType();
49         nsXPTCMiniVariant* dp = &dispatchParams[i];
50 
51         if(param.IsOut() || !type.IsArithmetic())
52         {
53             dp->val.p = (void*) *ap;
54             continue;
55         }
56         // else
57         switch(type)
58         {
59         case nsXPTType::T_BOOL   : dp->val.b   = *((int64_t*)  ap);      break;
60         case nsXPTType::T_CHAR   : dp->val.c   = *((uint64_t*) ap);      break;
61         case nsXPTType::T_WCHAR  : dp->val.wc  = *((int64_t*) ap);       break;
62         case nsXPTType::T_I8     : dp->val.i8  = *((int64_t*)  ap);      break;
63         case nsXPTType::T_I16    : dp->val.i16 = *((int64_t*) ap);       break;
64         case nsXPTType::T_I32    : dp->val.i32 = *((int64_t*) ap);       break;
65         case nsXPTType::T_I64    : dp->val.i64 = *((int64_t*) ap);       break;
66         case nsXPTType::T_U8     : dp->val.u8  = *((uint64_t*) ap);      break;
67         case nsXPTType::T_U16    : dp->val.u16 = *((uint64_t*)ap);       break;
68         case nsXPTType::T_U32    : dp->val.u32 = *((uint64_t*)ap);       break;
69         case nsXPTType::T_U64    : dp->val.u64 = *((uint64_t*) ap);      break;
70         case nsXPTType::T_FLOAT  : dp->val.f   = ((float*)   ap)[1];     break;
71         case nsXPTType::T_DOUBLE : dp->val.d   = *((double*) ap);        break;
72         default:
73             NS_ERROR("bad type");
74             break;
75         }
76     }
77 
78     result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams);
79 
80     if(dispatchParams != paramBuffer)
81         delete [] dispatchParams;
82 
83     return result;
84 }
85 
86 extern "C" nsresult SharedStub(int, int*);
87 
88 #define STUB_ENTRY(n) \
89 nsresult nsXPTCStubBase::Stub##n() \
90 { \
91 	int dummy; /* defeat tail-call optimization */ \
92 	return SharedStub(n, &dummy); \
93 }
94 
95 #define SENTINEL_ENTRY(n) \
96 nsresult nsXPTCStubBase::Sentinel##n() \
97 { \
98     NS_ERROR("nsXPTCStubBase::Sentinel called"); \
99     return NS_ERROR_NOT_IMPLEMENTED; \
100 }
101 
102 #include "xptcstubsdef.inc"
103 
104 #endif /* sparc || __sparc__ */
105