Back to index

lightning-sunbird  0.9+nobinonly
xptcstubs_mac.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* Implement shared vtbl methods. */
00039 
00040 #pragma export on
00041 
00042 #include "xptcprivate.h"
00043 
00044 #if defined(XP_MAC)
00045 
00046 /*
00047        For mac, the first 8 integral and the first 13 f.p. parameters arrive
00048        in a separate chunk of data that has been loaded from the registers. The
00049        args pointer has been set to the start of the parameters BEYOND the ones
00050        arriving in registers
00051 */
00052 extern "C" nsresult
00053 PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData)
00054 {
00055 #define PARAM_BUFFER_COUNT     16
00056 #define PARAM_GPR_COUNT                   7
00057 
00058     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
00059     nsXPTCMiniVariant* dispatchParams = NULL;
00060     nsIInterfaceInfo* iface_info = NULL;
00061     const nsXPTMethodInfo* info;
00062     PRUint8 paramCount;
00063     PRUint8 i;
00064     nsresult result = NS_ERROR_FAILURE;
00065 
00066     NS_ASSERTION(self,"no self");
00067 
00068     self->GetInterfaceInfo(&iface_info);
00069     NS_ASSERTION(iface_info,"no interface info");
00070 
00071     iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
00072     NS_ASSERTION(info,"no interface info");
00073 
00074     paramCount = info->GetParamCount();
00075 
00076     // setup variant array pointer
00077     if(paramCount > PARAM_BUFFER_COUNT)
00078         dispatchParams = new nsXPTCMiniVariant[paramCount];
00079     else
00080         dispatchParams = paramBuffer;
00081     NS_ASSERTION(dispatchParams,"no place for params");
00082 
00083     PRUint32* ap = args;
00084     PRUint32 iCount = 0;
00085     PRUint32 fpCount = 0;
00086     for(i = 0; i < paramCount; i++)
00087     {
00088         const nsXPTParamInfo& param = info->GetParam(i);
00089         const nsXPTType& type = param.GetType();
00090         nsXPTCMiniVariant* dp = &dispatchParams[i];
00091 
00092         if(param.IsOut() || !type.IsArithmetic())
00093         {
00094             if (iCount < PARAM_GPR_COUNT)
00095               dp->val.p = (void*) gprData[iCount++];
00096             else
00097               dp->val.p = (void*) *ap++;
00098             continue;
00099         }
00100         // else
00101         switch(type)
00102         {
00103         case nsXPTType::T_I8     :  if (iCount < PARAM_GPR_COUNT)
00104                                                                dp->val.i8  = (PRInt8) gprData[iCount++];
00105                                                         else
00106                                                                dp->val.i8  = (PRInt8)  *ap++;
00107                                                         break;
00108         case nsXPTType::T_I16     :  if (iCount < PARAM_GPR_COUNT)
00109                                                                dp->val.i16  = (PRInt16) gprData[iCount++];
00110                                                         else
00111                                                                dp->val.i16  = (PRInt16)  *ap++;
00112                                                         break;
00113         case nsXPTType::T_I32     :  if (iCount < PARAM_GPR_COUNT)
00114                                                                dp->val.i32  = (PRInt32) gprData[iCount++];
00115                                                         else
00116                                                                dp->val.i32  = (PRInt32)  *ap++;
00117                                                         break;
00118         case nsXPTType::T_I64     :
00119 #ifdef HAVE_LONG_LONG
00120                                                         PRUint64 tempu64;
00121                                                         if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
00122                                                         if ((iCount + 1) < PARAM_GPR_COUNT)
00123                                                         {
00124                                                                tempu64 = *(PRUint64*) &gprData[iCount];
00125                                                                       iCount += 2;
00126                                                                }
00127                                                                else
00128                                                                {
00129                                                                       if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack
00130                                                                       tempu64 = *(PRUint64*) ap;
00131                                                                       ap += 2;
00132                                                                }
00133                                                                dp->val.i64 = (PRUint64)tempu64;
00134 #else
00135                                                         if (iCount < PARAM_GPR_COUNT)
00136                                                                dp->val.i64.hi  = (PRInt32) gprData[iCount++];
00137                                                         else
00138                                                                dp->val.i64.hi  = (PRInt32)  *ap++;
00139                                                         if (iCount < PARAM_GPR_COUNT)
00140                                                                dp->val.i64.lo  = (PRUint32) gprData[iCount++];
00141                                                         else
00142                                                                dp->val.i64.lo  = (PRUint32)  *ap++;
00143 #endif
00144                                                         break;
00145         case nsXPTType::T_U8     :  if (iCount < PARAM_GPR_COUNT)
00146                                                                dp->val.i8  = (PRUint8) gprData[iCount++];
00147                                                         else
00148                                                                dp->val.i8  = (PRUint8)  *ap++;
00149                                                         break;
00150         case nsXPTType::T_U16     :  if (iCount < PARAM_GPR_COUNT)
00151                                                                dp->val.i16  = (PRUint16) gprData[iCount++];
00152                                                         else
00153                                                                dp->val.i16  = (PRUint16)  *ap++;
00154                                                         break;
00155         case nsXPTType::T_U32     :  if (iCount < PARAM_GPR_COUNT)
00156                                                                dp->val.i32  = (PRUint32) gprData[iCount++];
00157                                                         else
00158                                                                dp->val.i32  = (PRUint32)  *ap++;
00159                                                         break;
00160         case nsXPTType::T_U64     :
00161 #ifdef HAVE_LONG_LONG
00162                                                         // PRUint64 tempu64; // declared above and still in scope
00163                                                         if (iCount & 1) iCount++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
00164                                                         if ((iCount + 1) < PARAM_GPR_COUNT)
00165                                                         {
00166                                                                tempu64 = *(PRUint64*) &gprData[iCount];
00167                                                                       iCount += 2;
00168                                                                }
00169                                                                else
00170                                                                {
00171                                                                       if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack
00172                                                                       tempu64 = *(PRUint64*) ap;
00173                                                                       ap += 2;
00174                                                                }
00175                                                                dp->val.i64 = (PRUint64)tempu64;
00176 #else
00177                                                         if (iCount < PARAM_GPR_COUNT)
00178                                                                dp->val.i64.hi  = (PRUint32) gprData[iCount++];
00179                                                         else
00180                                                                dp->val.i64.hi  = (PRUint32)  *ap++;
00181                                                         if (iCount < PARAM_GPR_COUNT)
00182                                                                dp->val.i64.lo  = (PRUint32) gprData[iCount++];
00183                                                         else
00184                                                                dp->val.i64.lo  = (PRUint32)  *ap++;
00185 #endif
00186                                                         break;
00187         case nsXPTType::T_FLOAT  : if (fpCount < 13) {
00188                                                                dp->val.f  = (float) fprData[fpCount++];
00189                                                                if (iCount < PARAM_GPR_COUNT)
00190                                                                       ++iCount;
00191                                                                else
00192                                                                       ++ap;
00193                                                         }
00194                                                         else
00195                                                                dp->val.f   = *((float*)   ap++);
00196                                                   break;
00197         case nsXPTType::T_DOUBLE : if (fpCount < 13) {
00198                                                                dp->val.d  = (double) fprData[fpCount++];
00199                                                                if (iCount < PARAM_GPR_COUNT)
00200                                                                       ++iCount;
00201                                                                else
00202                                                                       ++ap;
00203                                                                if (iCount < PARAM_GPR_COUNT)
00204                                                                       ++iCount;
00205                                                                else
00206                                                                       ++ap;
00207                                                         }
00208                                                         else {
00209                                                                dp->val.f   = *((double*)   ap);
00210                                                                ap += 2;
00211                                                         }
00212                                                   break;
00213         case nsXPTType::T_BOOL     :  if (iCount < PARAM_GPR_COUNT)
00214                                                                dp->val.b  = (PRBool) gprData[iCount++];
00215                                                         else
00216                                                                dp->val.b  = (PRBool)  *ap++;
00217                                                         break;
00218         case nsXPTType::T_CHAR     :  if (iCount < PARAM_GPR_COUNT)
00219                                                                dp->val.c  = (char) gprData[iCount++];
00220                                                         else
00221                                                                dp->val.c  = (char)  *ap++;
00222                                                         break;
00223         case nsXPTType::T_WCHAR     :  if (iCount < PARAM_GPR_COUNT)
00224                                                                dp->val.wc  = (wchar_t) gprData[iCount++];
00225                                                         else
00226                                                                dp->val.wc  = (wchar_t)  *ap++;
00227                                                         break;
00228         default:
00229             NS_ASSERTION(0, "bad type");
00230             break;
00231         }
00232     }
00233 
00234     result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
00235 
00236     NS_RELEASE(iface_info);
00237 
00238     if(dispatchParams != paramBuffer)
00239         delete [] dispatchParams;
00240 
00241     return result;
00242 }
00243 
00244 extern "C" void SharedStub();
00245 
00246 #define STUB_ENTRY(n)                                          \
00247 asm nsresult nsXPTCStubBase::Stub##n()    \
00248 {                                                                            \
00249               addi   r12,r0,n;                                 \
00250               b             SharedStub                                \
00251 }
00252 
00253 #define SENTINEL_ENTRY(n) \
00254 nsresult nsXPTCStubBase::Sentinel##n() \
00255 { \
00256     NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
00257     return NS_ERROR_NOT_IMPLEMENTED; \
00258 }
00259 
00260 
00261 #include "xptcstubsdef.inc"
00262 
00263 #pragma export off
00264 
00265 #endif