google-protobuf 3.11.0 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of google-protobuf might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +96 -8
- data/ext/google/protobuf_c/encode_decode.c +74 -37
- data/ext/google/protobuf_c/extconf.rb +0 -0
- data/ext/google/protobuf_c/map.c +20 -46
- data/ext/google/protobuf_c/message.c +20 -11
- data/ext/google/protobuf_c/protobuf.h +1 -0
- data/ext/google/protobuf_c/storage.c +72 -23
- data/ext/google/protobuf_c/upb.c +1810 -1282
- data/ext/google/protobuf_c/upb.h +1031 -1339
- data/lib/google/protobuf/well_known_types.rb +0 -0
- data/tests/basic.rb +146 -48
- data/tests/generated_code_test.rb +0 -0
- data/tests/stress.rb +0 -0
- metadata +16 -10
File without changes
|
data/ext/google/protobuf_c/map.c
CHANGED
@@ -100,11 +100,11 @@ static VALUE table_key(Map* self, VALUE key,
|
|
100
100
|
return key;
|
101
101
|
}
|
102
102
|
|
103
|
-
static VALUE table_key_to_ruby(Map* self,
|
103
|
+
static VALUE table_key_to_ruby(Map* self, upb_strview key) {
|
104
104
|
switch (self->key_type) {
|
105
105
|
case UPB_TYPE_BYTES:
|
106
106
|
case UPB_TYPE_STRING: {
|
107
|
-
VALUE ret = rb_str_new(
|
107
|
+
VALUE ret = rb_str_new(key.data, key.size);
|
108
108
|
rb_enc_associate(ret,
|
109
109
|
(self->key_type == UPB_TYPE_BYTES) ?
|
110
110
|
kRubyString8bitEncoding : kRubyStringUtf8Encoding);
|
@@ -116,7 +116,7 @@ static VALUE table_key_to_ruby(Map* self, const char* buf, size_t length) {
|
|
116
116
|
case UPB_TYPE_INT64:
|
117
117
|
case UPB_TYPE_UINT32:
|
118
118
|
case UPB_TYPE_UINT64:
|
119
|
-
return native_slot_get(self->key_type, Qnil,
|
119
|
+
return native_slot_get(self->key_type, Qnil, key.data);
|
120
120
|
|
121
121
|
default:
|
122
122
|
assert(false);
|
@@ -289,9 +289,7 @@ VALUE Map_each(VALUE _self) {
|
|
289
289
|
for (upb_strtable_begin(&it, &self->table);
|
290
290
|
!upb_strtable_done(&it);
|
291
291
|
upb_strtable_next(&it)) {
|
292
|
-
|
293
|
-
VALUE key = table_key_to_ruby(
|
294
|
-
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
292
|
+
VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it));
|
295
293
|
|
296
294
|
upb_value v = upb_strtable_iter_value(&it);
|
297
295
|
void* mem = value_memory(&v);
|
@@ -319,9 +317,7 @@ VALUE Map_keys(VALUE _self) {
|
|
319
317
|
for (upb_strtable_begin(&it, &self->table);
|
320
318
|
!upb_strtable_done(&it);
|
321
319
|
upb_strtable_next(&it)) {
|
322
|
-
|
323
|
-
VALUE key = table_key_to_ruby(
|
324
|
-
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
320
|
+
VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it));
|
325
321
|
|
326
322
|
rb_ary_push(ret, key);
|
327
323
|
}
|
@@ -526,17 +522,14 @@ VALUE Map_dup(VALUE _self) {
|
|
526
522
|
for (upb_strtable_begin(&it, &self->table);
|
527
523
|
!upb_strtable_done(&it);
|
528
524
|
upb_strtable_next(&it)) {
|
529
|
-
|
525
|
+
upb_strview k = upb_strtable_iter_key(&it);
|
530
526
|
upb_value v = upb_strtable_iter_value(&it);
|
531
527
|
void* mem = value_memory(&v);
|
532
528
|
upb_value dup;
|
533
529
|
void* dup_mem = value_memory(&dup);
|
534
530
|
native_slot_dup(self->value_type, dup_mem, mem);
|
535
531
|
|
536
|
-
if (!upb_strtable_insert2(&new_self->table,
|
537
|
-
upb_strtable_iter_key(&it),
|
538
|
-
upb_strtable_iter_keylength(&it),
|
539
|
-
dup)) {
|
532
|
+
if (!upb_strtable_insert2(&new_self->table, k.data, k.size, dup)) {
|
540
533
|
rb_raise(rb_eRuntimeError, "Error inserting value into new table");
|
541
534
|
}
|
542
535
|
}
|
@@ -554,7 +547,7 @@ VALUE Map_deep_copy(VALUE _self) {
|
|
554
547
|
for (upb_strtable_begin(&it, &self->table);
|
555
548
|
!upb_strtable_done(&it);
|
556
549
|
upb_strtable_next(&it)) {
|
557
|
-
|
550
|
+
upb_strview k = upb_strtable_iter_key(&it);
|
558
551
|
upb_value v = upb_strtable_iter_value(&it);
|
559
552
|
void* mem = value_memory(&v);
|
560
553
|
upb_value dup;
|
@@ -562,10 +555,7 @@ VALUE Map_deep_copy(VALUE _self) {
|
|
562
555
|
native_slot_deep_copy(self->value_type, self->value_type_class, dup_mem,
|
563
556
|
mem);
|
564
557
|
|
565
|
-
if (!upb_strtable_insert2(&new_self->table,
|
566
|
-
upb_strtable_iter_key(&it),
|
567
|
-
upb_strtable_iter_keylength(&it),
|
568
|
-
dup)) {
|
558
|
+
if (!upb_strtable_insert2(&new_self->table, k.data, k.size, dup)) {
|
569
559
|
rb_raise(rb_eRuntimeError, "Error inserting value into new table");
|
570
560
|
}
|
571
561
|
}
|
@@ -618,16 +608,13 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
618
608
|
for (upb_strtable_begin(&it, &self->table);
|
619
609
|
!upb_strtable_done(&it);
|
620
610
|
upb_strtable_next(&it)) {
|
621
|
-
|
611
|
+
upb_strview k = upb_strtable_iter_key(&it);
|
622
612
|
upb_value v = upb_strtable_iter_value(&it);
|
623
613
|
void* mem = value_memory(&v);
|
624
614
|
upb_value other_v;
|
625
615
|
void* other_mem = value_memory(&other_v);
|
626
616
|
|
627
|
-
if (!upb_strtable_lookup2(&other->table,
|
628
|
-
upb_strtable_iter_key(&it),
|
629
|
-
upb_strtable_iter_keylength(&it),
|
630
|
-
&other_v)) {
|
617
|
+
if (!upb_strtable_lookup2(&other->table, k.data, k.size, &other_v)) {
|
631
618
|
// Not present in other map.
|
632
619
|
return Qfalse;
|
633
620
|
}
|
@@ -655,11 +642,9 @@ VALUE Map_hash(VALUE _self) {
|
|
655
642
|
VALUE hash_sym = rb_intern("hash");
|
656
643
|
|
657
644
|
upb_strtable_iter it;
|
658
|
-
for (upb_strtable_begin(&it, &self->table);
|
659
|
-
!upb_strtable_done(&it);
|
645
|
+
for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it);
|
660
646
|
upb_strtable_next(&it)) {
|
661
|
-
VALUE key = table_key_to_ruby(
|
662
|
-
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
647
|
+
VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it));
|
663
648
|
|
664
649
|
upb_value v = upb_strtable_iter_value(&it);
|
665
650
|
void* mem = value_memory(&v);
|
@@ -687,8 +672,7 @@ VALUE Map_to_h(VALUE _self) {
|
|
687
672
|
for (upb_strtable_begin(&it, &self->table);
|
688
673
|
!upb_strtable_done(&it);
|
689
674
|
upb_strtable_next(&it)) {
|
690
|
-
VALUE key = table_key_to_ruby(
|
691
|
-
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
675
|
+
VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it));
|
692
676
|
upb_value v = upb_strtable_iter_value(&it);
|
693
677
|
void* mem = value_memory(&v);
|
694
678
|
VALUE value = native_slot_get(self->value_type,
|
@@ -720,11 +704,9 @@ VALUE Map_inspect(VALUE _self) {
|
|
720
704
|
VALUE inspect_sym = rb_intern("inspect");
|
721
705
|
|
722
706
|
upb_strtable_iter it;
|
723
|
-
for (upb_strtable_begin(&it, &self->table);
|
724
|
-
!upb_strtable_done(&it);
|
707
|
+
for (upb_strtable_begin(&it, &self->table); !upb_strtable_done(&it);
|
725
708
|
upb_strtable_next(&it)) {
|
726
|
-
VALUE key = table_key_to_ruby(
|
727
|
-
self, upb_strtable_iter_key(&it), upb_strtable_iter_keylength(&it));
|
709
|
+
VALUE key = table_key_to_ruby(self, upb_strtable_iter_key(&it));
|
728
710
|
|
729
711
|
upb_value v = upb_strtable_iter_value(&it);
|
730
712
|
void* mem = value_memory(&v);
|
@@ -785,20 +767,15 @@ VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
785
767
|
for (upb_strtable_begin(&it, &other->table);
|
786
768
|
!upb_strtable_done(&it);
|
787
769
|
upb_strtable_next(&it)) {
|
770
|
+
upb_strview k = upb_strtable_iter_key(&it);
|
788
771
|
|
789
772
|
// Replace any existing value by issuing a 'remove' operation first.
|
790
773
|
upb_value v;
|
791
774
|
upb_value oldv;
|
792
|
-
upb_strtable_remove2(&self->table,
|
793
|
-
upb_strtable_iter_key(&it),
|
794
|
-
upb_strtable_iter_keylength(&it),
|
795
|
-
&oldv);
|
775
|
+
upb_strtable_remove2(&self->table, k.data, k.size, &oldv);
|
796
776
|
|
797
777
|
v = upb_strtable_iter_value(&it);
|
798
|
-
upb_strtable_insert2(&self->table,
|
799
|
-
upb_strtable_iter_key(&it),
|
800
|
-
upb_strtable_iter_keylength(&it),
|
801
|
-
v);
|
778
|
+
upb_strtable_insert2(&self->table, k.data, k.size, v);
|
802
779
|
}
|
803
780
|
} else {
|
804
781
|
rb_raise(rb_eArgError, "Unknown type merging into Map");
|
@@ -822,10 +799,7 @@ bool Map_done(Map_iter* iter) {
|
|
822
799
|
}
|
823
800
|
|
824
801
|
VALUE Map_iter_key(Map_iter* iter) {
|
825
|
-
return table_key_to_ruby(
|
826
|
-
iter->self,
|
827
|
-
upb_strtable_iter_key(&iter->it),
|
828
|
-
upb_strtable_iter_keylength(&iter->it));
|
802
|
+
return table_key_to_ruby(iter->self, upb_strtable_iter_key(&iter->it));
|
829
803
|
}
|
830
804
|
|
831
805
|
VALUE Map_iter_value(Map_iter* iter) {
|
@@ -242,9 +242,14 @@ static int extract_method_call(VALUE method_name, MessageHeader* self,
|
|
242
242
|
// Method calls like 'has_foo?' are not allowed if field "foo" does not have
|
243
243
|
// a hasbit (e.g. repeated fields or non-message type fields for proto3
|
244
244
|
// syntax).
|
245
|
-
if (accessor_type == METHOD_PRESENCE && test_f != NULL
|
246
|
-
|
247
|
-
|
245
|
+
if (accessor_type == METHOD_PRESENCE && test_f != NULL) {
|
246
|
+
if (!upb_fielddef_haspresence(test_f)) return METHOD_UNKNOWN;
|
247
|
+
|
248
|
+
// TODO(haberman): remove this case, allow for proto3 oneofs.
|
249
|
+
if (upb_fielddef_realcontainingoneof(test_f) &&
|
250
|
+
upb_filedef_syntax(upb_fielddef_file(test_f)) == UPB_SYNTAX_PROTO3) {
|
251
|
+
return METHOD_UNKNOWN;
|
252
|
+
}
|
248
253
|
}
|
249
254
|
|
250
255
|
*o = test_o;
|
@@ -605,11 +610,17 @@ VALUE Message_inspect(VALUE _self) {
|
|
605
610
|
*/
|
606
611
|
VALUE Message_to_h(VALUE _self) {
|
607
612
|
MessageHeader* self;
|
608
|
-
VALUE hash;
|
613
|
+
VALUE hash = rb_hash_new();
|
609
614
|
upb_msg_field_iter it;
|
615
|
+
bool is_proto2;
|
610
616
|
TypedData_Get_Struct(_self, MessageHeader, &Message_type, self);
|
611
617
|
|
612
|
-
|
618
|
+
// We currently have a few behaviors that are specific to proto2.
|
619
|
+
// This is unfortunate, we should key behaviors off field attributes (like
|
620
|
+
// whether a field has presence), not proto2 vs. proto3. We should see if we
|
621
|
+
// can change this without breaking users.
|
622
|
+
is_proto2 =
|
623
|
+
upb_msgdef_syntax(self->descriptor->msgdef) == UPB_SYNTAX_PROTO2;
|
613
624
|
|
614
625
|
for (upb_msg_field_begin(&it, self->descriptor->msgdef);
|
615
626
|
!upb_msg_field_done(&it);
|
@@ -618,10 +629,9 @@ VALUE Message_to_h(VALUE _self) {
|
|
618
629
|
VALUE msg_value;
|
619
630
|
VALUE msg_key;
|
620
631
|
|
621
|
-
//
|
622
|
-
if (
|
623
|
-
|
624
|
-
!layout_has(self->descriptor->layout, Message_data(self), field)) {
|
632
|
+
// Do not include fields that are not present (oneof or optional fields).
|
633
|
+
if (is_proto2 && upb_fielddef_haspresence(field) &&
|
634
|
+
!layout_has(self->descriptor->layout, Message_data(self), field)) {
|
625
635
|
continue;
|
626
636
|
}
|
627
637
|
|
@@ -631,8 +641,7 @@ VALUE Message_to_h(VALUE _self) {
|
|
631
641
|
msg_value = Map_to_h(msg_value);
|
632
642
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
633
643
|
msg_value = RepeatedField_to_ary(msg_value);
|
634
|
-
if (
|
635
|
-
RARRAY_LEN(msg_value) == 0) {
|
644
|
+
if (is_proto2 && RARRAY_LEN(msg_value) == 0) {
|
636
645
|
continue;
|
637
646
|
}
|
638
647
|
|
@@ -285,6 +285,7 @@ VALUE MessageBuilderContext_initialize(VALUE _self,
|
|
285
285
|
VALUE _file_builder,
|
286
286
|
VALUE name);
|
287
287
|
VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self);
|
288
|
+
VALUE MessageBuilderContext_proto3_optional(int argc, VALUE* argv, VALUE _self);
|
288
289
|
VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self);
|
289
290
|
VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self);
|
290
291
|
VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self);
|
@@ -496,11 +496,14 @@ void create_layout(Descriptor* desc) {
|
|
496
496
|
const upb_msgdef *msgdef = desc->msgdef;
|
497
497
|
MessageLayout* layout = ALLOC(MessageLayout);
|
498
498
|
int nfields = upb_msgdef_numfields(msgdef);
|
499
|
-
int noneofs =
|
499
|
+
int noneofs = upb_msgdef_numrealoneofs(msgdef);
|
500
500
|
upb_msg_field_iter it;
|
501
501
|
upb_msg_oneof_iter oit;
|
502
502
|
size_t off = 0;
|
503
503
|
size_t hasbit = 0;
|
504
|
+
int i;
|
505
|
+
|
506
|
+
(void)i;
|
504
507
|
|
505
508
|
layout->empty_template = NULL;
|
506
509
|
layout->desc = desc;
|
@@ -513,11 +516,22 @@ void create_layout(Descriptor* desc) {
|
|
513
516
|
layout->oneofs = ALLOC_N(MessageOneof, noneofs);
|
514
517
|
}
|
515
518
|
|
519
|
+
#ifndef NDEBUG
|
520
|
+
for (i = 0; i < nfields; i++) {
|
521
|
+
layout->fields[i].offset = -1;
|
522
|
+
}
|
523
|
+
|
524
|
+
for (i = 0; i < noneofs; i++) {
|
525
|
+
layout->oneofs[i].offset = -1;
|
526
|
+
}
|
527
|
+
#endif
|
528
|
+
|
516
529
|
for (upb_msg_field_begin(&it, msgdef);
|
517
530
|
!upb_msg_field_done(&it);
|
518
531
|
upb_msg_field_next(&it)) {
|
519
532
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
520
|
-
if (upb_fielddef_haspresence(field)
|
533
|
+
if (upb_fielddef_haspresence(field) &&
|
534
|
+
!upb_fielddef_realcontainingoneof(field)) {
|
521
535
|
layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
|
522
536
|
} else {
|
523
537
|
layout->fields[upb_fielddef_index(field)].hasbit =
|
@@ -540,7 +554,7 @@ void create_layout(Descriptor* desc) {
|
|
540
554
|
!upb_msg_field_done(&it);
|
541
555
|
upb_msg_field_next(&it)) {
|
542
556
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
543
|
-
if (
|
557
|
+
if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) ||
|
544
558
|
upb_fielddef_ismap(field)) {
|
545
559
|
continue;
|
546
560
|
}
|
@@ -555,7 +569,7 @@ void create_layout(Descriptor* desc) {
|
|
555
569
|
!upb_msg_field_done(&it);
|
556
570
|
upb_msg_field_next(&it)) {
|
557
571
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
558
|
-
if (
|
572
|
+
if (upb_fielddef_realcontainingoneof(field) || !upb_fielddef_isseq(field) ||
|
559
573
|
!upb_fielddef_ismap(field)) {
|
560
574
|
continue;
|
561
575
|
}
|
@@ -572,7 +586,7 @@ void create_layout(Descriptor* desc) {
|
|
572
586
|
!upb_msg_field_done(&it);
|
573
587
|
upb_msg_field_next(&it)) {
|
574
588
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
575
|
-
if (
|
589
|
+
if (upb_fielddef_realcontainingoneof(field) || !is_value_field(field) ||
|
576
590
|
upb_fielddef_isseq(field)) {
|
577
591
|
continue;
|
578
592
|
}
|
@@ -589,7 +603,7 @@ void create_layout(Descriptor* desc) {
|
|
589
603
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
590
604
|
size_t field_size;
|
591
605
|
|
592
|
-
if (
|
606
|
+
if (upb_fielddef_realcontainingoneof(field) || is_value_field(field)) {
|
593
607
|
continue;
|
594
608
|
}
|
595
609
|
|
@@ -624,6 +638,10 @@ void create_layout(Descriptor* desc) {
|
|
624
638
|
// Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
|
625
639
|
// all fields.
|
626
640
|
size_t field_size = NATIVE_SLOT_MAX_SIZE;
|
641
|
+
|
642
|
+
if (upb_oneofdef_issynthetic(oneof)) continue;
|
643
|
+
assert(upb_oneofdef_index(oneof) < noneofs);
|
644
|
+
|
627
645
|
// Align the offset.
|
628
646
|
off = align_up_to(off, field_size);
|
629
647
|
// Assign all fields in the oneof this same offset.
|
@@ -643,6 +661,8 @@ void create_layout(Descriptor* desc) {
|
|
643
661
|
upb_msg_oneof_next(&oit)) {
|
644
662
|
const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
|
645
663
|
size_t field_size = sizeof(uint32_t);
|
664
|
+
if (upb_oneofdef_issynthetic(oneof)) continue;
|
665
|
+
assert(upb_oneofdef_index(oneof) < noneofs);
|
646
666
|
// Align the offset.
|
647
667
|
off = (off + field_size - 1) & ~(field_size - 1);
|
648
668
|
layout->oneofs[upb_oneofdef_index(oneof)].case_offset = off;
|
@@ -652,6 +672,16 @@ void create_layout(Descriptor* desc) {
|
|
652
672
|
layout->size = off;
|
653
673
|
layout->msgdef = msgdef;
|
654
674
|
|
675
|
+
#ifndef NDEBUG
|
676
|
+
for (i = 0; i < nfields; i++) {
|
677
|
+
assert(layout->fields[i].offset != -1);
|
678
|
+
}
|
679
|
+
|
680
|
+
for (i = 0; i < noneofs; i++) {
|
681
|
+
assert(layout->oneofs[i].offset != -1);
|
682
|
+
}
|
683
|
+
#endif
|
684
|
+
|
655
685
|
// Create the empty message template.
|
656
686
|
layout->empty_template = ALLOC_N(char, layout->size);
|
657
687
|
memset(layout->empty_template, 0, layout->size);
|
@@ -725,10 +755,7 @@ static bool slot_is_hasbit_set(MessageLayout* layout,
|
|
725
755
|
const void* storage,
|
726
756
|
const upb_fielddef* field) {
|
727
757
|
size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
|
728
|
-
|
729
|
-
return false;
|
730
|
-
}
|
731
|
-
|
758
|
+
assert(field_contains_hasbit(layout, field));
|
732
759
|
return DEREF_OFFSET(
|
733
760
|
(uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
|
734
761
|
}
|
@@ -736,15 +763,21 @@ static bool slot_is_hasbit_set(MessageLayout* layout,
|
|
736
763
|
VALUE layout_has(MessageLayout* layout,
|
737
764
|
const void* storage,
|
738
765
|
const upb_fielddef* field) {
|
739
|
-
|
740
|
-
|
766
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
767
|
+
assert(upb_fielddef_haspresence(field));
|
768
|
+
if (oneof) {
|
769
|
+
uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof);
|
770
|
+
return oneof_case == upb_fielddef_number(field) ? Qtrue : Qfalse;
|
771
|
+
} else {
|
772
|
+
return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
|
773
|
+
}
|
741
774
|
}
|
742
775
|
|
743
776
|
void layout_clear(MessageLayout* layout,
|
744
777
|
const void* storage,
|
745
778
|
const upb_fielddef* field) {
|
746
779
|
void* memory = slot_memory(layout, storage, field);
|
747
|
-
const upb_oneofdef* oneof =
|
780
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
748
781
|
|
749
782
|
if (field_contains_hasbit(layout, field)) {
|
750
783
|
slot_clear_hasbit(layout, storage, field);
|
@@ -837,7 +870,7 @@ VALUE layout_get(MessageLayout* layout,
|
|
837
870
|
const void* storage,
|
838
871
|
const upb_fielddef* field) {
|
839
872
|
void* memory = slot_memory(layout, storage, field);
|
840
|
-
const upb_oneofdef* oneof =
|
873
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
841
874
|
bool field_set;
|
842
875
|
if (field_contains_hasbit(layout, field)) {
|
843
876
|
field_set = slot_is_hasbit_set(layout, storage, field);
|
@@ -910,7 +943,7 @@ void layout_set(MessageLayout* layout,
|
|
910
943
|
const upb_fielddef* field,
|
911
944
|
VALUE val) {
|
912
945
|
void* memory = slot_memory(layout, storage, field);
|
913
|
-
const upb_oneofdef* oneof =
|
946
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
914
947
|
|
915
948
|
if (oneof) {
|
916
949
|
uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
|
@@ -953,7 +986,16 @@ void layout_set(MessageLayout* layout,
|
|
953
986
|
|
954
987
|
if (layout->fields[upb_fielddef_index(field)].hasbit !=
|
955
988
|
MESSAGE_FIELD_NO_HASBIT) {
|
956
|
-
|
989
|
+
if (val == Qnil) {
|
990
|
+
// No other field type has a hasbit and allows nil assignment.
|
991
|
+
if (upb_fielddef_type(field) != UPB_TYPE_MESSAGE) {
|
992
|
+
fprintf(stderr, "field: %s\n", upb_fielddef_fullname(field));
|
993
|
+
}
|
994
|
+
assert(upb_fielddef_type(field) == UPB_TYPE_MESSAGE);
|
995
|
+
slot_clear_hasbit(layout, storage, field);
|
996
|
+
} else {
|
997
|
+
slot_set_hasbit(layout, storage, field);
|
998
|
+
}
|
957
999
|
}
|
958
1000
|
}
|
959
1001
|
|
@@ -972,7 +1014,7 @@ void layout_init(MessageLayout* layout, void* storage) {
|
|
972
1014
|
|
973
1015
|
void layout_mark(MessageLayout* layout, void* storage) {
|
974
1016
|
VALUE* values = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
|
975
|
-
int noneofs =
|
1017
|
+
int noneofs = upb_msgdef_numrealoneofs(layout->msgdef);
|
976
1018
|
int i;
|
977
1019
|
|
978
1020
|
for (i = 0; i < layout->value_count; i++) {
|
@@ -994,7 +1036,7 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
|
|
994
1036
|
!upb_msg_field_done(&it);
|
995
1037
|
upb_msg_field_next(&it)) {
|
996
1038
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
997
|
-
const upb_oneofdef* oneof =
|
1039
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
998
1040
|
|
999
1041
|
void* to_memory = slot_memory(layout, to, field);
|
1000
1042
|
void* from_memory = slot_memory(layout, from, field);
|
@@ -1028,7 +1070,7 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
|
|
1028
1070
|
!upb_msg_field_done(&it);
|
1029
1071
|
upb_msg_field_next(&it)) {
|
1030
1072
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
1031
|
-
const upb_oneofdef* oneof =
|
1073
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
1032
1074
|
|
1033
1075
|
void* to_memory = slot_memory(layout, to, field);
|
1034
1076
|
void* from_memory = slot_memory(layout, from, field);
|
@@ -1068,7 +1110,7 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
|
|
1068
1110
|
!upb_msg_field_done(&it);
|
1069
1111
|
upb_msg_field_next(&it)) {
|
1070
1112
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
1071
|
-
const upb_oneofdef* oneof =
|
1113
|
+
const upb_oneofdef* oneof = upb_fielddef_realcontainingoneof(field);
|
1072
1114
|
|
1073
1115
|
void* msg1_memory = slot_memory(layout, msg1, field);
|
1074
1116
|
void* msg2_memory = slot_memory(layout, msg2, field);
|
@@ -1095,9 +1137,16 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
|
|
1095
1137
|
return Qfalse;
|
1096
1138
|
}
|
1097
1139
|
} else {
|
1098
|
-
if (
|
1099
|
-
|
1100
|
-
|
1140
|
+
if (field_contains_hasbit(layout, field) &&
|
1141
|
+
slot_is_hasbit_set(layout, msg1, field) !=
|
1142
|
+
slot_is_hasbit_set(layout, msg2, field)) {
|
1143
|
+
// TODO(haberman): I don't think we should actually care about hasbits
|
1144
|
+
// here: an unset default should be able to equal a set default. But we
|
1145
|
+
// can address this later (will also have to make sure defaults are
|
1146
|
+
// being properly set when hasbit is clear).
|
1147
|
+
return Qfalse;
|
1148
|
+
}
|
1149
|
+
if (!native_slot_eq(upb_fielddef_type(field),
|
1101
1150
|
field_type_class(layout, field), msg1_memory,
|
1102
1151
|
msg2_memory)) {
|
1103
1152
|
return Qfalse;
|