From c02a6fbf2c2af8e82d917af6afc7ac4e4f73d9e2 Mon Sep 17 00:00:00 2001 From: Joshua Haberman <jhaberman@gmail.com> Date: Fri, 16 Aug 2019 09:37:36 -0700 Subject: [PATCH] Bugfix for GC mark of oneof fields. --- ruby/ext/google/protobuf_c/encode_decode.c | 3 +++ ruby/ext/google/protobuf_c/protobuf.h | 1 + ruby/ext/google/protobuf_c/storage.c | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ruby/ext/google/protobuf_c/encode_decode.c b/ruby/ext/google/protobuf_c/encode_decode.c index f4d3de2543..ad3d554706 100644 --- a/ruby/ext/google/protobuf_c/encode_decode.c +++ b/ruby/ext/google/protobuf_c/encode_decode.c @@ -155,6 +155,9 @@ static const void *newoneofhandlerdata(upb_handlers *h, // create a separate ID space. In addition, using the field tag number here // lets us easily look up the field in the oneof accessor. hd->oneof_case_num = upb_fielddef_number(f); + if (is_value_field(f)) { + hd->oneof_case_num |= ONEOF_CASE_MASK; + } hd->subklass = field_type_class(desc->layout, f); upb_handlers_addcleanup(h, hd, xfree); return hd; diff --git a/ruby/ext/google/protobuf_c/protobuf.h b/ruby/ext/google/protobuf_c/protobuf.h index 0925185e54..b8aed5a47f 100644 --- a/ruby/ext/google/protobuf_c/protobuf.h +++ b/ruby/ext/google/protobuf_c/protobuf.h @@ -370,6 +370,7 @@ VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value); void native_slot_check_int_range_precision(const char* name, upb_fieldtype_t type, VALUE value); uint32_t slot_read_oneof_case(MessageLayout* layout, const void* storage, const upb_oneofdef* oneof); +bool is_value_field(const upb_fielddef* f); extern rb_encoding* kRubyStringUtf8Encoding; extern rb_encoding* kRubyStringASCIIEncoding; diff --git a/ruby/ext/google/protobuf_c/storage.c b/ruby/ext/google/protobuf_c/storage.c index 25628ed0fe..e72fa10df4 100644 --- a/ruby/ext/google/protobuf_c/storage.c +++ b/ruby/ext/google/protobuf_c/storage.c @@ -473,7 +473,7 @@ static size_t align_up_to(size_t offset, size_t granularity) { return (offset + granularity - 1) & ~(granularity - 1); } -static bool is_value_field(const upb_fielddef* f) { +bool is_value_field(const upb_fielddef* f) { return upb_fielddef_isseq(f) || upb_fielddef_issubmsg(f) || upb_fielddef_isstring(f); }