google-protobuf 3.6.1-universal-darwin → 3.7.0.rc.2-universal-darwin

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.

@@ -38,6 +38,8 @@
38
38
  // Ruby <-> native slot management.
39
39
  // -----------------------------------------------------------------------------
40
40
 
41
+ #define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
42
+ #define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
41
43
  #define DEREF(memory, type) *(type*)(memory)
42
44
 
43
45
  size_t native_slot_size(upb_fieldtype_t type) {
@@ -57,37 +59,6 @@ size_t native_slot_size(upb_fieldtype_t type) {
57
59
  }
58
60
  }
59
61
 
60
- static VALUE value_from_default(const upb_fielddef *field) {
61
- switch (upb_fielddef_type(field)) {
62
- case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
63
- case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
64
- case UPB_TYPE_BOOL:
65
- return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
66
- case UPB_TYPE_MESSAGE: return Qnil;
67
- case UPB_TYPE_ENUM: {
68
- const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
69
- int32_t num = upb_fielddef_defaultint32(field);
70
- const char *label = upb_enumdef_iton(enumdef, num);
71
- if (label) {
72
- return ID2SYM(rb_intern(label));
73
- } else {
74
- return INT2NUM(num);
75
- }
76
- }
77
- case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
78
- case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
79
- case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
80
- case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
81
- case UPB_TYPE_STRING:
82
- case UPB_TYPE_BYTES: {
83
- size_t size;
84
- const char *str = upb_fielddef_defaultstr(field, &size);
85
- return rb_str_new(str, size);
86
- }
87
- default: return Qnil;
88
- }
89
- }
90
-
91
62
  static bool is_ruby_num(VALUE value) {
92
63
  return (TYPE(value) == T_FLOAT ||
93
64
  TYPE(value) == T_FIXNUM ||
@@ -96,7 +67,7 @@ static bool is_ruby_num(VALUE value) {
96
67
 
97
68
  void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
98
69
  if (!is_ruby_num(val)) {
99
- rb_raise(rb_eTypeError, "Expected number type for integral field.");
70
+ rb_raise(cTypeError, "Expected number type for integral field.");
100
71
  }
101
72
 
102
73
  // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
@@ -153,13 +124,13 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
153
124
  switch (type) {
154
125
  case UPB_TYPE_FLOAT:
155
126
  if (!is_ruby_num(value)) {
156
- rb_raise(rb_eTypeError, "Expected number type for float field.");
127
+ rb_raise(cTypeError, "Expected number type for float field.");
157
128
  }
158
129
  DEREF(memory, float) = NUM2DBL(value);
159
130
  break;
160
131
  case UPB_TYPE_DOUBLE:
161
132
  if (!is_ruby_num(value)) {
162
- rb_raise(rb_eTypeError, "Expected number type for double field.");
133
+ rb_raise(cTypeError, "Expected number type for double field.");
163
134
  }
164
135
  DEREF(memory, double) = NUM2DBL(value);
165
136
  break;
@@ -170,7 +141,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
170
141
  } else if (value == Qfalse) {
171
142
  val = 0;
172
143
  } else {
173
- rb_raise(rb_eTypeError, "Invalid argument for boolean field.");
144
+ rb_raise(cTypeError, "Invalid argument for boolean field.");
174
145
  }
175
146
  DEREF(memory, int8_t) = val;
176
147
  break;
@@ -179,7 +150,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
179
150
  if (CLASS_OF(value) == rb_cSymbol) {
180
151
  value = rb_funcall(value, rb_intern("to_s"), 0);
181
152
  } else if (CLASS_OF(value) != rb_cString) {
182
- rb_raise(rb_eTypeError, "Invalid argument for string field.");
153
+ rb_raise(cTypeError, "Invalid argument for string field.");
183
154
  }
184
155
 
185
156
  DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -187,7 +158,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
187
158
 
188
159
  case UPB_TYPE_BYTES: {
189
160
  if (CLASS_OF(value) != rb_cString) {
190
- rb_raise(rb_eTypeError, "Invalid argument for string field.");
161
+ rb_raise(cTypeError, "Invalid argument for string field.");
191
162
  }
192
163
 
193
164
  DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
@@ -197,7 +168,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
197
168
  if (CLASS_OF(value) == CLASS_OF(Qnil)) {
198
169
  value = Qnil;
199
170
  } else if (CLASS_OF(value) != type_class) {
200
- rb_raise(rb_eTypeError,
171
+ rb_raise(cTypeError,
201
172
  "Invalid type %s to assign to submessage field.",
202
173
  rb_class2name(CLASS_OF(value)));
203
174
  }
@@ -209,7 +180,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
209
180
  if (TYPE(value) == T_STRING) {
210
181
  value = rb_funcall(value, rb_intern("to_sym"), 0);
211
182
  } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
212
- rb_raise(rb_eTypeError,
183
+ rb_raise(cTypeError,
213
184
  "Expected number or symbol type for enum field.");
214
185
  }
215
186
  if (TYPE(value) == T_SYMBOL) {
@@ -404,7 +375,12 @@ const upb_msgdef *map_entry_msgdef(const upb_fielddef* field) {
404
375
  }
405
376
 
406
377
  bool is_map_field(const upb_fielddef *field) {
407
- return tryget_map_entry_msgdef(field) != NULL;
378
+ const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
379
+ if (subdef == NULL) return false;
380
+
381
+ // Map fields are a proto3 feature.
382
+ // If we're using proto2 syntax we need to fallback to the repeated field.
383
+ return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
408
384
  }
409
385
 
410
386
  const upb_fielddef* map_field_key(const upb_fielddef* field) {
@@ -433,6 +409,12 @@ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
433
409
  // Memory layout management.
434
410
  // -----------------------------------------------------------------------------
435
411
 
412
+ bool field_contains_hasbit(MessageLayout* layout,
413
+ const upb_fielddef* field) {
414
+ return layout->fields[upb_fielddef_index(field)].hasbit !=
415
+ MESSAGE_FIELD_NO_HASBIT;
416
+ }
417
+
436
418
  static size_t align_up_to(size_t offset, size_t granularity) {
437
419
  // Granularity must be a power of two.
438
420
  return (offset + granularity - 1) & ~(granularity - 1);
@@ -447,6 +429,23 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
447
429
 
448
430
  layout->fields = ALLOC_N(MessageField, nfields);
449
431
 
432
+ size_t hasbit = 0;
433
+ for (upb_msg_field_begin(&it, msgdef);
434
+ !upb_msg_field_done(&it);
435
+ upb_msg_field_next(&it)) {
436
+ const upb_fielddef* field = upb_msg_iter_field(&it);
437
+ if (upb_fielddef_haspresence(field)) {
438
+ layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
439
+ } else {
440
+ layout->fields[upb_fielddef_index(field)].hasbit =
441
+ MESSAGE_FIELD_NO_HASBIT;
442
+ }
443
+ }
444
+
445
+ if (hasbit != 0) {
446
+ off += (hasbit + 8 - 1) / 8;
447
+ }
448
+
450
449
  for (upb_msg_field_begin(&it, msgdef);
451
450
  !upb_msg_field_done(&it);
452
451
  upb_msg_field_next(&it)) {
@@ -569,6 +568,136 @@ static uint32_t* slot_oneof_case(MessageLayout* layout,
569
568
  layout->fields[upb_fielddef_index(field)].case_offset);
570
569
  }
571
570
 
571
+ static void slot_set_hasbit(MessageLayout* layout,
572
+ const void* storage,
573
+ const upb_fielddef* field) {
574
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
575
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
576
+
577
+ ((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
578
+ }
579
+
580
+ static void slot_clear_hasbit(MessageLayout* layout,
581
+ const void* storage,
582
+ const upb_fielddef* field) {
583
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
584
+ assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
585
+ ((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
586
+ }
587
+
588
+ static bool slot_is_hasbit_set(MessageLayout* layout,
589
+ const void* storage,
590
+ const upb_fielddef* field) {
591
+ size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
592
+ if (hasbit == MESSAGE_FIELD_NO_HASBIT) {
593
+ return false;
594
+ }
595
+
596
+ return DEREF_OFFSET(
597
+ (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
598
+ }
599
+
600
+ VALUE layout_has(MessageLayout* layout,
601
+ const void* storage,
602
+ const upb_fielddef* field) {
603
+ assert(field_contains_hasbit(layout, field));
604
+ return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
605
+ }
606
+
607
+ void layout_clear(MessageLayout* layout,
608
+ const void* storage,
609
+ const upb_fielddef* field) {
610
+ void* memory = slot_memory(layout, storage, field);
611
+ uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
612
+
613
+ if (field_contains_hasbit(layout, field)) {
614
+ slot_clear_hasbit(layout, storage, field);
615
+ }
616
+
617
+ if (upb_fielddef_containingoneof(field)) {
618
+ memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
619
+ *oneof_case = ONEOF_CASE_NONE;
620
+ } else if (is_map_field(field)) {
621
+ VALUE map = Qnil;
622
+
623
+ const upb_fielddef* key_field = map_field_key(field);
624
+ const upb_fielddef* value_field = map_field_value(field);
625
+ VALUE type_class = field_type_class(value_field);
626
+
627
+ if (type_class != Qnil) {
628
+ VALUE args[3] = {
629
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
630
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
631
+ type_class,
632
+ };
633
+ map = rb_class_new_instance(3, args, cMap);
634
+ } else {
635
+ VALUE args[2] = {
636
+ fieldtype_to_ruby(upb_fielddef_type(key_field)),
637
+ fieldtype_to_ruby(upb_fielddef_type(value_field)),
638
+ };
639
+ map = rb_class_new_instance(2, args, cMap);
640
+ }
641
+
642
+ DEREF(memory, VALUE) = map;
643
+ } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
644
+ VALUE ary = Qnil;
645
+
646
+ VALUE type_class = field_type_class(field);
647
+
648
+ if (type_class != Qnil) {
649
+ VALUE args[2] = {
650
+ fieldtype_to_ruby(upb_fielddef_type(field)),
651
+ type_class,
652
+ };
653
+ ary = rb_class_new_instance(2, args, cRepeatedField);
654
+ } else {
655
+ VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
656
+ ary = rb_class_new_instance(1, args, cRepeatedField);
657
+ }
658
+
659
+ DEREF(memory, VALUE) = ary;
660
+ } else {
661
+ native_slot_set(upb_fielddef_type(field), field_type_class(field),
662
+ memory, layout_get_default(field));
663
+ }
664
+ }
665
+
666
+ VALUE layout_get_default(const upb_fielddef *field) {
667
+ switch (upb_fielddef_type(field)) {
668
+ case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
669
+ case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
670
+ case UPB_TYPE_BOOL:
671
+ return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
672
+ case UPB_TYPE_MESSAGE: return Qnil;
673
+ case UPB_TYPE_ENUM: {
674
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
675
+ int32_t num = upb_fielddef_defaultint32(field);
676
+ const char *label = upb_enumdef_iton(enumdef, num);
677
+ if (label) {
678
+ return ID2SYM(rb_intern(label));
679
+ } else {
680
+ return INT2NUM(num);
681
+ }
682
+ }
683
+ case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
684
+ case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
685
+ case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
686
+ case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
687
+ case UPB_TYPE_STRING:
688
+ case UPB_TYPE_BYTES: {
689
+ size_t size;
690
+ const char *str = upb_fielddef_defaultstr(field, &size);
691
+ VALUE str_rb = rb_str_new(str, size);
692
+
693
+ rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
694
+ kRubyString8bitEncoding : kRubyStringUtf8Encoding);
695
+ rb_obj_freeze(str_rb);
696
+ return str_rb;
697
+ }
698
+ default: return Qnil;
699
+ }
700
+ }
572
701
 
573
702
  VALUE layout_get(MessageLayout* layout,
574
703
  const void* storage,
@@ -576,15 +705,24 @@ VALUE layout_get(MessageLayout* layout,
576
705
  void* memory = slot_memory(layout, storage, field);
577
706
  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
578
707
 
708
+ bool field_set;
709
+ if (field_contains_hasbit(layout, field)) {
710
+ field_set = slot_is_hasbit_set(layout, storage, field);
711
+ } else {
712
+ field_set = true;
713
+ }
714
+
579
715
  if (upb_fielddef_containingoneof(field)) {
580
716
  if (*oneof_case != upb_fielddef_number(field)) {
581
- return value_from_default(field);
717
+ return layout_get_default(field);
582
718
  }
583
719
  return native_slot_get(upb_fielddef_type(field),
584
720
  field_type_class(field),
585
721
  memory);
586
722
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
587
723
  return *((VALUE *)memory);
724
+ } else if (!field_set) {
725
+ return layout_get_default(field);
588
726
  } else {
589
727
  return native_slot_get(upb_fielddef_type(field),
590
728
  field_type_class(field),
@@ -598,18 +736,18 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
598
736
 
599
737
  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
600
738
  RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
601
- rb_raise(rb_eTypeError, "Expected repeated field array");
739
+ rb_raise(cTypeError, "Expected repeated field array");
602
740
  }
603
741
 
604
742
  self = ruby_to_RepeatedField(val);
605
743
  if (self->field_type != upb_fielddef_type(field)) {
606
- rb_raise(rb_eTypeError, "Repeated field array has wrong element type");
744
+ rb_raise(cTypeError, "Repeated field array has wrong element type");
607
745
  }
608
746
 
609
- if (self->field_type == UPB_TYPE_MESSAGE) {
747
+ if (self->field_type == UPB_TYPE_MESSAGE) {
610
748
  if (self->field_type_class !=
611
749
  Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
612
- rb_raise(rb_eTypeError,
750
+ rb_raise(cTypeError,
613
751
  "Repeated field array has wrong message class");
614
752
  }
615
753
  }
@@ -618,7 +756,7 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
618
756
  if (self->field_type == UPB_TYPE_ENUM) {
619
757
  if (self->field_type_class !=
620
758
  EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
621
- rb_raise(rb_eTypeError,
759
+ rb_raise(cTypeError,
622
760
  "Repeated field array has wrong enum class");
623
761
  }
624
762
  }
@@ -631,21 +769,21 @@ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
631
769
 
632
770
  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
633
771
  RTYPEDDATA_TYPE(val) != &Map_type) {
634
- rb_raise(rb_eTypeError, "Expected Map instance");
772
+ rb_raise(cTypeError, "Expected Map instance");
635
773
  }
636
774
 
637
775
  self = ruby_to_Map(val);
638
776
  if (self->key_type != upb_fielddef_type(key_field)) {
639
- rb_raise(rb_eTypeError, "Map key type does not match field's key type");
777
+ rb_raise(cTypeError, "Map key type does not match field's key type");
640
778
  }
641
779
  if (self->value_type != upb_fielddef_type(value_field)) {
642
- rb_raise(rb_eTypeError, "Map value type does not match field's value type");
780
+ rb_raise(cTypeError, "Map value type does not match field's value type");
643
781
  }
644
782
  if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
645
783
  upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
646
784
  if (self->value_type_class !=
647
785
  get_def_obj(upb_fielddef_subdef(value_field))) {
648
- rb_raise(rb_eTypeError,
786
+ rb_raise(cTypeError,
649
787
  "Map value type has wrong message/enum class");
650
788
  }
651
789
  }
@@ -689,67 +827,24 @@ void layout_set(MessageLayout* layout,
689
827
  check_repeated_field_type(val, field);
690
828
  DEREF(memory, VALUE) = val;
691
829
  } else {
692
- native_slot_set(upb_fielddef_type(field), field_type_class(field),
693
- memory, val);
830
+ native_slot_set(upb_fielddef_type(field), field_type_class(field), memory,
831
+ val);
832
+ }
833
+
834
+ if (layout->fields[upb_fielddef_index(field)].hasbit !=
835
+ MESSAGE_FIELD_NO_HASBIT) {
836
+ slot_set_hasbit(layout, storage, field);
694
837
  }
695
838
  }
696
839
 
697
840
  void layout_init(MessageLayout* layout,
698
841
  void* storage) {
842
+
699
843
  upb_msg_field_iter it;
700
844
  for (upb_msg_field_begin(&it, layout->msgdef);
701
845
  !upb_msg_field_done(&it);
702
846
  upb_msg_field_next(&it)) {
703
- const upb_fielddef* field = upb_msg_iter_field(&it);
704
- void* memory = slot_memory(layout, storage, field);
705
- uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
706
-
707
- if (upb_fielddef_containingoneof(field)) {
708
- memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
709
- *oneof_case = ONEOF_CASE_NONE;
710
- } else if (is_map_field(field)) {
711
- VALUE map = Qnil;
712
-
713
- const upb_fielddef* key_field = map_field_key(field);
714
- const upb_fielddef* value_field = map_field_value(field);
715
- VALUE type_class = field_type_class(value_field);
716
-
717
- if (type_class != Qnil) {
718
- VALUE args[3] = {
719
- fieldtype_to_ruby(upb_fielddef_type(key_field)),
720
- fieldtype_to_ruby(upb_fielddef_type(value_field)),
721
- type_class,
722
- };
723
- map = rb_class_new_instance(3, args, cMap);
724
- } else {
725
- VALUE args[2] = {
726
- fieldtype_to_ruby(upb_fielddef_type(key_field)),
727
- fieldtype_to_ruby(upb_fielddef_type(value_field)),
728
- };
729
- map = rb_class_new_instance(2, args, cMap);
730
- }
731
-
732
- DEREF(memory, VALUE) = map;
733
- } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
734
- VALUE ary = Qnil;
735
-
736
- VALUE type_class = field_type_class(field);
737
-
738
- if (type_class != Qnil) {
739
- VALUE args[2] = {
740
- fieldtype_to_ruby(upb_fielddef_type(field)),
741
- type_class,
742
- };
743
- ary = rb_class_new_instance(2, args, cRepeatedField);
744
- } else {
745
- VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
746
- ary = rb_class_new_instance(1, args, cRepeatedField);
747
- }
748
-
749
- DEREF(memory, VALUE) = ary;
750
- } else {
751
- native_slot_init(upb_fielddef_type(field), memory);
752
- }
847
+ layout_clear(layout, storage, upb_msg_iter_field(&it));
753
848
  }
754
849
  }
755
850
 
@@ -796,6 +891,11 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
796
891
  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
797
892
  DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
798
893
  } else {
894
+ if (field_contains_hasbit(layout, field)) {
895
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
896
+ slot_set_hasbit(layout, to, field);
897
+ }
898
+
799
899
  native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
800
900
  }
801
901
  }
@@ -825,6 +925,11 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
825
925
  DEREF(to_memory, VALUE) =
826
926
  RepeatedField_deep_copy(DEREF(from_memory, VALUE));
827
927
  } else {
928
+ if (field_contains_hasbit(layout, field)) {
929
+ if (!slot_is_hasbit_set(layout, from, field)) continue;
930
+ slot_set_hasbit(layout, to, field);
931
+ }
932
+
828
933
  native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
829
934
  }
830
935
  }
@@ -861,8 +966,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
861
966
  return Qfalse;
862
967
  }
863
968
  } else {
864
- if (!native_slot_eq(upb_fielddef_type(field),
865
- msg1_memory, msg2_memory)) {
969
+ if (slot_is_hasbit_set(layout, msg1, field) !=
970
+ slot_is_hasbit_set(layout, msg2, field) ||
971
+ !native_slot_eq(upb_fielddef_type(field),
972
+ msg1_memory, msg2_memory)) {
866
973
  return Qfalse;
867
974
  }
868
975
  }