google-protobuf 3.25.0.rc.2 → 4.26.1
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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/convert.c +7 -4
- data/ext/google/protobuf_c/defs.c +172 -24
- data/ext/google/protobuf_c/extconf.rb +1 -1
- data/ext/google/protobuf_c/glue.c +37 -2
- data/ext/google/protobuf_c/map.c +21 -8
- data/ext/google/protobuf_c/map.h +3 -0
- data/ext/google/protobuf_c/message.c +73 -71
- data/ext/google/protobuf_c/message.h +7 -0
- data/ext/google/protobuf_c/protobuf.c +19 -6
- data/ext/google/protobuf_c/repeated_field.c +14 -4
- data/ext/google/protobuf_c/repeated_field.h +3 -0
- data/ext/google/protobuf_c/ruby-upb.c +11788 -10795
- data/ext/google/protobuf_c/ruby-upb.h +5164 -4242
- data/ext/google/protobuf_c/shared_convert.c +5 -3
- data/ext/google/protobuf_c/shared_convert.h +2 -2
- data/ext/google/protobuf_c/shared_message.c +8 -6
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +467 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +9 -8
- data/lib/google/protobuf/any_pb.rb +1 -22
- data/lib/google/protobuf/api_pb.rb +1 -24
- data/lib/google/protobuf/descriptor_pb.rb +2 -23
- data/lib/google/protobuf/duration_pb.rb +1 -22
- data/lib/google/protobuf/empty_pb.rb +1 -22
- data/lib/google/protobuf/ffi/descriptor.rb +11 -1
- data/lib/google/protobuf/ffi/descriptor_pool.rb +14 -9
- data/lib/google/protobuf/ffi/enum_descriptor.rb +11 -1
- data/lib/google/protobuf/ffi/ffi.rb +3 -1
- data/lib/google/protobuf/ffi/field_descriptor.rb +34 -15
- data/lib/google/protobuf/ffi/file_descriptor.rb +11 -12
- data/lib/google/protobuf/ffi/internal/convert.rb +7 -23
- data/lib/google/protobuf/ffi/map.rb +13 -0
- data/lib/google/protobuf/ffi/message.rb +20 -2
- data/lib/google/protobuf/ffi/object_cache.rb +3 -3
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +18 -11
- data/lib/google/protobuf/ffi/repeated_field.rb +15 -133
- data/lib/google/protobuf/field_mask_pb.rb +1 -22
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/plugin_pb.rb +2 -24
- data/lib/google/protobuf/repeated_field.rb +1 -2
- data/lib/google/protobuf/source_context_pb.rb +1 -22
- data/lib/google/protobuf/struct_pb.rb +1 -22
- data/lib/google/protobuf/timestamp_pb.rb +1 -22
- data/lib/google/protobuf/type_pb.rb +1 -24
- data/lib/google/protobuf/wrappers_pb.rb +1 -22
- data/lib/google/protobuf.rb +1 -1
- data/lib/google/protobuf_ffi.rb +1 -2
- data/lib/google/protobuf_native.rb +0 -1
- data/lib/google/tasks/ffi.rake +43 -37
- metadata +10 -13
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
- data/lib/google/protobuf/descriptor_dsl.rb +0 -465
- data/lib/google/protobuf/object_cache.rb +0 -97
|
@@ -44,9 +44,11 @@ static void Message_mark(void* _self) {
|
|
|
44
44
|
rb_gc_mark(self->arena);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
static size_t Message_memsize(const void* _self) { return sizeof(Message); }
|
|
48
|
+
|
|
47
49
|
static rb_data_type_t Message_type = {
|
|
48
50
|
"Google::Protobuf::Message",
|
|
49
|
-
{Message_mark, RUBY_DEFAULT_FREE,
|
|
51
|
+
{Message_mark, RUBY_DEFAULT_FREE, Message_memsize},
|
|
50
52
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
|
51
53
|
};
|
|
52
54
|
|
|
@@ -488,7 +490,8 @@ static int Map_initialize_kwarg(VALUE key, VALUE val, VALUE _self) {
|
|
|
488
490
|
k = Convert_RubyToUpb(key, "", map_init->key_type, NULL);
|
|
489
491
|
|
|
490
492
|
if (map_init->val_type.type == kUpb_CType_Message && TYPE(val) == T_HASH) {
|
|
491
|
-
upb_MiniTable* t =
|
|
493
|
+
const upb_MiniTable* t =
|
|
494
|
+
upb_MessageDef_MiniTable(map_init->val_type.def.msgdef);
|
|
492
495
|
upb_Message* msg = upb_Message_New(t, map_init->arena);
|
|
493
496
|
Message_InitFromValue(msg, map_init->val_type.def.msgdef, val,
|
|
494
497
|
map_init->arena);
|
|
@@ -519,7 +522,7 @@ static upb_MessageValue MessageValue_FromValue(VALUE val, TypeInfo info,
|
|
|
519
522
|
upb_Arena* arena) {
|
|
520
523
|
if (info.type == kUpb_CType_Message) {
|
|
521
524
|
upb_MessageValue msgval;
|
|
522
|
-
upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
|
525
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(info.def.msgdef);
|
|
523
526
|
upb_Message* msg = upb_Message_New(t, arena);
|
|
524
527
|
Message_InitFromValue(msg, info.def.msgdef, val, arena);
|
|
525
528
|
msgval.msg_val = msg;
|
|
@@ -635,7 +638,7 @@ static VALUE Message_initialize(int argc, VALUE* argv, VALUE _self) {
|
|
|
635
638
|
Message* self = ruby_to_Message(_self);
|
|
636
639
|
VALUE arena_rb = Arena_new();
|
|
637
640
|
upb_Arena* arena = Arena_get(arena_rb);
|
|
638
|
-
upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
|
641
|
+
const upb_MiniTable* t = upb_MessageDef_MiniTable(self->msgdef);
|
|
639
642
|
upb_Message* msg = upb_Message_New(t, arena);
|
|
640
643
|
|
|
641
644
|
Message_InitPtr(_self, msg, arena_rb);
|
|
@@ -660,11 +663,8 @@ static VALUE Message_dup(VALUE _self) {
|
|
|
660
663
|
Message* self = ruby_to_Message(_self);
|
|
661
664
|
VALUE new_msg = rb_class_new_instance(0, NULL, CLASS_OF(_self));
|
|
662
665
|
Message* new_msg_self = ruby_to_Message(new_msg);
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
// TODO
|
|
666
|
-
// TODO
|
|
667
|
-
memcpy((upb_Message*)new_msg_self->msg, self->msg, size);
|
|
666
|
+
const upb_MiniTable* m = upb_MessageDef_MiniTable(self->msgdef);
|
|
667
|
+
upb_Message_ShallowCopy((upb_Message*)new_msg_self->msg, self->msg, m);
|
|
668
668
|
Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
|
|
669
669
|
return new_msg;
|
|
670
670
|
}
|
|
@@ -678,7 +678,8 @@ bool Message_Equal(const upb_Message* m1, const upb_Message* m2,
|
|
|
678
678
|
if (upb_Status_IsOk(&status)) {
|
|
679
679
|
return return_value;
|
|
680
680
|
} else {
|
|
681
|
-
rb_raise(cParseError,
|
|
681
|
+
rb_raise(cParseError, "Message_Equal(): %s",
|
|
682
|
+
upb_Status_ErrorMessage(&status));
|
|
682
683
|
}
|
|
683
684
|
}
|
|
684
685
|
|
|
@@ -709,7 +710,8 @@ uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
709
710
|
if (upb_Status_IsOk(&status)) {
|
|
710
711
|
return return_value;
|
|
711
712
|
} else {
|
|
712
|
-
rb_raise(cParseError,
|
|
713
|
+
rb_raise(cParseError, "Message_Hash(): %s",
|
|
714
|
+
upb_Status_ErrorMessage(&status));
|
|
713
715
|
}
|
|
714
716
|
}
|
|
715
717
|
|
|
@@ -766,58 +768,34 @@ static VALUE Message_CreateHash(const upb_Message* msg,
|
|
|
766
768
|
if (!msg) return Qnil;
|
|
767
769
|
|
|
768
770
|
VALUE hash = rb_hash_new();
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
// This is unfortunate, we should key behaviors off field attributes (like
|
|
774
|
-
// whether a field has presence), not proto2 vs. proto3. We should see if we
|
|
775
|
-
// can change this without breaking users.
|
|
776
|
-
is_proto2 = upb_MessageDef_Syntax(m) == kUpb_Syntax_Proto2;
|
|
777
|
-
|
|
778
|
-
for (int i = 0; i < n; i++) {
|
|
779
|
-
const upb_FieldDef* field = upb_MessageDef_Field(m, i);
|
|
780
|
-
TypeInfo type_info = TypeInfo_get(field);
|
|
781
|
-
upb_MessageValue msgval;
|
|
782
|
-
VALUE msg_value;
|
|
783
|
-
VALUE msg_key;
|
|
784
|
-
|
|
785
|
-
if (!is_proto2 && upb_FieldDef_IsSubMessage(field) &&
|
|
786
|
-
!upb_FieldDef_IsRepeated(field) &&
|
|
787
|
-
!upb_Message_HasFieldByDef(msg, field)) {
|
|
788
|
-
// TODO: Legacy behavior, remove when we fix the is_proto2 differences.
|
|
789
|
-
msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
|
790
|
-
rb_hash_aset(hash, msg_key, Qnil);
|
|
791
|
-
continue;
|
|
792
|
-
}
|
|
771
|
+
size_t iter = kUpb_Message_Begin;
|
|
772
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(m));
|
|
773
|
+
const upb_FieldDef* field;
|
|
774
|
+
upb_MessageValue val;
|
|
793
775
|
|
|
794
|
-
|
|
795
|
-
if (
|
|
796
|
-
|
|
776
|
+
while (upb_Message_Next(msg, m, pool, &field, &val, &iter)) {
|
|
777
|
+
if (upb_FieldDef_IsExtension(field)) {
|
|
778
|
+
// TODO: allow extensions once we have decided what naming scheme the
|
|
779
|
+
// symbol should use. eg. :"[pkg.ext]"
|
|
797
780
|
continue;
|
|
798
781
|
}
|
|
799
782
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
// Proto2 omits empty map/repeated filds also.
|
|
783
|
+
TypeInfo type_info = TypeInfo_get(field);
|
|
784
|
+
VALUE msg_value;
|
|
804
785
|
|
|
805
786
|
if (upb_FieldDef_IsMap(field)) {
|
|
806
787
|
const upb_MessageDef* entry_m = upb_FieldDef_MessageSubDef(field);
|
|
807
788
|
const upb_FieldDef* key_f = upb_MessageDef_FindFieldByNumber(entry_m, 1);
|
|
808
789
|
const upb_FieldDef* val_f = upb_MessageDef_FindFieldByNumber(entry_m, 2);
|
|
809
790
|
upb_CType key_type = upb_FieldDef_CType(key_f);
|
|
810
|
-
msg_value = Map_CreateHash(
|
|
791
|
+
msg_value = Map_CreateHash(val.map_val, key_type, TypeInfo_get(val_f));
|
|
811
792
|
} else if (upb_FieldDef_IsRepeated(field)) {
|
|
812
|
-
|
|
813
|
-
(!msgval.array_val || upb_Array_Size(msgval.array_val) == 0)) {
|
|
814
|
-
continue;
|
|
815
|
-
}
|
|
816
|
-
msg_value = RepeatedField_CreateArray(msgval.array_val, type_info);
|
|
793
|
+
msg_value = RepeatedField_CreateArray(val.array_val, type_info);
|
|
817
794
|
} else {
|
|
818
|
-
msg_value = Scalar_CreateHash(
|
|
795
|
+
msg_value = Scalar_CreateHash(val, type_info);
|
|
819
796
|
}
|
|
820
797
|
|
|
798
|
+
VALUE msg_key = ID2SYM(rb_intern(upb_FieldDef_Name(field)));
|
|
821
799
|
rb_hash_aset(hash, msg_key, msg_value);
|
|
822
800
|
}
|
|
823
801
|
|
|
@@ -850,11 +828,27 @@ static VALUE Message_to_h(VALUE _self) {
|
|
|
850
828
|
* Freezes the message object. We have to intercept this so we can pin the
|
|
851
829
|
* Ruby object into memory so we don't forget it's frozen.
|
|
852
830
|
*/
|
|
853
|
-
|
|
831
|
+
VALUE Message_freeze(VALUE _self) {
|
|
854
832
|
Message* self = ruby_to_Message(_self);
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
833
|
+
|
|
834
|
+
if (RB_OBJ_FROZEN(_self)) return _self;
|
|
835
|
+
Arena_Pin(self->arena, _self);
|
|
836
|
+
RB_OBJ_FREEZE(_self);
|
|
837
|
+
|
|
838
|
+
int n = upb_MessageDef_FieldCount(self->msgdef);
|
|
839
|
+
for (int i = 0; i < n; i++) {
|
|
840
|
+
const upb_FieldDef* f = upb_MessageDef_Field(self->msgdef, i);
|
|
841
|
+
VALUE field = Message_getfield(_self, f);
|
|
842
|
+
|
|
843
|
+
if (field != Qnil) {
|
|
844
|
+
if (upb_FieldDef_IsMap(f)) {
|
|
845
|
+
Map_freeze(field);
|
|
846
|
+
} else if (upb_FieldDef_IsRepeated(f)) {
|
|
847
|
+
RepeatedField_freeze(field);
|
|
848
|
+
} else if (upb_FieldDef_IsSubMessage(f)) {
|
|
849
|
+
Message_freeze(field);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
858
852
|
}
|
|
859
853
|
return _self;
|
|
860
854
|
}
|
|
@@ -911,7 +905,7 @@ static VALUE Message_index_set(VALUE _self, VALUE field_name, VALUE value) {
|
|
|
911
905
|
* MessageClass.decode(data, options) => message
|
|
912
906
|
*
|
|
913
907
|
* Decodes the given data (as a string containing bytes in protocol buffers wire
|
|
914
|
-
* format) under the
|
|
908
|
+
* format) under the interpretation given by this message class's definition
|
|
915
909
|
* and returns a message object with the corresponding field values.
|
|
916
910
|
* @param options [Hash] options for the decoder
|
|
917
911
|
* recursion_limit: set to maximum decoding depth for message (default is 64)
|
|
@@ -942,18 +936,27 @@ static VALUE Message_decode(int argc, VALUE* argv, VALUE klass) {
|
|
|
942
936
|
rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
|
|
943
937
|
}
|
|
944
938
|
|
|
939
|
+
return Message_decode_bytes(RSTRING_LEN(data), RSTRING_PTR(data), options,
|
|
940
|
+
klass, /*freeze*/ false);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
|
944
|
+
VALUE klass, bool freeze) {
|
|
945
945
|
VALUE msg_rb = initialize_rb_class_with_no_args(klass);
|
|
946
946
|
Message* msg = ruby_to_Message(msg_rb);
|
|
947
947
|
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
948
|
+
const upb_FileDef* file = upb_MessageDef_File(msg->msgdef);
|
|
949
|
+
const upb_ExtensionRegistry* extreg =
|
|
950
|
+
upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file));
|
|
951
|
+
upb_DecodeStatus status = upb_Decode(bytes, size, (upb_Message*)msg->msg,
|
|
952
|
+
upb_MessageDef_MiniTable(msg->msgdef),
|
|
953
|
+
extreg, options, Arena_get(msg->arena));
|
|
953
954
|
if (status != kUpb_DecodeStatus_Ok) {
|
|
954
955
|
rb_raise(cParseError, "Error occurred during parsing");
|
|
955
956
|
}
|
|
956
|
-
|
|
957
|
+
if (freeze) {
|
|
958
|
+
Message_freeze(msg_rb);
|
|
959
|
+
}
|
|
957
960
|
return msg_rb;
|
|
958
961
|
}
|
|
959
962
|
|
|
@@ -974,9 +977,6 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
974
977
|
int options = 0;
|
|
975
978
|
upb_Status status;
|
|
976
979
|
|
|
977
|
-
// TODO: use this message's pool instead.
|
|
978
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
|
979
|
-
|
|
980
980
|
if (argc < 1 || argc > 2) {
|
|
981
981
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
|
982
982
|
}
|
|
@@ -1010,8 +1010,9 @@ static VALUE Message_decode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
1010
1010
|
}
|
|
1011
1011
|
|
|
1012
1012
|
upb_Status_Clear(&status);
|
|
1013
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef));
|
|
1013
1014
|
if (!upb_JsonDecode(RSTRING_PTR(data), RSTRING_LEN(data),
|
|
1014
|
-
(upb_Message*)msg->msg, msg->msgdef,
|
|
1015
|
+
(upb_Message*)msg->msg, msg->msgdef, pool, options,
|
|
1015
1016
|
Arena_get(msg->arena), &status)) {
|
|
1016
1017
|
rb_raise(cParseError, "Error occurred during parsing: %s",
|
|
1017
1018
|
upb_Status_ErrorMessage(&status));
|
|
@@ -1090,9 +1091,6 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
1090
1091
|
size_t size;
|
|
1091
1092
|
upb_Status status;
|
|
1092
1093
|
|
|
1093
|
-
// TODO: use this message's pool instead.
|
|
1094
|
-
const upb_DefPool* symtab = DescriptorPool_GetSymtab(generated_pool);
|
|
1095
|
-
|
|
1096
1094
|
if (argc < 1 || argc > 2) {
|
|
1097
1095
|
rb_raise(rb_eArgError, "Expected 1 or 2 arguments.");
|
|
1098
1096
|
}
|
|
@@ -1127,8 +1125,9 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
1127
1125
|
}
|
|
1128
1126
|
|
|
1129
1127
|
upb_Status_Clear(&status);
|
|
1130
|
-
|
|
1131
|
-
|
|
1128
|
+
const upb_DefPool* pool = upb_FileDef_Pool(upb_MessageDef_File(msg->msgdef));
|
|
1129
|
+
size = upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf, sizeof(buf),
|
|
1130
|
+
&status);
|
|
1132
1131
|
|
|
1133
1132
|
if (!upb_Status_IsOk(&status)) {
|
|
1134
1133
|
rb_raise(cParseError, "Error occurred during encoding: %s",
|
|
@@ -1138,7 +1137,7 @@ static VALUE Message_encode_json(int argc, VALUE* argv, VALUE klass) {
|
|
|
1138
1137
|
VALUE ret;
|
|
1139
1138
|
if (size >= sizeof(buf)) {
|
|
1140
1139
|
char* buf2 = malloc(size + 1);
|
|
1141
|
-
upb_JsonEncode(msg->msg, msg->msgdef,
|
|
1140
|
+
upb_JsonEncode(msg->msg, msg->msgdef, pool, options, buf2, size + 1,
|
|
1142
1141
|
&status);
|
|
1143
1142
|
ret = rb_str_new(buf2, size);
|
|
1144
1143
|
free(buf2);
|
|
@@ -1271,9 +1270,12 @@ upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
|
|
1271
1270
|
upb_Message* new_msg = upb_Message_New(layout, arena);
|
|
1272
1271
|
char* data;
|
|
1273
1272
|
|
|
1273
|
+
const upb_FileDef* file = upb_MessageDef_File(m);
|
|
1274
|
+
const upb_ExtensionRegistry* extreg =
|
|
1275
|
+
upb_DefPool_ExtensionRegistry(upb_FileDef_Pool(file));
|
|
1274
1276
|
if (upb_Encode(msg, layout, 0, tmp_arena, &data, &size) !=
|
|
1275
1277
|
kUpb_EncodeStatus_Ok ||
|
|
1276
|
-
upb_Decode(data, size, new_msg, layout,
|
|
1278
|
+
upb_Decode(data, size, new_msg, layout, extreg, 0, arena) !=
|
|
1277
1279
|
kUpb_DecodeStatus_Ok) {
|
|
1278
1280
|
upb_Arena_Free(tmp_arena);
|
|
1279
1281
|
rb_raise(cParseError, "Error occurred copying proto");
|
|
@@ -73,6 +73,13 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc);
|
|
|
73
73
|
// module.
|
|
74
74
|
VALUE MessageOrEnum_GetDescriptor(VALUE klass);
|
|
75
75
|
|
|
76
|
+
// Decodes a Message from a byte sequence.
|
|
77
|
+
VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
|
78
|
+
VALUE klass, bool freeze);
|
|
79
|
+
|
|
80
|
+
// Recursively freeze message
|
|
81
|
+
VALUE Message_freeze(VALUE _self);
|
|
82
|
+
|
|
76
83
|
// Call at startup to register all types in this module.
|
|
77
84
|
void Message_register(VALUE protobuf);
|
|
78
85
|
|
|
@@ -164,11 +164,23 @@ static void Arena_free(void *data) {
|
|
|
164
164
|
xfree(arena);
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
static size_t Arena_memsize(const void *data) {
|
|
168
|
+
const Arena *arena = data;
|
|
169
|
+
size_t fused_count;
|
|
170
|
+
size_t memsize = upb_Arena_SpaceAllocated(arena->arena, &fused_count);
|
|
171
|
+
if (fused_count > 1) {
|
|
172
|
+
// If other arena were fused we attribute an equal
|
|
173
|
+
// share of memory usage to each one.
|
|
174
|
+
memsize /= fused_count;
|
|
175
|
+
}
|
|
176
|
+
return memsize + sizeof(Arena);
|
|
177
|
+
}
|
|
178
|
+
|
|
167
179
|
static VALUE cArena;
|
|
168
180
|
|
|
169
181
|
const rb_data_type_t Arena_type = {
|
|
170
182
|
"Google::Protobuf::Internal::Arena",
|
|
171
|
-
{Arena_mark, Arena_free,
|
|
183
|
+
{Arena_mark, Arena_free, Arena_memsize},
|
|
172
184
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
|
173
185
|
};
|
|
174
186
|
|
|
@@ -241,16 +253,17 @@ static void ObjectCache_Init(VALUE protobuf) {
|
|
|
241
253
|
item_try_add = rb_intern("try_add");
|
|
242
254
|
|
|
243
255
|
rb_gc_register_address(&weak_obj_cache);
|
|
256
|
+
VALUE internal = rb_const_get(protobuf, rb_intern("Internal"));
|
|
244
257
|
#if SIZEOF_LONG >= SIZEOF_VALUE
|
|
245
|
-
VALUE cache_class = rb_const_get(
|
|
258
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("ObjectCache"));
|
|
246
259
|
#else
|
|
247
|
-
VALUE cache_class = rb_const_get(
|
|
260
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("LegacyObjectCache"));
|
|
248
261
|
#endif
|
|
249
262
|
|
|
250
263
|
weak_obj_cache = rb_class_new_instance(0, NULL, cache_class);
|
|
251
|
-
rb_const_set(
|
|
252
|
-
rb_const_set(
|
|
253
|
-
rb_const_set(
|
|
264
|
+
rb_const_set(internal, rb_intern("OBJECT_CACHE"), weak_obj_cache);
|
|
265
|
+
rb_const_set(internal, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG));
|
|
266
|
+
rb_const_set(internal, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE));
|
|
254
267
|
}
|
|
255
268
|
|
|
256
269
|
static VALUE ObjectCache_GetKey(const void *key) {
|
|
@@ -478,11 +478,21 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
|
478
478
|
* Freezes the repeated field. We have to intercept this so we can pin the Ruby
|
|
479
479
|
* object into memory so we don't forget it's frozen.
|
|
480
480
|
*/
|
|
481
|
-
|
|
481
|
+
VALUE RepeatedField_freeze(VALUE _self) {
|
|
482
482
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
483
|
+
|
|
484
|
+
if (RB_OBJ_FROZEN(_self)) return _self;
|
|
485
|
+
Arena_Pin(self->arena, _self);
|
|
486
|
+
RB_OBJ_FREEZE(_self);
|
|
487
|
+
|
|
488
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
|
489
|
+
int size = upb_Array_Size(self->array);
|
|
490
|
+
int i;
|
|
491
|
+
for (i = 0; i < size; i++) {
|
|
492
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
|
493
|
+
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
|
494
|
+
Message_freeze(val);
|
|
495
|
+
}
|
|
486
496
|
}
|
|
487
497
|
return _self;
|
|
488
498
|
}
|
|
@@ -35,4 +35,7 @@ extern VALUE cRepeatedField;
|
|
|
35
35
|
// Call at startup to register all types in this module.
|
|
36
36
|
void RepeatedField_register(VALUE module);
|
|
37
37
|
|
|
38
|
+
// Recursively freeze RepeatedField.
|
|
39
|
+
VALUE RepeatedField_freeze(VALUE _self);
|
|
40
|
+
|
|
38
41
|
#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_
|