Bug 1442363, part 7 - Constify XPTInterfaceDescriptor::additional_types. draft
authorAndrew McCreight <continuation@gmail.com>
Tue, 27 Feb 2018 15:50:41 -0800
changeset 762234 fd427dcf84dfd98f6f1675c1e1403cc84207e5d2
parent 762233 cbb700837d8104d18e5c7f7ce84794b7620fe11f
child 762235 83525428fb47bf0abb76c9547fa738d7181f5225
push id101107
push userbmo:continuation@gmail.com
push dateThu, 01 Mar 2018 22:22:59 +0000
bugs1442363
milestone60.0a1
Bug 1442363, part 7 - Constify XPTInterfaceDescriptor::additional_types. The trick here is that we read in the element type before we expand the array, so that we can write it to the new array before it becomes constified. MozReview-Commit-ID: 2pbpNVZ3gPZ
xpcom/typelib/xpt/xpt_struct.cpp
xpcom/typelib/xpt/xpt_struct.h
--- a/xpcom/typelib/xpt/xpt_struct.cpp
+++ b/xpcom/typelib/xpt/xpt_struct.cpp
@@ -203,30 +203,34 @@ DoInterfaceDirectoryEntry(XPTArena *aren
         !DoInterfaceDescriptor(arena, cursor, &ide->interface_descriptor)) {
         return false;
     }
 
     return true;
 }
 
 static bool
-InterfaceDescriptorAddType(XPTArena *arena, XPTInterfaceDescriptor *id)
+InterfaceDescriptorAddType(XPTArena *arena,
+                           XPTInterfaceDescriptor *id,
+                           XPTTypeDescriptor *td)
 {
-    XPTTypeDescriptor *old = id->additional_types;
+    const XPTTypeDescriptor *old = id->additional_types;
     XPTTypeDescriptor *new_;
     size_t old_size = id->num_additional_types * sizeof(XPTTypeDescriptor);
     size_t new_size = old_size + sizeof(XPTTypeDescriptor);
 
     /* XXX should grow in chunks to minimize alloc overhead */
     new_ = static_cast<XPTTypeDescriptor*>(XPT_CALLOC8(arena, new_size));
     if (!new_)
         return false;
     if (old) {
         memcpy(new_, old, old_size);
     }
+
+    new_[id->num_additional_types] = *td;
     id->additional_types = new_;
 
     if (id->num_additional_types == UINT8_MAX)
         return false;
 
     id->num_additional_types += 1;
     return true;
 }
@@ -412,24 +416,23 @@ DoTypeDescriptor(XPTArena *arena, NotNul
         break;
       case TD_ARRAY: {
         // argnum2 appears in the on-disk format but it isn't used.
         uint8_t argnum2 = 0;
         if (!XPT_Do8(cursor, &td->u.array.argnum) ||
             !XPT_Do8(cursor, &argnum2))
             return false;
 
-        if (!InterfaceDescriptorAddType(arena, id))
+        XPTTypeDescriptor elementTypeDescriptor;
+        if (!DoTypeDescriptor(arena, cursor, &elementTypeDescriptor, id))
+            return false;
+        if (!InterfaceDescriptorAddType(arena, id, &elementTypeDescriptor))
             return false;
         td->u.array.additional_type = id->num_additional_types - 1;
 
-        if (!DoTypeDescriptor(arena, cursor,
-                              &id->additional_types[td->u.array.additional_type],
-                              id))
-            return false;
         break;
       }
       case TD_PSTRING_SIZE_IS:
       case TD_PWSTRING_SIZE_IS: {
         // argnum2 appears in the on-disk format but it isn't used.
         uint8_t argnum2 = 0;
         if (!XPT_Do8(cursor, &td->u.pstring_is.argnum) ||
             !XPT_Do8(cursor, &argnum2))
--- a/xpcom/typelib/xpt/xpt_struct.h
+++ b/xpcom/typelib/xpt/xpt_struct.h
@@ -98,17 +98,17 @@ struct XPTInterfaceDescriptor {
 
   /*
    * This field ordering minimizes the size of this struct.
    * The fields are serialized on disk in a different order.
    * See DoInterfaceDescriptor().
    */
   const XPTMethodDescriptor* method_descriptors;
   const XPTConstDescriptor* const_descriptors;
-  XPTTypeDescriptor* additional_types;
+  const XPTTypeDescriptor* additional_types;
   uint16_t parent_interface;
   uint16_t num_methods;
   uint16_t num_constants;
   uint8_t flags;
 
   /*
    * additional_types are used for arrays where we may need multiple
    * XPTTypeDescriptors for a single XPTMethodDescriptor. Since we still