Bug 683802 - Factor dipper handling out into a helper method. r=mrbkap

This commit is contained in:
Bobby Holley 2011-09-23 14:50:28 -07:00
Родитель 66ee33a251
Коммит 4080f17de7
1 изменённых файлов: 69 добавлений и 27 удалений

Просмотреть файл

@ -2240,6 +2240,9 @@ class CallMethodHelper
JS_ALWAYS_INLINE JSBool ConvertIndependentParam(uint8 i); JS_ALWAYS_INLINE JSBool ConvertIndependentParam(uint8 i);
JS_ALWAYS_INLINE JSBool ConvertDependentParams(); JS_ALWAYS_INLINE JSBool ConvertDependentParams();
JS_ALWAYS_INLINE JSBool HandleDipperParam(nsXPTCVariant* dp,
const nsXPTParamInfo& paramInfo);
JS_ALWAYS_INLINE nsresult Invoke(); JS_ALWAYS_INLINE nsresult Invoke();
public: public:
@ -2823,6 +2826,10 @@ CallMethodHelper::ConvertIndependentParam(uint8 i)
nsXPTCVariant* dp = GetDispatchParam(i); nsXPTCVariant* dp = GetDispatchParam(i);
dp->type = type; dp->type = type;
// Handle dipper types separately.
if(paramInfo.IsDipper())
return HandleDipperParam(dp, paramInfo);
if(type_tag == nsXPTType::T_INTERFACE) if(type_tag == nsXPTType::T_INTERFACE)
{ {
dp->SetValIsInterface(); dp->SetValIsInterface();
@ -2878,21 +2885,6 @@ CallMethodHelper::ConvertIndependentParam(uint8 i)
// Fall through to the T_DOMSTRING case // Fall through to the T_DOMSTRING case
case nsXPTType::T_DOMSTRING: case nsXPTType::T_DOMSTRING:
if(paramInfo.IsDipper())
{
// Is an 'out' DOMString. Make a new nsAString
// now and then continue in order to skip the call to
// JSData2Native
dp->SetValIsDOMString();
if(!(dp->val.p = new nsAutoString()))
{
JS_ReportOutOfMemory(mCallContext);
return JS_FALSE;
}
return JS_TRUE;
}
// else...
// Is an 'in' DOMString. Set 'useAllocator' to indicate // Is an 'in' DOMString. Set 'useAllocator' to indicate
// that JSData2Native should allocate a new // that JSData2Native should allocate a new
@ -2905,18 +2897,6 @@ CallMethodHelper::ConvertIndependentParam(uint8 i)
// Fall through to the C string case for now... // Fall through to the C string case for now...
case nsXPTType::T_CSTRING: case nsXPTType::T_CSTRING:
dp->SetValIsCString(); dp->SetValIsCString();
if(paramInfo.IsDipper())
{
// Is an 'out' CString.
if(!(dp->val.p = new nsCString()))
{
JS_ReportOutOfMemory(mCallContext);
return JS_FALSE;
}
return JS_TRUE;
}
// else ...
// Is an 'in' CString.
useAllocator = JS_TRUE; useAllocator = JS_TRUE;
break; break;
} }
@ -3099,6 +3079,68 @@ CallMethodHelper::ConvertDependentParams()
return JS_TRUE; return JS_TRUE;
} }
// Handle parameters with dipper types.
//
// Dipper types are one of the more inscrutable aspects of xpidl. In a
// nutshell, dippers are empty container objects, created and passed by
// the caller, and filled by the callee. The callee receives a
// fully-formed object, and thus does not have to construct anything. But
// the object is functionally empty, and the callee is responsible for
// putting something useful inside of it.
//
// XPIDL decides which types to make dippers. The list of these types
// is given in the isDipperType() function in typelib.py, and is currently
// limited to 4 string types.
//
// When a dipper type is declared as an 'out' parameter, xpidl internally
// converts it to an 'in', and sets the XPT_PD_DIPPER flag on it. For this
// reason, dipper types are sometimes referred to as 'out parameters
// masquerading as in'. The burden of maintaining this illusion falls mostly
// on XPConnect - we create the empty containers, and harvest the results
// after the call.
//
// This method creates these empty containers.
JSBool
CallMethodHelper::HandleDipperParam(nsXPTCVariant* dp,
const nsXPTParamInfo& paramInfo)
{
// Get something we can make comparisons with.
uint8 type_tag = paramInfo.GetType().TagPart();
// Dippers always have the 'in' and 'dipper' flags set. Never 'out'.
NS_ABORT_IF_FALSE(!paramInfo.IsOut(), "Dipper has unexpected flags.");
// xpidl.h specifies that dipper types will be used in exactly four
// cases, all strings. Verify that here.
NS_ABORT_IF_FALSE(type_tag == nsXPTType::T_ASTRING ||
type_tag == nsXPTType::T_DOMSTRING ||
type_tag == nsXPTType::T_UTF8STRING ||
type_tag == nsXPTType::T_CSTRING,
"Unexpected dipper type!");
// ASTRING and DOMSTRING are very similar, and both use nsAutoString.
// UTF8_STRING and CSTRING are also quite similar, and both use nsCString.
if(type_tag == nsXPTType::T_ASTRING || type_tag == nsXPTType::T_DOMSTRING)
{
dp->SetValIsDOMString();
dp->val.p = new nsAutoString();
}
else
{
dp->SetValIsCString();
dp->val.p = new nsCString();
}
// Check for OOM, in either case.
if(!dp->val.p)
{
JS_ReportOutOfMemory(mCallContext);
return JS_FALSE;
}
return JS_TRUE;
}
nsresult nsresult
CallMethodHelper::Invoke() CallMethodHelper::Invoke()
{ {