From 93be16ebcd4ef3e21b55f99abd9b42f32dd7cf4d Mon Sep 17 00:00:00 2001 From: "cls%seawood.org" Date: Mon, 10 Mar 2003 20:40:06 +0000 Subject: [PATCH] Landing mingw/win32 gcc support for xptcall. Bug #134113 r=dbradley --- xpcom/reflect/xptcall/src/md/test/Makefile.in | 5 +-- .../reflect/xptcall/src/md/test/stub_test.cpp | 42 ++++++++++++++----- .../xptcall/src/md/unix/xptc_gcc_x86_unix.h | 6 +++ .../src/md/unix/xptc_platforms_unixish_x86.h | 3 ++ .../src/md/unix/xptcinvoke_gcc_x86_unix.cpp | 15 ++++--- .../reflect/xptcall/src/md/win32/Makefile.in | 14 ++++++- .../xptcall/src/md/win32/xptcstubs.cpp | 36 +++++++++++++++- 7 files changed, 99 insertions(+), 22 deletions(-) diff --git a/xpcom/reflect/xptcall/src/md/test/Makefile.in b/xpcom/reflect/xptcall/src/md/test/Makefile.in index a9bbe871dd8..3943c367e6c 100644 --- a/xpcom/reflect/xptcall/src/md/test/Makefile.in +++ b/xpcom/reflect/xptcall/src/md/test/Makefile.in @@ -27,9 +27,8 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = xpcom -SIMPLE_PROGRAMS = invoke_test - -CPPSRCS = invoke_test.cpp +CPPSRCS = stub_test.cpp #invoke_test.cpp +SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) include $(topsrcdir)/config/rules.mk diff --git a/xpcom/reflect/xptcall/src/md/test/stub_test.cpp b/xpcom/reflect/xptcall/src/md/test/stub_test.cpp index 5bd5a011ab8..10935299503 100644 --- a/xpcom/reflect/xptcall/src/md/test/stub_test.cpp +++ b/xpcom/reflect/xptcall/src/md/test/stub_test.cpp @@ -52,19 +52,19 @@ NS_IMETHODIMP bar::ignored(){return 0;} NS_IMETHODIMP bar::callme1(int i, int j) { printf("called bar::callme1 with: %d %d\n", i, j); - return 5; + return 15; } NS_IMETHODIMP bar::callme2(int i, int j) { printf("called bar::callme2 with: %d %d\n", i, j); - return 5; + return 25; } NS_IMETHODIMP bar::callme3(int i, int j) { printf("called bar::callme3 with: %d %d\n", i, j); - return 5; + return 35; } void docall(foo* f, int i, int j){ @@ -78,19 +78,23 @@ static int __stdcall PrepareAndDispatch(baz* self, PRUint32 methodIndex, PRUint32* args, PRUint32* stackBytesToPop) { + fprintf(stdout, "PrepareAndDispatch (%p, %d, %p)\n", + (void*)self, methodIndex, (void*)args); foo* a = self->other; int p1 = (int) *args; int p2 = (int) *(args+1); + int out = 0; switch(methodIndex) { - case 1: a->callme1(p1, p2); break; - case 2: a->callme2(p1, p2); break; - case 3: a->callme3(p1, p2); break; + case 1: out = a->callme1(p1, p2); break; + case 2: out = a->callme2(p1, p2); break; + case 3: out = a->callme3(p1, p2); break; } *stackBytesToPop = 2*4; - return 1; + return out; } +#ifndef __GNUC__ static __declspec(naked) void SharedStub(void) { __asm { @@ -121,6 +125,26 @@ static __declspec(naked) void SharedStub(void) __declspec(naked) nsresult __stdcall baz::callme##n() \ { __asm push n __asm jmp SharedStub } +#else /* __GNUC__ */ + +#define STUB_ENTRY(n) \ +nsresult __stdcall baz::callme##n() \ +{ \ + PRUint32 *args, stackBytesToPop; \ + int result = 0; \ + baz *obj; \ + __asm__ __volatile__ ( \ + "leal 0x0c(%%ebp), %0\n\t" /* args */ \ + "movl 0x08(%%ebp), %1\n\t" /* this */ \ + : "=r" (args), \ + "=r" (obj)); \ + result = PrepareAndDispatch(obj, n, args,&stackBytesToPop); \ + fprintf(stdout, "stub returning: %d\n", result); \ + fprintf(stdout, "bytes to pop: %d\n", stackBytesToPop); \ + return result; \ +} + +#endif /* ! __GNUC__ */ #else /***************************************************************************/ @@ -141,8 +165,6 @@ PrepareAndDispatch(baz* self, PRUint32 methodIndex, PRUint32* args) return 1; } -//nsresult nsXPCWrappedJS::Stub##n() \ - #define STUB_ENTRY(n) \ nsresult baz::callme##n() \ { \ @@ -157,7 +179,7 @@ nsresult baz::callme##n() \ "call *%%edx" /* PrepareAndDispatch */ \ : "=a" (result) /* %0 */ \ : "d" (method) /* %1 */ \ - : "ax", "dx", "cx", "memory" ); \ + : "memory" ); \ return result; \ } diff --git a/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h b/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h index 42a7cc2681b..9a5825a0e38 100644 --- a/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h +++ b/xpcom/reflect/xptcall/src/md/unix/xptc_gcc_x86_unix.h @@ -49,6 +49,12 @@ #define ATTRIBUTE_STDCALL #endif +#ifdef MOZ_NEED_LEADING_UNDERSCORE +#define SYMBOL_UNDERSCORE "_" +#else +#define SYMBOL_UNDERSCORE +#endif + /* What are those keeper functions? diff --git a/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h b/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h index 0dd3ad0cce8..d8cf3976c24 100644 --- a/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h +++ b/xpcom/reflect/xptcall/src/md/unix/xptc_platforms_unixish_x86.h @@ -133,6 +133,9 @@ #elif defined(__sun__) || defined(__sun) #define CFRONT_STYLE_THIS_ADJUST +#elif defined(_WIN32) +#define THUNK_BASED_THIS_ADJUST + #else #error "need a platform define if using unixish x86 code" #endif diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp index f3796fa6aa0..d45ed43cc87 100644 --- a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_gcc_x86_unix.cpp @@ -44,7 +44,10 @@ #include "xptc_gcc_x86_unix.h" extern "C" { -static void ATTRIBUTE_USED ATTRIBUTE_STDCALL +#ifndef XP_WIN32 +static +#endif +void ATTRIBUTE_USED ATTRIBUTE_STDCALL invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d) { for(PRUint32 i = paramCount; i >0; i--, d++, s++) @@ -111,9 +114,9 @@ xptc_invoke_copy_to_stack_keeper (void) __asm__ ( ".text\n\t" ".align 16\n\t" - ".globl XPTC_InvokeByIndex\n\t" - ".type XPTC_InvokeByIndex,@function\n" - "XPTC_InvokeByIndex:\n\t" + ".globl " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t" + ".type " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex,@function\n" + SYMBOL_UNDERSCORE "XPTC_InvokeByIndex:\n\t" "pushl %ebp\n\t" "movl %esp, %ebp\n\t" #ifdef MOZ_PRESERVE_PIC @@ -132,7 +135,7 @@ __asm__ ( "pushl %esp\n\t" "pushl 0x14(%ebp)\n\t" "pushl %eax\n\t" - "call invoke_copy_to_stack\n\t" + "call " SYMBOL_UNDERSCORE "invoke_copy_to_stack\n\t" #ifndef MOZ_USE_STDCALL "addl $0x0c, %esp\n\t" /* done with param stuff */ #endif @@ -164,7 +167,7 @@ __asm__ ( "movl %ebp, %esp\n\t" "popl %ebp\n\t" "ret\n" - ".size XPTC_InvokeByIndex, . - XPTC_InvokeByIndex\n\t" + ".size " SYMBOL_UNDERSCORE "XPTC_InvokeByIndex, . -" SYMBOL_UNDERSCORE "XPTC_InvokeByIndex\n\t" ); #else diff --git a/xpcom/reflect/xptcall/src/md/win32/Makefile.in b/xpcom/reflect/xptcall/src/md/win32/Makefile.in index ae987e4395c..b9d610d3aea 100644 --- a/xpcom/reflect/xptcall/src/md/win32/Makefile.in +++ b/xpcom/reflect/xptcall/src/md/win32/Makefile.in @@ -32,7 +32,17 @@ LIBRARY_NAME = xptcmd # # The default is this buildable, but non-functioning code. # -CPPSRCS := xptcinvoke.cpp xptcstubs.cpp +ifdef GNU_CXX +CPPSRCS = \ + ../unix/xptcinvoke_gcc_x86_unix.cpp \ + xptcstubs.cpp \ + $(NULL) +LOCAL_INCLUDES = -I$(srcdir)/../unix +DEFINES += -DMOZ_USE_STDCALL -DMOZ_NEED_LEADING_UNDERSCORE +else +CPPSRCS = xptcinvoke.cpp xptcstubs.cpp +endif + # Force use of PIC FORCE_USE_PIC = 1 @@ -53,4 +63,4 @@ include $(topsrcdir)/config/rules.mk DEFINES += -DEXPORT_XPTC_API -D_IMPL_NS_COM -D_IMPL_NS_BASE -LOCAL_INCLUDES = -I$(srcdir)/../.. +LOCAL_INCLUDES += -I$(srcdir)/../.. diff --git a/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp b/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp index 77806e69d44..c21465943bc 100644 --- a/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp +++ b/xpcom/reflect/xptcall/src/md/win32/xptcstubs.cpp @@ -43,6 +43,8 @@ #error "This code is for Win32 only" #endif +extern "C" { + static nsresult __stdcall PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32* stackBytesToPop) @@ -122,7 +124,13 @@ PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, return result; } -static __declspec(naked) void SharedStub(void) +} // extern "C" + +// declspec(naked) is broken in gcc +#ifndef __GNUC__ +static +__declspec(naked) +void SharedStub(void) { __asm { push ebp // set up simple stack frame @@ -151,6 +159,25 @@ static __declspec(naked) void SharedStub(void) __declspec(naked) nsresult __stdcall nsXPTCStubBase::Stub##n() \ { __asm mov ecx, n __asm jmp SharedStub } +#else + +#define STUB_ENTRY(n) \ +nsresult __stdcall nsXPTCStubBase::Stub##n() \ +{ \ + PRUint32 *args, stackBytesToPop = 0; \ + nsresult result = 0; \ + nsXPTCStubBase *obj; \ + __asm__ __volatile__ ( \ + "leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \ + "movl 0x08(%%ebp), %%edx\n\t" /* this */ \ + : "=c" (args), \ + "=d" (obj)); \ + result = PrepareAndDispatch(obj, n, args, &stackBytesToPop); \ + return result; \ +} + +#endif /* __GNUC__ */ + #define SENTINEL_ENTRY(n) \ nsresult __stdcall nsXPTCStubBase::Sentinel##n() \ { \ @@ -158,11 +185,18 @@ nsresult __stdcall nsXPTCStubBase::Sentinel##n() \ return NS_ERROR_NOT_IMPLEMENTED; \ } +#ifdef _MSC_VER #pragma warning(disable : 4035) // OK to have no return value +#endif #include "xptcstubsdef.inc" +#ifdef _MSC_VER #pragma warning(default : 4035) // restore default +#endif void +#ifdef __GNUC__ +__cdecl +#endif xptc_dummy() { }