google-protobuf 3.21.12 → 3.25.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +23 -70
- data/ext/google/protobuf_c/convert.h +3 -28
- data/ext/google/protobuf_c/defs.c +178 -55
- data/ext/google/protobuf_c/defs.h +3 -28
- data/ext/google/protobuf_c/extconf.rb +4 -4
- data/ext/google/protobuf_c/glue.c +56 -0
- data/ext/google/protobuf_c/map.c +54 -70
- data/ext/google/protobuf_c/map.h +6 -28
- data/ext/google/protobuf_c/message.c +178 -161
- data/ext/google/protobuf_c/message.h +10 -28
- data/ext/google/protobuf_c/protobuf.c +39 -176
- data/ext/google/protobuf_c/protobuf.h +24 -32
- data/ext/google/protobuf_c/repeated_field.c +28 -29
- data/ext/google/protobuf_c/repeated_field.h +6 -28
- data/ext/google/protobuf_c/ruby-upb.c +11381 -9496
- data/ext/google/protobuf_c/ruby-upb.h +11819 -5116
- data/ext/google/protobuf_c/shared_convert.c +64 -0
- data/ext/google/protobuf_c/shared_convert.h +26 -0
- data/ext/google/protobuf_c/shared_message.c +65 -0
- data/ext/google/protobuf_c/shared_message.h +25 -0
- data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +1 -0
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -0
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +1 -1
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +13 -1
- data/ext/google/protobuf_c/wrap_memcpy.c +3 -26
- data/lib/google/protobuf/any_pb.rb +24 -5
- data/lib/google/protobuf/api_pb.rb +26 -23
- data/lib/google/protobuf/descriptor_dsl.rb +0 -0
- data/lib/google/protobuf/descriptor_pb.rb +43 -226
- data/lib/google/protobuf/duration_pb.rb +24 -5
- data/lib/google/protobuf/empty_pb.rb +24 -3
- data/lib/google/protobuf/ffi/descriptor.rb +165 -0
- data/lib/google/protobuf/ffi/descriptor_pool.rb +75 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +171 -0
- data/lib/google/protobuf/ffi/ffi.rb +213 -0
- data/lib/google/protobuf/ffi/field_descriptor.rb +319 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +66 -0
- data/lib/google/protobuf/ffi/internal/convert.rb +305 -0
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
- data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
- data/lib/google/protobuf/ffi/map.rb +407 -0
- data/lib/google/protobuf/ffi/message.rb +662 -0
- data/lib/google/protobuf/ffi/object_cache.rb +30 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +95 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +383 -0
- data/lib/google/protobuf/field_mask_pb.rb +24 -4
- data/lib/google/protobuf/message_exts.rb +8 -26
- data/lib/google/protobuf/object_cache.rb +97 -0
- data/lib/google/protobuf/plugin_pb.rb +47 -0
- data/lib/google/protobuf/repeated_field.rb +3 -26
- data/lib/google/protobuf/source_context_pb.rb +24 -4
- data/lib/google/protobuf/struct_pb.rb +24 -20
- data/lib/google/protobuf/timestamp_pb.rb +24 -5
- data/lib/google/protobuf/type_pb.rb +26 -68
- data/lib/google/protobuf/well_known_types.rb +5 -34
- data/lib/google/protobuf/wrappers_pb.rb +24 -28
- data/lib/google/protobuf.rb +27 -45
- data/lib/google/protobuf_ffi.rb +50 -0
- data/lib/google/protobuf_native.rb +20 -0
- data/lib/google/tasks/ffi.rake +102 -0
- metadata +75 -12
- data/tests/basic.rb +0 -739
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -1,38 +1,13 @@
|
|
1
1
|
// Protocol Buffers - Google's data interchange format
|
2
2
|
// Copyright 2008 Google Inc. All rights reserved.
|
3
|
-
// https://developers.google.com/protocol-buffers/
|
4
3
|
//
|
5
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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
|
30
7
|
|
31
8
|
#ifndef RUBY_PROTOBUF_MESSAGE_H_
|
32
9
|
#define RUBY_PROTOBUF_MESSAGE_H_
|
33
10
|
|
34
|
-
#include <ruby/ruby.h>
|
35
|
-
|
36
11
|
#include "protobuf.h"
|
37
12
|
#include "ruby-upb.h"
|
38
13
|
|
@@ -98,6 +73,13 @@ VALUE build_module_from_enumdesc(VALUE _enumdesc);
|
|
98
73
|
// module.
|
99
74
|
VALUE MessageOrEnum_GetDescriptor(VALUE klass);
|
100
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_internal_deep_freeze(VALUE _self);
|
82
|
+
|
101
83
|
// Call at startup to register all types in this module.
|
102
84
|
void Message_register(VALUE protobuf);
|
103
85
|
|
@@ -1,32 +1,9 @@
|
|
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
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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
|
30
7
|
|
31
8
|
#include "protobuf.h"
|
32
9
|
|
@@ -171,6 +148,8 @@ void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val,
|
|
171
148
|
|
172
149
|
typedef struct {
|
173
150
|
upb_Arena *arena;
|
151
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
152
|
+
// macro to update VALUE references, as to trigger write barriers.
|
174
153
|
VALUE pinned_objs;
|
175
154
|
} Arena;
|
176
155
|
|
@@ -190,10 +169,11 @@ static VALUE cArena;
|
|
190
169
|
const rb_data_type_t Arena_type = {
|
191
170
|
"Google::Protobuf::Internal::Arena",
|
192
171
|
{Arena_mark, Arena_free, NULL},
|
193
|
-
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
172
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
194
173
|
};
|
195
174
|
|
196
|
-
static void*
|
175
|
+
static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
|
176
|
+
size_t size) {
|
197
177
|
if (size == 0) {
|
198
178
|
xfree(ptr);
|
199
179
|
return NULL;
|
@@ -233,7 +213,7 @@ void Arena_Pin(VALUE _arena, VALUE obj) {
|
|
233
213
|
Arena *arena;
|
234
214
|
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
|
235
215
|
if (arena->pinned_objs == Qnil) {
|
236
|
-
arena->pinned_objs
|
216
|
+
RB_OBJ_WRITE(_arena, &arena->pinned_objs, rb_ary_new());
|
237
217
|
}
|
238
218
|
rb_ary_push(arena->pinned_objs, obj);
|
239
219
|
}
|
@@ -250,164 +230,48 @@ void Arena_register(VALUE module) {
|
|
250
230
|
// Object Cache
|
251
231
|
// -----------------------------------------------------------------------------
|
252
232
|
|
253
|
-
// A pointer -> Ruby Object cache that keeps references to Ruby wrapper
|
254
|
-
// objects. This allows us to look up any Ruby wrapper object by the address
|
255
|
-
// of the object it is wrapping. That way we can avoid ever creating two
|
256
|
-
// different wrapper objects for the same C object, which saves memory and
|
257
|
-
// preserves object identity.
|
258
|
-
//
|
259
|
-
// We use WeakMap for the cache. For Ruby <2.7 we also need a secondary Hash
|
260
|
-
// to store WeakMap keys because Ruby <2.7 WeakMap doesn't allow non-finalizable
|
261
|
-
// keys.
|
262
|
-
//
|
263
|
-
// We also need the secondary Hash if sizeof(long) < sizeof(VALUE), because this
|
264
|
-
// means it may not be possible to fit a pointer into a Fixnum. Keys are
|
265
|
-
// pointers, and if they fit into a Fixnum, Ruby doesn't collect them, but if
|
266
|
-
// they overflow and require allocating a Bignum, they could get collected
|
267
|
-
// prematurely, thus removing the cache entry. This happens on 64-bit Windows,
|
268
|
-
// on which pointers are 64 bits but longs are 32 bits. In this case, we enable
|
269
|
-
// the secondary Hash to hold the keys and prevent them from being collected.
|
270
|
-
|
271
|
-
#if RUBY_API_VERSION_CODE >= 20700 && SIZEOF_LONG >= SIZEOF_VALUE
|
272
|
-
#define USE_SECONDARY_MAP 0
|
273
|
-
#else
|
274
|
-
#define USE_SECONDARY_MAP 1
|
275
|
-
#endif
|
276
|
-
|
277
|
-
#if USE_SECONDARY_MAP
|
278
|
-
|
279
|
-
// Maps Numeric -> Object. The object is then used as a key into the WeakMap.
|
280
|
-
// This is needed for Ruby <2.7 where a number cannot be a key to WeakMap.
|
281
|
-
// The object is used only for its identity; it does not contain any data.
|
282
|
-
VALUE secondary_map = Qnil;
|
283
|
-
|
284
|
-
// Mutations to the map are under a mutex, because SeconaryMap_MaybeGC()
|
285
|
-
// iterates over the map which cannot happen in parallel with insertions, or
|
286
|
-
// Ruby will throw:
|
287
|
-
// can't add a new key into hash during iteration (RuntimeError)
|
288
|
-
VALUE secondary_map_mutex = Qnil;
|
289
|
-
|
290
|
-
// Lambda that will GC entries from the secondary map that are no longer present
|
291
|
-
// in the primary map.
|
292
|
-
VALUE gc_secondary_map_lambda = Qnil;
|
293
|
-
ID length;
|
294
|
-
|
295
|
-
extern VALUE weak_obj_cache;
|
296
|
-
|
297
|
-
static void SecondaryMap_Init() {
|
298
|
-
rb_gc_register_address(&secondary_map);
|
299
|
-
rb_gc_register_address(&gc_secondary_map_lambda);
|
300
|
-
rb_gc_register_address(&secondary_map_mutex);
|
301
|
-
secondary_map = rb_hash_new();
|
302
|
-
gc_secondary_map_lambda = rb_eval_string(
|
303
|
-
"->(secondary, weak) {\n"
|
304
|
-
" secondary.delete_if { |k, v| !weak.key?(v) }\n"
|
305
|
-
"}\n");
|
306
|
-
secondary_map_mutex = rb_mutex_new();
|
307
|
-
length = rb_intern("length");
|
308
|
-
}
|
309
|
-
|
310
|
-
// The secondary map is a regular Hash, and will never shrink on its own.
|
311
|
-
// The main object cache is a WeakMap that will automatically remove entries
|
312
|
-
// when the target object is no longer reachable, but unless we manually
|
313
|
-
// remove the corresponding entries from the secondary map, it will grow
|
314
|
-
// without bound.
|
315
|
-
//
|
316
|
-
// To avoid this unbounded growth we periodically remove entries from the
|
317
|
-
// secondary map that are no longer present in the WeakMap. The logic of
|
318
|
-
// how often to perform this GC is an artbirary tuning parameter that
|
319
|
-
// represents a straightforward CPU/memory tradeoff.
|
320
|
-
//
|
321
|
-
// Requires: secondary_map_mutex is held.
|
322
|
-
static void SecondaryMap_MaybeGC() {
|
323
|
-
PBRUBY_ASSERT(rb_mutex_locked_p(secondary_map_mutex) == Qtrue);
|
324
|
-
size_t weak_len = NUM2ULL(rb_funcall(weak_obj_cache, length, 0));
|
325
|
-
size_t secondary_len = RHASH_SIZE(secondary_map);
|
326
|
-
if (secondary_len < weak_len) {
|
327
|
-
// Logically this case should not be possible: a valid entry cannot exist in
|
328
|
-
// the weak table unless there is a corresponding entry in the secondary
|
329
|
-
// table. It should *always* be the case that secondary_len >= weak_len.
|
330
|
-
//
|
331
|
-
// However ObjectSpace::WeakMap#length (and therefore weak_len) is
|
332
|
-
// unreliable: it overreports its true length by including non-live objects.
|
333
|
-
// However these non-live objects are not yielded in iteration, so we may
|
334
|
-
// have previously deleted them from the secondary map in a previous
|
335
|
-
// invocation of SecondaryMap_MaybeGC().
|
336
|
-
//
|
337
|
-
// In this case, we can't measure any waste, so we just return.
|
338
|
-
return;
|
339
|
-
}
|
340
|
-
size_t waste = secondary_len - weak_len;
|
341
|
-
// GC if we could remove at least 2000 entries or 20% of the table size
|
342
|
-
// (whichever is greater). Since the cost of the GC pass is O(N), we
|
343
|
-
// want to make sure that we condition this on overall table size, to
|
344
|
-
// avoid O(N^2) CPU costs.
|
345
|
-
size_t threshold = PBRUBY_MAX(secondary_len * 0.2, 2000);
|
346
|
-
if (waste > threshold) {
|
347
|
-
rb_funcall(gc_secondary_map_lambda, rb_intern("call"), 2, secondary_map,
|
348
|
-
weak_obj_cache);
|
349
|
-
}
|
350
|
-
}
|
351
|
-
|
352
|
-
// Requires: secondary_map_mutex is held by this thread iff create == true.
|
353
|
-
static VALUE SecondaryMap_Get(VALUE key, bool create) {
|
354
|
-
PBRUBY_ASSERT(!create || rb_mutex_locked_p(secondary_map_mutex) == Qtrue);
|
355
|
-
VALUE ret = rb_hash_lookup(secondary_map, key);
|
356
|
-
if (ret == Qnil && create) {
|
357
|
-
SecondaryMap_MaybeGC();
|
358
|
-
ret = rb_class_new_instance(0, NULL, rb_cObject);
|
359
|
-
rb_hash_aset(secondary_map, key, ret);
|
360
|
-
}
|
361
|
-
return ret;
|
362
|
-
}
|
363
|
-
|
364
|
-
#endif
|
365
|
-
|
366
|
-
// Requires: secondary_map_mutex is held by this thread iff create == true.
|
367
|
-
static VALUE ObjectCache_GetKey(const void *key, bool create) {
|
368
|
-
VALUE key_val = (VALUE)key;
|
369
|
-
PBRUBY_ASSERT((key_val & 3) == 0);
|
370
|
-
VALUE ret = LL2NUM(key_val >> 2);
|
371
|
-
#if USE_SECONDARY_MAP
|
372
|
-
ret = SecondaryMap_Get(ret, create);
|
373
|
-
#endif
|
374
|
-
return ret;
|
375
|
-
}
|
376
|
-
|
377
233
|
// Public ObjectCache API.
|
378
234
|
|
379
235
|
VALUE weak_obj_cache = Qnil;
|
380
236
|
ID item_get;
|
381
|
-
ID
|
237
|
+
ID item_try_add;
|
238
|
+
|
239
|
+
static void ObjectCache_Init(VALUE protobuf) {
|
240
|
+
item_get = rb_intern("get");
|
241
|
+
item_try_add = rb_intern("try_add");
|
382
242
|
|
383
|
-
static void ObjectCache_Init() {
|
384
243
|
rb_gc_register_address(&weak_obj_cache);
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
#if USE_SECONDARY_MAP
|
390
|
-
SecondaryMap_Init();
|
244
|
+
#if SIZEOF_LONG >= SIZEOF_VALUE
|
245
|
+
VALUE cache_class = rb_const_get(protobuf, rb_intern("ObjectCache"));
|
246
|
+
#else
|
247
|
+
VALUE cache_class = rb_const_get(protobuf, rb_intern("LegacyObjectCache"));
|
391
248
|
#endif
|
249
|
+
|
250
|
+
weak_obj_cache = rb_class_new_instance(0, NULL, cache_class);
|
251
|
+
rb_const_set(protobuf, rb_intern("OBJECT_CACHE"), weak_obj_cache);
|
252
|
+
rb_const_set(protobuf, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG));
|
253
|
+
rb_const_set(protobuf, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE));
|
392
254
|
}
|
393
255
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
VALUE
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
256
|
+
static VALUE ObjectCache_GetKey(const void *key) {
|
257
|
+
VALUE key_val = (VALUE)key;
|
258
|
+
PBRUBY_ASSERT((key_val & 3) == 0);
|
259
|
+
// Ensure the key can be stored as a Fixnum since 1 bit is needed for
|
260
|
+
// FIXNUM_FLAG and 1 bit is needed for the sign bit.
|
261
|
+
VALUE new_key = LL2NUM(key_val >> 2);
|
262
|
+
PBRUBY_ASSERT(FIXNUM_P(new_key));
|
263
|
+
return new_key;
|
264
|
+
}
|
265
|
+
|
266
|
+
VALUE ObjectCache_TryAdd(const void *key, VALUE val) {
|
267
|
+
VALUE key_val = ObjectCache_GetKey(key);
|
268
|
+
return rb_funcall(weak_obj_cache, item_try_add, 2, key_val, val);
|
405
269
|
}
|
406
270
|
|
407
271
|
// Returns the cached object for this key, if any. Otherwise returns Qnil.
|
408
272
|
VALUE ObjectCache_Get(const void *key) {
|
409
|
-
VALUE
|
410
|
-
return rb_funcall(weak_obj_cache, item_get, 1,
|
273
|
+
VALUE key_val = ObjectCache_GetKey(key);
|
274
|
+
return rb_funcall(weak_obj_cache, item_get, 1, key_val);
|
411
275
|
}
|
412
276
|
|
413
277
|
/*
|
@@ -457,11 +321,10 @@ VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
|
|
457
321
|
// This must be named "Init_protobuf_c" because the Ruby module is named
|
458
322
|
// "protobuf_c" -- the VM looks for this symbol in our .so.
|
459
323
|
__attribute__((visibility("default"))) void Init_protobuf_c() {
|
460
|
-
ObjectCache_Init();
|
461
|
-
|
462
324
|
VALUE google = rb_define_module("Google");
|
463
325
|
VALUE protobuf = rb_define_module_under(google, "Protobuf");
|
464
326
|
|
327
|
+
ObjectCache_Init(protobuf);
|
465
328
|
Arena_register(protobuf);
|
466
329
|
Defs_register(protobuf);
|
467
330
|
RepeatedField_register(protobuf);
|
@@ -1,38 +1,29 @@
|
|
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
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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
|
30
7
|
|
31
8
|
#ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|
32
9
|
#define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|
33
10
|
|
11
|
+
// Ruby 3+ defines NDEBUG itself, see: https://bugs.ruby-lang.org/issues/18777
|
12
|
+
#ifdef NDEBUG
|
13
|
+
#include <ruby.h>
|
14
|
+
#else
|
15
|
+
#include <ruby.h>
|
16
|
+
#undef NDEBUG
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include <ruby/version.h>
|
20
|
+
|
21
|
+
#if RUBY_API_VERSION_CODE < 20700
|
22
|
+
#error Protobuf requires Ruby >= 2.7
|
23
|
+
#endif
|
24
|
+
|
25
|
+
#include <assert.h> // Must be included after the NDEBUG logic above.
|
34
26
|
#include <ruby/encoding.h>
|
35
|
-
#include <ruby/ruby.h>
|
36
27
|
#include <ruby/vm.h>
|
37
28
|
|
38
29
|
#include "defs.h"
|
@@ -76,10 +67,9 @@ void Arena_Pin(VALUE arena, VALUE obj);
|
|
76
67
|
// being collected (though in Ruby <2.7 is it effectively strong, due to
|
77
68
|
// implementation limitations).
|
78
69
|
|
79
|
-
//
|
80
|
-
//
|
81
|
-
|
82
|
-
void ObjectCache_Add(const void* key, VALUE val);
|
70
|
+
// Tries to add a new entry to the cache, returning the newly installed value or
|
71
|
+
// the pre-existing entry.
|
72
|
+
VALUE ObjectCache_TryAdd(const void* key, VALUE val);
|
83
73
|
|
84
74
|
// Returns the cached object for this key, if any. Otherwise returns Qnil.
|
85
75
|
VALUE ObjectCache_Get(const void* key);
|
@@ -110,7 +100,9 @@ extern VALUE cTypeError;
|
|
110
100
|
do { \
|
111
101
|
} while (false && (expr))
|
112
102
|
#else
|
113
|
-
#define PBRUBY_ASSERT(expr)
|
103
|
+
#define PBRUBY_ASSERT(expr) \
|
104
|
+
if (!(expr)) \
|
105
|
+
rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr)
|
114
106
|
#endif
|
115
107
|
|
116
108
|
#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
@@ -1,32 +1,9 @@
|
|
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
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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
|
30
7
|
|
31
8
|
#include "repeated_field.h"
|
32
9
|
|
@@ -87,7 +64,6 @@ VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info,
|
|
87
64
|
if (val == Qnil) {
|
88
65
|
val = RepeatedField_alloc(cRepeatedField);
|
89
66
|
RepeatedField* self;
|
90
|
-
ObjectCache_Add(array, val);
|
91
67
|
TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
|
92
68
|
self->array = array;
|
93
69
|
self->arena = arena;
|
@@ -95,11 +71,14 @@ VALUE RepeatedField_GetRubyWrapper(upb_Array* array, TypeInfo type_info,
|
|
95
71
|
if (self->type_info.type == kUpb_CType_Message) {
|
96
72
|
self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
|
97
73
|
}
|
74
|
+
val = ObjectCache_TryAdd(array, val);
|
98
75
|
}
|
99
76
|
|
100
77
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
|
101
78
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
|
102
79
|
type_info.def.msgdef);
|
80
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
|
81
|
+
|
103
82
|
return val;
|
104
83
|
}
|
105
84
|
|
@@ -284,7 +263,7 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
|
284
263
|
memset(&fill, 0, sizeof(fill));
|
285
264
|
for (int i = size; i < index; i++) {
|
286
265
|
// Fill default values.
|
287
|
-
// TODO
|
266
|
+
// TODO: should this happen at the upb level?
|
288
267
|
upb_Array_Set(array, i, fill);
|
289
268
|
}
|
290
269
|
}
|
@@ -508,6 +487,25 @@ static VALUE RepeatedField_freeze(VALUE _self) {
|
|
508
487
|
return _self;
|
509
488
|
}
|
510
489
|
|
490
|
+
/*
|
491
|
+
* Deep freezes the repeated field and values recursively.
|
492
|
+
* Internal use only.
|
493
|
+
*/
|
494
|
+
VALUE RepeatedField_internal_deep_freeze(VALUE _self) {
|
495
|
+
RepeatedField* self = ruby_to_RepeatedField(_self);
|
496
|
+
RepeatedField_freeze(_self);
|
497
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
498
|
+
int size = upb_Array_Size(self->array);
|
499
|
+
int i;
|
500
|
+
for (i = 0; i < size; i++) {
|
501
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
502
|
+
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
503
|
+
Message_internal_deep_freeze(val);
|
504
|
+
}
|
505
|
+
}
|
506
|
+
return _self;
|
507
|
+
}
|
508
|
+
|
511
509
|
/*
|
512
510
|
* call-seq:
|
513
511
|
* RepeatedField.hash => hash_value
|
@@ -613,7 +611,8 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
|
613
611
|
|
614
612
|
self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
|
615
613
|
self->array = upb_Array_New(arena, self->type_info.type);
|
616
|
-
|
614
|
+
VALUE stored_val = ObjectCache_TryAdd(self->array, _self);
|
615
|
+
PBRUBY_ASSERT(stored_val == _self);
|
617
616
|
|
618
617
|
if (ary != Qnil) {
|
619
618
|
if (!RB_TYPE_P(ary, T_ARRAY)) {
|
@@ -1,38 +1,13 @@
|
|
1
1
|
// Protocol Buffers - Google's data interchange format
|
2
2
|
// Copyright 2008 Google Inc. All rights reserved.
|
3
|
-
// https://developers.google.com/protocol-buffers/
|
4
3
|
//
|
5
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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
|
30
7
|
|
31
8
|
#ifndef RUBY_PROTOBUF_REPEATED_FIELD_H_
|
32
9
|
#define RUBY_PROTOBUF_REPEATED_FIELD_H_
|
33
10
|
|
34
|
-
#include <ruby/ruby.h>
|
35
|
-
|
36
11
|
#include "protobuf.h"
|
37
12
|
#include "ruby-upb.h"
|
38
13
|
|
@@ -60,4 +35,7 @@ extern VALUE cRepeatedField;
|
|
60
35
|
// Call at startup to register all types in this module.
|
61
36
|
void RepeatedField_register(VALUE module);
|
62
37
|
|
38
|
+
// Recursively freeze RepeatedField.
|
39
|
+
VALUE RepeatedField_internal_deep_freeze(VALUE _self);
|
40
|
+
|
63
41
|
#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_
|