Bug 1448454 - Make some fields in xpt_struct.h private. r=njn draft
authorAndrew McCreight <continuation@gmail.com>
Mon, 26 Mar 2018 14:06:01 -0700
changeset 777320 9aca4c648cdd8732a8b398eba200fa21283fded0
parent 777163 ff0efa4132f0efd78af0910762aec7dcc1a8de66
push id105170
push userbmo:continuation@gmail.com
push dateWed, 04 Apr 2018 16:44:09 +0000
reviewersnjn
bugs1448454
milestone61.0a1
Bug 1448454 - Make some fields in xpt_struct.h private. r=njn Many of these fields have accessors, and can only be read indirectly by going through the XPTHeader data structure anyways, so they should be marked private. This makes the generated XPT data file noisier due to the need for constexpr constructors. I had to fix the ctors for the classes in xptinfo.h to be less weird because there was a compiler error. Members in two of the classes need to be marked protected because they have subclasses in xptinfo.h. Ideally those classes would be merged in. MozReview-Commit-ID: 70IdFAhp5je
xpcom/reflect/xptinfo/xptinfo.h
xpcom/typelib/xpt/tools/xpt.py
xpcom/typelib/xpt/xpt_struct.h
--- a/xpcom/reflect/xptinfo/xptinfo.h
+++ b/xpcom/reflect/xptinfo/xptinfo.h
@@ -114,19 +114,19 @@ public:
     };
 // NO DATA - this a flyweight wrapper
 };
 
 class nsXPTParamInfo : public XPTParamDescriptor
 {
 // NO DATA - this a flyweight wrapper
 public:
-    MOZ_IMPLICIT nsXPTParamInfo(const XPTParamDescriptor& desc)
-        {*(XPTParamDescriptor*)this = desc;}
-
+    MOZ_IMPLICIT nsXPTParamInfo(const XPTParamDescriptor& aDesc)
+        : XPTParamDescriptor(aDesc)
+    {}
 
     bool IsIn() const {return !!(mFlags & kInMask);}
     bool IsOut() const {return !!(mFlags & kOutMask);}
     bool IsRetval() const {return !!(mFlags & kRetvalMask);}
     bool IsShared() const {return !!(mFlags & kSharedMask);}
 
     // Dipper types are one of the more inscrutable aspects of xpidl. In a
     // nutshell, dippers are empty container objects, created and passed by
@@ -180,18 +180,19 @@ private:
     nsXPTParamInfo() = delete;
 // NO DATA - this a flyweight wrapper
 };
 
 class nsXPTMethodInfo : public XPTMethodDescriptor
 {
 // NO DATA - this a flyweight wrapper
 public:
-    MOZ_IMPLICIT nsXPTMethodInfo(const XPTMethodDescriptor& desc)
-        {*(XPTMethodDescriptor*)this = desc;}
+    MOZ_IMPLICIT nsXPTMethodInfo(const XPTMethodDescriptor& aDesc)
+        : XPTMethodDescriptor(aDesc)
+    {}
 
     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 Name(); }
--- a/xpcom/typelib/xpt/tools/xpt.py
+++ b/xpcom/typelib/xpt/tools/xpt.py
@@ -431,17 +431,17 @@ class SimpleType(Type):
         if self.pointer:
             if self.reference:
                 s += " &"
             else:
                 s += " *"
         return s
 
     def code_gen(self, typelib, cd):
-        return "{%s, 0, 0}" % self.typeDescriptorPrefixString()
+        return "XPTTypeDescriptor(%s)" % self.typeDescriptorPrefixString()
 
 
 class InterfaceType(Type):
     """
     A type representing a pointer to an IDL-defined interface.
     (InterfaceTypeDescriptor from the typelib specification.)
 
     """
@@ -492,17 +492,17 @@ class InterfaceType(Type):
         Type.write(self, typelib, file)
         # write out the interface index (1-based)
         file.write(InterfaceType._descriptor.pack(typelib.interfaces.index(self.iface) + 1))
 
     def code_gen(self, typelib, cd):
         index = typelib.interfaces.index(self.iface) + 1
         hi = int(index / 256)
         lo = index - (hi * 256)
-        return "{%s, %d, %d}" % (self.typeDescriptorPrefixString(), hi, lo)
+        return "XPTTypeDescriptor(%s, %d, %d)" % (self.typeDescriptorPrefixString(), hi, lo)
 
     def __str__(self):
         if self.iface:
             return self.iface.name
         return "unknown interface"
 
 
 class InterfaceIsType(Type):
@@ -554,18 +554,18 @@ class InterfaceIsType(Type):
         Write an InterfaceIsTypeDescriptor to |file|, which is assumed
         to be seeked to the proper position.
 
         """
         Type.write(self, typelib, file)
         file.write(InterfaceIsType._descriptor.pack(self.param_index))
 
     def code_gen(self, typelib, cd):
-        return "{%s, %d, 0}" % (self.typeDescriptorPrefixString(),
-                                self.param_index)
+        return "XPTTypeDescriptor(%s, %d)" % (self.typeDescriptorPrefixString(),
+                                              self.param_index)
 
     def __str__(self):
         return "InterfaceIs *"
 
 
 class ArrayType(Type):
     """
     A type representing an Array of elements of another type, whose
@@ -619,19 +619,19 @@ class ArrayType(Type):
         """
         Type.write(self, typelib, file)
         file.write(ArrayType._descriptor.pack(self.size_is_arg_num,
                                               self.length_is_arg_num))
         self.element_type.write(typelib, file)
 
     def code_gen(self, typelib, cd):
         element_type_index = cd.add_type(self.element_type.code_gen(typelib, cd))
-        return "{%s, %d, %d}" % (self.typeDescriptorPrefixString(),
-                                 self.size_is_arg_num,
-                                 element_type_index)
+        return "XPTTypeDescriptor(%s, %d, %d)" % (self.typeDescriptorPrefixString(),
+                                                  self.size_is_arg_num,
+                                                  element_type_index)
 
     def __str__(self):
         return "%s []" % str(self.element_type)
 
 
 class StringWithSizeType(Type):
     """
     A type representing a UTF-8 encoded string whose size and length
@@ -680,18 +680,18 @@ class StringWithSizeType(Type):
         to be seeked to the proper position.
 
         """
         Type.write(self, typelib, file)
         file.write(StringWithSizeType._descriptor.pack(self.size_is_arg_num,
                                                        self.length_is_arg_num))
 
     def code_gen(self, typelib, cd):
-        return "{%s, %d, 0}" % (self.typeDescriptorPrefixString(),
-                                self.size_is_arg_num)
+        return "XPTTypeDescriptor(%s, %d)" % (self.typeDescriptorPrefixString(),
+                                              self.size_is_arg_num)
 
     def __str__(self):
         return "string_s"
 
 
 class WideStringWithSizeType(Type):
     """
     A type representing a UTF-16 encoded string whose size and length
@@ -740,18 +740,18 @@ class WideStringWithSizeType(Type):
         to be seeked to the proper position.
 
         """
         Type.write(self, typelib, file)
         file.write(WideStringWithSizeType._descriptor.pack(self.size_is_arg_num,
                                                            self.length_is_arg_num))
 
     def code_gen(self, typelib, cd):
-        return "{%s, %d, 0}" % (self.typeDescriptorPrefixString(),
-                                self.size_is_arg_num)
+        return "XPTTypeDescriptor(%s, %d)" % (self.typeDescriptorPrefixString(),
+                                              self.size_is_arg_num)
 
     def __str__(self):
         return "wstring_s"
 
 
 class CachedStringWriter(object):
     """
     A cache that sits in front of a file to avoid adding the same
@@ -872,17 +872,17 @@ class Param(object):
         Write a ParamDescriptor to |file|, which is assumed to be seeked
         to the correct position.
 
         """
         file.write(Param._descriptorstart.pack(self.encodeflags()))
         self.type.write(typelib, file)
 
     def code_gen(self, typelib, cd):
-        return "{0x%x, %s}" % (self.encodeflags(), self.type.code_gen(typelib, cd))
+        return "XPTParamDescriptor(0x%x, %s)" % (self.encodeflags(), self.type.code_gen(typelib, cd))
 
     def prefix(self):
         """
         Return a human-readable string representing the flags set
         on this Param.
 
         """
         s = ""
@@ -1065,20 +1065,20 @@ class Method(object):
             string_index = 0
             param_index = 0
             num_params = 0
         else:
             string_index = cd.add_string(self.name)
             param_index = cd.add_params([p.code_gen(typelib, cd) for p in self.params])
             num_params = len(self.params)
 
-        return "{%d, %d, 0x%x, %d}" % (string_index,
-                                       param_index,
-                                       self.encodeflags(),
-                                       num_params)
+        return "XPTMethodDescriptor(%d, %d, 0x%x, %d)" % (string_index,
+                                                          param_index,
+                                                          self.encodeflags(),
+                                                          num_params)
 
 class Constant(object):
     """
     A constant value of a specific type defined on an interface.
     (ConstantDescriptor from the typelib specification.)
 
     """
     _descriptorstart = struct.Struct(">I")
@@ -1148,20 +1148,20 @@ class Constant(object):
 
         """
         self._name_offset = string_writer.write(self.name)
 
     def code_gen(self, typelib, cd):
         string_index = cd.add_string(self.name)
 
         # The static cast is needed for disambiguation.
-        return "{%d, %s, XPTConstValue(static_cast<%s>(%d))}" % (string_index,
-                                                                 self.type.code_gen(typelib, cd),
-                                                                 Constant.memberTypeMap[self.type.tag],
-                                                                 self.value)
+        return "XPTConstDescriptor(%d, %s, XPTConstValue(static_cast<%s>(%d)))" % (string_index,
+                                                                                   self.type.code_gen(typelib, cd),
+                                                                                   Constant.memberTypeMap[self.type.tag],
+                                                                                   self.value)
 
     def __repr__(self):
         return "Constant(%s, %s, %d)" % (self.name, str(self.type), self.value)
 
 
 class Interface(object):
     """
     An Interface represents an object, with its associated methods
@@ -1366,17 +1366,17 @@ class Interface(object):
         else:
             # Unresolved interfaces only have their name and IID set to non-zero values.
             methods_index = 0
             constants_index = 0
             assert len(self.methods) == 0
             assert len(self.constants) == 0
             assert self.encodeflags() == 0
 
-        return "{%s, %s, %d, %d, %d, %d, %d, 0x%x} /* %s */" % (
+        return "XPTInterfaceDescriptor(%s, %s, %d, %d, %d, %d, %d, 0x%x) /* %s */" % (
             iid,
             string_index,
             methods_index,
             constants_index,
             parent_idx,
             len(self.methods),
             len(self.constants),
             self.encodeflags(),
--- a/xpcom/typelib/xpt/xpt_struct.h
+++ b/xpcom/typelib/xpt/xpt_struct.h
@@ -19,33 +19,58 @@
 struct XPTInterfaceDescriptor;
 struct XPTConstDescriptor;
 struct XPTMethodDescriptor;
 struct XPTParamDescriptor;
 struct XPTTypeDescriptor;
 struct XPTTypeDescriptorPrefix;
 
 struct XPTHeader {
+  friend struct XPTInterfaceDescriptor;
+  friend struct XPTConstDescriptor;
+  friend struct XPTMethodDescriptor;
+  friend struct XPTTypeDescriptor;
+
   static const uint16_t kNumInterfaces;
   static const XPTInterfaceDescriptor kInterfaces[];
+
+private:
   static const XPTTypeDescriptor kTypes[];
   static const XPTParamDescriptor kParams[];
   static const XPTMethodDescriptor kMethods[];
   static const XPTConstDescriptor kConsts[];
 
   // All of the strings for this header, including their null
   // terminators, concatenated into a single string.
   static const char kStrings[];
 };
 
 /*
  * An InterfaceDescriptor describes a single XPCOM interface, including all of
  * its methods.
  */
 struct XPTInterfaceDescriptor {
+  constexpr XPTInterfaceDescriptor(nsID aIID,
+                                   uint32_t aName,
+                                   uint16_t aMethodDescriptors,
+                                   uint16_t aConstDescriptors,
+                                   uint16_t aParentInterface,
+                                   uint16_t aNumMethods,
+                                   uint16_t aNumConstants,
+                                   uint8_t aFlags)
+    : mIID(aIID)
+    , mName(aName)
+    , mMethodDescriptors(aMethodDescriptors)
+    , mConstDescriptors(aConstDescriptors)
+    , mParentInterface(aParentInterface)
+    , mNumMethods(aNumMethods)
+    , mNumConstants(aNumConstants)
+    , mFlags(aFlags)
+  {}
+
   static const uint8_t kScriptableMask =                0x80;
   static const uint8_t kFunctionMask =                  0x40;
   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); }
@@ -54,22 +79,28 @@ struct XPTInterfaceDescriptor {
   inline const char* Name() const;
   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.
    */
   nsID mIID;
+
+private:
   uint32_t mName; // Index into XPTHeader::mStrings.
   uint16_t mMethodDescriptors; // Index into XPTHeader::mMethods.
   uint16_t mConstDescriptors; // Index into XPTHeader::mConsts.
+
+public:
   uint16_t mParentInterface;
   uint16_t mNumMethods;
   uint16_t mNumConstants;
+
+private:
   uint8_t mFlags;
 };
 
 /*
  * A TypeDescriptor is a union used to identify the type of a method
  * argument or return value.
  *
  * There are three types of TypeDescriptors:
@@ -124,16 +155,24 @@ enum XPTTypeDescriptorTags {
   TD_PWSTRING_SIZE_IS  = 22,
   TD_UTF8STRING        = 23,
   TD_CSTRING           = 24,
   TD_ASTRING           = 25,
   TD_JSVAL             = 26
 };
 
 struct XPTTypeDescriptor {
+  explicit constexpr XPTTypeDescriptor(XPTTypeDescriptorPrefix aPrefix,
+                                       uint8_t aData1 = 0,
+                                       uint8_t aData2 = 0)
+    : mPrefix(aPrefix)
+    , mData1(aData1)
+    , mData2(aData2)
+  {}
+
   uint8_t Tag() const {
     return mPrefix.TagPart();
   }
 
   uint8_t ArgNum() const {
     MOZ_ASSERT(Tag() == TD_INTERFACE_IS_TYPE ||
                Tag() == TD_PSTRING_SIZE_IS ||
                Tag() == TD_PWSTRING_SIZE_IS ||
@@ -151,16 +190,17 @@ struct XPTTypeDescriptor {
   // reduces its size and also the size of XPTParamDescriptor.
   uint16_t InterfaceIndex() const {
     MOZ_ASSERT(Tag() == TD_INTERFACE_TYPE);
     return (mData1 << 8) | mData2;
   }
 
   XPTTypeDescriptorPrefix mPrefix;
 
+private:
   // The data for the different variants is stored in these two data fields.
   // These should only be accessed via the getter methods above, which will
   // assert if the tag is invalid. The memory layout here doesn't exactly match
   // the on-disk format. This is to save memory. Some fields for some cases are
   // smaller than they are on disk or omitted entirely.
   uint8_t mData1;
   uint8_t mData2;
 };
@@ -185,47 +225,80 @@ union XPTConstValue {
   // is run at startup, to enable sharing of this memory between Firefox processes.
   explicit constexpr XPTConstValue(int16_t aInt) : i16(aInt) {}
   explicit constexpr XPTConstValue(uint16_t aInt) : ui16(aInt) {}
   explicit constexpr XPTConstValue(int32_t aInt) : i32(aInt) {}
   explicit constexpr XPTConstValue(uint32_t aInt) : ui32(aInt) {}
 };
 
 struct XPTConstDescriptor {
+  constexpr XPTConstDescriptor(uint32_t aName,
+                               const XPTTypeDescriptor& aType,
+                               const XPTConstValue& aValue)
+    : mName(aName)
+    , mType(aType)
+    , mValue(aValue)
+  {}
+
   const char* Name() const {
     return &XPTHeader::kStrings[mName];
   }
 
+private:
   uint32_t mName; // Index into XPTHeader::mStrings.
+
+public:
   XPTTypeDescriptor mType;
   XPTConstValue mValue;
 };
 
 /*
  * A ParamDescriptor is used to describe either a single argument to a method or
  * a method's result.
  */
 struct XPTParamDescriptor {
+  constexpr XPTParamDescriptor(uint8_t aFlags,
+                               const XPTTypeDescriptor& aType)
+    : mFlags(aFlags)
+    , mType(aType)
+  {}
+
+protected:
   uint8_t mFlags;
+
+public:
   XPTTypeDescriptor mType;
 };
 
 /*
  * A MethodDescriptor is used to describe a single interface method.
  */
 struct XPTMethodDescriptor {
+  constexpr XPTMethodDescriptor(uint32_t aName,
+                                uint32_t aParams,
+                                uint8_t aFlags,
+                                uint8_t aNumArgs)
+    : mName(aName)
+    , mParams(aParams)
+    , mFlags(aFlags)
+    , mNumArgs(aNumArgs)
+  {}
+
   const char* Name() const {
     return &XPTHeader::kStrings[mName];
   }
   const XPTParamDescriptor& Param(uint8_t aIndex) const {
     return XPTHeader::kParams[mParams + aIndex];
   }
 
+private:
   uint32_t mName; // Index into XPTHeader::mStrings.
   uint32_t mParams; // Index into XPTHeader::mParams.
+
+protected:
   uint8_t mFlags;
   uint8_t mNumArgs;
 };
 
 const char*
 XPTInterfaceDescriptor::Name() const {
   return &XPTHeader::kStrings[mName];
 }