Fix for bug 72841 - Solaris Intel xptcall code should really be in separate files.

sr=shaver@mozilla.org
This commit is contained in:
rich.burridge%sun.com 2001-04-04 23:42:40 +00:00
parent c229aff430
commit 85fb69863e
5 changed files with 341 additions and 65 deletions

View File

@ -42,16 +42,10 @@ include $(topsrcdir)/config/config.mk
#
# Lots of Unixish x86 flavors
#
ifneq (,$(filter SunOS Linux FreeBSD NetBSD OpenBSD BSD_OS,$(OS_ARCH)))
ifneq (,$(filter Linux FreeBSD NetBSD OpenBSD BSD_OS,$(OS_ARCH)))
ifeq (86,$(findstring 86,$(OS_TEST)))
CPPSRCS := xptcinvoke_unixish_x86.cpp xptcstubs_unixish_x86.cpp
endif
# 28817: if Solaris Intel OS, and native compiler, always build optimised.
ifeq ($(OS_ARCH),SunOS)
ifndef GNU_CC
OS_CXXFLAGS += -O
endif
endif
endif
#
# BeOS/Intel (uses the same unixish_x86 code)
@ -66,6 +60,22 @@ ifeq ($(OS_TARGET)$(OS_TEST),NTOx86)
CPPSRCS := xptcinvoke_unixish_x86.cpp xptcstubs_unixish_x86.cpp
endif
######################################################################
# Solaris/Intel
######################################################################
#
# Solaris/Intel
#
ifeq ($(OS_ARCH),SunOS)
ifeq ($(OS_TEST),i86pc)
CPPSRCS := xptcinvoke_x86_solaris.cpp xptcstubs_x86_solaris.cpp
# 28817: if Solaris Intel OS, and native compiler, always build optimised.
ifndef GNU_CC
OS_CXXFLAGS += -O
endif
endif
endif
######################################################################
# Alpha
######################################################################

View File

@ -138,45 +138,6 @@ XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
);
return result;
#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */
asm(
"\n\t /: PRUint32 n = invoke_count_words (paramCount, params) * 4;"
"\n\t pushl %ebx / preserve ebx"
"\n\t pushl %esi / preserve esi"
"\n\t movl %esp, %ebx / save address of pushed esi and ebx"
"\n\t pushl 20(%ebp) / \"params\""
"\n\t pushl 16(%ebp) / \"paramCount\""
"\n\t call invoke_count_words"
"\n\t mov %ebx, %esp / restore esp"
"\n\t sall $2,%eax"
"\n\t subl %eax, %esp / make room for arguments"
"\n\t movl %esp, %esi / save new esp"
"\n\t pushl %esp"
"\n\t pushl 20(%ebp) / \"params\""
"\n\t pushl 16(%ebp) / \"paramCount\""
"\n\t call invoke_copy_to_stack / copy params"
"\n\t movl %esi, %esp / restore new esp"
"\n\t movl 8(%ebp),%ecx / \"that\""
"\n\t pushl %ecx / \"that\""
"\n\t movl (%ecx), %edx"
"\n\t movl 12(%ebp), %eax / function index: \"methodIndex\""
"\n\t movl 8(%edx,%eax,4), %edx"
"\n\t call *%edx"
"\n\t mov %ebx, %esp"
"\n\t popl %esi"
"\n\t popl %ebx"
);
/* result == %eax */
if(0) /* supress "*** is expected to return a value." error */
return 0;
#else
#error "can't find a compiler to use"

View File

@ -0,0 +1,183 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "MPL"); you may not use this file except in
* compliance with the MPL. You may obtain a copy of the MPL at
* http://www.mozilla.org/MPL/
*
* Software distributed under the MPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
* for the specific language governing rights and limitations under the
* MPL.
*
* The Initial Developer of this code under the MPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributor(s):
*/
/* Platform specific code to invoke XPCOM methods on native objects */
#include "xptcprivate.h"
#include "xptc_platforms_unixish_x86.h"
extern "C" {
// Remember that these 'words' are 32bit DWORDS
static PRUint32
invoke_count_words(PRUint32 paramCount, nsXPTCVariant* s)
{
PRUint32 result = 0;
for(PRUint32 i = 0; i < paramCount; i++, s++)
{
if(s->IsPtrData())
{
result++;
continue;
}
result++;
switch(s->type)
{
case nsXPTType::T_I64 :
case nsXPTType::T_U64 :
case nsXPTType::T_DOUBLE :
result++;
break;
}
}
return result;
}
static void
invoke_copy_to_stack(PRUint32 paramCount, nsXPTCVariant* s, PRUint32* d)
{
for(PRUint32 i = 0; i < paramCount; i++, d++, s++)
{
if(s->IsPtrData())
{
*((void**)d) = s->ptr;
continue;
}
/* XXX: the following line is here (rather than as the default clause in
* the following switch statement) so that the Sun native compiler
* will generate the correct assembly code on the Solaris Intel
* platform. See the comments in bug #28817 for more details.
*/
*((void**)d) = s->val.p;
switch(s->type)
{
case nsXPTType::T_I64 : *((PRInt64*) d) = s->val.i64; d++; break;
case nsXPTType::T_U64 : *((PRUint64*)d) = s->val.u64; d++; break;
case nsXPTType::T_DOUBLE : *((double*) d) = s->val.d; d++; break;
}
}
}
}
XPTC_PUBLIC_API(nsresult)
XPTC_InvokeByIndex(nsISupports* that, PRUint32 methodIndex,
PRUint32 paramCount, nsXPTCVariant* params)
{
#ifdef __GNUC__ /* Gnu compiler. */
PRUint32 result;
PRUint32 n = invoke_count_words (paramCount, params) * 4;
void (*fn_copy) (unsigned int, nsXPTCVariant *, PRUint32 *) = invoke_copy_to_stack;
int temp1, temp2, temp3;
__asm__ __volatile__(
"subl %8, %%esp\n\t" /* make room for params */
"pushl %%esp\n\t"
"pushl %7\n\t"
"pushl %6\n\t"
"call *%0\n\t" /* copy params */
"addl $0xc, %%esp\n\t"
"movl %4, %%ecx\n\t"
#ifdef CFRONT_STYLE_THIS_ADJUST
"movl (%%ecx), %%edx\n\t"
"movl %5, %%eax\n\t" /* function index */
"shl $3, %%eax\n\t" /* *= 8 */
"addl $8, %%eax\n\t" /* += 8 skip first entry */
"addl %%eax, %%edx\n\t"
"movswl (%%edx), %%eax\n\t" /* 'this' offset */
"addl %%eax, %%ecx\n\t"
"pushl %%ecx\n\t"
"addl $4, %%edx\n\t" /* += 4, method pointer */
#else /* THUNK_BASED_THIS_ADJUST */
"pushl %%ecx\n\t"
"movl (%%ecx), %%edx\n\t"
"movl %5, %%eax\n\t" /* function index */
#if defined(__GXX_ABI_VERSION) && __GXX_ABI_VERSION >= 100 /* G++ V3 ABI */
"leal (%%edx,%%eax,4), %%edx\n\t"
#else /* not G++ V3 ABI */
"leal 8(%%edx,%%eax,4), %%edx\n\t"
#endif /* G++ V3 ABI */
#endif
"call *(%%edx)\n\t" /* safe to not cleanup esp */
"addl $4, %%esp\n\t"
"addl %8, %%esp"
: "=a" (result), /* %0 */
"=c" (temp1), /* %1 */
"=d" (temp2), /* %2 */
"=g" (temp3) /* %3 */
: "g" (that), /* %4 */
"g" (methodIndex), /* %5 */
"1" (paramCount), /* %6 */
"2" (params), /* %7 */
"g" (n), /* %8 */
"0" (fn_copy) /* %3 */
: "memory"
);
return result;
#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */
asm(
"\n\t /: PRUint32 n = invoke_count_words (paramCount, params) * 4;"
"\n\t pushl %ebx / preserve ebx"
"\n\t pushl %esi / preserve esi"
"\n\t movl %esp, %ebx / save address of pushed esi and ebx"
"\n\t pushl 20(%ebp) / \"params\""
"\n\t pushl 16(%ebp) / \"paramCount\""
"\n\t call invoke_count_words"
"\n\t mov %ebx, %esp / restore esp"
"\n\t sall $2,%eax"
"\n\t subl %eax, %esp / make room for arguments"
"\n\t movl %esp, %esi / save new esp"
"\n\t pushl %esp"
"\n\t pushl 20(%ebp) / \"params\""
"\n\t pushl 16(%ebp) / \"paramCount\""
"\n\t call invoke_copy_to_stack / copy params"
"\n\t movl %esi, %esp / restore new esp"
"\n\t movl 8(%ebp),%ecx / \"that\""
"\n\t pushl %ecx / \"that\""
"\n\t movl (%ecx), %edx"
"\n\t movl 12(%ebp), %eax / function index: \"methodIndex\""
"\n\t movl 8(%edx,%eax,4), %edx"
"\n\t call *%edx"
"\n\t mov %ebx, %esp"
"\n\t popl %esi"
"\n\t popl %ebx"
);
/* result == %eax */
if(0) /* supress "*** is expected to return a value." error */
return 0;
#else
#error "can't find a compiler to use"
#endif /* __GNUC__ */
}

View File

@ -110,25 +110,6 @@ nsresult nsXPTCStubBase::Stub##n() \
return result; \
}
#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
asm ( \
"\n\t leal 0x0c(%ebp), %ecx\t / args" \
"\n\t pushl %ecx" \
"\n\t pushl $"#n"\t / method index" \
"\n\t movl 0x08(%ebp), %ecx\t / this" \
"\n\t pushl %ecx" \
"\n\t call __1cSPrepareAndDispatch6FpnOnsXPTCStubBase_IpI_I_\t / PrepareAndDispatch" \
"\n\t addl $12, %esp" \
); \
/* result == %eax */ \
if(0) /* supress "*** is expected to return a value." error */ \
return 0; \
}
#else
#error "can't find a compiler to use"
#endif /* __GNUC__ */

View File

@ -0,0 +1,141 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "MPL"); you may not use this file except in
* compliance with the MPL. You may obtain a copy of the MPL at
* http://www.mozilla.org/MPL/
*
* Software distributed under the MPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
* for the specific language governing rights and limitations under the
* MPL.
*
* The Initial Developer of this code under the MPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*
* Contributor(s):
*/
/* Implement shared vtbl methods. */
#include "xptcprivate.h"
#include "xptc_platforms_unixish_x86.h"
static nsresult
PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint32* args)
{
#define PARAM_BUFFER_COUNT 16
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
nsXPTCMiniVariant* dispatchParams = NULL;
nsIInterfaceInfo* iface_info = NULL;
const nsXPTMethodInfo* info;
PRUint8 paramCount;
PRUint8 i;
nsresult result = NS_ERROR_FAILURE;
NS_ASSERTION(self,"no self");
self->GetInterfaceInfo(&iface_info);
NS_ASSERTION(iface_info,"no interface info");
iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
NS_ASSERTION(info,"no interface info");
paramCount = info->GetParamCount();
// setup variant array pointer
if(paramCount > PARAM_BUFFER_COUNT)
dispatchParams = new nsXPTCMiniVariant[paramCount];
else
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
PRUint32* ap = args;
for(i = 0; i < paramCount; i++, ap++)
{
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
dp->val.p = (void*) *ap;
continue;
}
// else
dp->val.p = (void*) *ap;
switch(type)
{
case nsXPTType::T_I64 : dp->val.i64 = *((PRInt64*) ap); ap++; break;
case nsXPTType::T_U64 : dp->val.u64 = *((PRUint64*)ap); ap++; break;
case nsXPTType::T_DOUBLE : dp->val.d = *((double*) ap); ap++; break;
}
}
result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
NS_RELEASE(iface_info);
if(dispatchParams != paramBuffer)
delete [] dispatchParams;
return result;
}
#ifdef __GNUC__ /* Gnu Compiler. */
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
register nsresult (*method) (nsXPTCStubBase *, uint32, PRUint32 *) = PrepareAndDispatch; \
int temp0, temp1; \
register nsresult result; \
__asm__ __volatile__( \
"leal 0x0c(%%ebp), %%ecx\n\t" /* args */ \
"pushl %%ecx\n\t" \
"pushl $"#n"\n\t" /* method index */ \
"movl 0x08(%%ebp), %%ecx\n\t" /* this */ \
"pushl %%ecx\n\t" \
"call *%%edx\n\t" /* PrepareAndDispatch */ \
"addl $12, %%esp" \
: "=a" (result), /* %0 */ \
"=&c" (temp0), /* %1 */ \
"=d" (temp1) /* %2 */ \
: "2" (method) /* %2 */ \
: "memory" ); \
return result; \
}
#elif defined(__SUNPRO_CC) /* Sun Workshop Compiler. */
#define STUB_ENTRY(n) \
nsresult nsXPTCStubBase::Stub##n() \
{ \
asm ( \
"\n\t leal 0x0c(%ebp), %ecx\t / args" \
"\n\t pushl %ecx" \
"\n\t pushl $"#n"\t / method index" \
"\n\t movl 0x08(%ebp), %ecx\t / this" \
"\n\t pushl %ecx" \
"\n\t call __1cSPrepareAndDispatch6FpnOnsXPTCStubBase_IpI_I_\t / PrepareAndDispatch" \
"\n\t addl $12, %esp" \
); \
/* result == %eax */ \
if(0) /* supress "*** is expected to return a value." error */ \
return 0; \
}
#else
#error "can't find a compiler to use"
#endif /* __GNUC__ */
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
{ \
NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"