/* 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; }
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; }
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; }
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 ¶m = 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; }
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; }
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; }
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 }
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; }
/* 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; }