/*
        For PPC (AIX & 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
*/
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint64 methodIndex, PRUint64* args, PRUint64 *gprData, double *fprData)
{

#define PARAM_BUFFER_COUNT     16
#define PARAM_GPR_COUNT         7

    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");

    PRUint64* 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     :
            if (iCount < PARAM_GPR_COUNT)
                dp->val.i64  = (PRInt64) gprData[iCount++];
            else
                dp->val.i64  = (PRInt64) *ap++;
            break;
        case nsXPTType::T_U8      :
            if (iCount < PARAM_GPR_COUNT)
                dp->val.u8  = (PRUint8) gprData[iCount++];
            else
                dp->val.u8  = (PRUint8)  *ap++;
            break;
        case nsXPTType::T_U16     :
            if (iCount < PARAM_GPR_COUNT)
                dp->val.u16  = (PRUint16) gprData[iCount++];
            else
                dp->val.u16  = (PRUint16)  *ap++;
            break;
        case nsXPTType::T_U32     :
            if (iCount < PARAM_GPR_COUNT)
                dp->val.u32  = (PRUint32) gprData[iCount++];
            else
                dp->val.u32  = (PRUint32)  *ap++;
            break;
        case nsXPTType::T_U64     :
            if (iCount < PARAM_GPR_COUNT)
                dp->val.u64  = (PRUint64) gprData[iCount++];
            else
                dp->val.u64  = (PRUint64)  *ap++;
            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;
        }
    }

    result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
예제 #2
0
    PrepareAndDispatch(uint32 methodIndex, nsXPTCStubBase* self, PRUint32* args)
    {
#define PARAM_BUFFER_COUNT     16

        nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
        nsXPTCMiniVariant* dispatchParams = NULL;
        const nsXPTMethodInfo* info;
        PRUint8 paramCount;
        PRUint8 i;
        nsresult result = NS_ERROR_FAILURE;

        NS_ASSERTION(self,"no self");

        self->mEntry->GetMethodInfo(PRUint16(methodIndex), &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->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams);

        if(dispatchParams != paramBuffer)
            delete [] dispatchParams;

        return result;
    }
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint64* args,
                   PRUint64 *gprData, double *fprData)
{
#define PARAM_BUFFER_COUNT  16
//
// "this" pointer is first parameter, so parameter count is 3.
//
#define PARAM_GPR_COUNT   3
#define PARAM_FPR_COUNT   3

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info = NULL;
    PRUint8 paramCount;
    PRUint8 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method 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");

    PRUint64* ap = args;
    PRUint32 iCount = 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:
            if (iCount < PARAM_GPR_COUNT)
               dp->val.i64  = (PRInt64)gprData[iCount++];
            else
               dp->val.i64  = *((PRInt64*)ap++);
            break;

        case nsXPTType::T_U8:
            if (iCount < PARAM_GPR_COUNT)
               dp->val.u8  = (PRUint8)gprData[iCount++];
            else
               dp->val.u8  = *((PRUint8*)ap++);
            break;

        case nsXPTType::T_U16:
            if (iCount < PARAM_GPR_COUNT)
               dp->val.u16  = (PRUint16)gprData[iCount++];
            else
                dp->val.u16  = *((PRUint16*)ap++);
            break;

        case nsXPTType::T_U32:
            if (iCount < PARAM_GPR_COUNT)
               dp->val.u32  = (PRUint32)gprData[iCount++];
            else
               dp->val.u32  = *((PRUint32*)ap++);
            break;

        case nsXPTType::T_U64:
            if (iCount < PARAM_GPR_COUNT)
               dp->val.u64  = (PRUint64)gprData[iCount++];
            else
               dp->val.u64  = *((PRUint64*)ap++);
            break;

        case nsXPTType::T_FLOAT:
             if (iCount < PARAM_FPR_COUNT)
                // The value in xmm register is already prepared to
                // be retrieved as a float. Therefore, we pass the
                // value verbatim, as a double without conversion.
                dp->val.d  = (double)fprData[iCount++];
             else
                dp->val.f  = *((float*)ap++);
             break;

        case nsXPTType::T_DOUBLE:
              if (iCount < PARAM_FPR_COUNT)
                 dp->val.d  = (double)fprData[iCount++];
              else
                 dp->val.d  = *((double*)ap++);
              break;

        case nsXPTType::T_BOOL:
           if (iCount < PARAM_GPR_COUNT)
              // We need cast to PRUint8 to remove garbage on upper 56-bit
              // at first.
              dp->val.b  = (bool)(PRUint8)gprData[iCount++];
           else
              dp->val.b  = *((bool*)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_ERROR("bad type");
            break;
        }
    }

    result = self->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
/* 
   Dispatch function for all stubs.  

   The parameters to the original function are spread between 'data' which 
   is value of the stack pointer when the stub was called, intRegParams which
   points to an area containing the values of r5, r6 and r7 when the stub was
   called and floatRegParams which points to an area containing the values
   of float registers fr4 to fr11 when the stub was called.  

 */
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, int methodIndex, PRUint32* data, 
				   PRUint32 *intRegParams, float *floatRegParams)
{
#define PARAM_BUFFER_COUNT     16

	nsresult result = NS_ERROR_FAILURE;
	int intCount = 0;
	int floatCount = 0;
    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    nsIInterfaceInfo* iface_info = NULL;
    const nsXPTMethodInfo* info;
    PRUint8 paramCount;
	PRUint8 i;

	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");

	for ( i = 0; i < paramCount; ++i ) {
		const nsXPTParamInfo& param = info->GetParam(i);
		nsXPTCMiniVariant* dp = &dispatchParams[i];
		nsXPTType type = param.IsOut() ? nsXPTType::T_I32 : param.GetType();

		switch ( type ) {
		case nsXPTType::T_I64:
		case nsXPTType::T_U64:
			// Was this passed  in a register?
			if ( (c_int_register_params - intCount) >= 2 ) {
				dp->val.i64 = *((PRInt64 *) intRegParams);
				intRegParams += 2;
				intCount += 2;
			}
			else {
				dp->val.i64 = *((PRInt64*) data);
				data += 2;
			}
			break;
        case nsXPTType::T_FLOAT:
			// Was this passed  in a register?
			if ( floatCount < c_float_register_params ) {
				dp->val.f = *floatRegParams;
				++floatCount;
				++floatRegParams;
			}
			else {
				dp->val.f = *((float*) data);
				++data;
			}			
			break;
        case nsXPTType::T_DOUBLE:
			// Was this passed  in a register?
			if ( (c_float_register_params - floatCount) >= 2  ) {
				if ( floatCount & 1 != 0 ) {
					++floatCount;
					++floatRegParams;
				}
				dp->val.d = *(double *)floatRegParams;
				floatCount += 2;
				floatRegParams += 2;
			}
			else {
				dp->val.d = *((double *) data);
				data += 2;
			}			
			break;
		default:		// 32-bit (non-float) value
			// Was this passed  in a register?
			if ( intCount < c_int_register_params ) {
				dp->val.i32 = *intRegParams;
				++intRegParams;
				++intCount;
			}
			else {
				dp->val.i32 = *data;
				++data;
			}
			break;
        }
	}

	result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);

	NS_RELEASE(iface_info);

	if(dispatchParams != paramBuffer)
		delete [] dispatchParams;

	return result;
}
예제 #5
0
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex,
  uint64_t* intargs, uint64_t* floatargs, uint64_t* restargs)
{

#define PARAM_BUFFER_COUNT     16

  nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
  nsXPTCMiniVariant* dispatchParams = NULL;
  nsIInterfaceInfo* iface_info = NULL;
  const nsXPTMethodInfo* info;
  nsresult result = NS_ERROR_FAILURE;
  uint64_t* iargs = intargs;
  uint64_t* fargs = floatargs;
  PRUint8 paramCount;
  PRUint8 i;

  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");

  for(i = 0; i < paramCount; ++i)
  {
    int isfloat = 0;
    const nsXPTParamInfo& param = info->GetParam(i);
    const nsXPTType& type = param.GetType();
    nsXPTCMiniVariant* dp = &dispatchParams[i];

    if(param.IsOut() || !type.IsArithmetic())
    {
#ifdef __LP64__
        /* 64 bit pointer mode */
        dp->val.p = (void*) *iargs;
#else
        /* 32 bit pointer mode */
        uint32_t* adr = (uint32_t*) iargs;
        dp->val.p = (void*) (*(adr+1));
#endif
    }
    else
    switch(type)
    {
    case nsXPTType::T_I8     : dp->val.i8  = *(iargs); break;
    case nsXPTType::T_I16    : dp->val.i16 = *(iargs); break;
    case nsXPTType::T_I32    : dp->val.i32 = *(iargs); break;
    case nsXPTType::T_I64    : dp->val.i64 = *(iargs); break;
    case nsXPTType::T_U8     : dp->val.u8  = *(iargs); break;
    case nsXPTType::T_U16    : dp->val.u16 = *(iargs); break;
    case nsXPTType::T_U32    : dp->val.u32 = *(iargs); break;
    case nsXPTType::T_U64    : dp->val.u64 = *(iargs); break;
    case nsXPTType::T_FLOAT  :
      isfloat = 1;
      if (i < 7)
        dp->val.f = (float) *((double*) fargs); /* register */
      else
        dp->val.u32 = *(fargs); /* memory */
      break;
    case nsXPTType::T_DOUBLE :
      isfloat = 1;
      dp->val.u64 = *(fargs);
      break;
    case nsXPTType::T_BOOL   : dp->val.b   = *(iargs); break;
    case nsXPTType::T_CHAR   : dp->val.c   = *(iargs); break;
    case nsXPTType::T_WCHAR  : dp->val.wc  = *(iargs); break;
    default:
      NS_ASSERTION(0, "bad type");
      break;
    }
    if (i < 7)
    {
      /* we are parsing register arguments */
      if (i == 6)
      {
        // run out of register arguments, move on to memory arguments
        iargs = restargs;
        fargs = restargs;
      }
      else
      {
        ++iargs; // advance one integer register slot
        if (isfloat) ++fargs; // advance float register slot if isfloat
      }
    }
    else
    {
      /* we are parsing memory arguments */
      ++iargs;
      ++fargs;
    }
  }

  result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams);

  NS_RELEASE(iface_info);

  if(dispatchParams != paramBuffer)
    delete [] dispatchParams;

  return result;
}
    nsresult
    PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args)
    {
#define PARAM_BUFFER_COUNT     16

        nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
        nsXPTCMiniVariant* dispatchParams = NULL;
        const nsXPTMethodInfo* info;
        PRUint8 paramCount;
        PRUint8 i;
        nsresult result = NS_ERROR_FAILURE;

        NS_ASSERTION(self,"no self");

        self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
        NS_ASSERTION(info,"no method 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;
            }

            switch(type)
            {
            // the 8 and 16 bit types will have been promoted to 32 bits before
            // being pushed onto the stack. Since the 68k is big endian, we
            // need to skip over the leading high order bytes.
            case nsXPTType::T_I8     : dp->val.i8  = *(((PRInt8*) ap) + 3);  break;
            case nsXPTType::T_I16    : dp->val.i16 = *(((PRInt16*) ap) + 1); break;
            case nsXPTType::T_I32    : dp->val.i32 = *((PRInt32*) ap);       break;
            case nsXPTType::T_I64    : dp->val.i64 = *((PRInt64*) ap); ap++; break;
            case nsXPTType::T_U8     : dp->val.u8  = *(((PRUint8*) ap) + 3); break;
            case nsXPTType::T_U16    : dp->val.u16 = *(((PRUint16*)ap) + 1); break;
            case nsXPTType::T_U32    : dp->val.u32 = *((PRUint32*)ap);       break;
            case nsXPTType::T_U64    : dp->val.u64 = *((PRUint64*)ap); ap++; break;
            case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
            case nsXPTType::T_DOUBLE : dp->val.d   = *((double*)  ap); ap++; break;
            case nsXPTType::T_BOOL   : dp->val.b   = *((PRBool*)  ap);       break;
            case nsXPTType::T_CHAR   : dp->val.c   = *(((char*)   ap) + 3);  break;
            case nsXPTType::T_WCHAR  : dp->val.wc  = *((wchar_t*) ap);       break;
            default:
                NS_ERROR("bad type");
                break;
            }
        }

        result = self->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams);

        if(dispatchParams != paramBuffer)
            delete [] dispatchParams;

        return result;
    }
NS_IMETHODIMP
nsSocketTransportService::Run()
{
    LOG(("nsSocketTransportService::Run"));

    gSocketThread = PR_GetCurrentThread();

    //
    // add thread event to poll list (mThreadEvent may be NULL)
    //
    mPollList[0].fd = mThreadEvent;
    mPollList[0].in_flags = PR_POLL_READ;
    mPollList[0].out_flags = 0;

    PRInt32 i, count;

    //
    // poll loop
    //
    PRBool active = PR_TRUE;
    while (active) {
        //
        // walk active list backwards to see if any sockets should actually be
        // idle, then walk the idle list backwards to see if any idle sockets
        // should become active.  take care to check only idle sockets that
        // were idle to begin with ;-)
        //
        count = mIdleCount;
        for (i=mActiveCount-1; i>=0; --i) {
            //---
            LOG(("  active [%u] { handler=%x condition=%x pollflags=%hu }\n", i,
                mActiveList[i].mHandler,
                mActiveList[i].mHandler->mCondition,
                mActiveList[i].mHandler->mPollFlags));
            //---
            if (NS_FAILED(mActiveList[i].mHandler->mCondition))
                DetachSocket(&mActiveList[i]);
            else {
                PRUint16 in_flags = mActiveList[i].mHandler->mPollFlags;
                if (in_flags == 0)
                    MoveToIdleList(&mActiveList[i]);
                else {
                    // update poll flags
                    mPollList[i+1].in_flags = in_flags;
                    mPollList[i+1].out_flags = 0;
                }
            }
        }
        for (i=count-1; i>=0; --i) {
            //---
            LOG(("  idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i,
                mIdleList[i].mHandler,
                mIdleList[i].mHandler->mCondition,
                mIdleList[i].mHandler->mPollFlags));
            //---
            if (NS_FAILED(mIdleList[i].mHandler->mCondition))
                DetachSocket(&mIdleList[i]);
            else if (mIdleList[i].mHandler->mPollFlags != 0)
                MoveToPollList(&mIdleList[i]);
        }

        LOG(("  calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount));

        // Measures seconds spent while blocked on PR_Poll
        PRUint32 pollInterval;

        PRInt32 n = Poll(&pollInterval);
        if (n < 0) {
            LOG(("  PR_Poll error [%d]\n", PR_GetError()));
            active = PR_FALSE;
        }
        else {
            //
            // service "active" sockets...
            //
            for (i=0; i<PRInt32(mActiveCount); ++i) {
                PRPollDesc &desc = mPollList[i+1];
                SocketContext &s = mActiveList[i];
                if (n > 0 && desc.out_flags != 0) {
                    s.mElapsedTime = 0;
                    s.mHandler->OnSocketReady(desc.fd, desc.out_flags);
                }
                // check for timeout errors unless disabled...
                else if (s.mHandler->mPollTimeout != PR_UINT16_MAX) {
                    // update elapsed time counter
                    if (NS_UNLIKELY(pollInterval > (PR_UINT16_MAX - s.mElapsedTime)))
                        s.mElapsedTime = PR_UINT16_MAX;
                    else
                        s.mElapsedTime += PRUint16(pollInterval);
                    // check for timeout expiration 
                    if (s.mElapsedTime >= s.mHandler->mPollTimeout) {
                        s.mElapsedTime = 0;
                        s.mHandler->OnSocketReady(desc.fd, -1);
                    }
                }
            }

            //
            // check for "dead" sockets and remove them (need to do this in
            // reverse order obviously).
            //
            for (i=mActiveCount-1; i>=0; --i) {
                if (NS_FAILED(mActiveList[i].mHandler->mCondition))
                    DetachSocket(&mActiveList[i]);
            }

            //
            // service the event queue (mPollList[0].fd == mThreadEvent)
            //
            if (n == 0)
                active = ServiceEventQ();
            else if (mPollList[0].out_flags == PR_POLL_READ) {
                // acknowledge pollable event (wait should not block)
                if (PR_WaitForPollableEvent(mThreadEvent) != PR_SUCCESS) {
                    // On Windows, the TCP loopback connection in the
                    // pollable event may become broken when a laptop
                    // switches between wired and wireless networks or
                    // wakes up from hibernation.  We try to create a
                    // new pollable event.  If that fails, we fall back
                    // on "busy wait".
                    {
                        nsAutoLock lock(mEventQLock);
                        PR_DestroyPollableEvent(mThreadEvent);
                        mThreadEvent = PR_NewPollableEvent();
                    }
                    if (!mThreadEvent) {
                        NS_WARNING("running socket transport thread without "
                                   "a pollable event");
                        LOG(("running socket transport thread without "
                             "a pollable event"));
                    }
                    mPollList[0].fd = mThreadEvent;
                    // mPollList[0].in_flags was already set to PR_POLL_READ
                    // at the beginning of this method.
                    mPollList[0].out_flags = 0;
                }
                active = ServiceEventQ();
            }
        }
    }

    //
    // shutdown thread
    //
    
    LOG(("shutting down socket transport thread...\n"));

    mShuttingDown = PR_TRUE;

    // detach any sockets
    for (i=mActiveCount-1; i>=0; --i)
        DetachSocket(&mActiveList[i]);
    for (i=mIdleCount-1; i>=0; --i)
        DetachSocket(&mIdleList[i]);

    mShuttingDown = PR_FALSE;

    // Final pass over the event queue. This makes sure that events posted by
    // socket detach handlers get processed.
    ServiceEventQ();

    gSocketThread = nsnull;
    return NS_OK;
}
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint64 methodIndex, PRUint64* args)
{

#define PARAM_BUFFER_COUNT     16

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info;
    PRUint8 paramCount;
    PRUint8 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->mEntry->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");

    PRUint64* 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
        switch(type)
        {
        case nsXPTType::T_I8     :
            dp->val.i8  = *((PRInt64*) ap);
            break;
        case nsXPTType::T_I16    :
            dp->val.i16 = *((PRInt64*) ap);
            break;
        case nsXPTType::T_I32    :
            dp->val.i32 = *((PRInt64*) ap);
            break;
        case nsXPTType::T_DOUBLE :
            dp->val.d   = *((double*)  ap);
            break;
        case nsXPTType::T_U64    :
            dp->val.u64 = *((PRUint64*)ap);
            break;
        case nsXPTType::T_I64    :
            dp->val.i64 = *((PRInt64*) ap);
            break;
        case nsXPTType::T_U8     :
            dp->val.u8  = *((PRUint64*)ap);
            break;
        case nsXPTType::T_U16    :
            dp->val.u16 = *((PRUint64*)ap);
            break;
        case nsXPTType::T_U32    :
            dp->val.u32 = *((PRUint64*)ap);
            break;
        case nsXPTType::T_FLOAT  :
            dp->val.f   =  ((float*)   ap)[1];
            break;
        case nsXPTType::T_BOOL   :
            dp->val.b   = *((PRUint64*)ap);
            break;
        case nsXPTType::T_CHAR   :
            dp->val.c   = *((PRUint64*)ap);
            break;
        case nsXPTType::T_WCHAR  :
            dp->val.wc  = *((PRInt64*) ap);
            break;
        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase * self, PRUint32 methodIndex,
                   PRUint64 * args, PRUint64 * gpregs, double *fpregs)
{
    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info;
    PRUint32 paramCount;
    PRUint32 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method info");
    if (!info)
        return NS_ERROR_UNEXPECTED;

    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");
    if (!dispatchParams)
        return NS_ERROR_OUT_OF_MEMORY;

    PRUint64* ap = args;
    PRUint32 nr_gpr = 1;    // skip one GPR register for 'that'
    PRUint32 nr_fpr = 0;
    PRUint64 value;

    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 == nsXPTType::T_DOUBLE) {
            if (nr_fpr < FPR_COUNT)
                dp->val.d = fpregs[nr_fpr++];
            else
                dp->val.d = *(double*) ap++;
            continue;
        }
        else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
            if (nr_fpr < FPR_COUNT)
                // The value in %xmm register is already prepared to
                // be retrieved as a float. Therefore, we pass the
                // value verbatim, as a double without conversion.
                dp->val.d = *(double*) ap++;
            else
                dp->val.f = *(float*) ap++;
            continue;
        }
        else {
            if (nr_gpr < GPR_COUNT)
                value = gpregs[nr_gpr++];
            else
                value = *ap++;
        }

        if (param.IsOut() || !type.IsArithmetic()) {
            dp->val.p = (void*) value;
            continue;
        }

        switch (type) {
        case nsXPTType::T_I8:      dp->val.i8  = (PRInt8)   value; break;
        case nsXPTType::T_I16:     dp->val.i16 = (PRInt16)  value; break;
        case nsXPTType::T_I32:     dp->val.i32 = (PRInt32)  value; break;
        case nsXPTType::T_I64:     dp->val.i64 = (PRInt64)  value; break;
        case nsXPTType::T_U8:      dp->val.u8  = (PRUint8)  value; break;
        case nsXPTType::T_U16:     dp->val.u16 = (PRUint16) value; break;
        case nsXPTType::T_U32:     dp->val.u32 = (PRUint32) value; break;
        case nsXPTType::T_U64:     dp->val.u64 = (PRUint64) value; break;
        case nsXPTType::T_BOOL:    dp->val.b   = (PRBool)   value; break;
        case nsXPTType::T_CHAR:    dp->val.c   = (char)     value; break;
        case nsXPTType::T_WCHAR:   dp->val.wc  = (wchar_t)  value; break;

        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->mOuter->CallMethod((PRUint16) methodIndex, info, dispatchParams);

    if (dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
예제 #10
0
NS_IMETHODIMP aptMgrCmdReader::Run()
{
    nsresult rv = NS_OK;
    
    BlockDumper recvDump("Recv");
    nsCOMPtr<aptIManagerCmdService> mcs = do_GetService("@aptana.com/managercmdservice;1", &rv);
    if (NS_FAILED(rv))
    {
        gJaxerLog.Log(eERROR, "aptMgrCmdReader: get aptIManagerCmdService failed: rv=0x%x", rv);
        gJaxerState = eEXITING;
    }

    // we are in msg mode, so each read gets one msg
    while (gJaxerState != eEXITING)
    {
        DWORD nRead = 0;
        mFD = INVALID_SOCKET;
        
#ifdef _WIN32
        BOOL rc = TRUE;
        DWORD nAvail = 0;
        ::ReadFile(mMgrSocket, mRecvBuf, CMDBUFSIZE, &nRead, &mOverlapped);
        DWORD wState = WaitForSingleObject(mOverlapped.hEvent,INFINITE);
        //gJaxerLog.Log(eTRACE, "wState=%x  error %d", wState, WAIT_OBJECT_0, GetLastError());

        if (WAIT_OBJECT_0 != wState)
        {
            gJaxerState = eEXITING;
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "WaitForSingleObject failed:%d", GetLastError());
            break;
        }
        
        //  Signalled on the overlapped event handle, check the result
        if (! GetOverlappedResult(mMgrSocket, &mOverlapped, &nRead, TRUE))
        {
            gJaxerState = eEXITING;
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "GetOverlappedResult failed:%d", GetLastError());
            break;
        }

#if 0
        while(nAvail==0 && rc)
        {
            rc = PeekNamedPipe(mMgrSocket, NULL, 0, NULL, &nAvail, NULL);
            if (!rc)
            {
                gJaxerState = eEXITING;
                rv = NS_ERROR_FAILURE;
                gJaxerLog.Log(eFATAL, "PeekNamedPipe failed:%d", GetLastError());
                break;
            }
            if (gJaxerState == eEXITING)
            {
                break;
            }

            SleepEx(1, TRUE);
        }
        if (gJaxerState == eEXITING)
            break;

        rc = ReadFile(mMgrSocket, mRecvBuf, CMDBUFSIZE, &nRead, NULL);
        if (!rc) 
        {
            rv = NS_ERROR_FAILURE;
            gJaxerLog.Log(eFATAL, "ReadFile failed:%d", GetLastError());
            break;
        }
#endif
#else
        iovec iov;
        iov.iov_base = (char*) mRecvBuf;
        iov.iov_len = CMDBUFSIZE;

        char msgbuf[CMSG_SPACE(sizeof(int))];
        msghdr msg;
        memset(&msg, 0, sizeof(msg));
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = msgbuf;
        msg.msg_controllen = sizeof(msgbuf);

        do {
                nRead = recvmsg(mMgrSocket, &msg, 0);
                gJaxerLog.Log(eTRACE, "recvmsg: nRead=%d errno=%d (EINTR=%d)", nRead, errno, EINTR);
           } while (nRead < 0 && errno == EINTR);
    

        if (nRead < 0) 
        {
            gJaxerLog.Log(eFATAL, "Could not receive message from pipe");
            break;
        } else if (nRead == 0)
        {
            gJaxerLog.Log(eINFO, "Connection to JaxerManager closed.");
            break;
        } else if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
        {
            gJaxerLog.Log(eFATAL, "Control message truncated.");
            break;
        }

        cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg)
        {
            if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
                  cmsg->cmsg_level == SOL_SOCKET &&
                  cmsg->cmsg_type == SCM_RIGHTS)
            {
                mFD = *(int *)CMSG_DATA(cmsg);
            } else
            {
                // LogFatal("No socket descriptor in control message.");
                mFD = INVALID_SOCKET;
            }
        } else
        {
            mFD = INVALID_SOCKET;
        }

        if (mRecvBuf[0] != eNEW_REQUEST_MSG  && 
			mRecvBuf[0] != eNEW_HTTP_REQUEST_MSG &&
			mRecvBuf[0] != eNEW_ADMIN_REQUEST_MSG &&
			mFD != INVALID_SOCKET)
        {
            close(mFD);
            mFD = INVALID_SOCKET;
        }

        if (mFD == INVALID_SOCKET &&
			(mRecvBuf[0] == eNEW_REQUEST_MSG || 
			 mRecvBuf[0] == eNEW_HTTP_REQUEST_MSG ||
			 mRecvBuf[0] == eNEW_ADMIN_REQUEST_MSG
			)
		   )
        {
          gJaxerLog.Log(eFATAL, "No socket descriptor in control message.");
          mRecvBuf[0] = eEXIT_MSG;
        }
#endif
        mRecvIn = PRUint16(nRead);

        if (gJaxerLog.GetDumpEnabled()) 
        {
            gJaxerLog.Log(eINFO, "Message from manager:");
            recvDump.LogContents(mRecvBuf, mRecvIn, true);
            recvDump.Flush();
        }
    
        
        // 0-type [12]-len, [...]-msg data
        PRUint8 msgType = mRecvBuf[0];
        PRUint16 msgLen = (mRecvBuf[1] << 8) | mRecvBuf[2];
        if (mRecvIn<3 || mRecvIn != msgLen + 3)
        {
            //error - msg has to have at least 3 bytes
            gJaxerLog.Log(eFATAL, "Invalid message received from manager: RecvLen=%d, msglen=%d, msgType=%d.",
                mRecvIn, msgLen, msgType);
            //Exit
            msgType = eEXIT_MSG;

        }
        
        switch (msgType) 
        {
            case eNEW_REQUEST_MSG:
			case eNEW_HTTP_REQUEST_MSG:
			case eNEW_ADMIN_REQUEST_MSG:
                gJaxerLog.Log(eTRACE, "Received START_REQ_MSG.");
#ifdef _WIN32
                //Extract the socket
                WSAPROTOCOL_INFO sockInfo;
                if (msgLen != (PRUint16) sizeof(sockInfo))
                {
                    gJaxerLog.Log(eFATAL, "Wrong data received for socket info: Expected length=%d, received length=%d",
                        sizeof(sockInfo), mRecvIn);
                    return NS_ERROR_FAILURE;
                }
                memcpy(&sockInfo, mRecvBuf+3, msgLen);
                mFD = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sockInfo, 0, 0);
#endif
                // New request
                {
                    nsCOMPtr<aptManagerEvent> ReqEvent = new aptManagerEvent((eMSG_TYPE)msgType);
                    ReqEvent->SetWebSocket(mFD);
                    ReqEvent->SetMgrSocket(mMgrSocket);
                    // We need this be async
                    rv = NS_DispatchToMainThread(ReqEvent, NS_DISPATCH_NORMAL);
                }
                break;

            case eSET_PREF_MSG:
                gJaxerLog.Log(eTRACE, "Received SET_PREF_MSG.");
                // Pref request
                {
                    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eSET_PREF_MSG);
                    rv = aEvent->SetEventData(mRecvBuf + 1, mRecvIn-1);
                    // We need this be async
                    rv = NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
                }
                
                break;
                
            case eCMD_RESP_MSG:
                gJaxerLog.Log(eTRACE, "Received eCMD_RESP_MSG.");
                rv = mcs->SetCmdRespData((const char*)mRecvBuf);
                if (NS_FAILED(rv))
                {
                    gJaxerLog.Log(eFATAL, "Set cmd response data failed: rv=0x%x.", rv);
                    // exit
                    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eEXIT_MSG);
                    NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
                    return rv;
                }
                break;

            case eEXIT_MSG:
            default:
                if (msgType == eEXIT_MSG)
                {
                    gJaxerLog.Log(eINFO, "Received exit message from manager.  Exiting...");
                }else
                {
                    gJaxerLog.Log(eFATAL, "Unknown message (%d) from manager.", mRecvBuf[0]);
                }
                gJaxerState = eEXITING;

                break;
        }
    }

    if (mcs)
        mcs->NotifyPossibleCmdFailure();

    // exit
    nsCOMPtr<aptManagerEvent> aEvent = new aptManagerEvent(eEXIT_MSG);                   
    rv = NS_DispatchToMainThread(aEvent, NS_DISPATCH_NORMAL);
            
    gJaxerLog.Log(eTRACE, "MgrCmdReader thread returning with code %d.", rv);

    return rv;
}
extern "C" nsresult
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

  nsXPTCMiniVariant      paramBuffer[PARAM_BUFFER_COUNT];
  nsXPTCMiniVariant     *dispatchParams = NULL;
  const nsXPTMethodInfo *methodInfo;
  PRUint8                paramCount;
  PRUint8                i;
  nsresult               result         = NS_ERROR_FAILURE;
  PRUint32               argIndex       = 0;
  PRUint32               fprIndex       = 0;

  typedef struct {
    PRUint32 hi;
    PRUint32 lo;
  } DU;

  NS_ASSERTION(self, "no self");

  self->mEntry->GetMethodInfo(PRUint16(methodIndex), &methodInfo);
  NS_ASSERTION(methodInfo, "no method info");

  paramCount = methodInfo->GetParamCount();

  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
      theParam = argsStack[argIndex];

    if(param.IsOut() || !type.IsArithmetic())
      dp->val.p = (void *) theParam;
    else {
      switch(type) {
        case nsXPTType::T_I8:
          dp->val.i8  =   (PRInt8) theParam;
          break;
        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   =   (bool) 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;
        default:
          NS_ERROR("bad type");
          break;
      }
    }
  }

  result = self->mOuter->
    CallMethod((PRUint16)methodIndex, methodInfo, dispatchParams);

  if(dispatchParams != paramBuffer)
    delete [] dispatchParams;

  return result;
}
예제 #12
0
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex,
                   PRUint32* args, PRUint32* floatargs)
{

    typedef struct {
        uint32 hi;
        uint32 lo;
    } DU;

#define PARAM_BUFFER_COUNT     16

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info;
    PRInt32 regwords = 1; /* self pointer is not in the variant records */
    nsresult result = NS_ERROR_FAILURE;
    PRUint8 paramCount;
    PRUint8 i;

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method info");
    if (!info)
        return NS_ERROR_UNEXPECTED;

    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");
    if (!dispatchParams)
        return NS_ERROR_OUT_OF_MEMORY;

    for(i = 0; i < paramCount; ++i, --args)
    {
        const nsXPTParamInfo& param = info->GetParam(i);
        const nsXPTType& type = param.GetType();
        nsXPTCMiniVariant* dp = &dispatchParams[i];

        if(param.IsOut() || !type.IsArithmetic())
        {
            dp->val.p = (void*) *args;
            ++regwords;
            continue;
        }
        switch(type)
        {
        case nsXPTType::T_I8     :
            dp->val.i8  = *((PRInt32*) args);
            break;
        case nsXPTType::T_I16    :
            dp->val.i16 = *((PRInt32*) args);
            break;
        case nsXPTType::T_I32    :
            dp->val.i32 = *((PRInt32*) args);
            break;
        case nsXPTType::T_DOUBLE :
            if (regwords & 1)
            {
                ++regwords; /* align on double word */
                --args;
            }
            if (regwords == 0 || regwords == 2)
            {
                dp->val.d=*((double*) (floatargs + regwords));
                --args;
            }
            else
            {
                dp->val.d = *((double*) --args);
            }
            regwords += 2;
            continue;
        case nsXPTType::T_U64    :
        case nsXPTType::T_I64    :
            if (regwords & 1)
            {
                ++regwords; /* align on double word */
                --args;
            }
            ((DU *)dp)->lo = *((PRUint32*) args);
            ((DU *)dp)->hi = *((PRUint32*) --args);
            regwords += 2;
            continue;
        case nsXPTType::T_FLOAT  :
            if (regwords >= 4)
                dp->val.f = *((float*) args);
            else
                dp->val.f = *((float*) floatargs+4+regwords);
            break;
        case nsXPTType::T_U8     :
            dp->val.u8  = *((PRUint32*) args);
            break;
        case nsXPTType::T_U16    :
            dp->val.u16 = *((PRUint32*) args);
            break;
        case nsXPTType::T_U32    :
            dp->val.u32 = *((PRUint32*) args);
            break;
        case nsXPTType::T_BOOL   :
            dp->val.b   = *((PRBool*)   args);
            break;
        case nsXPTType::T_CHAR   :
            dp->val.c   = *((PRUint32*) args);
            break;
        case nsXPTType::T_WCHAR  :
            dp->val.wc  = *((PRInt32*)  args);
            break;
        default:
            NS_ASSERTION(0, "bad type");
            break;
        }
        ++regwords;
    }

    result = self->mOuter->CallMethod((PRUint16) methodIndex, info, dispatchParams);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
예제 #13
0
static
#endif
nsresult __stdcall
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex,
                   PRUint32* args, PRUint32* stackBytesToPop)
{
#define PARAM_BUFFER_COUNT     16

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info = NULL;
    PRUint8 paramCount;
    PRUint8 i;
    nsresult result = NS_ERROR_FAILURE;

    // If anything fails before stackBytesToPop can be set then
    // the failure is completely catastrophic!

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method 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
        switch(type)
        {
        case nsXPTType::T_I8     : dp->val.i8  = *((PRInt8*)  ap);       break;
        case nsXPTType::T_I16    : dp->val.i16 = *((PRInt16*) ap);       break;
        case nsXPTType::T_I32    : dp->val.i32 = *((PRInt32*) ap);       break;
        case nsXPTType::T_I64    : dp->val.i64 = *((PRInt64*) ap); ap++; break;
        case nsXPTType::T_U8     : dp->val.u8  = *((PRUint8*) ap);       break;
        case nsXPTType::T_U16    : dp->val.u16 = *((PRUint16*)ap);       break;
        case nsXPTType::T_U32    : dp->val.u32 = *((PRUint32*)ap);       break;
        case nsXPTType::T_U64    : dp->val.u64 = *((PRUint64*)ap); ap++; break;
        case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
        case nsXPTType::T_DOUBLE : dp->val.d   = *((double*)  ap); ap++; break;
        case nsXPTType::T_BOOL   : dp->val.b   = *((bool*)  ap);       break;
        case nsXPTType::T_CHAR   : dp->val.c   = *((char*)    ap);       break;
        case nsXPTType::T_WCHAR  : dp->val.wc  = *((wchar_t*) ap);       break;
        default:
            NS_ERROR("bad type");
            break;
        }
    }
    *stackBytesToPop = ((PRUint32)ap) - ((PRUint32)args);

    result = self->mOuter->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
예제 #14
0
void
gfxDWriteFont::ComputeMetrics()
{
    DWRITE_FONT_METRICS fontMetrics;
    mFontFace->GetMetrics(&fontMetrics);

    if (mStyle.sizeAdjust != 0.0) {
        gfxFloat aspect = (gfxFloat)fontMetrics.xHeight /
                   fontMetrics.designUnitsPerEm;
        mAdjustedSize = mStyle.GetAdjustedSize(aspect);
    } else {
        mAdjustedSize = mStyle.size;
    }

    mMetrics.xHeight =
        ((gfxFloat)fontMetrics.xHeight /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;

    mMetrics.maxAscent = 
        ceil(((gfxFloat)fontMetrics.ascent /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.maxDescent = 
        ceil(((gfxFloat)fontMetrics.descent /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.maxHeight = mMetrics.maxAscent + mMetrics.maxDescent;

    mMetrics.emHeight = mAdjustedSize;
    mMetrics.emAscent = mMetrics.emHeight *
        mMetrics.maxAscent / mMetrics.maxHeight;
    mMetrics.emDescent = mMetrics.emHeight - mMetrics.emAscent;

    mMetrics.maxAdvance = mAdjustedSize;

    // try to get the true maxAdvance value from 'hhea'
    PRUint8 *tableData;
    PRUint32 len;
    void *tableContext = NULL;
    BOOL exists;
    HRESULT hr =
        mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('h', 'h', 'e', 'a'),
                                   (const void**)&tableData,
                                   &len,
                                   &tableContext,
                                   &exists);
    if (SUCCEEDED(hr)) {
        if (exists && len >= sizeof(mozilla::HheaTable)) {
            const mozilla::HheaTable* hhea =
                reinterpret_cast<const mozilla::HheaTable*>(tableData);
            mMetrics.maxAdvance = ((gfxFloat)PRUint16(hhea->advanceWidthMax) /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
        mFontFace->ReleaseFontTable(tableContext);
    }

    mMetrics.internalLeading = 
        ceil(((gfxFloat)(fontMetrics.ascent + 
                    fontMetrics.descent - 
                    fontMetrics.designUnitsPerEm) / 
                    fontMetrics.designUnitsPerEm) * mAdjustedSize);
    mMetrics.externalLeading = 
        ceil(((gfxFloat)fontMetrics.lineGap /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize);

    UINT16 glyph = (PRUint16)GetSpaceGlyph();
    DWRITE_GLYPH_METRICS metrics;
    mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics);
    mMetrics.spaceWidth = 
        ((gfxFloat)metrics.advanceWidth /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;

    // try to get aveCharWidth from the OS/2 table, fall back to measuring 'x'
    // if the table is not available
    mMetrics.aveCharWidth = 0;
    hr = mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('O', 'S', '/', '2'),
                                    (const void**)&tableData,
                                    &len,
                                    &tableContext,
                                    &exists);
    if (SUCCEEDED(hr)) {
        if (exists && len >= 4) {
            // Not checking against sizeof(mozilla::OS2Table) here because older
            // versions of the table have different sizes; we only need the first
            // two 16-bit fields here.
            const mozilla::OS2Table* os2 =
                reinterpret_cast<const mozilla::OS2Table*>(tableData);
            mMetrics.aveCharWidth = ((gfxFloat)PRInt16(os2->xAvgCharWidth) /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
        mFontFace->ReleaseFontTable(tableContext);
    }

    UINT32 ucs;
    if (mMetrics.aveCharWidth < 1) {
        ucs = L'x';
        if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
            SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {    
            mMetrics.aveCharWidth = 
                ((gfxFloat)metrics.advanceWidth /
                           fontMetrics.designUnitsPerEm) * mAdjustedSize;
        } else {
            // Let's just assume the X is square.
            mMetrics.aveCharWidth = 
                ((gfxFloat)fontMetrics.xHeight /
                           fontMetrics.designUnitsPerEm) * mAdjustedSize;
        }
    }

    ucs = L'0';
    if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
        SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
        mMetrics.zeroOrAveCharWidth = 
            ((gfxFloat)metrics.advanceWidth /
                       fontMetrics.designUnitsPerEm) * mAdjustedSize;
    } else {
        mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
    }

    mMetrics.underlineOffset = 
        ((gfxFloat)fontMetrics.underlinePosition /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.underlineSize = 
        ((gfxFloat)fontMetrics.underlineThickness /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.strikeoutOffset = 
        ((gfxFloat)fontMetrics.strikethroughPosition /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.strikeoutSize = 
        ((gfxFloat)fontMetrics.strikethroughThickness /
                   fontMetrics.designUnitsPerEm) * mAdjustedSize;
    mMetrics.superscriptOffset = 0;
    mMetrics.subscriptOffset = 0;

    mFUnitsConvFactor = GetAdjustedSize() / fontMetrics.designUnitsPerEm;

    SanitizeMetrics(&mMetrics, GetFontEntry()->mIsBadUnderlineFont);

#if 0
    printf("Font: %p (%s) size: %f\n", this,
           NS_ConvertUTF16toUTF8(GetName()).get(), mStyle.size);
    printf("    emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
    printf("    maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
    printf("    internalLeading: %f externalLeading: %f\n", mMetrics.internalLeading, mMetrics.externalLeading);
    printf("    spaceWidth: %f aveCharWidth: %f zeroOrAve: %f xHeight: %f\n",
           mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.zeroOrAveCharWidth, mMetrics.xHeight);
    printf("    uOff: %f uSize: %f stOff: %f stSize: %f supOff: %f subOff: %f\n",
           mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize,
           mMetrics.superscriptOffset, mMetrics.subscriptOffset);
#endif
}
예제 #15
0
static nsresult
PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, PRUint64* args)
{
    const PRUint8 PARAM_BUFFER_COUNT = 16;
    const PRUint8 NUM_ARG_REGS = 6-1;        // -1 for "this" pointer

    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");

    // args[0] to args[NUM_ARG_REGS] hold floating point register values
    PRUint64* ap = args + NUM_ARG_REGS;
    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
        switch(type)
        {
        case nsXPTType::T_I8     : dp->val.i8  = (PRInt8)    *ap;    break;
        case nsXPTType::T_I16    : dp->val.i16 = (PRInt16)   *ap;    break;
        case nsXPTType::T_I32    : dp->val.i32 = (PRInt32)   *ap;    break;
        case nsXPTType::T_I64    : dp->val.i64 = (PRInt64)   *ap;    break;
        case nsXPTType::T_U8     : dp->val.u8  = (PRUint8)   *ap;    break;
        case nsXPTType::T_U16    : dp->val.u16 = (PRUint16)  *ap;    break;
        case nsXPTType::T_U32    : dp->val.u32 = (PRUint32)  *ap;    break;
        case nsXPTType::T_U64    : dp->val.u64 = (PRUint64)  *ap;    break;
        case nsXPTType::T_FLOAT  :
            if(i < NUM_ARG_REGS)
            {
                // floats passed via registers are stored as doubles
                // in the first NUM_ARG_REGS entries in args
                dp->val.u64 = (PRUint64) args[i];
                dp->val.f = (float) dp->val.d;    // convert double to float
            }
            else
                dp->val.u32 = (PRUint32) *ap;
            break;
        case nsXPTType::T_DOUBLE :
            // doubles passed via registers are also stored
            // in the first NUM_ARG_REGS entries in args
            dp->val.u64 = (i < NUM_ARG_REGS) ? args[i] : *ap;
            break;
        case nsXPTType::T_BOOL   : dp->val.b   = (PRBool)    *ap;    break;
        case nsXPTType::T_CHAR   : dp->val.c   = (char)      *ap;    break;
        case nsXPTType::T_WCHAR  : dp->val.wc  = (PRUnichar) *ap;    break;
        default:
            NS_ASSERTION(0, "bad type");
            break;
        }
    }

    result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, uint32 methodIndex, uint32* args)
{

    typedef struct {
        uint32 hi;
        uint32 lo;
    } DU;               // have to move 64 bit entities as 32 bit halves since
                        // stack slots are not guaranteed 16 byte aligned

#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
        switch(type)
        {
        case nsXPTType::T_I8     : dp->val.i8  = *((PRInt32*)  ap);       break;
        case nsXPTType::T_I16    : dp->val.i16 = *((PRInt32*) ap);       break;
        case nsXPTType::T_I32    : dp->val.i32 = *((PRInt32*) ap);       break;
        case nsXPTType::T_DOUBLE :
        case nsXPTType::T_U64    :
        case nsXPTType::T_I64    : ((DU *)dp)->hi = ((DU *)ap)->hi; 
                                   ((DU *)dp)->lo = ((DU *)ap)->lo;
                                   ap++;
                                   break;
        case nsXPTType::T_U8     : dp->val.u8  = *((PRUint32*)ap);       break;
        case nsXPTType::T_U16    : dp->val.u16 = *((PRUint32*)ap);       break;
        case nsXPTType::T_U32    : dp->val.u32 = *((PRUint32*)ap);       break;
        case nsXPTType::T_FLOAT  : dp->val.f   = *((float*)   ap);       break;
        case nsXPTType::T_BOOL   : dp->val.b   = *((PRUint32*)ap);       break;
        case nsXPTType::T_CHAR   : dp->val.c   = *((PRUint32*)ap);       break;
        case nsXPTType::T_WCHAR  : dp->val.wc  = *((PRInt32*) ap);       break;
        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->CallMethod((PRUint16)methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self,
                   PRUint32 methodIndex,
                   PRUint32* args,
                   PRUint32 *gprData,
                   double *fprData)
{
    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    nsIInterfaceInfo* iface_info = NULL;
    const nsXPTMethodInfo* info;
    PRUint32 paramCount;
    PRUint32 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->GetInterfaceInfo(&iface_info);
    NS_ASSERTION(iface_info,"no interface info");
    if (! iface_info)
        return NS_ERROR_UNEXPECTED;

    iface_info->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method info");
    if (! info)
        return NS_ERROR_UNEXPECTED;

    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");
    if (! dispatchParams)
        return NS_ERROR_OUT_OF_MEMORY;

    PRUint32* ap = args;
    PRUint32 gpr = 1;    // skip one GPR register
    PRUint32 fpr = 0;
    PRUint32 tempu32;
    PRUint64 tempu64;

    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 == nsXPTType::T_DOUBLE) {
            if (fpr < FPR_COUNT)
                dp->val.d = fprData[fpr++];
            else {
                if ((PRUint32) ap & 4) ap++; // doubles are 8-byte aligned on stack
                dp->val.d = *(double*) ap;
                ap += 2;
		if (gpr < GPR_COUNT)
		    gpr += 2;
            }
            continue;
        }
        else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
            if (fpr < FPR_COUNT)
                dp->val.f = (float) fprData[fpr++]; // in registers floats are passed as doubles
            else {
                dp->val.f = *(float*) ap;
		ap += 1;
		if (gpr < GPR_COUNT)
		    gpr += 1;
            }
            continue;
        }
        else if (!param.IsOut() && (type == nsXPTType::T_I64
                                    || type == nsXPTType::T_U64)) {
            if (gpr & 1) gpr++; // longlongs are aligned in odd/even register pairs, eg. r5/r6
            if ((gpr + 1) < GPR_COUNT) {
                tempu64 = *(PRUint64*) &gprData[gpr];
                gpr += 2;
            }
            else {
                if ((PRUint32) ap & 4) ap++; // longlongs are 8-byte aligned on stack
                tempu64 = *(PRUint64*) ap;
                ap += 2;
            }
        }
        else {
            if (gpr < GPR_COUNT)
                tempu32 = gprData[gpr++];
            else
                tempu32 = *ap++;
        }

        if(param.IsOut() || !type.IsArithmetic()) {
            dp->val.p = (void*) tempu32;
            continue;
        }

        switch(type) {
        case nsXPTType::T_I8:      dp->val.i8  = (PRInt8)   tempu32; break;
        case nsXPTType::T_I16:     dp->val.i16 = (PRInt16)  tempu32; break;
        case nsXPTType::T_I32:     dp->val.i32 = (PRInt32)  tempu32; break;
        case nsXPTType::T_I64:     dp->val.i64 = (PRInt64)  tempu64; break;
        case nsXPTType::T_U8:      dp->val.u8  = (PRUint8)  tempu32; break;
        case nsXPTType::T_U16:     dp->val.u16 = (PRUint16) tempu32; break;
        case nsXPTType::T_U32:     dp->val.u32 = (PRUint32) tempu32; break;
        case nsXPTType::T_U64:     dp->val.u64 = (PRUint64) tempu64; break;
        case nsXPTType::T_BOOL:    dp->val.b   = (bool)   tempu32; break;
        case nsXPTType::T_CHAR:    dp->val.c   = (char)     tempu32; break;
        case nsXPTType::T_WCHAR:   dp->val.wc  = (wchar_t)  tempu32; break;

        default:
            NS_ERROR("bad type");
            break;
        }
    }

    result = self->CallMethod((PRUint16) methodIndex, info, dispatchParams);

    NS_RELEASE(iface_info);

    if (dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self,
                   PRUint64 methodIndex,
                   PRUint64* args,
                   PRUint64 *gprData,
                   double *fprData)
{
    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info;
    PRUint32 paramCount;
    PRUint32 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method info");
    if (! info)
        return NS_ERROR_UNEXPECTED;

    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");
    if (! dispatchParams)
        return NS_ERROR_OUT_OF_MEMORY;

    PRUint64* ap = args;
    PRUint64 tempu64;

    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 == nsXPTType::T_DOUBLE) {
            if (i < FPR_COUNT)
                dp->val.d = fprData[i];
            else
                dp->val.d = *(double*) ap;
        } else if (!param.IsOut() && type == nsXPTType::T_FLOAT) {
            if (i < FPR_COUNT)
                dp->val.f = (float) fprData[i]; // in registers floats are passed as doubles
            else {
                float *p = (float *)ap;
                p++;
                dp->val.f = *p;
            }
        } else { /* integer type or pointer */
            if (i < GPR_COUNT)
                tempu64 = gprData[i];
            else
                tempu64 = *ap;

            if (param.IsOut() || !type.IsArithmetic())
                dp->val.p = (void*) tempu64;
            else if (type == nsXPTType::T_I8)
                dp->val.i8  = (PRInt8)   tempu64;
            else if (type == nsXPTType::T_I16)
                dp->val.i16 = (PRInt16)  tempu64;
            else if (type == nsXPTType::T_I32)
                dp->val.i32 = (PRInt32)  tempu64;
            else if (type == nsXPTType::T_I64)
                dp->val.i64 = (PRInt64)  tempu64;
            else if (type == nsXPTType::T_U8)
                dp->val.u8  = (PRUint8)  tempu64;
            else if (type == nsXPTType::T_U16)
                dp->val.u16 = (PRUint16) tempu64;
            else if (type == nsXPTType::T_U32)
                dp->val.u32 = (PRUint32) tempu64;
            else if (type == nsXPTType::T_U64)
                dp->val.u64 = (PRUint64) tempu64;
            else if (type == nsXPTType::T_BOOL)
                dp->val.b   = (bool)   tempu64;
            else if (type == nsXPTType::T_CHAR)
                dp->val.c   = (char)     tempu64;
            else if (type == nsXPTType::T_WCHAR)
                dp->val.wc  = (wchar_t)  tempu64;
            else
                NS_ERROR("bad type");
        }

        if (i >= 7)
            ap++;
    }

    result = self->mOuter->CallMethod((PRUint16) methodIndex, info,
                                      dispatchParams);

    if (dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}
예제 #19
0
/*
        For PPC (AIX & 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
*/
extern "C" nsresult
PrepareAndDispatch(nsXPTCStubBase* self, PRUint32 methodIndex, PRUint32* args, PRUint32 *gprData, double *fprData)
{
    typedef struct {
        uint32 hi;
        uint32 lo;      // have to move 64 bit entities as 32 bit halves since
    } DU;               // stack slots are not guaranteed 16 byte aligned

#define PARAM_BUFFER_COUNT     16
#define PARAM_GPR_COUNT         7  

    nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT];
    nsXPTCMiniVariant* dispatchParams = NULL;
    const nsXPTMethodInfo* info = NULL;
    PRUint8 paramCount;
    PRUint8 i;
    nsresult result = NS_ERROR_FAILURE;

    NS_ASSERTION(self,"no self");

    self->mEntry->GetMethodInfo(PRUint16(methodIndex), &info);
    NS_ASSERTION(info,"no method 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;
    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     :  if (iCount < PARAM_GPR_COUNT)
                                         ((DU *)dp)->hi  = (PRInt32) gprData[iCount++];
                                     else
                                         ((DU *)dp)->hi  = (PRInt32)  *ap++;
                                     if (iCount < PARAM_GPR_COUNT)
                                         ((DU *)dp)->lo  = (PRUint32) gprData[iCount++];
                                     else
                                         ((DU *)dp)->lo  = (PRUint32)  *ap++;
                                     break;
        case nsXPTType::T_U8      :  if (iCount < PARAM_GPR_COUNT)
                                         dp->val.u8  = (PRUint8) gprData[iCount++];
                                     else
                                         dp->val.u8  = (PRUint8)  *ap++;
                                     break;
        case nsXPTType::T_U16     :  if (iCount < PARAM_GPR_COUNT)
                                         dp->val.u16  = (PRUint16) gprData[iCount++];
                                     else
                                         dp->val.u16  = (PRUint16)  *ap++;
                                     break;
        case nsXPTType::T_U32     :  if (iCount < PARAM_GPR_COUNT)
                                         dp->val.u32  = (PRUint32) gprData[iCount++];
                                     else
                                         dp->val.u32  = (PRUint32)  *ap++;
                                     break;
        case nsXPTType::T_U64     :  if (iCount < PARAM_GPR_COUNT)
                                         ((DU *)dp)->hi  = (PRUint32) gprData[iCount++];
                                     else
                                         ((DU *)dp)->hi  = (PRUint32)  *ap++;
                                     if (iCount < PARAM_GPR_COUNT)
                                         ((DU *)dp)->lo  = (PRUint32) gprData[iCount++];
                                     else
                                         ((DU *)dp)->lo  = (PRUint32)  *ap++;
                                     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  = (bool) gprData[iCount++];
                                     else
                                         dp->val.b  = (bool)  *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_ERROR("bad type");
            break;
        }
    }

    result = self->mOuter->CallMethod((PRUint16)methodIndex,info,dispatchParams);

    if(dispatchParams != paramBuffer)
        delete [] dispatchParams;

    return result;
}