Bug 1438688, part 1 - Add methods for accessing arrays in xpt_struct.h. r=njn
This lets us hide later changes to how these arrays are stored. There
should be no behavioral change. Some methods in xpt_struct.h are
declared inline at the end of the header due to the order that classes
are declared in the header.
MozReview-Commit-ID: KAxUKn3sDOD
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
@@ -24,24 +24,24 @@ xptiInterfaceEntry::Create(const XPTInte
return nullptr;
}
return new (place) xptiInterfaceEntry(aEntry, aTypelib);
}
xptiInterfaceEntry::xptiInterfaceEntry(const XPTInterfaceDirectoryEntry* aEntry,
xptiTypelibGuts* aTypelib)
: mIID(aEntry->mIID)
- , mDescriptor(aEntry->mInterfaceDescriptor)
+ , mDescriptor(aEntry->InterfaceDescriptor())
, mTypelib(aTypelib)
, mParent(nullptr)
, mInfo(nullptr)
, mMethodBaseIndex(0)
, mConstantBaseIndex(0)
, mFlags(0)
- , mName(aEntry->mName)
+ , mName(aEntry->Name())
{
SetResolvedState(PARTIALLY_RESOLVED);
SetScriptableFlag(mDescriptor->IsScriptable());
SetBuiltinClassFlag(mDescriptor->IsBuiltinClass());
SetMainProcessScriptableOnlyFlag(mDescriptor->IsMainProcessScriptableOnly());
}
bool
@@ -80,17 +80,17 @@ xptiInterfaceEntry::ResolveLocked()
}
mParent = parent;
if (parent->GetHasNotXPCOMFlag()) {
SetHasNotXPCOMFlag();
} else {
for (uint16_t idx = 0; idx < mDescriptor->mNumMethods; ++idx) {
const nsXPTMethodInfo* method = static_cast<const nsXPTMethodInfo*>(
- mDescriptor->mMethodDescriptors + idx);
+ &mDescriptor->Method(idx));
if (method->IsNotXPCOM()) {
SetHasNotXPCOMFlag();
break;
}
}
}
@@ -184,32 +184,32 @@ xptiInterfaceEntry::GetMethodInfo(uint16
{
NS_ERROR("bad param");
*info = nullptr;
return NS_ERROR_INVALID_ARG;
}
// else...
*info = static_cast<const nsXPTMethodInfo*>
- (&mDescriptor->mMethodDescriptors[index - mMethodBaseIndex]);
+ (&mDescriptor->Method(index - mMethodBaseIndex));
return NS_OK;
}
nsresult
xptiInterfaceEntry::GetMethodInfoForName(const char* methodName, uint16_t *index,
const nsXPTMethodInfo** result)
{
if(!EnsureResolved())
return NS_ERROR_UNEXPECTED;
// This is a slow algorithm, but this is not expected to be called much.
for(uint16_t i = 0; i < mDescriptor->mNumMethods; ++i)
{
const nsXPTMethodInfo* info;
- info = static_cast<const nsXPTMethodInfo*>(&mDescriptor->mMethodDescriptors[i]);
+ info = static_cast<const nsXPTMethodInfo*>(&mDescriptor->Method(i));
if (PL_strcmp(methodName, info->GetName()) == 0) {
*index = i + mMethodBaseIndex;
*result = info;
return NS_OK;
}
}
if(mParent)
@@ -234,17 +234,17 @@ xptiInterfaceEntry::GetConstant(uint16_t
if(index >= mConstantBaseIndex +
mDescriptor->mNumConstants)
{
NS_PRECONDITION(0, "bad param");
return NS_ERROR_INVALID_ARG;
}
- const auto& c = mDescriptor->mConstDescriptors[index - mConstantBaseIndex];
+ const auto& c = mDescriptor->Const(index - mConstantBaseIndex);
AutoJSContext cx;
JS::Rooted<JS::Value> v(cx);
v.setUndefined();
switch (c.mType.mPrefix.mFlags) {
case nsXPTType::T_I16:
{
v.setInt32(c.mValue.i16);
@@ -267,17 +267,17 @@ xptiInterfaceEntry::GetConstant(uint16_t
}
default:
{
MOZ_ASSERT(false, "Invalid constant type found in interface");
}
}
constant.set(v);
- *name = ToNewCString(nsDependentCString(c.mName));
+ *name = ToNewCString(nsDependentCString(c.Name()));
return NS_OK;
}
// this is a private helper
nsresult
xptiInterfaceEntry::GetInterfaceIndexForParam(uint16_t methodIndex,
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
@@ -129,26 +129,26 @@ XPTInterfaceInfoManager::RegisterXPTHead
VerifyAndAddEntryIfNew(aHeader->mInterfaceDirectory + k, k, typelib);
}
void
XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface,
uint16_t idx,
xptiTypelibGuts* typelib)
{
- if (!iface->mInterfaceDescriptor)
+ if (!iface->InterfaceDescriptor())
return;
// The number of maximum methods is not arbitrary. It is the same value as
// in xpcom/reflect/xptcall/genstubs.pl; do not change this value
// without changing that one or you WILL see problems.
- if (iface->mInterfaceDescriptor->mNumMethods > 250 &&
- !iface->mInterfaceDescriptor->IsBuiltinClass()) {
+ if (iface->InterfaceDescriptor()->mNumMethods > 250 &&
+ !iface->InterfaceDescriptor()->IsBuiltinClass()) {
NS_ASSERTION(0, "Too many methods to handle for the stub, cannot load");
- fprintf(stderr, "ignoring too large interface: %s\n", iface->mName);
+ fprintf(stderr, "ignoring too large interface: %s\n", iface->Name());
return;
}
mWorkingSet.mTableReentrantMonitor.AssertCurrentThreadIn();
xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->mIID);
if (entry) {
// XXX validate this info to find possible inconsistencies
return;
--- a/xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
+++ b/xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
@@ -47,17 +47,17 @@ xptiTypelibGuts::GetEntryAt(uint16_t i)
const XPTInterfaceDirectoryEntry* iface = mHeader->mInterfaceDirectory + i;
XPTInterfaceInfoManager::xptiWorkingSet& set =
XPTInterfaceInfoManager::GetSingleton()->mWorkingSet;
{
ReentrantMonitorAutoEnter monitor(set.mTableReentrantMonitor);
if (iface->mIID.Equals(zeroIID))
- r = set.mNameTable.Get(iface->mName);
+ r = set.mNameTable.Get(iface->Name());
else
r = set.mIIDTable.Get(iface->mIID);
}
if (r)
SetEntryAt(i, r);
return r;
@@ -66,10 +66,10 @@ xptiTypelibGuts::GetEntryAt(uint16_t i)
const char*
xptiTypelibGuts::GetEntryNameAt(uint16_t i)
{
NS_ASSERTION(mHeader, "bad state");
NS_ASSERTION(i < GetEntryCount(), "bad index");
const XPTInterfaceDirectoryEntry* iface = mHeader->mInterfaceDirectory + i;
- return iface->mName;
+ return iface->Name();
}
--- a/xpcom/reflect/xptinfo/xptinfo.h
+++ b/xpcom/reflect/xptinfo/xptinfo.h
@@ -189,21 +189,21 @@ public:
{*(XPTMethodDescriptor*)this = desc;}
bool IsGetter() const { return !!(mFlags & kGetterMask); }
bool IsSetter() const { return !!(mFlags & kSetterMask); }
bool IsNotXPCOM() const { return !!(mFlags & kNotXPCOMMask); }
bool IsHidden() const { return !!(mFlags & kHiddenMask); }
bool WantsOptArgc() const { return !!(mFlags & kOptArgcMask); }
bool WantsContext() const { return !!(mFlags & kContextMask); }
- const char* GetName() const { return mName; }
+ const char* GetName() const { return Name(); }
uint8_t GetParamCount() const { return mNumArgs; }
const nsXPTParamInfo GetParam(uint8_t idx) const {
MOZ_ASSERT(idx < GetParamCount(), "bad arg");
- return mParams[idx];
+ return Param(idx);
}
private:
static const uint8_t kGetterMask = 0x80;
static const uint8_t kSetterMask = 0x40;
static const uint8_t kNotXPCOMMask = 0x20;
static const uint8_t kHiddenMask = 0x08;
static const uint8_t kOptArgcMask = 0x04;
--- a/xpcom/typelib/xpt/xpt_struct.h
+++ b/xpcom/typelib/xpt/xpt_struct.h
@@ -67,16 +67,19 @@ struct XPTHeader {
/*
* A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
* the byte offset identified by the mInterfaceDirectory field in the file
* header. The array is used to quickly locate an interface description
* using its IID. No interface should appear more than once in the array.
*/
struct XPTInterfaceDirectoryEntry {
+ inline const XPTInterfaceDescriptor* InterfaceDescriptor() const;
+ inline const char* Name() const;
+
nsID mIID;
const char* mName;
// This field exists in the on-disk format. But it isn't used so we don't
// allocate space for it in memory.
//const char* mNameSpace;
const XPTInterfaceDescriptor* mInterfaceDescriptor;
@@ -92,16 +95,19 @@ struct XPTInterfaceDescriptor {
static const uint8_t kBuiltinClassMask = 0x20;
static const uint8_t kMainProcessScriptableOnlyMask = 0x10;
bool IsScriptable() const { return !!(mFlags & kScriptableMask); }
bool IsFunction() const { return !!(mFlags & kFunctionMask); }
bool IsBuiltinClass() const { return !!(mFlags & kBuiltinClassMask); }
bool IsMainProcessScriptableOnly() const { return !!(mFlags & kMainProcessScriptableOnlyMask); }
+ inline const XPTMethodDescriptor& Method(size_t aIndex) const;
+ inline const XPTConstDescriptor& Const(size_t aIndex) const;
+
/*
* This field ordering minimizes the size of this struct.
* The fields are serialized on disk in a different order.
* See DoInterfaceDescriptor().
*/
const XPTMethodDescriptor* mMethodDescriptors;
const XPTConstDescriptor* mConstDescriptors;
const XPTTypeDescriptor* mAdditionalTypes;
@@ -240,16 +246,20 @@ struct XPTTypeDescriptor {
union XPTConstValue {
int16_t i16;
uint16_t ui16;
int32_t i32;
uint32_t ui32;
}; /* varies according to type */
struct XPTConstDescriptor {
+ const char* Name() const {
+ return mName;
+ }
+
const char* mName;
XPTTypeDescriptor mType;
union XPTConstValue mValue;
};
/*
* A ParamDescriptor is a variable-size record used to describe either a
* single argument to a method or a method's result.
@@ -259,16 +269,43 @@ struct XPTParamDescriptor {
XPTTypeDescriptor mType;
};
/*
* A MethodDescriptor is a variable-size record used to describe a single
* interface method.
*/
struct XPTMethodDescriptor {
+ const char* Name() const {
+ return mName;
+ }
+ const XPTParamDescriptor& Param(uint8_t aIndex) const {
+ return mParams[aIndex];
+ }
+
const char* mName;
const XPTParamDescriptor* mParams;
//XPTParamDescriptor mResult; // Present on disk, omitted here.
uint8_t mFlags;
uint8_t mNumArgs;
};
+const char*
+XPTInterfaceDirectoryEntry::Name() const {
+ return mName;
+}
+
+const XPTInterfaceDescriptor*
+XPTInterfaceDirectoryEntry::InterfaceDescriptor() const {
+ return mInterfaceDescriptor;
+}
+
+const XPTMethodDescriptor&
+XPTInterfaceDescriptor::Method(size_t aIndex) const {
+ return mMethodDescriptors[aIndex];
+}
+
+const XPTConstDescriptor&
+XPTInterfaceDescriptor::Const(size_t aIndex) const {
+ return mConstDescriptors[aIndex];
+}
+
#endif /* xpt_struct_h */