Bug 289724 - [Mac] Missing progress bar animation in download window. patch from Mark Mentovai <mark@moxienet.com>, r=bryner sr+a=brendan

This commit is contained in:
mozilla.mano%sent.com 2005-04-20 01:01:13 +00:00
parent 2f2e21550d
commit f4e7c3a5f7
2 changed files with 222 additions and 249 deletions

View File

@ -1,9 +1,9 @@
/* -*- Mode: asm; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: asm -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License") ; you may not use this file except in compliance with
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Mentovai <mark@moxienet.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,90 +38,114 @@
.text
.globl _SharedStub
dnl
define(STUB_MANGLED_ENTRY,
` .globl '$2`
.align 2
` .globl '$2`
.align 2
'$2`:
addi r12, 0, '$1`
b _SharedStub
')
addi r12, 0,'$1`
b _SharedStub')
dnl
define(STUB_ENTRY,
`#ifdef HAVE_GCC3_ABI
.if '$1` < 10
.if '$1` < 10
STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase5Stub'$1`Ev')
.elseif '$1` < 100
STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase6Stub'$1`Ev')
.elseif '$1` < 1000
STUB_MANGLED_ENTRY('$1`, `__ZN14nsXPTCStubBase7Stub'$1`Ev')
.else
.err "Stub'$1` >= 1000 not yet supported."
.err "Stub'$1` >= 1000 not yet supported."
.endif
#else /* !defined(HAVE_GCC3_ABI) */
STUB_MANGLED_ENTRY('$1`, `_Stub'$1`__14nsXPTCStubBase')
#endif /* !defined(HAVE_GCC3_ABI) */
')
dnl
define(SENTINEL_ENTRY, `')
dnl
include(xptcstubsdef.inc)
dnl
// See also xptcstubs_ppc_rhapsody.cpp:PrepareAndDispatch.
_SharedStub:
mflr r0
stw r0,8(r1)
stwu r1,-176(r1)
stw r4,44(r1)
stw r5,48(r1)
stw r6,52(r1)
stw r7,56(r1)
stw r8,60(r1)
stw r9,64(r1)
stw r10,68(r1)
stfd f1,72(r1)
stfd f2,80(r1)
stfd f3,88(r1)
stfd f4,96(r1)
stfd f5,104(r1)
stfd f6,112(r1)
stfd f7,120(r1)
stfd f8,128(r1)
stfd f9,136(r1)
stfd f10,144(r1)
stfd f11,152(r1)
stfd f12,156(r1)
stfd f13,164(r1)
addi r6,r1,44
addi r7,r1,72
mr r4,r12
addi r5,r1,232
// Prolog(ue)
mflr r0 // Save the link register in the caller's
stw r0, 8(r1) // stack frame
stwu r1,-176(r1) // Allocate stack space for our own frame and
// adjust stack pointer
// Linkage area, 0(r1) to 24(r1)
// Original sp saved at 0(r1)
// Parameter area, 20 bytes from 24(r1) to
// 44(r1) to accomodate 5 arguments passed
// to PrepareAndDispatch
// Local variables, 132 bytes from 44(r1)
// to 176(r1), to accomodate 5 words and
// 13 doubles
stw r4, 44(r1) // Save parameters passed in GPRs r4-r10;
stw r5, 48(r1) // a pointer to here will be passed to
stw r6, 52(r1) // PrepareAndDispatch for access to
stw r7, 56(r1) // arguments passed in registers. r3,
stw r8, 60(r1) // the self pointer, is used for the
stw r9, 64(r1) // call but isn't otherwise needed in
stw r10, 68(r1) // PrepareAndDispatch, so it is not saved.
stfd f1, 72(r1) // Do the same for floating-point parameters
stfd f2, 80(r1) // passed in FPRs f1-f13
stfd f3, 88(r1)
stfd f4, 96(r1)
stfd f5, 104(r1)
stfd f6, 112(r1)
stfd f7, 120(r1)
stfd f8, 128(r1)
stfd f9, 136(r1)
stfd f10, 144(r1)
stfd f11, 152(r1)
stfd f12, 160(r1)
stfd f13, 168(r1)
// Set up parameters for call to
// PrepareAndDispatch. argument=
// 0, pointer to self, already in r3
mr r4,r12 // 1, stub number
addi r5, r1, 204 // 2, pointer to the parameter area in our
// caller's stack, for access to
// parameters beyond those passed in
// registers. Skip past the first parameter
// (corresponding to r3) for the same reason
// as above. 176 (size of our frame) + 24
// (size of caller's linkage) + 4 (skipped
// parameter)
addi r6, r1, 44 // 3, pointer to saved GPRs
addi r7, r1, 72 // 4, pointer to saved FPRs
bl L_PrepareAndDispatch$stub
nop
lwz r0,184(r1)
addi r1,r1,176
mtlr r0
blr
// Do it
nop // Leave room for linker magic
// Epilog(ue)
lwz r0, 184(r1) // Retrieve old link register value
addi r1, r1, 176 // Restore stack pointer
mtlr r0 // Restore link register
blr // Return
.picsymbol_stub
L_PrepareAndDispatch$stub:
L_PrepareAndDispatch$stub: // Standard PIC symbol stub
.indirect_symbol _PrepareAndDispatch
mflr r0
bcl 20,31,L1$pb
mflr r0
bcl 20,31,L1$pb
L1$pb:
mflr r11
addis r11,r11,ha16(L1$lz-L1$pb)
mtlr r0
lwz r12,lo16(L1$lz-L1$pb)(r11)
mtctr r12
addi r11,r11,lo16(L1$lz-L1$pb)
mflr r11
addis r11,r11,ha16(L1$lz-L1$pb)
mtlr r0
lwz r12,lo16(L1$lz-L1$pb)(r11)
mtctr r12
addi r11,r11,lo16(L1$lz-L1$pb)
bctr
.lazy_symbol_pointer
L1$lz:
.indirect_symbol _PrepareAndDispatch
.long dyld_stub_binding_helper
.long dyld_stub_binding_helper

View File

@ -1,4 +1,4 @@
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* -*- Mode: C -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mark Mentovai <mark@moxienet.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -35,213 +36,161 @@
*
* ***** END LICENSE BLOCK ***** */
/* Implement shared vtbl methods. */
#include "xptcprivate.h"
/*
For mac, the first 8 integral and the first 13 f.p. parameters arrive
in a separate chunk of data that has been loaded from the registers. The
args pointer has been set to the start of the parameters BEYOND the ones
arriving in registers
*/
/* Under the Mac OS X PowerPC ABI, the first 8 integer and 13 floating point
* parameters are delivered in registers and are not on the stack, although
* stack space is allocated for them. The integer parameters are delivered
* in GPRs r3 through r10. The first 8 words of the parameter area on the
* stack shadow these registers. A word will either be in a register or on
* the stack, but not in both. Although the first floating point parameters
* are passed in floating point registers, GPR space and stack space is
* reserved for them as well.
*
* SharedStub has passed pointers to the parameter section of the stack
* and saved copies of the GPRs and FPRs used for parameter passing. We
* don't care about the first parameter (which is delivered here as the self
* pointer), so SharedStub pointed us past that. argsGPR thus points to GPR
* r4 (corresponding to the first argument after the self pointer) and
* argsStack points to the parameter section of the caller's stack frame
* reserved for the same argument. This way, it is possible to reference
* either argsGPR or argsStack with the same index.
*
* Contrary to the assumption made by the previous implementation, the
* Mac OS X PowerPC ABI doesn't impose any special alignment restrictions on
* parameter sections of stacks. Values that are 64 bits wide appear on the
* stack without any special padding.
*
* See also xptcstubs_asm_ppc_darwin.s.m4:_SharedStub.
*
* ABI reference:
* http://developer.apple.com/documentation/DeveloperTools/Conceptual/
* MachORuntime/PowerPCConventions/chapter_3_section_1.html */
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData)
{
#define PARAM_BUFFER_COUNT 16
#define PARAM_GPR_COUNT 7
PrepareAndDispatch(
nsXPTCStubBase *self,
PRUint32 methodIndex,
PRUint32 *argsStack,
PRUint32 *argsGPR,
double *argsFPR) {
#define PARAM_BUFFER_COUNT 16
#define PARAM_FPR_COUNT 13
#define PARAM_GPR_COUNT 7
// fprintf(stderr, "PrepareAndDispatch %p, %d, %p, %p, %p\n", self, methodIndex, args, gprData, fprData);
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
nsXPTCMiniVariant *dispatchParams = NULL;
nsIInterfaceInfo *interfaceInfo = NULL;
const nsXPTMethodInfo *methodInfo;
PRUint8 paramCount;
PRUint8 i;
nsresult result = NS_ERROR_FAILURE;
PRUint32 argIndex = 0;
PRUint32 fprIndex = 0;
nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
nsXPTCMiniVariant* dispatchParams = NULL;
nsIInterfaceInfo* iface_info = NULL;
const nsXPTMethodInfo* info;
PRUint8 paramCount;
PRUint8 i;
nsresult result = NS_ERROR_FAILURE;
typedef struct {
PRUint32 hi;
PRUint32 lo;
} DU;
NS_ASSERTION(self,"no self");
NS_ASSERTION(self, "no self");
self->GetInterfaceInfo(&iface_info);
NS_ASSERTION(iface_info,"no interface info");
self->GetInterfaceInfo(&interfaceInfo);
NS_ASSERTION(interfaceInfo, "no interface info");
iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
NS_ASSERTION(info,"no interface info");
interfaceInfo->GetMethodInfo(PRUint16(methodIndex), &methodInfo);
NS_ASSERTION(methodInfo, "no method info");
paramCount = info->GetParamCount();
paramCount = methodInfo->GetParamCount();
// setup variant array pointer
if(paramCount > PARAM_BUFFER_COUNT)
dispatchParams = new nsXPTCMiniVariant[paramCount];
if(paramCount > PARAM_BUFFER_COUNT) {
dispatchParams = new nsXPTCMiniVariant[paramCount];
}
else {
dispatchParams = paramBuffer;
}
NS_ASSERTION(dispatchParams,"no place for params");
for(i = 0; i < paramCount; i++, argIndex++) {
const nsXPTParamInfo &param = methodInfo->GetParam(i);
const nsXPTType &type = param.GetType();
nsXPTCMiniVariant *dp = &dispatchParams[i];
PRUint32 theParam;
if(argIndex < PARAM_GPR_COUNT)
theParam = argsGPR[argIndex];
else
dispatchParams = paramBuffer;
NS_ASSERTION(dispatchParams,"no place for params");
theParam = argsStack[argIndex];
PRUint32* ap = args;
PRUint32 iCount = 0;
PRUint32 fpCount = 0;
for(i = 0; i < paramCount; i++)
{
const nsXPTParamInfo& param = info->GetParam(i);
const nsXPTType& type = param.GetType();
nsXPTCMiniVariant* dp = &dispatchParams[i];
if(param.IsOut() || !type.IsArithmetic())
{
if (iCount < PARAM_GPR_COUNT)
dp->val.p = (void*) gprData[iCount++];
else
dp->val.p = (void*) *ap++;
continue;
}
// else
switch(type)
{
case nsXPTType::T_I8 : if (iCount < PARAM_GPR_COUNT)
dp->val.i8 = (PRInt8) gprData[iCount++];
else
dp->val.i8 = (PRInt8) *ap++;
break;
case nsXPTType::T_I16 : if (iCount < PARAM_GPR_COUNT)
dp->val.i16 = (PRInt16) gprData[iCount++];
else
dp->val.i16 = (PRInt16) *ap++;
break;
case nsXPTType::T_I32 : if (iCount < PARAM_GPR_COUNT)
dp->val.i32 = (PRInt32) gprData[iCount++];
else
dp->val.i32 = (PRInt32) *ap++;
break;
case nsXPTType::T_I64 :
{
PRUint64 tempu64;
if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
if ((iCount + 1) < PARAM_GPR_COUNT) {
tempu64 = *(PRUint64*) &gprData[iCount];
iCount += 2;
}
else {
if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack
tempu64 = *(PRUint64*) ap;
ap += 2;
}
dp->val.i64 = (PRUint64)tempu64;
}
if(param.IsOut() || !type.IsArithmetic())
dp->val.p = (void *) theParam;
else {
switch(type) {
case nsXPTType::T_I8:
dp->val.i8 = (PRInt8) theParam;
break;
#if 0
case nsXPTType::T_I64 : if (iCount < PARAM_GPR_COUNT)
dp->val.i64.hi = (PRInt32) gprData[iCount++];
else
dp->val.i64.hi = (PRInt32) *ap++;
if (iCount < PARAM_GPR_COUNT)
dp->val.i64.lo = (PRUint32) gprData[iCount++];
else
dp->val.i64.lo = (PRUint32) *ap++;
break;
#endif
case nsXPTType::T_U8 : if (iCount < PARAM_GPR_COUNT)
dp->val.i8 = (PRUint8) gprData[iCount++];
else
dp->val.i8 = (PRUint8) *ap++;
break;
case nsXPTType::T_U16 : if (iCount < PARAM_GPR_COUNT)
dp->val.i16 = (PRUint16) gprData[iCount++];
else
dp->val.i16 = (PRUint16) *ap++;
break;
case nsXPTType::T_U32 : if (iCount < PARAM_GPR_COUNT)
dp->val.i32 = (PRUint32) gprData[iCount++];
else
dp->val.i32 = (PRUint32) *ap++;
break;
case nsXPTType::T_U64 :
#if 0
if (iCount < PARAM_GPR_COUNT)
dp->val.i64.hi = (PRUint32) gprData[iCount++];
else
dp->val.i64.hi = (PRUint32) *ap++;
if (iCount < PARAM_GPR_COUNT)
dp->val.i64.lo = (PRUint32) gprData[iCount++];
else
dp->val.i64.lo = (PRUint32) *ap++;
#endif
{
PRUint64 tempu64;
if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
if ((iCount + 1) < PARAM_GPR_COUNT) {
tempu64 = *(PRUint64*) &gprData[iCount];
iCount += 2;
}
else {
if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack
tempu64 = *(PRUint64*) ap;
ap += 2;
}
dp->val.i64 = (PRUint64)tempu64;
}
case nsXPTType::T_I16:
dp->val.i16 = (PRInt16) theParam;
break;
case nsXPTType::T_I32:
dp->val.i32 = (PRInt32) theParam;
break;
case nsXPTType::T_U8:
dp->val.u8 = (PRUint8) theParam;
break;
case nsXPTType::T_U16:
dp->val.u16 = (PRUint16) theParam;
break;
case nsXPTType::T_U32:
dp->val.u32 = (PRUint32) theParam;
break;
case nsXPTType::T_I64:
case nsXPTType::T_U64:
((DU *)dp)->hi = (PRUint32) theParam;
if(++argIndex < PARAM_GPR_COUNT)
((DU *)dp)->lo = (PRUint32) argsGPR[argIndex];
else
((DU *)dp)->lo = (PRUint32) argsStack[argIndex];
break;
case nsXPTType::T_BOOL:
dp->val.b = (PRBool) theParam;
break;
case nsXPTType::T_CHAR:
dp->val.c = (char) theParam;
break;
case nsXPTType::T_WCHAR:
dp->val.wc = (wchar_t) theParam;
break;
case nsXPTType::T_FLOAT:
if(fprIndex < PARAM_FPR_COUNT)
dp->val.f = (float) argsFPR[fprIndex++];
else
dp->val.f = *(float *) &argsStack[argIndex];
break;
case nsXPTType::T_DOUBLE:
if(fprIndex < PARAM_FPR_COUNT)
dp->val.d = argsFPR[fprIndex++];
else
dp->val.d = *(double *) &argsStack[argIndex];
argIndex++;
break;
case nsXPTType::T_FLOAT : if (fpCount < 13) {
dp->val.f = (float) fprData[fpCount++];
if (iCount < PARAM_GPR_COUNT)
++iCount;
else
++ap;
}
else
dp->val.f = *((float*) ap++);
break;
case nsXPTType::T_DOUBLE : if (fpCount < 13) {
dp->val.d = (double) fprData[fpCount++];
if (iCount < PARAM_GPR_COUNT)
++iCount;
else
++ap;
if (iCount < PARAM_GPR_COUNT)
++iCount;
else
++ap;
}
else {
dp->val.f = *((double*) ap);
ap += 2;
}
break;
case nsXPTType::T_BOOL : if (iCount < PARAM_GPR_COUNT)
dp->val.b = (PRBool) gprData[iCount++];
else
dp->val.b = (PRBool) *ap++;
break;
case nsXPTType::T_CHAR : if (iCount < PARAM_GPR_COUNT)
dp->val.c = (char) gprData[iCount++];
else
dp->val.c = (char) *ap++;
break;
case nsXPTType::T_WCHAR : if (iCount < PARAM_GPR_COUNT)
dp->val.wc = (wchar_t) gprData[iCount++];
else
dp->val.wc = (wchar_t) *ap++;
break;
default:
NS_ASSERTION(0, "bad type");
break;
}
NS_ASSERTION(0, "bad type");
break;
}
}
}
result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
result = self->CallMethod((PRUint16)methodIndex, methodInfo, dispatchParams);
NS_RELEASE(iface_info);
NS_RELEASE(interfaceInfo);
if(dispatchParams != paramBuffer)
delete [] dispatchParams;
if(dispatchParams != paramBuffer)
delete [] dispatchParams;
return result;
return result;
}
#define STUB_ENTRY(n)
#define SENTINEL_ENTRY(n) \
nsresult nsXPTCStubBase::Sentinel##n() \
@ -250,5 +199,4 @@ nsresult nsXPTCStubBase::Sentinel##n() \
return NS_ERROR_NOT_IMPLEMENTED; \
}
#include "xptcstubsdef.inc"