google-protobuf 3.11.0 → 3.12.0
Sign up to get free protection for your applications and to get access to all the features.
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;
|