Back to index

lightning-sunbird  0.9+nobinonly
xptcstubs_ppc_rhapsody.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C -*- */
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  *   Mark Mentovai <mark@moxienet.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "xptcprivate.h"
00040 
00041 /* Under the Mac OS X PowerPC ABI, the first 8 integer and 13 floating point
00042  * parameters are delivered in registers and are not on the stack, although
00043  * stack space is allocated for them.  The integer parameters are delivered
00044  * in GPRs r3 through r10.  The first 8 words of the parameter area on the
00045  * stack shadow these registers.  A word will either be in a register or on
00046  * the stack, but not in both.  Although the first floating point parameters
00047  * are passed in floating point registers, GPR space and stack space is
00048  * reserved for them as well.
00049  *
00050  * SharedStub has passed pointers to the parameter section of the stack
00051  * and saved copies of the GPRs and FPRs used for parameter passing.  We
00052  * don't care about the first parameter (which is delivered here as the self
00053  * pointer), so SharedStub pointed us past that.  argsGPR thus points to GPR
00054  * r4 (corresponding to the first argument after the self pointer) and
00055  * argsStack points to the parameter section of the caller's stack frame
00056  * reserved for the same argument.  This way, it is possible to reference
00057  * either argsGPR or argsStack with the same index.
00058  *
00059  * Contrary to the assumption made by the previous implementation, the
00060  * Mac OS X PowerPC ABI doesn't impose any special alignment restrictions on
00061  * parameter sections of stacks.  Values that are 64 bits wide appear on the
00062  * stack without any special padding.
00063  *
00064  * See also xptcstubs_asm_ppc_darwin.s.m4:_SharedStub.
00065  *
00066  * ABI reference:
00067  * http://developer.apple.com/documentation/DeveloperTools/Conceptual/
00068  *  MachORuntime/PowerPCConventions/chapter_3_section_1.html */
00069 
00070 extern "C" nsresult
00071 PrepareAndDispatch(
00072   nsXPTCStubBase *self,
00073   PRUint32        methodIndex,
00074   PRUint32       *argsStack,
00075   PRUint32       *argsGPR,
00076   double         *argsFPR) {
00077 #define PARAM_BUFFER_COUNT 16
00078 #define PARAM_FPR_COUNT    13
00079 #define PARAM_GPR_COUNT     7
00080 
00081   nsXPTCMiniVariant      paramBuffer[PARAM_BUFFER_COUNT];
00082   nsXPTCMiniVariant     *dispatchParams = NULL;
00083   nsIInterfaceInfo      *interfaceInfo  = NULL;
00084   const nsXPTMethodInfo *methodInfo;
00085   PRUint8                paramCount;
00086   PRUint8                i;
00087   nsresult               result         = NS_ERROR_FAILURE;
00088   PRUint32               argIndex       = 0;
00089   PRUint32               fprIndex       = 0;
00090 
00091   typedef struct {
00092     PRUint32 hi;
00093     PRUint32 lo;
00094   } DU;
00095 
00096   NS_ASSERTION(self, "no self");
00097 
00098   self->GetInterfaceInfo(&interfaceInfo);
00099   NS_ASSERTION(interfaceInfo, "no interface info");
00100 
00101   interfaceInfo->GetMethodInfo(PRUint16(methodIndex), &methodInfo);
00102   NS_ASSERTION(methodInfo, "no method info");
00103 
00104   paramCount = methodInfo->GetParamCount();
00105 
00106   if(paramCount > PARAM_BUFFER_COUNT) {
00107     dispatchParams = new nsXPTCMiniVariant[paramCount];
00108   }
00109   else {
00110     dispatchParams = paramBuffer;
00111   }
00112   NS_ASSERTION(dispatchParams,"no place for params");
00113 
00114   for(i = 0; i < paramCount; i++, argIndex++) {
00115     const nsXPTParamInfo &param = methodInfo->GetParam(i);
00116     const nsXPTType      &type  = param.GetType();
00117     nsXPTCMiniVariant    *dp    = &dispatchParams[i];
00118     PRUint32              theParam;
00119 
00120     if(argIndex < PARAM_GPR_COUNT)
00121       theParam =   argsGPR[argIndex];
00122     else
00123       theParam = argsStack[argIndex];
00124 
00125     if(param.IsOut() || !type.IsArithmetic())
00126       dp->val.p = (void *) theParam;
00127     else {
00128       switch(type) {
00129         case nsXPTType::T_I8:
00130           dp->val.i8  =   (PRInt8) theParam;
00131           break;
00132         case nsXPTType::T_I16:
00133           dp->val.i16 =  (PRInt16) theParam;
00134           break;
00135         case nsXPTType::T_I32:
00136           dp->val.i32 =  (PRInt32) theParam;
00137           break;
00138         case nsXPTType::T_U8:
00139           dp->val.u8  =  (PRUint8) theParam;
00140           break;
00141         case nsXPTType::T_U16:
00142           dp->val.u16 = (PRUint16) theParam;
00143           break;
00144         case nsXPTType::T_U32:
00145           dp->val.u32 = (PRUint32) theParam;
00146           break;
00147         case nsXPTType::T_I64:
00148         case nsXPTType::T_U64:
00149           ((DU *)dp)->hi = (PRUint32) theParam;
00150           if(++argIndex < PARAM_GPR_COUNT)
00151             ((DU *)dp)->lo = (PRUint32)   argsGPR[argIndex];
00152           else
00153             ((DU *)dp)->lo = (PRUint32) argsStack[argIndex];
00154           break;
00155         case nsXPTType::T_BOOL:
00156           dp->val.b   =   (PRBool) theParam;
00157           break;
00158         case nsXPTType::T_CHAR:
00159           dp->val.c   =     (char) theParam;
00160           break;
00161         case nsXPTType::T_WCHAR:
00162           dp->val.wc  =  (wchar_t) theParam;
00163           break;
00164         case nsXPTType::T_FLOAT:
00165           if(fprIndex < PARAM_FPR_COUNT)
00166             dp->val.f = (float) argsFPR[fprIndex++];
00167           else
00168             dp->val.f = *(float *) &argsStack[argIndex];
00169           break;
00170         case nsXPTType::T_DOUBLE:
00171           if(fprIndex < PARAM_FPR_COUNT)
00172             dp->val.d = argsFPR[fprIndex++];
00173           else
00174             dp->val.d = *(double *) &argsStack[argIndex];
00175           argIndex++;
00176           break;
00177         default:
00178           NS_ASSERTION(0, "bad type");
00179           break;
00180       }
00181     }
00182   }
00183 
00184   result = self->CallMethod((PRUint16)methodIndex, methodInfo, dispatchParams);
00185 
00186   NS_RELEASE(interfaceInfo);
00187 
00188   if(dispatchParams != paramBuffer)
00189     delete [] dispatchParams;
00190 
00191   return result;
00192 }
00193 
00194 #define STUB_ENTRY(n)
00195 #define SENTINEL_ENTRY(n) \
00196 nsresult nsXPTCStubBase::Sentinel##n() \
00197 { \
00198     NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
00199     return NS_ERROR_NOT_IMPLEMENTED; \
00200 }
00201 
00202 #include "xptcstubsdef.inc"