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
--- 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