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 #include "xptc_gcc_x86_unix.h"
10 
11 extern "C" {
12 static nsresult ATTRIBUTE_USED
13 __attribute__ ((regparm (3)))
PrepareAndDispatch(uint32_t methodIndex,nsXPTCStubBase * self,uint32_t * args)14 PrepareAndDispatch(uint32_t methodIndex, nsXPTCStubBase* self, uint32_t* args)
15 {
16 
17     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
18     const nsXPTMethodInfo* info;
19     uint8_t paramCount;
20     uint8_t i;
21 
22     NS_ASSERTION(self,"no self");
23 
24     self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info);
25     paramCount = info->GetParamCount();
26 
27     const uint8_t indexOfJSContext = info->IndexOfJSContext();
28 
29     uint32_t* ap = args;
30     for(i = 0; i < paramCount; i++, ap++)
31     {
32         const nsXPTParamInfo& param = info->GetParam(i);
33         const nsXPTType& type = param.GetType();
34         nsXPTCMiniVariant* dp = &paramBuffer[i];
35 
36         if (i == indexOfJSContext)
37             ap++;
38 
39         if(param.IsOut() || !type.IsArithmetic())
40         {
41             dp->val.p = (void*) *ap;
42             continue;
43         }
44         // else
45 	    dp->val.p = (void*) *ap;
46         switch(type)
47         {
48         case nsXPTType::T_I64    : dp->val.i64 = *((int64_t*) ap); ap++; break;
49         case nsXPTType::T_U64    : dp->val.u64 = *((uint64_t*)ap); ap++; break;
50         case nsXPTType::T_DOUBLE : dp->val.d   = *((double*)  ap); ap++; break;
51         default                  : break;
52         }
53     }
54 
55     nsresult result = self->mOuter->CallMethod((uint16_t)methodIndex, info,
56                                                paramBuffer);
57 
58     return result;
59 }
60 } // extern "C"
61 
62 #if !defined(XP_MACOSX)
63 
64 #define STUB_HEADER(a, b) ".hidden " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase" #a "Stub" #b "Ev\n\t" \
65                           ".type   " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase" #a "Stub" #b "Ev,@function\n"
66 
67 #define STUB_SIZE(a, b)  ".size        " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase" #a "Stub" #b "Ev,.-" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase" #a "Stub" #b "Ev\n\t"
68 
69 #else
70 
71 #define STUB_HEADER(a, b)
72 #define STUB_SIZE(a, b)
73 
74 #endif
75 
76 // gcc3 mangling tends to insert the length of the method name
77 #define STUB_ENTRY(n) \
78 asm(".text\n\t" \
79     ".align	2\n\t" \
80     ".if	" #n " < 10\n\t" \
81     ".globl	" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev\n\t" \
82     STUB_HEADER(5, n)                                                   \
83     SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase5Stub" #n "Ev:\n\t" \
84     ".elseif	" #n " < 100\n\t" \
85     ".globl	" SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev\n\t" \
86     STUB_HEADER(6, n)                                                   \
87     SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase6Stub" #n "Ev:\n\t" \
88     ".elseif    " #n " < 1000\n\t" \
89     ".globl     " SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev\n\t" \
90     STUB_HEADER(7, n)                                                   \
91     SYMBOL_UNDERSCORE "_ZN14nsXPTCStubBase7Stub" #n "Ev:\n\t" \
92     ".else\n\t" \
93     ".err	\"stub number " #n " >= 1000 not yet supported\"\n\t" \
94     ".endif\n\t" \
95     "movl	$" #n ", %eax\n\t" \
96     "jmp	" SYMBOL_UNDERSCORE "SharedStub\n\t" \
97     ".if	" #n " < 10\n\t" \
98     STUB_SIZE(5, n) \
99     ".elseif	" #n " < 100\n\t" \
100     STUB_SIZE(6, n) \
101     ".else\n\t" \
102     STUB_SIZE(7, n) \
103     ".endif");
104 
105 // static nsresult SharedStub(uint32_t methodIndex) __attribute__((regparm(1)))
106 asm(".text\n\t"
107     ".align	2\n\t"
108 #if !defined(XP_MACOSX)
109     ".type	" SYMBOL_UNDERSCORE "SharedStub,@function\n\t"
110 #endif
111     SYMBOL_UNDERSCORE "SharedStub:\n\t"
112     "leal	0x08(%esp), %ecx\n\t"
113     "movl	0x04(%esp), %edx\n\t"
114     "jmp	" SYMBOL_UNDERSCORE "PrepareAndDispatch\n\t"
115 #if !defined(XP_MACOSX)
116     ".size	" SYMBOL_UNDERSCORE "SharedStub,.-" SYMBOL_UNDERSCORE "SharedStub"
117 #endif
118 );
119 
120 #define SENTINEL_ENTRY(n) \
121 nsresult nsXPTCStubBase::Sentinel##n() \
122 { \
123     NS_ERROR("nsXPTCStubBase::Sentinel called"); \
124     return NS_ERROR_NOT_IMPLEMENTED; \
125 }
126 
127 #include "xptcstubsdef.inc"
128 
129 void
xptc_dummy()130 xptc_dummy()
131 {
132 }
133