$NetBSD: patch-xj,v 1.1 2010/03/16 10:59:10 tnn Exp $ NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. --- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp.orig 2009-06-29 18:15:33.000000000 +0200 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp @@ -41,6 +41,7 @@ // Implement shared vtbl methods. #include "xptcprivate.h" +#include "xptiprivate.h" // The Linux/PPC ABI (aka PPC/SYSV ABI) passes the first 8 integral // parameters and the first 8 floating point parameters in registers @@ -71,7 +72,6 @@ PrepareAndDispatch(nsXPTCStubBase* self, { nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; nsXPTCMiniVariant* dispatchParams = NULL; - nsIInterfaceInfo* iface_info = NULL; const nsXPTMethodInfo* info; PRUint32 paramCount; PRUint32 i; @@ -79,12 +79,7 @@ PrepareAndDispatch(nsXPTCStubBase* self, NS_ASSERTION(self,"no self"); - self->GetInterfaceInfo(&iface_info); - NS_ASSERTION(iface_info,"no interface info"); - if (! iface_info) - return NS_ERROR_UNEXPECTED; - - iface_info->GetMethodInfo(PRUint16(methodIndex), &info); + self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info); NS_ASSERTION(info,"no method info"); if (! info) return NS_ERROR_UNEXPECTED; @@ -119,8 +114,10 @@ PrepareAndDispatch(nsXPTCStubBase* self, if ((PRUint32) ap & 4) ap++; // doubles are 8-byte aligned on stack dp->val.d = *(double*) ap; ap += 2; +#if __GXX_ABI_VERSION < 100 if (gpr < GPR_COUNT) gpr += 2; +#endif } continue; } @@ -130,8 +127,10 @@ PrepareAndDispatch(nsXPTCStubBase* self, else { dp->val.f = *(float*) ap; ap += 1; +#if __GXX_ABI_VERSION < 100 if (gpr < GPR_COUNT) gpr += 1; +#endif } continue; } @@ -179,9 +178,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, } } - result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams); - - NS_RELEASE(iface_info); + result = self->mOuter->CallMethod((PRUint16) methodIndex, + info, + dispatchParams); if (dispatchParams != paramBuffer) delete [] dispatchParams; @@ -195,7 +194,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, // however, it's quick, dirty, and'll break when the ABI changes on // us, which is what we want ;-). -#define STUB_ENTRY(n) \ +#if __GXX_ABI_VERSION < 100 +// gcc-2 version +# define STUB_ENTRY(n) \ __asm__ ( \ ".section \".text\" \n\t" \ ".align 2 \n\t" \ @@ -206,6 +207,46 @@ __asm__ ( "li 11,"#n" \n\t" \ "b SharedStub@local \n" \ ); +#else +// gcc-3 version +// +// As G++3 ABI contains the length of the functionname in the mangled +// name, it is difficult to get a generic assembler mechanism like +// in the G++ 2.95 case. +// Create names would be like: +// _ZN14nsXPTCStubBase5Stub1Ev +// _ZN14nsXPTCStubBase6Stub12Ev +// _ZN14nsXPTCStubBase7Stub123Ev +// _ZN14nsXPTCStubBase8Stub1234Ev +// etc. +// Use assembler directives to get the names right... + +# define STUB_ENTRY(n) \ +__asm__ ( \ + ".align 2 \n\t" \ + ".if "#n" < 10 \n\t" \ + ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \ + \ + ".elseif "#n" < 100 \n\t" \ + ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \ + \ + ".elseif "#n" < 1000 \n\t" \ + ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ + ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \ +"_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \ + \ + ".else \n\t" \ + ".err \"stub number "#n" >= 1000 not yet supported\"\n" \ + ".endif \n\t" \ + \ + "li 11,"#n" \n\t" \ + "b SharedStub@local \n" \ +); +#endif #define SENTINEL_ENTRY(n) \ nsresult nsXPTCStubBase::Sentinel##n() \