google-protobuf 3.14.0 → 4.31.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/ext/google/protobuf_c/Rakefile +3 -0
  3. data/ext/google/protobuf_c/convert.c +335 -0
  4. data/ext/google/protobuf_c/convert.h +50 -0
  5. data/ext/google/protobuf_c/defs.c +1174 -1608
  6. data/ext/google/protobuf_c/defs.h +82 -0
  7. data/ext/google/protobuf_c/extconf.rb +31 -8
  8. data/ext/google/protobuf_c/glue.c +135 -0
  9. data/ext/google/protobuf_c/map.c +380 -485
  10. data/ext/google/protobuf_c/map.h +48 -0
  11. data/ext/google/protobuf_c/message.c +1098 -531
  12. data/ext/google/protobuf_c/message.h +82 -0
  13. data/ext/google/protobuf_c/protobuf.c +313 -92
  14. data/ext/google/protobuf_c/protobuf.h +59 -624
  15. data/ext/google/protobuf_c/repeated_field.c +358 -353
  16. data/ext/google/protobuf_c/repeated_field.h +45 -0
  17. data/ext/google/protobuf_c/ruby-upb.c +18305 -0
  18. data/ext/google/protobuf_c/ruby-upb.h +16315 -0
  19. data/ext/google/protobuf_c/shared_convert.c +69 -0
  20. data/ext/google/protobuf_c/shared_convert.h +26 -0
  21. data/ext/google/protobuf_c/shared_message.c +37 -0
  22. data/ext/google/protobuf_c/shared_message.h +21 -0
  23. data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
  24. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
  25. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
  26. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
  27. data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
  28. data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
  29. data/lib/google/protobuf/any_pb.rb +6 -8
  30. data/lib/google/protobuf/api_pb.rb +7 -26
  31. data/lib/google/protobuf/descriptor_pb.rb +70 -0
  32. data/lib/google/protobuf/duration_pb.rb +6 -8
  33. data/lib/google/protobuf/empty_pb.rb +6 -6
  34. data/lib/google/protobuf/ffi/descriptor.rb +175 -0
  35. data/lib/google/protobuf/ffi/descriptor_pool.rb +79 -0
  36. data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
  37. data/lib/google/protobuf/ffi/ffi.rb +214 -0
  38. data/lib/google/protobuf/ffi/field_descriptor.rb +346 -0
  39. data/lib/google/protobuf/ffi/file_descriptor.rb +85 -0
  40. data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
  41. data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
  42. data/lib/google/protobuf/ffi/internal/pointer_helper.rb +36 -0
  43. data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
  44. data/lib/google/protobuf/ffi/map.rb +433 -0
  45. data/lib/google/protobuf/ffi/message.rb +783 -0
  46. data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
  47. data/lib/google/protobuf/ffi/object_cache.rb +30 -0
  48. data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
  49. data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
  50. data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
  51. data/lib/google/protobuf/field_mask_pb.rb +6 -7
  52. data/lib/google/protobuf/internal/object_cache.rb +99 -0
  53. data/lib/google/protobuf/message_exts.rb +14 -28
  54. data/lib/google/protobuf/plugin_pb.rb +25 -0
  55. data/lib/google/protobuf/repeated_field.rb +22 -33
  56. data/lib/google/protobuf/source_context_pb.rb +6 -7
  57. data/lib/google/protobuf/struct_pb.rb +6 -23
  58. data/lib/google/protobuf/timestamp_pb.rb +6 -8
  59. data/lib/google/protobuf/type_pb.rb +7 -71
  60. data/lib/google/protobuf/well_known_types.rb +17 -36
  61. data/lib/google/protobuf/wrappers_pb.rb +6 -31
  62. data/lib/google/protobuf.rb +32 -118
  63. data/lib/google/protobuf_ffi.rb +52 -0
  64. data/lib/google/protobuf_native.rb +19 -0
  65. data/lib/google/tasks/ffi.rake +100 -0
  66. metadata +107 -38
  67. data/ext/google/protobuf_c/encode_decode.c +0 -1795
  68. data/ext/google/protobuf_c/storage.c +0 -1198
  69. data/ext/google/protobuf_c/upb.c +0 -13817
  70. data/ext/google/protobuf_c/upb.h +0 -6777
  71. data/tests/basic.rb +0 -543
  72. data/tests/generated_code_test.rb +0 -23
  73. data/tests/stress.rb +0 -38
@@ -1,76 +1,192 @@
1
1
  // Protocol Buffers - Google's data interchange format
2
2
  // Copyright 2014 Google Inc. All rights reserved.
3
- // https://developers.google.com/protocol-buffers/
4
3
  //
5
- // Redistribution and use in source and binary forms, with or without
6
- // modification, are permitted provided that the following conditions are
7
- // met:
8
- //
9
- // * Redistributions of source code must retain the above copyright
10
- // notice, this list of conditions and the following disclaimer.
11
- // * Redistributions in binary form must reproduce the above
12
- // copyright notice, this list of conditions and the following disclaimer
13
- // in the documentation and/or other materials provided with the
14
- // distribution.
15
- // * Neither the name of Google Inc. nor the names of its
16
- // contributors may be used to endorse or promote products derived from
17
- // this software without specific prior written permission.
18
- //
19
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4
+ // Use of this source code is governed by a BSD-style
5
+ // license that can be found in the LICENSE file or at
6
+ // https://developers.google.com/open-source/licenses/bsd
7
+
8
+ #include "repeated_field.h"
30
9
 
10
+ #include "convert.h"
11
+ #include "defs.h"
12
+ #include "message.h"
31
13
  #include "protobuf.h"
32
14
 
33
15
  // -----------------------------------------------------------------------------
34
16
  // Repeated field container type.
35
17
  // -----------------------------------------------------------------------------
36
18
 
37
- const rb_data_type_t RepeatedField_type = {
38
- "Google::Protobuf::RepeatedField",
39
- { RepeatedField_mark, RepeatedField_free, NULL },
40
- };
19
+ typedef struct {
20
+ const upb_Array* array; // Can get as mutable when non-frozen.
21
+ TypeInfo type_info;
22
+ VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
23
+ VALUE arena; // To GC-root the upb_Array.
24
+ } RepeatedField;
41
25
 
42
26
  VALUE cRepeatedField;
43
27
 
44
- RepeatedField* ruby_to_RepeatedField(VALUE _self) {
28
+ static void RepeatedField_mark(void* _self) {
29
+ RepeatedField* self = (RepeatedField*)_self;
30
+ rb_gc_mark(self->type_class);
31
+ rb_gc_mark(self->arena);
32
+ }
33
+
34
+ const rb_data_type_t RepeatedField_type = {
35
+ "Google::Protobuf::RepeatedField",
36
+ {RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
37
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
38
+ };
39
+
40
+ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
45
41
  RepeatedField* self;
46
42
  TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self);
47
43
  return self;
48
44
  }
49
45
 
50
- void* RepeatedField_memoryat(RepeatedField* self, int index, int element_size) {
51
- return ((uint8_t *)self->elements) + index * element_size;
46
+ static upb_Array* RepeatedField_GetMutable(VALUE _self) {
47
+ const upb_Array* array = ruby_to_RepeatedField(_self)->array;
48
+ Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array));
49
+ return (upb_Array*)array;
50
+ }
51
+
52
+ VALUE RepeatedField_alloc(VALUE klass) {
53
+ RepeatedField* self = ALLOC(RepeatedField);
54
+ self->arena = Qnil;
55
+ self->type_class = Qnil;
56
+ self->array = NULL;
57
+ return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
58
+ }
59
+
60
+ VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) {
61
+ PBRUBY_ASSERT(upb_FieldDef_IsRepeated(f));
62
+ VALUE val = ObjectCache_Get(f);
63
+
64
+ if (val == Qnil) {
65
+ val = RepeatedField_alloc(cRepeatedField);
66
+ RepeatedField* self;
67
+ TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
68
+ self->arena = Arena_new();
69
+ TypeInfo type_info = TypeInfo_get(f);
70
+ self->array = upb_Array_New(Arena_get(self->arena), type_info.type);
71
+ self->type_info = type_info;
72
+ if (self->type_info.type == kUpb_CType_Message) {
73
+ self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
74
+ }
75
+ val = ObjectCache_TryAdd(f, RepeatedField_freeze(val));
76
+ }
77
+ PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
78
+ PBRUBY_ASSERT(upb_Array_IsFrozen(ruby_to_RepeatedField(val)->array));
79
+ return val;
80
+ }
81
+
82
+ VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info,
83
+ VALUE arena) {
84
+ PBRUBY_ASSERT(array);
85
+ PBRUBY_ASSERT(arena != Qnil);
86
+ VALUE val = ObjectCache_Get(array);
87
+
88
+ if (val == Qnil) {
89
+ val = RepeatedField_alloc(cRepeatedField);
90
+ RepeatedField* self;
91
+ TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
92
+ self->array = array;
93
+ self->arena = arena;
94
+ self->type_info = type_info;
95
+ if (self->type_info.type == kUpb_CType_Message) {
96
+ self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
97
+ }
98
+ val = ObjectCache_TryAdd(array, val);
99
+ }
100
+
101
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
102
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
103
+ type_info.def.msgdef);
104
+ PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
105
+ return val;
106
+ }
107
+
108
+ static VALUE RepeatedField_new_this_type(RepeatedField* from) {
109
+ VALUE arena_rb = Arena_new();
110
+ upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
111
+ VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
112
+ PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
113
+ return ret;
114
+ }
115
+
116
+ void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
117
+ TypeInfo info) {
118
+ bool first = true;
119
+ StringBuilder_Printf(b, "[");
120
+ size_t n = array ? upb_Array_Size(array) : 0;
121
+ for (size_t i = 0; i < n; i++) {
122
+ if (first) {
123
+ first = false;
124
+ } else {
125
+ StringBuilder_Printf(b, ", ");
126
+ }
127
+ StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
128
+ }
129
+ StringBuilder_Printf(b, "]");
130
+ }
131
+
132
+ VALUE RepeatedField_deep_copy(VALUE _self) {
133
+ RepeatedField* self = ruby_to_RepeatedField(_self);
134
+ VALUE new_rptfield = RepeatedField_new_this_type(self);
135
+ RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
136
+ VALUE arena_rb = new_self->arena;
137
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
138
+ upb_Arena* arena = Arena_get(arena_rb);
139
+ size_t elements = upb_Array_Size(self->array);
140
+
141
+ upb_Array_Resize(new_array, elements, arena);
142
+
143
+ size_t size = upb_Array_Size(self->array);
144
+ for (size_t i = 0; i < size; i++) {
145
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
146
+ upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena);
147
+ upb_Array_Set(new_array, i, copy);
148
+ }
149
+
150
+ return new_rptfield;
151
+ }
152
+
153
+ const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
154
+ upb_Arena* arena) {
155
+ RepeatedField* self;
156
+ TypeInfo type_info = TypeInfo_get(field);
157
+
158
+ if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
159
+ RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
160
+ rb_raise(cTypeError, "Expected repeated field array");
161
+ }
162
+
163
+ self = ruby_to_RepeatedField(val);
164
+ if (self->type_info.type != type_info.type) {
165
+ rb_raise(cTypeError, "Repeated field array has wrong element type");
166
+ }
167
+
168
+ if (self->type_info.def.msgdef != type_info.def.msgdef) {
169
+ rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
170
+ }
171
+
172
+ Arena_fuse(self->arena, arena);
173
+ return self->array;
52
174
  }
53
175
 
54
176
  static int index_position(VALUE _index, RepeatedField* repeated_field) {
55
177
  int index = NUM2INT(_index);
56
- if (index < 0 && repeated_field->size > 0) {
57
- index = repeated_field->size + index;
58
- }
178
+ if (index < 0) index += upb_Array_Size(repeated_field->array);
59
179
  return index;
60
180
  }
61
181
 
62
- VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
63
- RepeatedField* self = ruby_to_RepeatedField(_self);
64
- int element_size = native_slot_size(self->field_type);
65
- upb_fieldtype_t field_type = self->field_type;
66
- VALUE field_type_class = self->field_type_class;
67
- size_t off = beg * element_size;
68
- VALUE ary = rb_ary_new2(len);
69
- int i;
182
+ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
183
+ size_t size = upb_Array_Size(self->array);
184
+ VALUE ary = rb_ary_new2(size);
185
+ long i;
70
186
 
71
- for (i = beg; i < beg + len; i++, off += element_size) {
72
- void* mem = ((uint8_t *)self->elements) + off;
73
- VALUE elem = native_slot_get(field_type, field_type_class, mem);
187
+ for (i = beg; i < beg + len; i++) {
188
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
189
+ VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
74
190
  rb_ary_push(ary, elem);
75
191
  }
76
192
  return ary;
@@ -84,70 +200,65 @@ VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
84
200
  * also includes Enumerable; combined with this method, the repeated field thus
85
201
  * acts like an ordinary Ruby sequence.
86
202
  */
87
- VALUE RepeatedField_each(VALUE _self) {
203
+ static VALUE RepeatedField_each(VALUE _self) {
88
204
  RepeatedField* self = ruby_to_RepeatedField(_self);
89
- upb_fieldtype_t field_type = self->field_type;
90
- VALUE field_type_class = self->field_type_class;
91
- int element_size = native_slot_size(field_type);
92
- size_t off = 0;
205
+ int size = upb_Array_Size(self->array);
93
206
  int i;
94
207
 
95
- for (i = 0; i < self->size; i++, off += element_size) {
96
- void* memory = (void *) (((uint8_t *)self->elements) + off);
97
- VALUE val = native_slot_get(field_type, field_type_class, memory);
208
+ for (i = 0; i < size; i++) {
209
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
210
+ VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
98
211
  rb_yield(val);
99
212
  }
100
213
  return _self;
101
214
  }
102
215
 
103
-
104
216
  /*
105
217
  * call-seq:
106
218
  * RepeatedField.[](index) => value
107
219
  *
108
220
  * Accesses the element at the given index. Returns nil on out-of-bounds
109
221
  */
110
- VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
222
+ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
111
223
  RepeatedField* self = ruby_to_RepeatedField(_self);
112
- int element_size = native_slot_size(self->field_type);
113
- upb_fieldtype_t field_type = self->field_type;
114
- VALUE field_type_class = self->field_type_class;
224
+ long size = upb_Array_Size(self->array);
115
225
 
116
226
  VALUE arg = argv[0];
117
227
  long beg, len;
118
228
 
119
- if (argc == 1){
229
+ if (argc == 1) {
120
230
  if (FIXNUM_P(arg)) {
121
231
  /* standard case */
122
- void* memory;
232
+ upb_MessageValue msgval;
123
233
  int index = index_position(argv[0], self);
124
- if (index < 0 || index >= self->size) {
234
+ if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
125
235
  return Qnil;
126
236
  }
127
- memory = RepeatedField_memoryat(self, index, element_size);
128
- return native_slot_get(field_type, field_type_class, memory);
129
- }else{
237
+ msgval = upb_Array_Get(self->array, index);
238
+ return Convert_UpbToRuby(msgval, self->type_info, self->arena);
239
+ } else {
130
240
  /* check if idx is Range */
131
- switch (rb_range_beg_len(arg, &beg, &len, self->size, 0)) {
241
+ switch (rb_range_beg_len(arg, &beg, &len, size, 0)) {
132
242
  case Qfalse:
133
243
  break;
134
244
  case Qnil:
135
245
  return Qnil;
136
246
  default:
137
- return RepeatedField_subarray(_self, beg, len);
247
+ return RepeatedField_subarray(self, beg, len);
138
248
  }
139
249
  }
140
250
  }
251
+
141
252
  /* assume 2 arguments */
142
253
  beg = NUM2LONG(argv[0]);
143
254
  len = NUM2LONG(argv[1]);
144
255
  if (beg < 0) {
145
- beg += self->size;
256
+ beg += size;
146
257
  }
147
- if (beg >= self->size) {
258
+ if (beg >= size) {
148
259
  return Qnil;
149
260
  }
150
- return RepeatedField_subarray(_self, beg, len);
261
+ return RepeatedField_subarray(self, beg, len);
151
262
  }
152
263
 
153
264
  /*
@@ -157,128 +268,89 @@ VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
157
268
  * Sets the element at the given index. On out-of-bounds assignments, extends
158
269
  * the array and fills the hole (if any) with default values.
159
270
  */
160
- VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
271
+ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
161
272
  RepeatedField* self = ruby_to_RepeatedField(_self);
162
- upb_fieldtype_t field_type = self->field_type;
163
- VALUE field_type_class = self->field_type_class;
164
- int element_size = native_slot_size(field_type);
165
- void* memory;
273
+ int size = upb_Array_Size(self->array);
274
+ upb_Array* array = RepeatedField_GetMutable(_self);
275
+ upb_Arena* arena = Arena_get(self->arena);
276
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
166
277
 
167
278
  int index = index_position(_index, self);
168
279
  if (index < 0 || index >= (INT_MAX - 1)) {
169
280
  return Qnil;
170
281
  }
171
- if (index >= self->size) {
172
- upb_fieldtype_t field_type = self->field_type;
173
- int element_size = native_slot_size(field_type);
174
- int i;
175
282
 
176
- RepeatedField_reserve(self, index + 1);
177
- for (i = self->size; i <= index; i++) {
178
- void* elem = RepeatedField_memoryat(self, i, element_size);
179
- native_slot_init(field_type, elem);
283
+ if (index >= size) {
284
+ upb_Array_Resize(array, index + 1, arena);
285
+ upb_MessageValue fill;
286
+ memset(&fill, 0, sizeof(fill));
287
+ for (int i = size; i < index; i++) {
288
+ // Fill default values.
289
+ // TODO: should this happen at the upb level?
290
+ upb_Array_Set(array, i, fill);
180
291
  }
181
- self->size = index + 1;
182
292
  }
183
293
 
184
- memory = RepeatedField_memoryat(self, index, element_size);
185
- native_slot_set("", field_type, field_type_class, memory, val);
294
+ upb_Array_Set(array, index, msgval);
186
295
  return Qnil;
187
296
  }
188
297
 
189
- static int kInitialSize = 8;
190
-
191
- void RepeatedField_reserve(RepeatedField* self, int new_size) {
192
- void* old_elems = self->elements;
193
- int elem_size = native_slot_size(self->field_type);
194
- if (new_size <= self->capacity) {
195
- return;
196
- }
197
- if (self->capacity == 0) {
198
- self->capacity = kInitialSize;
199
- }
200
- while (self->capacity < new_size) {
201
- self->capacity *= 2;
202
- }
203
- self->elements = ALLOC_N(uint8_t, elem_size * self->capacity);
204
- if (old_elems != NULL) {
205
- memcpy(self->elements, old_elems, self->size * elem_size);
206
- xfree(old_elems);
207
- }
208
- }
209
-
210
298
  /*
211
299
  * call-seq:
212
- * RepeatedField.push(value)
300
+ * RepeatedField.push(value, ...)
213
301
  *
214
302
  * Adds a new element to the repeated field.
215
303
  */
216
- VALUE RepeatedField_push(VALUE _self, VALUE val) {
304
+ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
217
305
  RepeatedField* self = ruby_to_RepeatedField(_self);
218
- upb_fieldtype_t field_type = self->field_type;
219
- int element_size = native_slot_size(field_type);
220
- void* memory;
221
-
222
- RepeatedField_reserve(self, self->size + 1);
223
- memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
224
- native_slot_set("", field_type, self->field_type_class, memory, val);
225
- // native_slot_set may raise an error; bump size only after set.
226
- self->size++;
227
- return _self;
228
- }
229
-
230
- VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
306
+ upb_Arena* arena = Arena_get(self->arena);
307
+ upb_Array* array = RepeatedField_GetMutable(_self);
231
308
  int i;
232
- for (i = 0; i < RARRAY_LEN(args); i++) {
233
- RepeatedField_push(_self, rb_ary_entry(args, i));
309
+
310
+ for (i = 0; i < argc; i++) {
311
+ upb_MessageValue msgval =
312
+ Convert_RubyToUpb(argv[i], "", self->type_info, arena);
313
+ upb_Array_Append(array, msgval, arena);
234
314
  }
315
+
235
316
  return _self;
236
317
  }
237
318
 
238
- // Used by parsing handlers.
239
- void RepeatedField_push_native(VALUE _self, void* data) {
319
+ /*
320
+ * call-seq:
321
+ * RepeatedField.<<(value)
322
+ *
323
+ * Adds a new element to the repeated field.
324
+ */
325
+ static VALUE RepeatedField_push(VALUE _self, VALUE val) {
240
326
  RepeatedField* self = ruby_to_RepeatedField(_self);
241
- upb_fieldtype_t field_type = self->field_type;
242
- int element_size = native_slot_size(field_type);
243
- void* memory;
244
-
245
- RepeatedField_reserve(self, self->size + 1);
246
- memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
247
- memcpy(memory, data, element_size);
248
- self->size++;
249
- }
327
+ upb_Arena* arena = Arena_get(self->arena);
328
+ upb_Array* array = RepeatedField_GetMutable(_self);
250
329
 
251
- void* RepeatedField_index_native(VALUE _self, int index) {
252
- RepeatedField* self = ruby_to_RepeatedField(_self);
253
- upb_fieldtype_t field_type = self->field_type;
254
- int element_size = native_slot_size(field_type);
255
- return RepeatedField_memoryat(self, index, element_size);
256
- }
330
+ upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
331
+ upb_Array_Append(array, msgval, arena);
257
332
 
258
- int RepeatedField_size(VALUE _self) {
259
- RepeatedField* self = ruby_to_RepeatedField(_self);
260
- return self->size;
333
+ return _self;
261
334
  }
262
335
 
263
336
  /*
264
337
  * Private ruby method, used by RepeatedField.pop
265
338
  */
266
- VALUE RepeatedField_pop_one(VALUE _self) {
339
+ static VALUE RepeatedField_pop_one(VALUE _self) {
267
340
  RepeatedField* self = ruby_to_RepeatedField(_self);
268
- upb_fieldtype_t field_type = self->field_type;
269
- VALUE field_type_class = self->field_type_class;
270
- int element_size = native_slot_size(field_type);
271
- int index;
272
- void* memory;
341
+ size_t size = upb_Array_Size(self->array);
342
+ upb_Array* array = RepeatedField_GetMutable(_self);
343
+ upb_MessageValue last;
273
344
  VALUE ret;
274
345
 
275
- if (self->size == 0) {
346
+ if (size == 0) {
276
347
  return Qnil;
277
348
  }
278
- index = self->size - 1;
279
- memory = RepeatedField_memoryat(self, index, element_size);
280
- ret = native_slot_get(field_type, field_type_class, memory);
281
- self->size--;
349
+
350
+ last = upb_Array_Get(self->array, size - 1);
351
+ ret = Convert_UpbToRuby(last, self->type_info, self->arena);
352
+
353
+ upb_Array_Resize(array, size - 1, Arena_get(self->arena));
282
354
  return ret;
283
355
  }
284
356
 
@@ -288,15 +360,18 @@ VALUE RepeatedField_pop_one(VALUE _self) {
288
360
  *
289
361
  * Replaces the contents of the repeated field with the given list of elements.
290
362
  */
291
- VALUE RepeatedField_replace(VALUE _self, VALUE list) {
363
+ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
292
364
  RepeatedField* self = ruby_to_RepeatedField(_self);
365
+ upb_Array* array = RepeatedField_GetMutable(_self);
293
366
  int i;
294
367
 
295
368
  Check_Type(list, T_ARRAY);
296
- self->size = 0;
369
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
370
+
297
371
  for (i = 0; i < RARRAY_LEN(list); i++) {
298
372
  RepeatedField_push(_self, rb_ary_entry(list, i));
299
373
  }
374
+
300
375
  return list;
301
376
  }
302
377
 
@@ -306,9 +381,10 @@ VALUE RepeatedField_replace(VALUE _self, VALUE list) {
306
381
  *
307
382
  * Clears (removes all elements from) this repeated field.
308
383
  */
309
- VALUE RepeatedField_clear(VALUE _self) {
384
+ static VALUE RepeatedField_clear(VALUE _self) {
310
385
  RepeatedField* self = ruby_to_RepeatedField(_self);
311
- self->size = 0;
386
+ upb_Array* array = RepeatedField_GetMutable(_self);
387
+ upb_Array_Resize(array, 0, Arena_get(self->arena));
312
388
  return _self;
313
389
  }
314
390
 
@@ -318,23 +394,9 @@ VALUE RepeatedField_clear(VALUE _self) {
318
394
  *
319
395
  * Returns the length of this repeated field.
320
396
  */
321
- VALUE RepeatedField_length(VALUE _self) {
397
+ static VALUE RepeatedField_length(VALUE _self) {
322
398
  RepeatedField* self = ruby_to_RepeatedField(_self);
323
- return INT2NUM(self->size);
324
- }
325
-
326
- VALUE RepeatedField_new_this_type(VALUE _self) {
327
- RepeatedField* self = ruby_to_RepeatedField(_self);
328
- VALUE new_rptfield = Qnil;
329
- VALUE element_type = fieldtype_to_ruby(self->field_type);
330
- if (self->field_type_class != Qnil) {
331
- new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 2,
332
- element_type, self->field_type_class);
333
- } else {
334
- new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 1,
335
- element_type);
336
- }
337
- return new_rptfield;
399
+ return INT2NUM(upb_Array_Size(self->array));
338
400
  }
339
401
 
340
402
  /*
@@ -344,42 +406,20 @@ VALUE RepeatedField_new_this_type(VALUE _self) {
344
406
  * Duplicates this repeated field with a shallow copy. References to all
345
407
  * non-primitive element objects (e.g., submessages) are shared.
346
408
  */
347
- VALUE RepeatedField_dup(VALUE _self) {
409
+ static VALUE RepeatedField_dup(VALUE _self) {
348
410
  RepeatedField* self = ruby_to_RepeatedField(_self);
349
- VALUE new_rptfield = RepeatedField_new_this_type(_self);
411
+ VALUE new_rptfield = RepeatedField_new_this_type(self);
350
412
  RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
351
- upb_fieldtype_t field_type = self->field_type;
352
- size_t elem_size = native_slot_size(field_type);
353
- size_t off = 0;
413
+ upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
414
+ upb_Arena* arena = Arena_get(new_rptfield_self->arena);
415
+ int size = upb_Array_Size(self->array);
354
416
  int i;
355
417
 
356
- RepeatedField_reserve(new_rptfield_self, self->size);
357
- for (i = 0; i < self->size; i++, off += elem_size) {
358
- void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
359
- void* from_mem = (uint8_t *)self->elements + off;
360
- native_slot_dup(field_type, to_mem, from_mem);
361
- new_rptfield_self->size++;
362
- }
418
+ Arena_fuse(self->arena, arena);
363
419
 
364
- return new_rptfield;
365
- }
366
-
367
- // Internal only: used by Google::Protobuf.deep_copy.
368
- VALUE RepeatedField_deep_copy(VALUE _self) {
369
- RepeatedField* self = ruby_to_RepeatedField(_self);
370
- VALUE new_rptfield = RepeatedField_new_this_type(_self);
371
- RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
372
- upb_fieldtype_t field_type = self->field_type;
373
- size_t elem_size = native_slot_size(field_type);
374
- size_t off = 0;
375
- int i;
376
-
377
- RepeatedField_reserve(new_rptfield_self, self->size);
378
- for (i = 0; i < self->size; i++, off += elem_size) {
379
- void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
380
- void* from_mem = (uint8_t *)self->elements + off;
381
- native_slot_deep_copy(field_type, self->field_type_class, to_mem, from_mem);
382
- new_rptfield_self->size++;
420
+ for (i = 0; i < size; i++) {
421
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
422
+ upb_Array_Append(new_array, msgval, arena);
383
423
  }
384
424
 
385
425
  return new_rptfield;
@@ -394,17 +434,16 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
394
434
  */
395
435
  VALUE RepeatedField_to_ary(VALUE _self) {
396
436
  RepeatedField* self = ruby_to_RepeatedField(_self);
397
- upb_fieldtype_t field_type = self->field_type;
398
- size_t elem_size = native_slot_size(field_type);
399
- size_t off = 0;
400
- VALUE ary = rb_ary_new2(self->size);
437
+ int size = upb_Array_Size(self->array);
438
+ VALUE ary = rb_ary_new2(size);
401
439
  int i;
402
440
 
403
- for (i = 0; i < self->size; i++, off += elem_size) {
404
- void* mem = ((uint8_t *)self->elements) + off;
405
- VALUE elem = native_slot_get(field_type, self->field_type_class, mem);
406
- rb_ary_push(ary, elem);
441
+ for (i = 0; i < size; i++) {
442
+ upb_MessageValue msgval = upb_Array_Get(self->array, i);
443
+ VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
444
+ rb_ary_push(ary, val);
407
445
  }
446
+
408
447
  return ary;
409
448
  }
410
449
 
@@ -436,28 +475,69 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
436
475
 
437
476
  self = ruby_to_RepeatedField(_self);
438
477
  other = ruby_to_RepeatedField(_other);
439
- if (self->field_type != other->field_type ||
440
- self->field_type_class != other->field_type_class ||
441
- self->size != other->size) {
478
+ size_t n = upb_Array_Size(self->array);
479
+
480
+ if (self->type_info.type != other->type_info.type ||
481
+ self->type_class != other->type_class ||
482
+ upb_Array_Size(other->array) != n) {
442
483
  return Qfalse;
443
484
  }
444
485
 
445
- {
446
- upb_fieldtype_t field_type = self->field_type;
447
- size_t elem_size = native_slot_size(field_type);
448
- size_t off = 0;
449
- int i;
486
+ for (size_t i = 0; i < n; i++) {
487
+ upb_MessageValue val1 = upb_Array_Get(self->array, i);
488
+ upb_MessageValue val2 = upb_Array_Get(other->array, i);
489
+ if (!Msgval_IsEqual(val1, val2, self->type_info)) {
490
+ return Qfalse;
491
+ }
492
+ }
450
493
 
451
- for (i = 0; i < self->size; i++, off += elem_size) {
452
- void* self_mem = ((uint8_t *)self->elements) + off;
453
- void* other_mem = ((uint8_t *)other->elements) + off;
454
- if (!native_slot_eq(field_type, self->field_type_class, self_mem,
455
- other_mem)) {
456
- return Qfalse;
457
- }
494
+ return Qtrue;
495
+ }
496
+
497
+ /*
498
+ * call-seq:
499
+ * RepeatedField.frozen? => bool
500
+ *
501
+ * Returns true if the repeated field is frozen in either Ruby or the underlying
502
+ * representation. Freezes the Ruby repeated field object if it is not already
503
+ * frozen in Ruby but it is frozen in the underlying representation.
504
+ */
505
+ VALUE RepeatedField_frozen(VALUE _self) {
506
+ RepeatedField* self = ruby_to_RepeatedField(_self);
507
+ if (!upb_Array_IsFrozen(self->array)) {
508
+ PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
509
+ return Qfalse;
510
+ }
511
+
512
+ // Lazily freeze the Ruby wrapper.
513
+ if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
514
+ return Qtrue;
515
+ }
516
+
517
+ /*
518
+ * call-seq:
519
+ * RepeatedField.freeze => self
520
+ *
521
+ * Freezes the repeated field object. We have to intercept this so we can freeze
522
+ * the underlying representation, not just the Ruby wrapper.
523
+ */
524
+ VALUE RepeatedField_freeze(VALUE _self) {
525
+ RepeatedField* self = ruby_to_RepeatedField(_self);
526
+ if (RB_OBJ_FROZEN(_self)) {
527
+ PBRUBY_ASSERT(upb_Array_IsFrozen(self->array));
528
+ return _self;
529
+ }
530
+
531
+ if (!upb_Array_IsFrozen(self->array)) {
532
+ if (self->type_info.type == kUpb_CType_Message) {
533
+ upb_Array_Freeze(RepeatedField_GetMutable(_self),
534
+ upb_MessageDef_MiniTable(self->type_info.def.msgdef));
535
+ } else {
536
+ upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL);
458
537
  }
459
- return Qtrue;
460
538
  }
539
+ RB_OBJ_FREEZE(_self);
540
+ return _self;
461
541
  }
462
542
 
463
543
  /*
@@ -468,22 +548,15 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
468
548
  */
469
549
  VALUE RepeatedField_hash(VALUE _self) {
470
550
  RepeatedField* self = ruby_to_RepeatedField(_self);
471
- st_index_t h = rb_hash_start(0);
472
- VALUE hash_sym = rb_intern("hash");
473
- upb_fieldtype_t field_type = self->field_type;
474
- VALUE field_type_class = self->field_type_class;
475
- size_t elem_size = native_slot_size(field_type);
476
- size_t off = 0;
477
- int i;
551
+ uint64_t hash = 0;
552
+ size_t n = upb_Array_Size(self->array);
478
553
 
479
- for (i = 0; i < self->size; i++, off += elem_size) {
480
- void* mem = ((uint8_t *)self->elements) + off;
481
- VALUE elem = native_slot_get(field_type, field_type_class, mem);
482
- h = rb_hash_uint(h, NUM2LONG(rb_funcall(elem, hash_sym, 0)));
554
+ for (size_t i = 0; i < n; i++) {
555
+ upb_MessageValue val = upb_Array_Get(self->array, i);
556
+ hash = Msgval_GetHash(val, self->type_info, hash);
483
557
  }
484
- h = rb_hash_end(h);
485
558
 
486
- return INT2FIX(h);
559
+ return LL2NUM(hash);
487
560
  }
488
561
 
489
562
  /*
@@ -495,34 +568,40 @@ VALUE RepeatedField_hash(VALUE _self) {
495
568
  * be either another repeated field or a Ruby array.
496
569
  */
497
570
  VALUE RepeatedField_plus(VALUE _self, VALUE list) {
498
- VALUE dupped = RepeatedField_dup(_self);
571
+ VALUE dupped_ = RepeatedField_dup(_self);
499
572
 
500
573
  if (TYPE(list) == T_ARRAY) {
501
574
  int i;
502
575
  for (i = 0; i < RARRAY_LEN(list); i++) {
503
576
  VALUE elem = rb_ary_entry(list, i);
504
- RepeatedField_push(dupped, elem);
577
+ RepeatedField_push(dupped_, elem);
505
578
  }
506
579
  } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) &&
507
580
  RTYPEDDATA_TYPE(list) == &RepeatedField_type) {
508
581
  RepeatedField* self = ruby_to_RepeatedField(_self);
509
582
  RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
583
+ RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
584
+ upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
585
+ upb_Arena* arena = Arena_get(dupped->arena);
586
+ Arena_fuse(list_rptfield->arena, arena);
587
+ int size = upb_Array_Size(list_rptfield->array);
510
588
  int i;
511
589
 
512
- if (self->field_type != list_rptfield->field_type ||
513
- self->field_type_class != list_rptfield->field_type_class) {
590
+ if (self->type_info.type != list_rptfield->type_info.type ||
591
+ self->type_class != list_rptfield->type_class) {
514
592
  rb_raise(rb_eArgError,
515
593
  "Attempt to append RepeatedField with different element type.");
516
594
  }
517
- for (i = 0; i < list_rptfield->size; i++) {
518
- void* mem = RepeatedField_index_native(list, i);
519
- RepeatedField_push_native(dupped, mem);
595
+
596
+ for (i = 0; i < size; i++) {
597
+ upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
598
+ upb_Array_Append(dupped_array, msgval, arena);
520
599
  }
521
600
  } else {
522
601
  rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
523
602
  }
524
603
 
525
- return dupped;
604
+ return dupped_;
526
605
  }
527
606
 
528
607
  /*
@@ -541,133 +620,57 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
541
620
  return _self;
542
621
  }
543
622
 
544
-
545
- void validate_type_class(upb_fieldtype_t type, VALUE klass) {
546
- if (rb_ivar_get(klass, descriptor_instancevar_interned) == Qnil) {
547
- rb_raise(rb_eArgError,
548
- "Type class has no descriptor. Please pass a "
549
- "class or enum as returned by the DescriptorPool.");
550
- }
551
- if (type == UPB_TYPE_MESSAGE) {
552
- VALUE desc = rb_ivar_get(klass, descriptor_instancevar_interned);
553
- if (!RB_TYPE_P(desc, T_DATA) || !RTYPEDDATA_P(desc) ||
554
- RTYPEDDATA_TYPE(desc) != &_Descriptor_type) {
555
- rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
556
- }
557
- if (rb_get_alloc_func(klass) != &Message_alloc) {
558
- rb_raise(rb_eArgError,
559
- "Message class was not returned by the DescriptorPool.");
560
- }
561
- } else if (type == UPB_TYPE_ENUM) {
562
- VALUE enumdesc = rb_ivar_get(klass, descriptor_instancevar_interned);
563
- if (!RB_TYPE_P(enumdesc, T_DATA) || !RTYPEDDATA_P(enumdesc) ||
564
- RTYPEDDATA_TYPE(enumdesc) != &_EnumDescriptor_type) {
565
- rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
566
- }
567
- }
568
- }
569
-
570
- void RepeatedField_init_args(int argc, VALUE* argv,
571
- VALUE _self) {
623
+ /*
624
+ * call-seq:
625
+ * RepeatedField.new(type, type_class = nil, initial_elems = [])
626
+ *
627
+ * Creates a new repeated field. The provided type must be a Ruby symbol, and
628
+ * can take on the same values as those accepted by FieldDescriptor#type=. If
629
+ * the type is :message or :enum, type_class must be non-nil, and must be the
630
+ * Ruby class or module returned by Descriptor#msgclass or
631
+ * EnumDescriptor#enummodule, respectively. An initial list of elements may also
632
+ * be provided.
633
+ */
634
+ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
572
635
  RepeatedField* self = ruby_to_RepeatedField(_self);
636
+ upb_Arena* arena;
573
637
  VALUE ary = Qnil;
638
+
639
+ self->arena = Arena_new();
640
+ arena = Arena_get(self->arena);
641
+
574
642
  if (argc < 1) {
575
643
  rb_raise(rb_eArgError, "Expected at least 1 argument.");
576
644
  }
577
- self->field_type = ruby_to_fieldtype(argv[0]);
578
645
 
579
- if (self->field_type == UPB_TYPE_MESSAGE ||
580
- self->field_type == UPB_TYPE_ENUM) {
581
- if (argc < 2) {
582
- rb_raise(rb_eArgError, "Expected at least 2 arguments for message/enum.");
583
- }
584
- self->field_type_class = argv[1];
585
- if (argc > 2) {
586
- ary = argv[2];
587
- }
588
- validate_type_class(self->field_type, self->field_type_class);
589
- } else {
590
- if (argc > 2) {
591
- rb_raise(rb_eArgError, "Too many arguments: expected 1 or 2.");
592
- }
593
- if (argc > 1) {
594
- ary = argv[1];
595
- }
596
- }
646
+ self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
647
+ self->array = upb_Array_New(arena, self->type_info.type);
648
+ VALUE stored_val = ObjectCache_TryAdd(self->array, _self);
649
+ PBRUBY_ASSERT(stored_val == _self);
597
650
 
598
651
  if (ary != Qnil) {
599
- int i;
600
-
601
652
  if (!RB_TYPE_P(ary, T_ARRAY)) {
602
653
  rb_raise(rb_eArgError, "Expected array as initialize argument");
603
654
  }
604
- for (i = 0; i < RARRAY_LEN(ary); i++) {
655
+ for (int i = 0; i < RARRAY_LEN(ary); i++) {
605
656
  RepeatedField_push(_self, rb_ary_entry(ary, i));
606
657
  }
607
658
  }
608
- }
609
-
610
- // Mark, free, alloc, init and class setup functions.
611
-
612
- void RepeatedField_mark(void* _self) {
613
- RepeatedField* self = (RepeatedField*)_self;
614
- upb_fieldtype_t field_type = self->field_type;
615
- int element_size = native_slot_size(field_type);
616
- int i;
617
-
618
- rb_gc_mark(self->field_type_class);
619
- for (i = 0; i < self->size; i++) {
620
- void* memory = (((uint8_t *)self->elements) + i * element_size);
621
- native_slot_mark(self->field_type, memory);
622
- }
623
- }
624
-
625
- void RepeatedField_free(void* _self) {
626
- RepeatedField* self = (RepeatedField*)_self;
627
- xfree(self->elements);
628
- xfree(self);
629
- }
630
-
631
- /*
632
- * call-seq:
633
- * RepeatedField.new(type, type_class = nil, initial_elems = [])
634
- *
635
- * Creates a new repeated field. The provided type must be a Ruby symbol, and
636
- * can take on the same values as those accepted by FieldDescriptor#type=. If
637
- * the type is :message or :enum, type_class must be non-nil, and must be the
638
- * Ruby class or module returned by Descriptor#msgclass or
639
- * EnumDescriptor#enummodule, respectively. An initial list of elements may also
640
- * be provided.
641
- */
642
- VALUE RepeatedField_alloc(VALUE klass) {
643
- RepeatedField* self = ALLOC(RepeatedField);
644
- self->elements = NULL;
645
- self->size = 0;
646
- self->capacity = 0;
647
- self->field_type = -1;
648
- self->field_type_class = Qnil;
649
- return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
650
- }
651
-
652
- VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self) {
653
- RepeatedField_init_args(argc, argv, self);
654
659
  return Qnil;
655
660
  }
656
661
 
657
662
  void RepeatedField_register(VALUE module) {
658
- VALUE klass = rb_define_class_under(
659
- module, "RepeatedField", rb_cObject);
663
+ VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
660
664
  rb_define_alloc_func(klass, RepeatedField_alloc);
661
665
  rb_gc_register_address(&cRepeatedField);
662
666
  cRepeatedField = klass;
663
667
 
664
- rb_define_method(klass, "initialize",
665
- RepeatedField_init, -1);
668
+ rb_define_method(klass, "initialize", RepeatedField_init, -1);
666
669
  rb_define_method(klass, "each", RepeatedField_each, 0);
667
670
  rb_define_method(klass, "[]", RepeatedField_index, -1);
668
671
  rb_define_method(klass, "at", RepeatedField_index, -1);
669
672
  rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
670
- rb_define_method(klass, "push", RepeatedField_push_vararg, -2);
673
+ rb_define_method(klass, "push", RepeatedField_push_vararg, -1);
671
674
  rb_define_method(klass, "<<", RepeatedField_push, 1);
672
675
  rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
673
676
  rb_define_method(klass, "replace", RepeatedField_replace, 1);
@@ -679,6 +682,8 @@ void RepeatedField_register(VALUE module) {
679
682
  rb_define_method(klass, "clone", RepeatedField_dup, 0);
680
683
  rb_define_method(klass, "==", RepeatedField_eq, 1);
681
684
  rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
685
+ rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
686
+ rb_define_method(klass, "frozen?", RepeatedField_frozen, 0);
682
687
  rb_define_method(klass, "hash", RepeatedField_hash, 0);
683
688
  rb_define_method(klass, "+", RepeatedField_plus, 1);
684
689
  rb_define_method(klass, "concat", RepeatedField_concat, 1);