| Index: third_party/protobuf/src/google/protobuf/dynamic_message.cc
|
| ===================================================================
|
| --- third_party/protobuf/src/google/protobuf/dynamic_message.cc (revision 216642)
|
| +++ third_party/protobuf/src/google/protobuf/dynamic_message.cc (working copy)
|
| @@ -123,8 +123,10 @@
|
| case FD::CPPTYPE_FLOAT : return sizeof(float );
|
| case FD::CPPTYPE_BOOL : return sizeof(bool );
|
| case FD::CPPTYPE_ENUM : return sizeof(int );
|
| - case FD::CPPTYPE_MESSAGE: return sizeof(Message*);
|
|
|
| + case FD::CPPTYPE_MESSAGE:
|
| + return sizeof(Message*);
|
| +
|
| case FD::CPPTYPE_STRING:
|
| switch (field->options().ctype()) {
|
| default: // TODO(kenton): Support other string reps.
|
| @@ -178,7 +180,17 @@
|
| // important (the prototype must be deleted *before* the offsets).
|
| scoped_array<int> offsets;
|
| scoped_ptr<const GeneratedMessageReflection> reflection;
|
| - scoped_ptr<const DynamicMessage> prototype;
|
| + // Don't use a scoped_ptr to hold the prototype: the destructor for
|
| + // DynamicMessage needs to know whether it is the prototype, and does so by
|
| + // looking back at this field. This would assume details about the
|
| + // implementation of scoped_ptr.
|
| + const DynamicMessage* prototype;
|
| +
|
| + TypeInfo() : prototype(NULL) {}
|
| +
|
| + ~TypeInfo() {
|
| + delete prototype;
|
| + }
|
| };
|
|
|
| DynamicMessage(const TypeInfo* type_info);
|
| @@ -196,6 +208,14 @@
|
|
|
| Metadata GetMetadata() const;
|
|
|
| + // We actually allocate more memory than sizeof(*this) when this
|
| + // class's memory is allocated via the global operator new. Thus, we need to
|
| + // manually call the global operator delete. Calling the destructor is taken
|
| + // care of for us.
|
| + static void operator delete(void* ptr) {
|
| + ::operator delete(ptr);
|
| + }
|
| +
|
| private:
|
| GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DynamicMessage);
|
|
|
| @@ -368,11 +388,12 @@
|
| break;
|
| }
|
| }
|
| - } else if ((field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) &&
|
| - !is_prototype()) {
|
| - Message* message = *reinterpret_cast<Message**>(field_ptr);
|
| - if (message != NULL) {
|
| - delete message;
|
| + } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
|
| + if (!is_prototype()) {
|
| + Message* message = *reinterpret_cast<Message**>(field_ptr);
|
| + if (message != NULL) {
|
| + delete message;
|
| + }
|
| }
|
| }
|
| }
|
| @@ -403,7 +424,7 @@
|
| }
|
|
|
| Message* DynamicMessage::New() const {
|
| - void* new_base = reinterpret_cast<uint8*>(operator new(type_info_->size));
|
| + void* new_base = operator new(type_info_->size);
|
| memset(new_base, 0, type_info_->size);
|
| return new(new_base) DynamicMessage(type_info_);
|
| }
|
| @@ -465,7 +486,7 @@
|
| const DynamicMessage::TypeInfo** target = &prototypes_->map_[type];
|
| if (*target != NULL) {
|
| // Already exists.
|
| - return (*target)->prototype.get();
|
| + return (*target)->prototype;
|
| }
|
|
|
| DynamicMessage::TypeInfo* type_info = new DynamicMessage::TypeInfo;
|
| @@ -533,13 +554,13 @@
|
| void* base = operator new(size);
|
| memset(base, 0, size);
|
| DynamicMessage* prototype = new(base) DynamicMessage(type_info);
|
| - type_info->prototype.reset(prototype);
|
| + type_info->prototype = prototype;
|
|
|
| // Construct the reflection object.
|
| type_info->reflection.reset(
|
| new GeneratedMessageReflection(
|
| type_info->type,
|
| - type_info->prototype.get(),
|
| + type_info->prototype,
|
| type_info->offsets.get(),
|
| type_info->has_bits_offset,
|
| type_info->unknown_fields_offset,
|
|
|