google-protobuf 3.9.2-x64-mingw32 → 3.10.0.rc.1-x64-mingw32
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 +851 -830
- data/ext/google/protobuf_c/encode_decode.c +219 -285
- data/ext/google/protobuf_c/extconf.rb +2 -4
- data/ext/google/protobuf_c/map.c +15 -9
- data/ext/google/protobuf_c/message.c +84 -91
- data/ext/google/protobuf_c/protobuf.c +30 -15
- data/ext/google/protobuf_c/protobuf.h +100 -54
- data/ext/google/protobuf_c/repeated_field.c +44 -19
- data/ext/google/protobuf_c/storage.c +219 -153
- data/ext/google/protobuf_c/upb.c +4516 -8706
- data/ext/google/protobuf_c/upb.h +4920 -8476
- data/lib/google/2.3/protobuf_c.so +0 -0
- data/lib/google/2.4/protobuf_c.so +0 -0
- data/lib/google/2.5/protobuf_c.so +0 -0
- data/lib/google/2.6/protobuf_c.so +0 -0
- data/lib/google/protobuf.rb +66 -0
- data/lib/google/protobuf/any_pb.rb +1 -1
- data/lib/google/protobuf/api_pb.rb +3 -3
- data/lib/google/protobuf/duration_pb.rb +1 -1
- data/lib/google/protobuf/empty_pb.rb +1 -1
- data/lib/google/protobuf/field_mask_pb.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +1 -1
- data/lib/google/protobuf/struct_pb.rb +4 -4
- data/lib/google/protobuf/timestamp_pb.rb +1 -1
- data/lib/google/protobuf/type_pb.rb +8 -8
- data/lib/google/protobuf/well_known_types.rb +8 -2
- data/lib/google/protobuf/wrappers_pb.rb +9 -9
- data/tests/basic.rb +22 -6
- metadata +6 -5
@@ -96,17 +96,19 @@ VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value) {
|
|
96
96
|
kRubyStringUtf8Encoding : kRubyString8bitEncoding;
|
97
97
|
VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
|
98
98
|
|
99
|
-
|
100
|
-
|
99
|
+
if (rb_obj_encoding(value) != desired_encoding_value || !OBJ_FROZEN(value)) {
|
100
|
+
// Note: this will not duplicate underlying string data unless necessary.
|
101
|
+
value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
if (type == UPB_TYPE_STRING &&
|
104
|
+
rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
|
105
|
+
rb_raise(rb_eEncodingError, "String is invalid UTF-8");
|
106
|
+
}
|
106
107
|
|
107
|
-
|
108
|
-
|
109
|
-
|
108
|
+
// Ensure the data remains valid. Since we called #encode a moment ago,
|
109
|
+
// this does not freeze the string the user assigned.
|
110
|
+
rb_obj_freeze(value);
|
111
|
+
}
|
110
112
|
|
111
113
|
return value;
|
112
114
|
}
|
@@ -179,32 +181,43 @@ void native_slot_set_value_and_case(const char* name,
|
|
179
181
|
value = Qnil;
|
180
182
|
} else if (CLASS_OF(value) != type_class) {
|
181
183
|
// check for possible implicit conversions
|
182
|
-
VALUE converted_value =
|
183
|
-
char* field_type_name = rb_class2name(type_class);
|
184
|
+
VALUE converted_value = Qnil;
|
185
|
+
const char* field_type_name = rb_class2name(type_class);
|
184
186
|
|
185
187
|
if (strcmp(field_type_name, "Google::Protobuf::Timestamp") == 0 &&
|
186
188
|
rb_obj_is_kind_of(value, rb_cTime)) {
|
187
189
|
// Time -> Google::Protobuf::Timestamp
|
188
190
|
VALUE hash = rb_hash_new();
|
189
|
-
rb_hash_aset(hash, rb_str_new2("seconds"),
|
190
|
-
|
191
|
-
|
192
|
-
|
191
|
+
rb_hash_aset(hash, rb_str_new2("seconds"),
|
192
|
+
rb_funcall(value, rb_intern("to_i"), 0));
|
193
|
+
rb_hash_aset(hash, rb_str_new2("nanos"),
|
194
|
+
rb_funcall(value, rb_intern("nsec"), 0));
|
195
|
+
{
|
196
|
+
VALUE args[1] = {hash};
|
197
|
+
converted_value = rb_class_new_instance(1, args, type_class);
|
198
|
+
}
|
193
199
|
} else if (strcmp(field_type_name, "Google::Protobuf::Duration") == 0 &&
|
194
200
|
rb_obj_is_kind_of(value, rb_cNumeric)) {
|
195
201
|
// Numeric -> Google::Protobuf::Duration
|
196
202
|
VALUE hash = rb_hash_new();
|
197
|
-
rb_hash_aset(hash, rb_str_new2("seconds"),
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
203
|
+
rb_hash_aset(hash, rb_str_new2("seconds"),
|
204
|
+
rb_funcall(value, rb_intern("to_i"), 0));
|
205
|
+
{
|
206
|
+
VALUE n_value =
|
207
|
+
rb_funcall(value, rb_intern("remainder"), 1, INT2NUM(1));
|
208
|
+
n_value =
|
209
|
+
rb_funcall(n_value, rb_intern("*"), 1, INT2NUM(1000000000));
|
210
|
+
n_value = rb_funcall(n_value, rb_intern("round"), 0);
|
211
|
+
rb_hash_aset(hash, rb_str_new2("nanos"), n_value);
|
212
|
+
}
|
213
|
+
{
|
214
|
+
VALUE args[1] = { hash };
|
215
|
+
converted_value = rb_class_new_instance(1, args, type_class);
|
216
|
+
}
|
204
217
|
}
|
205
218
|
|
206
219
|
// raise if no suitable conversaion could be found
|
207
|
-
if (converted_value ==
|
220
|
+
if (converted_value == Qnil) {
|
208
221
|
rb_raise(cTypeError,
|
209
222
|
"Invalid type %s to assign to submessage field '%s'.",
|
210
223
|
rb_class2name(CLASS_OF(value)), name);
|
@@ -460,16 +473,32 @@ static size_t align_up_to(size_t offset, size_t granularity) {
|
|
460
473
|
return (offset + granularity - 1) & ~(granularity - 1);
|
461
474
|
}
|
462
475
|
|
463
|
-
|
476
|
+
bool is_value_field(const upb_fielddef* f) {
|
477
|
+
return upb_fielddef_isseq(f) || upb_fielddef_issubmsg(f) ||
|
478
|
+
upb_fielddef_isstring(f);
|
479
|
+
}
|
480
|
+
|
481
|
+
void create_layout(Descriptor* desc) {
|
482
|
+
const upb_msgdef *msgdef = desc->msgdef;
|
464
483
|
MessageLayout* layout = ALLOC(MessageLayout);
|
465
484
|
int nfields = upb_msgdef_numfields(msgdef);
|
485
|
+
int noneofs = upb_msgdef_numoneofs(msgdef);
|
466
486
|
upb_msg_field_iter it;
|
467
487
|
upb_msg_oneof_iter oit;
|
468
488
|
size_t off = 0;
|
489
|
+
size_t hasbit = 0;
|
490
|
+
|
491
|
+
layout->empty_template = NULL;
|
492
|
+
layout->desc = desc;
|
493
|
+
desc->layout = layout;
|
469
494
|
|
470
495
|
layout->fields = ALLOC_N(MessageField, nfields);
|
496
|
+
layout->oneofs = NULL;
|
497
|
+
|
498
|
+
if (noneofs > 0) {
|
499
|
+
layout->oneofs = ALLOC_N(MessageOneof, noneofs);
|
500
|
+
}
|
471
501
|
|
472
|
-
size_t hasbit = 0;
|
473
502
|
for (upb_msg_field_begin(&it, msgdef);
|
474
503
|
!upb_msg_field_done(&it);
|
475
504
|
upb_msg_field_next(&it)) {
|
@@ -478,7 +507,7 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
|
478
507
|
layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
|
479
508
|
} else {
|
480
509
|
layout->fields[upb_fielddef_index(field)].hasbit =
|
481
|
-
|
510
|
+
MESSAGE_FIELD_NO_HASBIT;
|
482
511
|
}
|
483
512
|
}
|
484
513
|
|
@@ -486,29 +515,76 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
|
486
515
|
off += (hasbit + 8 - 1) / 8;
|
487
516
|
}
|
488
517
|
|
518
|
+
off = align_up_to(off, sizeof(VALUE));
|
519
|
+
layout->value_offset = off;
|
520
|
+
layout->repeated_count = 0;
|
521
|
+
layout->map_count = 0;
|
522
|
+
layout->value_count = 0;
|
523
|
+
|
524
|
+
// Place all VALUE fields for repeated fields.
|
525
|
+
for (upb_msg_field_begin(&it, msgdef);
|
526
|
+
!upb_msg_field_done(&it);
|
527
|
+
upb_msg_field_next(&it)) {
|
528
|
+
const upb_fielddef* field = upb_msg_iter_field(&it);
|
529
|
+
if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) ||
|
530
|
+
upb_fielddef_ismap(field)) {
|
531
|
+
continue;
|
532
|
+
}
|
533
|
+
|
534
|
+
layout->fields[upb_fielddef_index(field)].offset = off;
|
535
|
+
off += sizeof(VALUE);
|
536
|
+
layout->repeated_count++;
|
537
|
+
}
|
538
|
+
|
539
|
+
// Place all VALUE fields for map fields.
|
540
|
+
for (upb_msg_field_begin(&it, msgdef);
|
541
|
+
!upb_msg_field_done(&it);
|
542
|
+
upb_msg_field_next(&it)) {
|
543
|
+
const upb_fielddef* field = upb_msg_iter_field(&it);
|
544
|
+
if (upb_fielddef_containingoneof(field) || !upb_fielddef_isseq(field) ||
|
545
|
+
!upb_fielddef_ismap(field)) {
|
546
|
+
continue;
|
547
|
+
}
|
548
|
+
|
549
|
+
layout->fields[upb_fielddef_index(field)].offset = off;
|
550
|
+
off += sizeof(VALUE);
|
551
|
+
layout->map_count++;
|
552
|
+
}
|
553
|
+
|
554
|
+
layout->value_count = layout->repeated_count + layout->map_count;
|
555
|
+
|
556
|
+
// Next place all other (non-oneof) VALUE fields.
|
557
|
+
for (upb_msg_field_begin(&it, msgdef);
|
558
|
+
!upb_msg_field_done(&it);
|
559
|
+
upb_msg_field_next(&it)) {
|
560
|
+
const upb_fielddef* field = upb_msg_iter_field(&it);
|
561
|
+
if (upb_fielddef_containingoneof(field) || !is_value_field(field) ||
|
562
|
+
upb_fielddef_isseq(field)) {
|
563
|
+
continue;
|
564
|
+
}
|
565
|
+
|
566
|
+
layout->fields[upb_fielddef_index(field)].offset = off;
|
567
|
+
off += sizeof(VALUE);
|
568
|
+
layout->value_count++;
|
569
|
+
}
|
570
|
+
|
571
|
+
// Now place all other (non-oneof) fields.
|
489
572
|
for (upb_msg_field_begin(&it, msgdef);
|
490
573
|
!upb_msg_field_done(&it);
|
491
574
|
upb_msg_field_next(&it)) {
|
492
575
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
493
576
|
size_t field_size;
|
494
577
|
|
495
|
-
if (upb_fielddef_containingoneof(field)) {
|
496
|
-
// Oneofs are handled separately below.
|
578
|
+
if (upb_fielddef_containingoneof(field) || is_value_field(field)) {
|
497
579
|
continue;
|
498
580
|
}
|
499
581
|
|
500
582
|
// Allocate |field_size| bytes for this field in the layout.
|
501
|
-
field_size =
|
502
|
-
|
503
|
-
field_size = sizeof(VALUE);
|
504
|
-
} else {
|
505
|
-
field_size = native_slot_size(upb_fielddef_type(field));
|
506
|
-
}
|
583
|
+
field_size = native_slot_size(upb_fielddef_type(field));
|
584
|
+
|
507
585
|
// Align current offset up to |size| granularity.
|
508
586
|
off = align_up_to(off, field_size);
|
509
587
|
layout->fields[upb_fielddef_index(field)].offset = off;
|
510
|
-
layout->fields[upb_fielddef_index(field)].case_offset =
|
511
|
-
MESSAGE_FIELD_NO_CASE;
|
512
588
|
off += field_size;
|
513
589
|
}
|
514
590
|
|
@@ -542,6 +618,7 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
|
542
618
|
upb_oneof_next(&fit)) {
|
543
619
|
const upb_fielddef* field = upb_oneof_iter_field(&fit);
|
544
620
|
layout->fields[upb_fielddef_index(field)].offset = off;
|
621
|
+
layout->oneofs[upb_oneofdef_index(oneof)].offset = off;
|
545
622
|
}
|
546
623
|
off += field_size;
|
547
624
|
}
|
@@ -551,44 +628,43 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
|
551
628
|
!upb_msg_oneof_done(&oit);
|
552
629
|
upb_msg_oneof_next(&oit)) {
|
553
630
|
const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
|
554
|
-
upb_oneof_iter fit;
|
555
|
-
|
556
631
|
size_t field_size = sizeof(uint32_t);
|
557
632
|
// Align the offset.
|
558
633
|
off = (off + field_size - 1) & ~(field_size - 1);
|
559
|
-
|
560
|
-
for (upb_oneof_begin(&fit, oneof);
|
561
|
-
!upb_oneof_done(&fit);
|
562
|
-
upb_oneof_next(&fit)) {
|
563
|
-
const upb_fielddef* field = upb_oneof_iter_field(&fit);
|
564
|
-
layout->fields[upb_fielddef_index(field)].case_offset = off;
|
565
|
-
}
|
634
|
+
layout->oneofs[upb_oneofdef_index(oneof)].case_offset = off;
|
566
635
|
off += field_size;
|
567
636
|
}
|
568
637
|
|
569
638
|
layout->size = off;
|
570
|
-
|
571
639
|
layout->msgdef = msgdef;
|
572
|
-
upb_msgdef_ref(layout->msgdef, &layout->msgdef);
|
573
640
|
|
574
|
-
|
641
|
+
// Create the empty message template.
|
642
|
+
layout->empty_template = ALLOC_N(char, layout->size);
|
643
|
+
memset(layout->empty_template, 0, layout->size);
|
644
|
+
|
645
|
+
for (upb_msg_field_begin(&it, layout->msgdef);
|
646
|
+
!upb_msg_field_done(&it);
|
647
|
+
upb_msg_field_next(&it)) {
|
648
|
+
layout_clear(layout, layout->empty_template, upb_msg_iter_field(&it));
|
649
|
+
}
|
575
650
|
}
|
576
651
|
|
577
652
|
void free_layout(MessageLayout* layout) {
|
653
|
+
xfree(layout->empty_template);
|
578
654
|
xfree(layout->fields);
|
579
|
-
|
655
|
+
xfree(layout->oneofs);
|
580
656
|
xfree(layout);
|
581
657
|
}
|
582
658
|
|
583
|
-
VALUE field_type_class(const upb_fielddef* field) {
|
659
|
+
VALUE field_type_class(const MessageLayout* layout, const upb_fielddef* field) {
|
584
660
|
VALUE type_class = Qnil;
|
585
661
|
if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) {
|
586
|
-
VALUE submsgdesc =
|
587
|
-
|
662
|
+
VALUE submsgdesc = get_msgdef_obj(layout->desc->descriptor_pool,
|
663
|
+
upb_fielddef_msgsubdef(field));
|
588
664
|
type_class = Descriptor_msgclass(submsgdesc);
|
589
665
|
} else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
|
590
|
-
VALUE subenumdesc =
|
591
|
-
|
666
|
+
VALUE subenumdesc = get_enumdef_obj(layout->desc->descriptor_pool,
|
667
|
+
upb_fielddef_enumsubdef(field));
|
592
668
|
type_class = EnumDescriptor_enummodule(subenumdesc);
|
593
669
|
}
|
594
670
|
return type_class;
|
@@ -603,9 +679,15 @@ static void* slot_memory(MessageLayout* layout,
|
|
603
679
|
|
604
680
|
static uint32_t* slot_oneof_case(MessageLayout* layout,
|
605
681
|
const void* storage,
|
606
|
-
const
|
607
|
-
return (uint32_t
|
608
|
-
|
682
|
+
const upb_oneofdef* oneof) {
|
683
|
+
return (uint32_t*)(((uint8_t*)storage) +
|
684
|
+
layout->oneofs[upb_oneofdef_index(oneof)].case_offset);
|
685
|
+
}
|
686
|
+
|
687
|
+
uint32_t slot_read_oneof_case(MessageLayout* layout, const void* storage,
|
688
|
+
const upb_oneofdef* oneof) {
|
689
|
+
uint32_t* ptr = slot_oneof_case(layout, storage, oneof);
|
690
|
+
return *ptr & ~ONEOF_CASE_MASK;
|
609
691
|
}
|
610
692
|
|
611
693
|
static void slot_set_hasbit(MessageLayout* layout,
|
@@ -648,13 +730,14 @@ void layout_clear(MessageLayout* layout,
|
|
648
730
|
const void* storage,
|
649
731
|
const upb_fielddef* field) {
|
650
732
|
void* memory = slot_memory(layout, storage, field);
|
651
|
-
|
733
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
652
734
|
|
653
735
|
if (field_contains_hasbit(layout, field)) {
|
654
736
|
slot_clear_hasbit(layout, storage, field);
|
655
737
|
}
|
656
738
|
|
657
|
-
if (
|
739
|
+
if (oneof) {
|
740
|
+
uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
|
658
741
|
memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
|
659
742
|
*oneof_case = ONEOF_CASE_NONE;
|
660
743
|
} else if (is_map_field(field)) {
|
@@ -662,7 +745,7 @@ void layout_clear(MessageLayout* layout,
|
|
662
745
|
|
663
746
|
const upb_fielddef* key_field = map_field_key(field);
|
664
747
|
const upb_fielddef* value_field = map_field_value(field);
|
665
|
-
VALUE type_class = field_type_class(value_field);
|
748
|
+
VALUE type_class = field_type_class(layout, value_field);
|
666
749
|
|
667
750
|
if (type_class != Qnil) {
|
668
751
|
VALUE args[3] = {
|
@@ -683,7 +766,7 @@ void layout_clear(MessageLayout* layout,
|
|
683
766
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
684
767
|
VALUE ary = Qnil;
|
685
768
|
|
686
|
-
VALUE type_class = field_type_class(field);
|
769
|
+
VALUE type_class = field_type_class(layout, field);
|
687
770
|
|
688
771
|
if (type_class != Qnil) {
|
689
772
|
VALUE args[2] = {
|
@@ -698,9 +781,9 @@ void layout_clear(MessageLayout* layout,
|
|
698
781
|
|
699
782
|
DEREF(memory, VALUE) = ary;
|
700
783
|
} else {
|
701
|
-
native_slot_set(upb_fielddef_name(field),
|
702
|
-
|
703
|
-
|
784
|
+
native_slot_set(upb_fielddef_name(field), upb_fielddef_type(field),
|
785
|
+
field_type_class(layout, field), memory,
|
786
|
+
layout_get_default(field));
|
704
787
|
}
|
705
788
|
}
|
706
789
|
|
@@ -729,12 +812,8 @@ VALUE layout_get_default(const upb_fielddef *field) {
|
|
729
812
|
case UPB_TYPE_BYTES: {
|
730
813
|
size_t size;
|
731
814
|
const char *str = upb_fielddef_defaultstr(field, &size);
|
732
|
-
|
733
|
-
|
734
|
-
rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
|
735
|
-
kRubyString8bitEncoding : kRubyStringUtf8Encoding);
|
736
|
-
rb_obj_freeze(str_rb);
|
737
|
-
return str_rb;
|
815
|
+
return get_frozen_string(str, size,
|
816
|
+
upb_fielddef_type(field) == UPB_TYPE_BYTES);
|
738
817
|
}
|
739
818
|
default: return Qnil;
|
740
819
|
}
|
@@ -744,8 +823,7 @@ VALUE layout_get(MessageLayout* layout,
|
|
744
823
|
const void* storage,
|
745
824
|
const upb_fielddef* field) {
|
746
825
|
void* memory = slot_memory(layout, storage, field);
|
747
|
-
|
748
|
-
|
826
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
749
827
|
bool field_set;
|
750
828
|
if (field_contains_hasbit(layout, field)) {
|
751
829
|
field_set = slot_is_hasbit_set(layout, storage, field);
|
@@ -753,25 +831,25 @@ VALUE layout_get(MessageLayout* layout,
|
|
753
831
|
field_set = true;
|
754
832
|
}
|
755
833
|
|
756
|
-
if (
|
757
|
-
|
834
|
+
if (oneof) {
|
835
|
+
uint32_t oneof_case = slot_read_oneof_case(layout, storage, oneof);
|
836
|
+
if (oneof_case != upb_fielddef_number(field)) {
|
758
837
|
return layout_get_default(field);
|
759
838
|
}
|
760
839
|
return native_slot_get(upb_fielddef_type(field),
|
761
|
-
field_type_class(field),
|
762
|
-
memory);
|
840
|
+
field_type_class(layout, field), memory);
|
763
841
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
764
842
|
return *((VALUE *)memory);
|
765
843
|
} else if (!field_set) {
|
766
844
|
return layout_get_default(field);
|
767
845
|
} else {
|
768
846
|
return native_slot_get(upb_fielddef_type(field),
|
769
|
-
field_type_class(field),
|
770
|
-
memory);
|
847
|
+
field_type_class(layout, field), memory);
|
771
848
|
}
|
772
849
|
}
|
773
850
|
|
774
|
-
static void check_repeated_field_type(
|
851
|
+
static void check_repeated_field_type(const MessageLayout* layout, VALUE val,
|
852
|
+
const upb_fielddef* field) {
|
775
853
|
RepeatedField* self;
|
776
854
|
assert(upb_fielddef_label(field) == UPB_LABEL_REPEATED);
|
777
855
|
|
@@ -785,25 +863,13 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
|
|
785
863
|
rb_raise(cTypeError, "Repeated field array has wrong element type");
|
786
864
|
}
|
787
865
|
|
788
|
-
if (self->
|
789
|
-
|
790
|
-
Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
|
791
|
-
rb_raise(cTypeError,
|
792
|
-
"Repeated field array has wrong message class");
|
793
|
-
}
|
794
|
-
}
|
795
|
-
|
796
|
-
|
797
|
-
if (self->field_type == UPB_TYPE_ENUM) {
|
798
|
-
if (self->field_type_class !=
|
799
|
-
EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
|
800
|
-
rb_raise(cTypeError,
|
801
|
-
"Repeated field array has wrong enum class");
|
802
|
-
}
|
866
|
+
if (self->field_type_class != field_type_class(layout, field)) {
|
867
|
+
rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
|
803
868
|
}
|
804
869
|
}
|
805
870
|
|
806
|
-
static void check_map_field_type(
|
871
|
+
static void check_map_field_type(const MessageLayout* layout, VALUE val,
|
872
|
+
const upb_fielddef* field) {
|
807
873
|
const upb_fielddef* key_field = map_field_key(field);
|
808
874
|
const upb_fielddef* value_field = map_field_value(field);
|
809
875
|
Map* self;
|
@@ -820,25 +886,20 @@ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
|
|
820
886
|
if (self->value_type != upb_fielddef_type(value_field)) {
|
821
887
|
rb_raise(cTypeError, "Map value type does not match field's value type");
|
822
888
|
}
|
823
|
-
if (
|
824
|
-
|
825
|
-
if (self->value_type_class !=
|
826
|
-
get_def_obj(upb_fielddef_subdef(value_field))) {
|
827
|
-
rb_raise(cTypeError,
|
828
|
-
"Map value type has wrong message/enum class");
|
829
|
-
}
|
889
|
+
if (self->value_type_class != field_type_class(layout, value_field)) {
|
890
|
+
rb_raise(cTypeError, "Map value type has wrong message/enum class");
|
830
891
|
}
|
831
892
|
}
|
832
893
|
|
833
|
-
|
834
894
|
void layout_set(MessageLayout* layout,
|
835
895
|
void* storage,
|
836
896
|
const upb_fielddef* field,
|
837
897
|
VALUE val) {
|
838
898
|
void* memory = slot_memory(layout, storage, field);
|
839
|
-
|
899
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
840
900
|
|
841
|
-
if (
|
901
|
+
if (oneof) {
|
902
|
+
uint32_t* oneof_case = slot_oneof_case(layout, storage, oneof);
|
842
903
|
if (val == Qnil) {
|
843
904
|
// Assigning nil to a oneof field clears the oneof completely.
|
844
905
|
*oneof_case = ONEOF_CASE_NONE;
|
@@ -856,22 +917,24 @@ void layout_set(MessageLayout* layout,
|
|
856
917
|
// sync with the value slot whenever the Ruby VM has been called. Thus, we
|
857
918
|
// use native_slot_set_value_and_case(), which ensures that both the value
|
858
919
|
// and case number are altered atomically (w.r.t. the Ruby VM).
|
920
|
+
uint32_t case_value = upb_fielddef_number(field);
|
921
|
+
if (upb_fielddef_issubmsg(field) || upb_fielddef_isstring(field)) {
|
922
|
+
case_value |= ONEOF_CASE_MASK;
|
923
|
+
}
|
924
|
+
|
859
925
|
native_slot_set_value_and_case(
|
860
|
-
upb_fielddef_name(field),
|
861
|
-
|
862
|
-
memory, val,
|
863
|
-
oneof_case, upb_fielddef_number(field));
|
926
|
+
upb_fielddef_name(field), upb_fielddef_type(field),
|
927
|
+
field_type_class(layout, field), memory, val, oneof_case, case_value);
|
864
928
|
}
|
865
929
|
} else if (is_map_field(field)) {
|
866
|
-
check_map_field_type(val, field);
|
930
|
+
check_map_field_type(layout, val, field);
|
867
931
|
DEREF(memory, VALUE) = val;
|
868
932
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
869
|
-
check_repeated_field_type(val, field);
|
933
|
+
check_repeated_field_type(layout, val, field);
|
870
934
|
DEREF(memory, VALUE) = val;
|
871
935
|
} else {
|
872
|
-
native_slot_set(upb_fielddef_name(field),
|
873
|
-
|
874
|
-
memory, val);
|
936
|
+
native_slot_set(upb_fielddef_name(field), upb_fielddef_type(field),
|
937
|
+
field_type_class(layout, field), memory, val);
|
875
938
|
}
|
876
939
|
|
877
940
|
if (layout->fields[upb_fielddef_index(field)].hasbit !=
|
@@ -880,34 +943,33 @@ void layout_set(MessageLayout* layout,
|
|
880
943
|
}
|
881
944
|
}
|
882
945
|
|
883
|
-
void layout_init(MessageLayout* layout,
|
884
|
-
|
946
|
+
void layout_init(MessageLayout* layout, void* storage) {
|
947
|
+
VALUE* value = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
|
948
|
+
int i;
|
885
949
|
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
950
|
+
for (i = 0; i < layout->repeated_count; i++, value++) {
|
951
|
+
*value = RepeatedField_new_this_type(*value);
|
952
|
+
}
|
953
|
+
|
954
|
+
for (i = 0; i < layout->map_count; i++, value++) {
|
955
|
+
*value = Map_new_this_type(*value);
|
891
956
|
}
|
892
957
|
}
|
893
958
|
|
894
959
|
void layout_mark(MessageLayout* layout, void* storage) {
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
upb_msg_field_next(&it)) {
|
899
|
-
const upb_fielddef* field = upb_msg_iter_field(&it);
|
900
|
-
void* memory = slot_memory(layout, storage, field);
|
901
|
-
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
|
960
|
+
VALUE* values = (VALUE*)CHARPTR_AT(storage, layout->value_offset);
|
961
|
+
int noneofs = upb_msgdef_numoneofs(layout->msgdef);
|
962
|
+
int i;
|
902
963
|
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
964
|
+
for (i = 0; i < layout->value_count; i++) {
|
965
|
+
rb_gc_mark(values[i]);
|
966
|
+
}
|
967
|
+
|
968
|
+
for (i = 0; i < noneofs; i++) {
|
969
|
+
MessageOneof* oneof = &layout->oneofs[i];
|
970
|
+
uint32_t* case_ptr = (uint32_t*)CHARPTR_AT(storage, oneof->case_offset);
|
971
|
+
if (*case_ptr & ONEOF_CASE_MASK) {
|
972
|
+
rb_gc_mark(DEREF_OFFSET(storage, oneof->offset, VALUE));
|
911
973
|
}
|
912
974
|
}
|
913
975
|
}
|
@@ -918,14 +980,16 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
|
|
918
980
|
!upb_msg_field_done(&it);
|
919
981
|
upb_msg_field_next(&it)) {
|
920
982
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
983
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
921
984
|
|
922
985
|
void* to_memory = slot_memory(layout, to, field);
|
923
|
-
uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
|
924
986
|
void* from_memory = slot_memory(layout, from, field);
|
925
|
-
uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
|
926
987
|
|
927
|
-
if (
|
928
|
-
|
988
|
+
if (oneof) {
|
989
|
+
uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
|
990
|
+
uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
|
991
|
+
if (slot_read_oneof_case(layout, from, oneof) ==
|
992
|
+
upb_fielddef_number(field)) {
|
929
993
|
*to_oneof_case = *from_oneof_case;
|
930
994
|
native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
|
931
995
|
}
|
@@ -950,14 +1014,16 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
|
|
950
1014
|
!upb_msg_field_done(&it);
|
951
1015
|
upb_msg_field_next(&it)) {
|
952
1016
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
1017
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
953
1018
|
|
954
1019
|
void* to_memory = slot_memory(layout, to, field);
|
955
|
-
uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
|
956
1020
|
void* from_memory = slot_memory(layout, from, field);
|
957
|
-
uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
|
958
1021
|
|
959
|
-
if (
|
960
|
-
|
1022
|
+
if (oneof) {
|
1023
|
+
uint32_t* to_oneof_case = slot_oneof_case(layout, to, oneof);
|
1024
|
+
uint32_t* from_oneof_case = slot_oneof_case(layout, from, oneof);
|
1025
|
+
if (slot_read_oneof_case(layout, from, oneof) ==
|
1026
|
+
upb_fielddef_number(field)) {
|
961
1027
|
*to_oneof_case = *from_oneof_case;
|
962
1028
|
native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
|
963
1029
|
}
|
@@ -984,17 +1050,18 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
|
|
984
1050
|
!upb_msg_field_done(&it);
|
985
1051
|
upb_msg_field_next(&it)) {
|
986
1052
|
const upb_fielddef* field = upb_msg_iter_field(&it);
|
1053
|
+
const upb_oneofdef* oneof = upb_fielddef_containingoneof(field);
|
987
1054
|
|
988
1055
|
void* msg1_memory = slot_memory(layout, msg1, field);
|
989
|
-
uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, field);
|
990
1056
|
void* msg2_memory = slot_memory(layout, msg2, field);
|
991
|
-
uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, field);
|
992
1057
|
|
993
|
-
if (
|
1058
|
+
if (oneof) {
|
1059
|
+
uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, oneof);
|
1060
|
+
uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, oneof);
|
994
1061
|
if (*msg1_oneof_case != *msg2_oneof_case ||
|
995
|
-
(
|
996
|
-
|
997
|
-
|
1062
|
+
(slot_read_oneof_case(layout, msg1, oneof) ==
|
1063
|
+
upb_fielddef_number(field) &&
|
1064
|
+
!native_slot_eq(upb_fielddef_type(field), msg1_memory,
|
998
1065
|
msg2_memory))) {
|
999
1066
|
return Qfalse;
|
1000
1067
|
}
|
@@ -1010,9 +1077,8 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
|
|
1010
1077
|
}
|
1011
1078
|
} else {
|
1012
1079
|
if (slot_is_hasbit_set(layout, msg1, field) !=
|
1013
|
-
|
1014
|
-
!native_slot_eq(upb_fielddef_type(field),
|
1015
|
-
msg1_memory, msg2_memory)) {
|
1080
|
+
slot_is_hasbit_set(layout, msg2, field) ||
|
1081
|
+
!native_slot_eq(upb_fielddef_type(field), msg1_memory, msg2_memory)) {
|
1016
1082
|
return Qfalse;
|
1017
1083
|
}
|
1018
1084
|
}
|