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 = ¶mBuffer[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