Back to index

lightning-sunbird  0.9+nobinonly
xptcstubs_nto_shle.cpp
Go to the documentation of this file.
00001 #include "xptcprivate.h"
00002 
00003 const int c_int_register_params = 3;
00004 const int c_float_register_params = 8;
00005 
00006 /* 
00007    Dispatch function for all stubs.  
00008 
00009    The parameters to the original function are spread between 'data' which 
00010    is value of the stack pointer when the stub was called, intRegParams which
00011    points to an area containing the values of r5, r6 and r7 when the stub was
00012    called and floatRegParams which points to an area containing the values
00013    of float registers fr4 to fr11 when the stub was called.  
00014 
00015  */
00016 extern "C" nsresult
00017 PrepareAndDispatch(nsXPTCStubBase* self, int methodIndex, PRUint32* data, 
00018                                PRUint32 *intRegParams, float *floatRegParams)
00019 {
00020 #define PARAM_BUFFER_COUNT     16
00021 
00022        nsresult result = NS_ERROR_FAILURE;
00023        int intCount = 0;
00024        int floatCount = 0;
00025     nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
00026     nsXPTCMiniVariant* dispatchParams = NULL;
00027     nsIInterfaceInfo* iface_info = NULL;
00028     const nsXPTMethodInfo* info;
00029     PRUint8 paramCount;
00030        PRUint8 i;
00031 
00032        NS_ASSERTION(self,"no self");
00033 
00034        self->GetInterfaceInfo(&iface_info);
00035        NS_ASSERTION(iface_info,"no interface info");
00036 
00037        iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
00038        NS_ASSERTION(info,"no interface info");
00039 
00040        paramCount = info->GetParamCount();
00041 
00042        // setup variant array pointer
00043        if(paramCount > PARAM_BUFFER_COUNT)
00044               dispatchParams = new nsXPTCMiniVariant[paramCount];
00045        else
00046               dispatchParams = paramBuffer;
00047        NS_ASSERTION(dispatchParams,"no place for params");
00048 
00049        for ( i = 0; i < paramCount; ++i ) {
00050               const nsXPTParamInfo& param = info->GetParam(i);
00051               nsXPTCMiniVariant* dp = &dispatchParams[i];
00052               nsXPTType type = param.IsOut() ? nsXPTType::T_I32 : param.GetType();
00053 
00054               switch ( type ) {
00055               case nsXPTType::T_I64:
00056               case nsXPTType::T_U64:
00057                      // Was this passed  in a register?
00058                      if ( (c_int_register_params - intCount) >= 2 ) {
00059                             dp->val.i64 = *((PRInt64 *) intRegParams);
00060                             intRegParams += 2;
00061                             intCount += 2;
00062                      }
00063                      else {
00064                             dp->val.i64 = *((PRInt64*) data);
00065                             data += 2;
00066                      }
00067                      break;
00068         case nsXPTType::T_FLOAT:
00069                      // Was this passed  in a register?
00070                      if ( floatCount < c_float_register_params ) {
00071                             dp->val.f = *floatRegParams;
00072                             ++floatCount;
00073                             ++floatRegParams;
00074                      }
00075                      else {
00076                             dp->val.f = *((float*) data);
00077                             ++data;
00078                      }                    
00079                      break;
00080         case nsXPTType::T_DOUBLE:
00081                      // Was this passed  in a register?
00082                      if ( (c_float_register_params - floatCount) >= 2  ) {
00083                             if ( floatCount & 1 != 0 ) {
00084                                    ++floatCount;
00085                                    ++floatRegParams;
00086                             }
00087                             dp->val.d = *(double *)floatRegParams;
00088                             floatCount += 2;
00089                             floatRegParams += 2;
00090                      }
00091                      else {
00092                             dp->val.d = *((double *) data);
00093                             data += 2;
00094                      }                    
00095                      break;
00096               default:             // 32-bit (non-float) value
00097                      // Was this passed  in a register?
00098                      if ( intCount < c_int_register_params ) {
00099                             dp->val.i32 = *intRegParams;
00100                             ++intRegParams;
00101                             ++intCount;
00102                      }
00103                      else {
00104                             dp->val.i32 = *data;
00105                             ++data;
00106                      }
00107                      break;
00108         }
00109        }
00110 
00111        result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);
00112 
00113        NS_RELEASE(iface_info);
00114 
00115        if(dispatchParams != paramBuffer)
00116               delete [] dispatchParams;
00117 
00118        return result;
00119 }
00120 
00121 #ifdef __GNUC__                    /* Gnu Compiler. */
00122 
00123 /* Stubs are defined in xptcstubs_asm_shle.s, so just define STUB_ENTRY(n) as
00124    nothing.  Defining the stubs as assembler here unnecessarily painful and
00125    larger than necessary since gcc won't give use naked functions.
00126 */
00127 #define STUB_ENTRY(n)
00128 
00129 #define SENTINEL_ENTRY(n) \
00130 nsresult nsXPTCStubBase::Sentinel##n() \
00131 { \
00132        NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \
00133        return NS_ERROR_NOT_IMPLEMENTED; \
00134 }
00135 
00136 #else
00137 #error "can't find a compiler to use"
00138 #endif /* __GNUC__ */
00139 
00140 #include "xptcstubsdef.inc"