Bug 1442363, part 7 - Constify XPTInterfaceDescriptor::additional_types. r=njn draft
authorAndrew McCreight <continuation@gmail.com>
Tue, 27 Feb 2018 15:50:41 -0800
changeset 764640 fef529d9cbb5cfc38707a146ef5de3f836d7c7e4
parent 764639 67af6ba0df0919f21b371c76e05bd65785825546
child 764641 de0a19898bf751b0f00775678e594ad68bac746a
push id101801
push userbmo:continuation@gmail.com
push dateWed, 07 Mar 2018 22:48:25 +0000
reviewersnjn
bugs1442363
milestone60.0a1
Bug 1442363, part 7 - Constify XPTInterfaceDescriptor::additional_types. r=njn 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