$NetBSD: patch-xj,v 1.1 2014/07/27 05:36:07 ryoon Exp $ NetBSD ppc xptcall support code. Originally from pkgsrc/www/mozilla. --- mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp.orig 2012-11-19 22:42:45.000000000 +0000 +++ mozilla/xpcom/reflect/xptcall/src/md/unix/xptcstubs_ppc_netbsd.cpp @@ -6,6 +6,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 @@ -36,7 +37,6 @@ PrepareAndDispatch(nsXPTCStubBase* self, { nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; nsXPTCMiniVariant* dispatchParams = NULL; - nsIInterfaceInfo* iface_info = NULL; const nsXPTMethodInfo* info; uint32_t paramCount; uint32_t i; @@ -44,11 +44,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; - + self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info); iface_info->GetMethodInfo(uint16_t(methodIndex), &info); NS_ASSERTION(info,"no method info"); if (! info) @@ -84,8 +80,10 @@ PrepareAndDispatch(nsXPTCStubBase* self, if ((uint32_t) 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; } @@ -95,8 +93,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; } @@ -144,9 +144,9 @@ PrepareAndDispatch(nsXPTCStubBase* self, } } - result = self->CallMethod((uint16_t) methodIndex, info, dispatchParams); - - NS_RELEASE(iface_info); + result = self->mOuter->CallMethod((PRUint16) methodIndex, + info, + dispatchParams); if (dispatchParams != paramBuffer) delete [] dispatchParams; @@ -160,7 +160,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" \ @@ -171,6 +173,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() \