aboutsummaryrefslogtreecommitdiffhomepage
path: root/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'ruby')
-rw-r--r--ruby/ext/google/protobuf_c/encode_decode.c23
-rw-r--r--ruby/tests/generated_code.rb70
2 files changed, 20 insertions, 73 deletions
diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c
index 0630f567..256fc829 100644
--- a/ruby/ext/google/protobuf_c/encode_decode.c
+++ b/ruby/ext/google/protobuf_c/encode_decode.c
@@ -208,7 +208,7 @@ typedef struct {
size_t ofs;
upb_fieldtype_t key_field_type;
upb_fieldtype_t value_field_type;
- VALUE value_field_typeclass;
+ const upb_def* value_field_subdef;
} map_handlerdata_t;
// Temporary frame for map parsing: at the beginning of a map entry message, a
@@ -248,8 +248,15 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
VALUE key = native_slot_get(
mapdata->key_field_type, Qnil,
&frame->key_storage);
+
+ VALUE value_field_typeclass = Qnil;
+ if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
+ mapdata->value_field_type == UPB_TYPE_ENUM) {
+ value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
+ }
+
VALUE value = native_slot_get(
- mapdata->value_field_type, mapdata->value_field_typeclass,
+ mapdata->value_field_type, value_field_typeclass,
&frame->value_storage);
Map_index_set(frame->map, key, value);
@@ -280,17 +287,7 @@ static map_handlerdata_t* new_map_handlerdata(
MAP_VALUE_FIELD);
assert(value_field != NULL);
hd->value_field_type = upb_fielddef_type(value_field);
- hd->value_field_typeclass = field_type_class(value_field);
-
- // Ensure that value_field_typeclass is properly GC-rooted. We must do this
- // because we hold a reference to the Ruby class in the handlerdata, which is
- // owned by the handlers. The handlers are owned by *this* message's Ruby
- // object, but each Ruby object is rooted independently at the def -> Ruby
- // object map. So we have to ensure that the Ruby objects we depend on will
- // stick around as long as we're around.
- if (hd->value_field_typeclass != Qnil) {
- rb_ary_push(desc->typeclass_references, hd->value_field_typeclass);
- }
+ hd->value_field_subdef = upb_fielddef_subdef(value_field);
return hd;
}
diff --git a/ruby/tests/generated_code.rb b/ruby/tests/generated_code.rb
index db762ad9..5a685433 100644
--- a/ruby/tests/generated_code.rb
+++ b/ruby/tests/generated_code.rb
@@ -27,16 +27,16 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
repeated :repeated_bytes, :string, 29
repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
- repeated :map_int32_string, :message, 61, "A.B.C.TestMessage.MapInt32StringEntry"
- repeated :map_int64_string, :message, 62, "A.B.C.TestMessage.MapInt64StringEntry"
- repeated :map_uint32_string, :message, 63, "A.B.C.TestMessage.MapUint32StringEntry"
- repeated :map_uint64_string, :message, 64, "A.B.C.TestMessage.MapUint64StringEntry"
- repeated :map_bool_string, :message, 65, "A.B.C.TestMessage.MapBoolStringEntry"
- repeated :map_string_string, :message, 66, "A.B.C.TestMessage.MapStringStringEntry"
- repeated :map_string_msg, :message, 67, "A.B.C.TestMessage.MapStringMsgEntry"
- repeated :map_string_enum, :message, 68, "A.B.C.TestMessage.MapStringEnumEntry"
- repeated :map_string_int32, :message, 69, "A.B.C.TestMessage.MapStringInt32Entry"
- repeated :map_string_bool, :message, 70, "A.B.C.TestMessage.MapStringBoolEntry"
+ map :map_int32_string, :int32, :string, 61
+ map :map_int64_string, :int64, :string, 62
+ map :map_uint32_string, :uint32, :string, 63
+ map :map_uint64_string, :uint64, :string, 64
+ map :map_bool_string, :bool, :string, 65
+ map :map_string_string, :string, :string, 66
+ map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
+ map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
+ map :map_string_int32, :string, :int32, 69
+ map :map_string_bool, :string, :bool, 70
optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
oneof :my_oneof do
optional :oneof_int32, :int32, 41
@@ -52,46 +52,6 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
end
end
- add_message "A.B.C.TestMessage.MapInt32StringEntry" do
- optional :key, :int32, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapInt64StringEntry" do
- optional :key, :int64, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapUint32StringEntry" do
- optional :key, :uint32, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapUint64StringEntry" do
- optional :key, :uint64, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapBoolStringEntry" do
- optional :key, :bool, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapStringStringEntry" do
- optional :key, :string, 1
- optional :value, :string, 2
- end
- add_message "A.B.C.TestMessage.MapStringMsgEntry" do
- optional :key, :string, 1
- optional :value, :message, 2, "A.B.C.TestMessage"
- end
- add_message "A.B.C.TestMessage.MapStringEnumEntry" do
- optional :key, :string, 1
- optional :value, :enum, 2, "A.B.C.TestEnum"
- end
- add_message "A.B.C.TestMessage.MapStringInt32Entry" do
- optional :key, :string, 1
- optional :value, :int32, 2
- end
- add_message "A.B.C.TestMessage.MapStringBoolEntry" do
- optional :key, :string, 1
- optional :value, :bool, 2
- end
add_message "A.B.C.TestMessage.NestedMessage" do
optional :foo, :int32, 1
end
@@ -107,16 +67,6 @@ module A
module B
module C
TestMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
- TestMessage::MapInt32StringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapInt32StringEntry").msgclass
- TestMessage::MapInt64StringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapInt64StringEntry").msgclass
- TestMessage::MapUint32StringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapUint32StringEntry").msgclass
- TestMessage::MapUint64StringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapUint64StringEntry").msgclass
- TestMessage::MapBoolStringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapBoolStringEntry").msgclass
- TestMessage::MapStringStringEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapStringStringEntry").msgclass
- TestMessage::MapStringMsgEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapStringMsgEntry").msgclass
- TestMessage::MapStringEnumEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapStringEnumEntry").msgclass
- TestMessage::MapStringInt32Entry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapStringInt32Entry").msgclass
- TestMessage::MapStringBoolEntry = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.MapStringBoolEntry").msgclass
TestMessage::NestedMessage = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
TestEnum = Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
end