4
typedef unsigned nsresult;
5
typedef unsigned PRUint32;
6
typedef unsigned nsXPCVariant;
10
#define NS_IMETHOD virtual nsresult __stdcall
11
#define NS_IMETHODIMP nsresult __stdcall
13
#define NS_IMETHOD virtual nsresult
14
#define NS_IMETHODIMP nsresult
20
NS_IMETHOD ignored() = 0;
23
class foo : public base {
25
NS_IMETHOD callme1(int i, int j) = 0;
26
NS_IMETHOD callme2(int i, int j) = 0;
27
NS_IMETHOD callme3(int i, int j) = 0;
30
class bar : public foo{
33
NS_IMETHOD callme1(int i, int j);
34
NS_IMETHOD callme2(int i, int j);
35
NS_IMETHOD callme3(int i, int j);
38
class baz : public base {
44
void setfoo(foo* f) {other = f;}
48
NS_IMETHODIMP baz::ignored(){return 0;}
50
NS_IMETHODIMP bar::ignored(){return 0;}
52
NS_IMETHODIMP bar::callme1(int i, int j)
54
printf("called bar::callme1 with: %d %d\n", i, j);
58
NS_IMETHODIMP bar::callme2(int i, int j)
60
printf("called bar::callme2 with: %d %d\n", i, j);
64
NS_IMETHODIMP bar::callme3(int i, int j)
66
printf("called bar::callme3 with: %d %d\n", i, j);
70
void docall(foo* f, int i, int j){
74
/***************************************************************************/
78
PrepareAndDispatch(baz* self, PRUint32 methodIndex,
79
PRUint32* args, PRUint32* stackBytesToPop)
81
fprintf(stdout, "PrepareAndDispatch (%p, %d, %p)\n",
82
(void*)self, methodIndex, (void*)args);
85
int p2 = (int) *(args+1);
89
case 1: out = a->callme1(p1, p2); break;
90
case 2: out = a->callme2(p1, p2); break;
91
case 3: out = a->callme3(p1, p2); break;
93
*stackBytesToPop = 2*4;
98
static __declspec(naked) void SharedStub(void)
101
push ebp // set up simple stack frame
102
mov ebp, esp // stack has: ebp/vtbl_index/retaddr/this/args
103
push ecx // make room for a ptr
104
lea eax, [ebp-4] // pointer to stackBytesToPop
106
lea ecx, [ebp+16] // pointer to args
108
mov edx, [ebp+4] // vtbl_index
110
mov eax, [ebp+12] // this
112
call PrepareAndDispatch
113
mov edx, [ebp+8] // return address
114
mov ecx, [ebp-4] // stackBytesToPop
115
add ecx, 12 // for this, the index, and ret address
118
add esp, ecx // fix up stack pointer
119
jmp edx // simulate __stdcall return
123
// these macros get expanded (many times) in the file #included below
124
#define STUB_ENTRY(n) \
125
__declspec(naked) nsresult __stdcall baz::callme##n() \
126
{ __asm push n __asm jmp SharedStub }
130
#define STUB_ENTRY(n) \
131
nsresult __stdcall baz::callme##n() \
133
PRUint32 *args, stackBytesToPop; \
136
__asm__ __volatile__ ( \
137
"leal 0x0c(%%ebp), %0\n\t" /* args */ \
138
"movl 0x08(%%ebp), %1\n\t" /* this */ \
141
result = PrepareAndDispatch(obj, n, args,&stackBytesToPop); \
142
fprintf(stdout, "stub returning: %d\n", result); \
143
fprintf(stdout, "bytes to pop: %d\n", stackBytesToPop); \
147
#endif /* ! __GNUC__ */
150
/***************************************************************************/
151
// just Linux_x86 now. Add other later...
154
PrepareAndDispatch(baz* self, PRUint32 methodIndex, PRUint32* args)
156
foo* a = self->other;
157
int p1 = (int) *args;
158
int p2 = (int) *(args+1);
161
case 1: a->callme1(p1, p2); break;
162
case 2: a->callme2(p1, p2); break;
163
case 3: a->callme3(p1, p2); break;
168
#define STUB_ENTRY(n) \
169
nsresult baz::callme##n() \
171
register void* method = PrepareAndDispatch; \
172
register nsresult result; \
173
__asm__ __volatile__( \
174
"leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \
176
"pushl $"#n"\n\t" /* method index */ \
177
"movl 0x08(%%ebp), %%ecx\n\t" /* this */ \
179
"call *%%edx" /* PrepareAndDispatch */ \
180
: "=a" (result) /* %0 */ \
181
: "d" (method) /* %1 */ \
187
/***************************************************************************/
198
/* here we make the global 'check for alloc failure' checker happy */