Bug 1315638: Modify MainThreadHandoff::FixArrayElements to be able to distinguish between outparams with different levels of indirection; r=jimm

MozReview-Commit-ID: HZgED9JT16m

--HG--
extra : rebase_source : 3b147251d55229aa5722d9f9ec6a9ad832a83c87
This commit is contained in:
Aaron Klotz 2016-11-07 16:04:06 -07:00
parent f3ebe78061
commit 31db1f008a
3 changed files with 33 additions and 9 deletions

View File

@ -28,10 +28,14 @@ static const mozilla::mscom::ArrayData sPlatformChildArrayData[] = {
{IID_IEnumVARIANT, 3, 1, VT_DISPATCH, IID_IDispatch, 2},
{IID_IAccessible2, 30, 1, VT_UNKNOWN | VT_BYREF, IID_IAccessibleRelation, 2},
{IID_IAccessibleRelation, 7, 1, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 2},
{IID_IAccessible2_2, 48, 2, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 3},
{IID_IAccessibleTableCell, 4, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1},
{IID_IAccessibleTableCell, 7, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1},
{IID_IAccessibleHypertext2, 25, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1}
{IID_IAccessible2_2, 48, 2, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 3,
mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
{IID_IAccessibleTableCell, 4, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
{IID_IAccessibleTableCell, 7, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
mozilla::mscom::ArrayData::Flag::eAllocatedByServer},
{IID_IAccessibleHypertext2, 25, 0, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 1,
mozilla::mscom::ArrayData::Flag::eAllocatedByServer}
};
// Type libraries are thread-neutral, so we can register those from any

View File

@ -256,10 +256,18 @@ MainThreadHandoff::FixArrayElements(ICallFrame* aFrame,
return hr;
}
PVOID stackBase = aFrame->GetStackLocation();
// We dereference because we need to obtain the value of a parameter
// from a stack offset. This pointer is the base of the array.
arrayPtr = *reinterpret_cast<PVOID*>(reinterpret_cast<PBYTE>(stackBase) +
paramInfo.stackOffset);
if (aArrayData.mFlag == ArrayData::Flag::eAllocatedByServer) {
// In order for the server to allocate the array's buffer and store it in
// an outparam, the parameter must be typed as Type***. Since the base
// of the array is Type*, we must dereference twice.
arrayPtr = **reinterpret_cast<PVOID**>(reinterpret_cast<PBYTE>(stackBase) +
paramInfo.stackOffset);
} else {
// We dereference because we need to obtain the value of a parameter
// from a stack offset. This pointer is the base of the array.
arrayPtr = *reinterpret_cast<PVOID*>(reinterpret_cast<PBYTE>(stackBase) +
paramInfo.stackOffset);
}
} else if (FAILED(hr)) {
return hr;
} else {

View File

@ -81,21 +81,30 @@ UniquePtr<RegisteredProxy> RegisterTypelib(const wchar_t* aLeafName,
*/
struct ArrayData
{
enum class Flag
{
eNone = 0,
eAllocatedByServer = 1 // This implies an extra level of indirection
};
ArrayData(REFIID aIid, ULONG aMethodIndex, ULONG aArrayParamIndex,
VARTYPE aArrayParamType, REFIID aArrayParamIid,
ULONG aLengthParamIndex)
ULONG aLengthParamIndex, Flag aFlag = Flag::eNone)
: mIid(aIid)
, mMethodIndex(aMethodIndex)
, mArrayParamIndex(aArrayParamIndex)
, mArrayParamType(aArrayParamType)
, mArrayParamIid(aArrayParamIid)
, mLengthParamIndex(aLengthParamIndex)
, mFlag(aFlag)
{
}
ArrayData(const ArrayData& aOther)
{
*this = aOther;
}
ArrayData& operator=(const ArrayData& aOther)
{
mIid = aOther.mIid;
@ -104,14 +113,17 @@ struct ArrayData
mArrayParamType = aOther.mArrayParamType;
mArrayParamIid = aOther.mArrayParamIid;
mLengthParamIndex = aOther.mLengthParamIndex;
mFlag = aOther.mFlag;
return *this;
}
IID mIid;
ULONG mMethodIndex;
ULONG mArrayParamIndex;
VARTYPE mArrayParamType;
IID mArrayParamIid;
ULONG mLengthParamIndex;
Flag mFlag;
};
void RegisterArrayData(const ArrayData* aArrayData, size_t aLength);