Bug 1438688, part 1 - Add methods for accessing arrays in xpt_struct.h. r=njn
☠☠ backed out by 70400746eb53 ☠ ☠
authorAndrew McCreight <continuation@gmail.com>
Wed, 28 Feb 2018 10:07:45 -0800
changeset 776467 08b1a5f904e447b46dd1f93551f01f8f10c87239
parent 776466 05b85c67123d3bdfb4a6c5186b05083e468e44c7
child 776468 186f916dcc7aabfea7981702c47c666338fcf869
push id104888
push userbmo:emilio@crisal.io
push dateTue, 03 Apr 2018 07:00:14 +0000
reviewersnjn
bugs1438688
milestone61.0a1
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
xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/xptinfo.h
xpcom/typelib/xpt/xpt_struct.h
--- 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 */