ruby/ext/google/protobuf_c/storage.c
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
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.
30 
31 #include "protobuf.h"
32 
33 #include <math.h>
34 
35 #include <ruby/encoding.h>
36 
37 // -----------------------------------------------------------------------------
38 // Ruby <-> native slot management.
39 // -----------------------------------------------------------------------------
40 
41 #define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
42 #define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
43 #define DEREF(memory, type) *(type*)(memory)
44 
46  switch (type) {
47  case UPB_TYPE_FLOAT: return 4;
48  case UPB_TYPE_DOUBLE: return 8;
49  case UPB_TYPE_BOOL: return 1;
50  case UPB_TYPE_STRING: return sizeof(VALUE);
51  case UPB_TYPE_BYTES: return sizeof(VALUE);
52  case UPB_TYPE_MESSAGE: return sizeof(VALUE);
53  case UPB_TYPE_ENUM: return 4;
54  case UPB_TYPE_INT32: return 4;
55  case UPB_TYPE_INT64: return 8;
56  case UPB_TYPE_UINT32: return 4;
57  case UPB_TYPE_UINT64: return 8;
58  default: return 0;
59  }
60 }
61 
62 static bool is_ruby_num(VALUE value) {
63  return (TYPE(value) == T_FLOAT ||
64  TYPE(value) == T_FIXNUM ||
65  TYPE(value) == T_BIGNUM);
66 }
67 
69  if (!is_ruby_num(val)) {
70  rb_raise(cTypeError, "Expected number type for integral field '%s' (given %s).",
71  name, rb_class2name(CLASS_OF(val)));
72  }
73 
74  // NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
75  // bound; we just need to do precision checks (i.e., disallow rounding) and
76  // check for < 0 on unsigned types.
77  if (TYPE(val) == T_FLOAT) {
78  double dbl_val = NUM2DBL(val);
79  if (floor(dbl_val) != dbl_val) {
80  rb_raise(rb_eRangeError,
81  "Non-integral floating point value assigned to integer field '%s' (given %s).",
82  name, rb_class2name(CLASS_OF(val)));
83  }
84  }
86  if (NUM2DBL(val) < 0) {
87  rb_raise(rb_eRangeError,
88  "Assigning negative value to unsigned integer field '%s' (given %s).",
89  name, rb_class2name(CLASS_OF(val)));
90  }
91  }
92 }
93 
95  rb_encoding* desired_encoding = (type == UPB_TYPE_STRING) ?
97  VALUE desired_encoding_value = rb_enc_from_encoding(desired_encoding);
98 
99  // Note: this will not duplicate underlying string data unless necessary.
100  value = rb_str_encode(value, desired_encoding_value, 0, Qnil);
101 
102  if (type == UPB_TYPE_STRING &&
103  rb_enc_str_coderange(value) == ENC_CODERANGE_BROKEN) {
104  rb_raise(rb_eEncodingError, "String is invalid UTF-8");
105  }
106 
107  // Ensure the data remains valid. Since we called #encode a moment ago,
108  // this does not freeze the string the user assigned.
109  rb_obj_freeze(value);
110 
111  return value;
112 }
113 
114 void native_slot_set(const char* name,
115  upb_fieldtype_t type, VALUE type_class,
116  void* memory, VALUE value) {
117  native_slot_set_value_and_case(name, type, type_class, memory, value, NULL, 0);
118 }
119 
121  upb_fieldtype_t type, VALUE type_class,
122  void* memory, VALUE value,
123  uint32_t* case_memory,
124  uint32_t case_number) {
125  // Note that in order to atomically change the value in memory and the case
126  // value (w.r.t. Ruby VM calls), we must set the value at |memory| only after
127  // all Ruby VM calls are complete. The case is then set at the bottom of this
128  // function.
129  switch (type) {
130  case UPB_TYPE_FLOAT:
131  if (!is_ruby_num(value)) {
132  rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
133  name, rb_class2name(CLASS_OF(value)));
134  }
135  DEREF(memory, float) = NUM2DBL(value);
136  break;
137  case UPB_TYPE_DOUBLE:
138  if (!is_ruby_num(value)) {
139  rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
140  name, rb_class2name(CLASS_OF(value)));
141  }
142  DEREF(memory, double) = NUM2DBL(value);
143  break;
144  case UPB_TYPE_BOOL: {
145  int8_t val = -1;
146  if (value == Qtrue) {
147  val = 1;
148  } else if (value == Qfalse) {
149  val = 0;
150  } else {
151  rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
152  name, rb_class2name(CLASS_OF(value)));
153  }
154  DEREF(memory, int8_t) = val;
155  break;
156  }
157  case UPB_TYPE_STRING:
158  if (CLASS_OF(value) == rb_cSymbol) {
159  value = rb_funcall(value, rb_intern("to_s"), 0);
160  } else if (CLASS_OF(value) != rb_cString) {
161  rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
162  name, rb_class2name(CLASS_OF(value)));
163  }
164 
166  break;
167 
168  case UPB_TYPE_BYTES: {
169  if (CLASS_OF(value) != rb_cString) {
170  rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
171  name, rb_class2name(CLASS_OF(value)));
172  }
173 
175  break;
176  }
177  case UPB_TYPE_MESSAGE: {
178  if (CLASS_OF(value) == CLASS_OF(Qnil)) {
179  value = Qnil;
180  } else if (CLASS_OF(value) != type_class) {
181  // check for possible implicit conversions
182  VALUE converted_value = NULL;
183  char* field_type_name = rb_class2name(type_class);
184 
185  if (strcmp(field_type_name, "Google::Protobuf::Timestamp") == 0 &&
186  rb_obj_is_kind_of(value, rb_cTime)) {
187  // Time -> Google::Protobuf::Timestamp
188  VALUE hash = rb_hash_new();
189  rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
190  rb_hash_aset(hash, rb_str_new2("nanos"), rb_funcall(value, rb_intern("nsec"), 0));
191  VALUE args[1] = { hash };
192  converted_value = rb_class_new_instance(1, args, type_class);
193  } else if (strcmp(field_type_name, "Google::Protobuf::Duration") == 0 &&
194  rb_obj_is_kind_of(value, rb_cNumeric)) {
195  // Numeric -> Google::Protobuf::Duration
196  VALUE hash = rb_hash_new();
197  rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
198  VALUE n_value = rb_funcall(value, rb_intern("remainder"), 1, INT2NUM(1));
199  n_value = rb_funcall(n_value, rb_intern("*"), 1, INT2NUM(1000000000));
200  n_value = rb_funcall(n_value, rb_intern("round"), 0);
201  rb_hash_aset(hash, rb_str_new2("nanos"), n_value);
202  VALUE args[1] = { hash };
203  converted_value = rb_class_new_instance(1, args, type_class);
204  }
205 
206  // raise if no suitable conversaion could be found
207  if (converted_value == NULL) {
208  rb_raise(cTypeError,
209  "Invalid type %s to assign to submessage field '%s'.",
210  rb_class2name(CLASS_OF(value)), name);
211  } else {
212  value = converted_value;
213  }
214  }
215  DEREF(memory, VALUE) = value;
216  break;
217  }
218  case UPB_TYPE_ENUM: {
219  int32_t int_val = 0;
220  if (TYPE(value) == T_STRING) {
221  value = rb_funcall(value, rb_intern("to_sym"), 0);
222  } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
223  rb_raise(cTypeError,
224  "Expected number or symbol type for enum field '%s'.", name);
225  }
226  if (TYPE(value) == T_SYMBOL) {
227  // Ensure that the given symbol exists in the enum module.
228  VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
229  if (lookup == Qnil) {
230  rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
231  } else {
232  int_val = NUM2INT(lookup);
233  }
234  } else {
236  int_val = NUM2INT(value);
237  }
238  DEREF(memory, int32_t) = int_val;
239  break;
240  }
241  case UPB_TYPE_INT32:
242  case UPB_TYPE_INT64:
243  case UPB_TYPE_UINT32:
244  case UPB_TYPE_UINT64:
246  switch (type) {
247  case UPB_TYPE_INT32:
248  DEREF(memory, int32_t) = NUM2INT(value);
249  break;
250  case UPB_TYPE_INT64:
251  DEREF(memory, int64_t) = NUM2LL(value);
252  break;
253  case UPB_TYPE_UINT32:
254  DEREF(memory, uint32_t) = NUM2UINT(value);
255  break;
256  case UPB_TYPE_UINT64:
257  DEREF(memory, uint64_t) = NUM2ULL(value);
258  break;
259  default:
260  break;
261  }
262  break;
263  default:
264  break;
265  }
266 
267  if (case_memory != NULL) {
268  *case_memory = case_number;
269  }
270 }
271 
273  VALUE type_class,
274  const void* memory) {
275  switch (type) {
276  case UPB_TYPE_FLOAT:
277  return DBL2NUM(DEREF(memory, float));
278  case UPB_TYPE_DOUBLE:
279  return DBL2NUM(DEREF(memory, double));
280  case UPB_TYPE_BOOL:
281  return DEREF(memory, int8_t) ? Qtrue : Qfalse;
282  case UPB_TYPE_STRING:
283  case UPB_TYPE_BYTES:
284  case UPB_TYPE_MESSAGE:
285  return DEREF(memory, VALUE);
286  case UPB_TYPE_ENUM: {
287  int32_t val = DEREF(memory, int32_t);
288  VALUE symbol = enum_lookup(type_class, INT2NUM(val));
289  if (symbol == Qnil) {
290  return INT2NUM(val);
291  } else {
292  return symbol;
293  }
294  }
295  case UPB_TYPE_INT32:
296  return INT2NUM(DEREF(memory, int32_t));
297  case UPB_TYPE_INT64:
298  return LL2NUM(DEREF(memory, int64_t));
299  case UPB_TYPE_UINT32:
300  return UINT2NUM(DEREF(memory, uint32_t));
301  case UPB_TYPE_UINT64:
302  return ULL2NUM(DEREF(memory, uint64_t));
303  default:
304  return Qnil;
305  }
306 }
307 
308 void native_slot_init(upb_fieldtype_t type, void* memory) {
309  switch (type) {
310  case UPB_TYPE_FLOAT:
311  DEREF(memory, float) = 0.0;
312  break;
313  case UPB_TYPE_DOUBLE:
314  DEREF(memory, double) = 0.0;
315  break;
316  case UPB_TYPE_BOOL:
317  DEREF(memory, int8_t) = 0;
318  break;
319  case UPB_TYPE_STRING:
320  case UPB_TYPE_BYTES:
321  DEREF(memory, VALUE) = rb_str_new2("");
322  rb_enc_associate(DEREF(memory, VALUE), (type == UPB_TYPE_BYTES) ?
324  break;
325  case UPB_TYPE_MESSAGE:
326  DEREF(memory, VALUE) = Qnil;
327  break;
328  case UPB_TYPE_ENUM:
329  case UPB_TYPE_INT32:
330  DEREF(memory, int32_t) = 0;
331  break;
332  case UPB_TYPE_INT64:
333  DEREF(memory, int64_t) = 0;
334  break;
335  case UPB_TYPE_UINT32:
336  DEREF(memory, uint32_t) = 0;
337  break;
338  case UPB_TYPE_UINT64:
339  DEREF(memory, uint64_t) = 0;
340  break;
341  default:
342  break;
343  }
344 }
345 
346 void native_slot_mark(upb_fieldtype_t type, void* memory) {
347  switch (type) {
348  case UPB_TYPE_STRING:
349  case UPB_TYPE_BYTES:
350  case UPB_TYPE_MESSAGE:
351  rb_gc_mark(DEREF(memory, VALUE));
352  break;
353  default:
354  break;
355  }
356 }
357 
358 void native_slot_dup(upb_fieldtype_t type, void* to, void* from) {
359  memcpy(to, from, native_slot_size(type));
360 }
361 
362 void native_slot_deep_copy(upb_fieldtype_t type, void* to, void* from) {
363  switch (type) {
364  case UPB_TYPE_STRING:
365  case UPB_TYPE_BYTES: {
366  VALUE from_val = DEREF(from, VALUE);
367  DEREF(to, VALUE) = (from_val != Qnil) ?
368  rb_funcall(from_val, rb_intern("dup"), 0) : Qnil;
369  break;
370  }
371  case UPB_TYPE_MESSAGE: {
372  VALUE from_val = DEREF(from, VALUE);
373  DEREF(to, VALUE) = (from_val != Qnil) ?
374  Message_deep_copy(from_val) : Qnil;
375  break;
376  }
377  default:
378  memcpy(to, from, native_slot_size(type));
379  }
380 }
381 
382 bool native_slot_eq(upb_fieldtype_t type, void* mem1, void* mem2) {
383  switch (type) {
384  case UPB_TYPE_STRING:
385  case UPB_TYPE_BYTES:
386  case UPB_TYPE_MESSAGE: {
387  VALUE val1 = DEREF(mem1, VALUE);
388  VALUE val2 = DEREF(mem2, VALUE);
389  VALUE ret = rb_funcall(val1, rb_intern("=="), 1, val2);
390  return ret == Qtrue;
391  }
392  default:
393  return !memcmp(mem1, mem2, native_slot_size(type));
394  }
395 }
396 
397 // -----------------------------------------------------------------------------
398 // Map field utilities.
399 // -----------------------------------------------------------------------------
400 
402  const upb_msgdef* subdef;
405  return NULL;
406  }
407  subdef = upb_fielddef_msgsubdef(field);
408  return upb_msgdef_mapentry(subdef) ? subdef : NULL;
409 }
410 
412  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
413  assert(subdef);
414  return subdef;
415 }
416 
418  const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
419  if (subdef == NULL) return false;
420 
421  // Map fields are a proto3 feature.
422  // If we're using proto2 syntax we need to fallback to the repeated field.
423  return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
424 }
425 
427  const upb_msgdef* subdef = map_entry_msgdef(field);
428  return map_entry_key(subdef);
429 }
430 
432  const upb_msgdef* subdef = map_entry_msgdef(field);
433  return map_entry_value(subdef);
434 }
435 
437  const upb_fielddef* key_field = upb_msgdef_itof(msgdef, MAP_KEY_FIELD);
438  assert(key_field != NULL);
439  return key_field;
440 }
441 
443  const upb_fielddef* value_field = upb_msgdef_itof(msgdef, MAP_VALUE_FIELD);
444  assert(value_field != NULL);
445  return value_field;
446 }
447 
448 // -----------------------------------------------------------------------------
449 // Memory layout management.
450 // -----------------------------------------------------------------------------
451 
453  const upb_fielddef* field) {
456 }
457 
458 static size_t align_up_to(size_t offset, size_t granularity) {
459  // Granularity must be a power of two.
460  return (offset + granularity - 1) & ~(granularity - 1);
461 }
462 
465  int nfields = upb_msgdef_numfields(msgdef);
467  upb_msg_oneof_iter oit;
468  size_t off = 0;
469 
470  layout->fields = ALLOC_N(MessageField, nfields);
471 
472  size_t hasbit = 0;
473  for (upb_msg_field_begin(&it, msgdef);
479  } else {
482  }
483  }
484 
485  if (hasbit != 0) {
486  off += (hasbit + 8 - 1) / 8;
487  }
488 
489  for (upb_msg_field_begin(&it, msgdef);
493  size_t field_size;
494 
496  // Oneofs are handled separately below.
497  continue;
498  }
499 
500  // Allocate |field_size| bytes for this field in the layout.
501  field_size = 0;
503  field_size = sizeof(VALUE);
504  } else {
506  }
507  // Align current offset up to |size| granularity.
508  off = align_up_to(off, field_size);
512  off += field_size;
513  }
514 
515  // Handle oneofs now -- we iterate over oneofs specifically and allocate only
516  // one slot per oneof.
517  //
518  // We assign all value slots first, then pack the 'case' fields at the end,
519  // since in the common case (modern 64-bit platform) these are 8 bytes and 4
520  // bytes respectively and we want to avoid alignment overhead.
521  //
522  // Note that we reserve 4 bytes (a uint32) per 'case' slot because the value
523  // space for oneof cases is conceptually as wide as field tag numbers. In
524  // practice, it's unlikely that a oneof would have more than e.g. 256 or 64K
525  // members (8 or 16 bits respectively), so conceivably we could assign
526  // consecutive case numbers and then pick a smaller oneof case slot size, but
527  // the complexity to implement this indirection is probably not worthwhile.
528  for (upb_msg_oneof_begin(&oit, msgdef);
529  !upb_msg_oneof_done(&oit);
530  upb_msg_oneof_next(&oit)) {
531  const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
532  upb_oneof_iter fit;
533 
534  // Always allocate NATIVE_SLOT_MAX_SIZE bytes, but share the slot between
535  // all fields.
536  size_t field_size = NATIVE_SLOT_MAX_SIZE;
537  // Align the offset.
538  off = align_up_to(off, field_size);
539  // Assign all fields in the oneof this same offset.
540  for (upb_oneof_begin(&fit, oneof);
541  !upb_oneof_done(&fit);
542  upb_oneof_next(&fit)) {
543  const upb_fielddef* field = upb_oneof_iter_field(&fit);
545  }
546  off += field_size;
547  }
548 
549  // Now the case fields.
550  for (upb_msg_oneof_begin(&oit, msgdef);
551  !upb_msg_oneof_done(&oit);
552  upb_msg_oneof_next(&oit)) {
553  const upb_oneofdef* oneof = upb_msg_iter_oneof(&oit);
554  upb_oneof_iter fit;
555 
556  size_t field_size = sizeof(uint32_t);
557  // Align the offset.
558  off = (off + field_size - 1) & ~(field_size - 1);
559  // Assign all fields in the oneof this same offset.
560  for (upb_oneof_begin(&fit, oneof);
561  !upb_oneof_done(&fit);
562  upb_oneof_next(&fit)) {
563  const upb_fielddef* field = upb_oneof_iter_field(&fit);
565  }
566  off += field_size;
567  }
568 
569  layout->size = off;
570 
571  layout->msgdef = msgdef;
572  upb_msgdef_ref(layout->msgdef, &layout->msgdef);
573 
574  return layout;
575 }
576 
578  xfree(layout->fields);
579  upb_msgdef_unref(layout->msgdef, &layout->msgdef);
580  xfree(layout);
581 }
582 
584  VALUE type_class = Qnil;
586  VALUE submsgdesc =
588  type_class = Descriptor_msgclass(submsgdesc);
589  } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) {
590  VALUE subenumdesc =
592  type_class = EnumDescriptor_enummodule(subenumdesc);
593  }
594  return type_class;
595 }
596 
598  const void* storage,
599  const upb_fielddef* field) {
600  return ((uint8_t *)storage) +
602 }
603 
605  const void* storage,
606  const upb_fielddef* field) {
607  return (uint32_t *)(((uint8_t *)storage) +
609 }
610 
612  const void* storage,
613  const upb_fielddef* field) {
614  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
615  assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
616 
617  ((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
618 }
619 
621  const void* storage,
622  const upb_fielddef* field) {
623  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
624  assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
625  ((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
626 }
627 
629  const void* storage,
630  const upb_fielddef* field) {
631  size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
632  if (hasbit == MESSAGE_FIELD_NO_HASBIT) {
633  return false;
634  }
635 
636  return DEREF_OFFSET(
637  (uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
638 }
639 
641  const void* storage,
642  const upb_fielddef* field) {
644  return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
645 }
646 
648  const void* storage,
649  const upb_fielddef* field) {
650  void* memory = slot_memory(layout, storage, field);
651  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
652 
654  slot_clear_hasbit(layout, storage, field);
655  }
656 
658  memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
659  *oneof_case = ONEOF_CASE_NONE;
660  } else if (is_map_field(field)) {
661  VALUE map = Qnil;
662 
663  const upb_fielddef* key_field = map_field_key(field);
664  const upb_fielddef* value_field = map_field_value(field);
665  VALUE type_class = field_type_class(value_field);
666 
667  if (type_class != Qnil) {
668  VALUE args[3] = {
670  fieldtype_to_ruby(upb_fielddef_type(value_field)),
671  type_class,
672  };
673  map = rb_class_new_instance(3, args, cMap);
674  } else {
675  VALUE args[2] = {
677  fieldtype_to_ruby(upb_fielddef_type(value_field)),
678  };
679  map = rb_class_new_instance(2, args, cMap);
680  }
681 
682  DEREF(memory, VALUE) = map;
684  VALUE ary = Qnil;
685 
686  VALUE type_class = field_type_class(field);
687 
688  if (type_class != Qnil) {
689  VALUE args[2] = {
691  type_class,
692  };
693  ary = rb_class_new_instance(2, args, cRepeatedField);
694  } else {
696  ary = rb_class_new_instance(1, args, cRepeatedField);
697  }
698 
699  DEREF(memory, VALUE) = ary;
700  } else {
703  memory, layout_get_default(field));
704  }
705 }
706 
708  switch (upb_fielddef_type(field)) {
709  case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
710  case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
711  case UPB_TYPE_BOOL:
712  return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
713  case UPB_TYPE_MESSAGE: return Qnil;
714  case UPB_TYPE_ENUM: {
716  int32_t num = upb_fielddef_defaultint32(field);
717  const char *label = upb_enumdef_iton(enumdef, num);
718  if (label) {
719  return ID2SYM(rb_intern(label));
720  } else {
721  return INT2NUM(num);
722  }
723  }
724  case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
725  case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
726  case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
727  case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
728  case UPB_TYPE_STRING:
729  case UPB_TYPE_BYTES: {
730  size_t size;
731  const char *str = upb_fielddef_defaultstr(field, &size);
732  VALUE str_rb = rb_str_new(str, size);
733 
734  rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
736  rb_obj_freeze(str_rb);
737  return str_rb;
738  }
739  default: return Qnil;
740  }
741 }
742 
744  const void* storage,
745  const upb_fielddef* field) {
746  void* memory = slot_memory(layout, storage, field);
747  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
748 
749  bool field_set;
751  field_set = slot_is_hasbit_set(layout, storage, field);
752  } else {
753  field_set = true;
754  }
755 
757  if (*oneof_case != upb_fielddef_number(field)) {
758  return layout_get_default(field);
759  }
762  memory);
764  return *((VALUE *)memory);
765  } else if (!field_set) {
766  return layout_get_default(field);
767  } else {
770  memory);
771  }
772 }
773 
774 static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
775  RepeatedField* self;
777 
778  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
779  RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
780  rb_raise(cTypeError, "Expected repeated field array");
781  }
782 
783  self = ruby_to_RepeatedField(val);
784  if (self->field_type != upb_fielddef_type(field)) {
785  rb_raise(cTypeError, "Repeated field array has wrong element type");
786  }
787 
788  if (self->field_type == UPB_TYPE_MESSAGE) {
789  if (self->field_type_class !=
791  rb_raise(cTypeError,
792  "Repeated field array has wrong message class");
793  }
794  }
795 
796 
797  if (self->field_type == UPB_TYPE_ENUM) {
798  if (self->field_type_class !=
800  rb_raise(cTypeError,
801  "Repeated field array has wrong enum class");
802  }
803  }
804 }
805 
806 static void check_map_field_type(VALUE val, const upb_fielddef* field) {
807  const upb_fielddef* key_field = map_field_key(field);
808  const upb_fielddef* value_field = map_field_value(field);
809  Map* self;
810 
811  if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
812  RTYPEDDATA_TYPE(val) != &Map_type) {
813  rb_raise(cTypeError, "Expected Map instance");
814  }
815 
816  self = ruby_to_Map(val);
817  if (self->key_type != upb_fielddef_type(key_field)) {
818  rb_raise(cTypeError, "Map key type does not match field's key type");
819  }
820  if (self->value_type != upb_fielddef_type(value_field)) {
821  rb_raise(cTypeError, "Map value type does not match field's value type");
822  }
823  if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
824  upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
825  if (self->value_type_class !=
826  get_def_obj(upb_fielddef_subdef(value_field))) {
827  rb_raise(cTypeError,
828  "Map value type has wrong message/enum class");
829  }
830  }
831 }
832 
833 
835  void* storage,
836  const upb_fielddef* field,
837  VALUE val) {
838  void* memory = slot_memory(layout, storage, field);
839  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
840 
842  if (val == Qnil) {
843  // Assigning nil to a oneof field clears the oneof completely.
844  *oneof_case = ONEOF_CASE_NONE;
845  memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
846  } else {
847  // The transition between field types for a single oneof (union) slot is
848  // somewhat complex because we need to ensure that a GC triggered at any
849  // point by a call into the Ruby VM sees a valid state for this field and
850  // does not either go off into the weeds (following what it thinks is a
851  // VALUE but is actually a different field type) or miss an object (seeing
852  // what it thinks is a primitive field but is actually a VALUE for the new
853  // field type).
854  //
855  // In order for the transition to be safe, the oneof case slot must be in
856  // sync with the value slot whenever the Ruby VM has been called. Thus, we
857  // use native_slot_set_value_and_case(), which ensures that both the value
858  // and case number are altered atomically (w.r.t. the Ruby VM).
862  memory, val,
863  oneof_case, upb_fielddef_number(field));
864  }
865  } else if (is_map_field(field)) {
867  DEREF(memory, VALUE) = val;
870  DEREF(memory, VALUE) = val;
871  } else {
874  memory, val);
875  }
876 
877  if (layout->fields[upb_fielddef_index(field)].hasbit !=
879  slot_set_hasbit(layout, storage, field);
880  }
881 }
882 
884  void* storage) {
885 
891  }
892 }
893 
894 void layout_mark(MessageLayout* layout, void* storage) {
900  void* memory = slot_memory(layout, storage, field);
901  uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
902 
904  if (*oneof_case == upb_fielddef_number(field)) {
906  }
908  rb_gc_mark(DEREF(memory, VALUE));
909  } else {
911  }
912  }
913 }
914 
915 void layout_dup(MessageLayout* layout, void* to, void* from) {
921 
922  void* to_memory = slot_memory(layout, to, field);
923  uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
924  void* from_memory = slot_memory(layout, from, field);
925  uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
926 
928  if (*from_oneof_case == upb_fielddef_number(field)) {
929  *to_oneof_case = *from_oneof_case;
930  native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
931  }
932  } else if (is_map_field(field)) {
933  DEREF(to_memory, VALUE) = Map_dup(DEREF(from_memory, VALUE));
935  DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
936  } else {
938  if (!slot_is_hasbit_set(layout, from, field)) continue;
940  }
941 
942  native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
943  }
944  }
945 }
946 
947 void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
953 
954  void* to_memory = slot_memory(layout, to, field);
955  uint32_t* to_oneof_case = slot_oneof_case(layout, to, field);
956  void* from_memory = slot_memory(layout, from, field);
957  uint32_t* from_oneof_case = slot_oneof_case(layout, from, field);
958 
960  if (*from_oneof_case == upb_fielddef_number(field)) {
961  *to_oneof_case = *from_oneof_case;
962  native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
963  }
964  } else if (is_map_field(field)) {
965  DEREF(to_memory, VALUE) =
966  Map_deep_copy(DEREF(from_memory, VALUE));
968  DEREF(to_memory, VALUE) =
969  RepeatedField_deep_copy(DEREF(from_memory, VALUE));
970  } else {
972  if (!slot_is_hasbit_set(layout, from, field)) continue;
974  }
975 
976  native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
977  }
978  }
979 }
980 
981 VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
987 
988  void* msg1_memory = slot_memory(layout, msg1, field);
989  uint32_t* msg1_oneof_case = slot_oneof_case(layout, msg1, field);
990  void* msg2_memory = slot_memory(layout, msg2, field);
991  uint32_t* msg2_oneof_case = slot_oneof_case(layout, msg2, field);
992 
994  if (*msg1_oneof_case != *msg2_oneof_case ||
995  (*msg1_oneof_case == upb_fielddef_number(field) &&
997  msg1_memory,
998  msg2_memory))) {
999  return Qfalse;
1000  }
1001  } else if (is_map_field(field)) {
1002  if (!Map_eq(DEREF(msg1_memory, VALUE),
1003  DEREF(msg2_memory, VALUE))) {
1004  return Qfalse;
1005  }
1006  } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
1007  if (!RepeatedField_eq(DEREF(msg1_memory, VALUE),
1008  DEREF(msg2_memory, VALUE))) {
1009  return Qfalse;
1010  }
1011  } else {
1012  if (slot_is_hasbit_set(layout, msg1, field) !=
1013  slot_is_hasbit_set(layout, msg2, field) ||
1015  msg1_memory, msg2_memory)) {
1016  return Qfalse;
1017  }
1018  }
1019  }
1020  return Qtrue;
1021 }
1022 
1023 VALUE layout_hash(MessageLayout* layout, void* storage) {
1025  st_index_t h = rb_hash_start(0);
1026  VALUE hash_sym = rb_intern("hash");
1029  upb_msg_field_next(&it)) {
1031  VALUE field_val = layout_get(layout, storage, field);
1032  h = rb_hash_uint(h, NUM2LONG(rb_funcall(field_val, hash_sym, 0)));
1033  }
1034  h = rb_hash_end(h);
1035 
1036  return INT2FIX(h);
1037 }
1038 
1039 VALUE layout_inspect(MessageLayout* layout, void* storage) {
1040  VALUE str = rb_str_new2("");
1041 
1043  bool first = true;
1046  upb_msg_field_next(&it)) {
1048  VALUE field_val = layout_get(layout, storage, field);
1049 
1050  if (!first) {
1051  str = rb_str_cat2(str, ", ");
1052  } else {
1053  first = false;
1054  }
1055  str = rb_str_cat2(str, upb_fielddef_name(field));
1056  str = rb_str_cat2(str, ": ");
1057 
1058  str = rb_str_append(str, rb_funcall(field_val, rb_intern("inspect"), 0));
1059  }
1060 
1061  return str;
1062 }
msgdef
const upb_msgdef * msgdef
Definition: php/ext/google/protobuf/protobuf.h:799
upb_fielddef_defaultint64
int64_t upb_fielddef_defaultint64(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1628
upb_fielddef_defaultuint64
uint64_t upb_fielddef_defaultuint64(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1638
upb_msg_iter_oneof
const upb_oneofdef * upb_msg_iter_oneof(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1867
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
MessageLayout::size
size_t size
Definition: php/ext/google/protobuf/protobuf.h:930
cMap
VALUE cMap
Definition: ruby/ext/google/protobuf_c/map.c:137
check_repeated_field_type
static void check_repeated_field_type(VALUE val, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:774
Map
Definition: ruby/ext/google/protobuf_c/protobuf.h:442
lookup
static int16_t lookup[CNT]
Definition: floatTolin.h:6
cRepeatedField
VALUE cRepeatedField
Definition: repeated_field.c:42
upb_msgdef_mapentry
bool upb_msgdef_mapentry(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1809
native_slot_check_int_range_precision
void native_slot_check_int_range_precision(const char *name, upb_fieldtype_t type, VALUE val)
Definition: ruby/ext/google/protobuf_c/storage.c:68
MessageField::offset
size_t offset
Definition: php/ext/google/protobuf/protobuf.h:921
field_type_class
VALUE field_type_class(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:583
NULL
NULL
Definition: test_security_zap.cpp:405
check_map_field_type
static void check_map_field_type(VALUE val, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:806
upb_enumdef_iton
const char * upb_enumdef_iton(const upb_enumdef *def, int32_t num)
Definition: php/ext/google/protobuf/upb.c:1484
upb_msg_field_begin
void upb_msg_field_begin(upb_msg_field_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1823
layout_eq
VALUE layout_eq(MessageLayout *layout, void *msg1, void *msg2)
Definition: ruby/ext/google/protobuf_c/storage.c:981
Map_dup
VALUE Map_dup(VALUE _self)
Definition: ruby/ext/google/protobuf_c/map.c:514
native_slot_encode_and_freeze_string
VALUE native_slot_encode_and_freeze_string(upb_fieldtype_t type, VALUE value)
Definition: ruby/ext/google/protobuf_c/storage.c:94
UPB_TYPE_INT32
@ UPB_TYPE_INT32
Definition: php/ext/google/protobuf/upb.h:415
layout_get_default
VALUE layout_get_default(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:707
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: php/ext/google/protobuf/map.c:543
slot_clear_hasbit
static void slot_clear_hasbit(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:620
EnumDescriptor_enummodule
VALUE EnumDescriptor_enummodule(VALUE _self)
Definition: defs.c:1460
label
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:4316
protobuf.h
layout_init
void layout_init(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:883
layout_mark
void layout_mark(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:894
map_field_value
const upb_fielddef * map_field_value(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:431
MessageField
Definition: php/ext/google/protobuf/protobuf.h:920
upb_fielddef_subdef
const upb_def * upb_fielddef_subdef(const upb_fielddef *f)
Definition: ruby/ext/google/protobuf_c/upb.c:2081
native_slot_eq
bool native_slot_eq(upb_fieldtype_t type, void *mem1, void *mem2)
Definition: ruby/ext/google/protobuf_c/storage.c:382
slot_memory
static void * slot_memory(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:597
slot_set_hasbit
static void slot_set_hasbit(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:611
upb_fielddef_enumsubdef
const upb_enumdef * upb_fielddef_enumsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1682
native_slot_size
size_t native_slot_size(upb_fieldtype_t type)
Definition: ruby/ext/google/protobuf_c/storage.c:45
align_up_to
static size_t align_up_to(size_t offset, size_t granularity)
Definition: ruby/ext/google/protobuf_c/storage.c:458
UPB_TYPE_FLOAT
@ UPB_TYPE_FLOAT
Definition: php/ext/google/protobuf/upb.h:414
map
zval * map
Definition: php/ext/google/protobuf/encode_decode.c:473
layout_inspect
VALUE layout_inspect(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:1039
layout
MessageLayout * layout
Definition: php/ext/google/protobuf/protobuf.h:800
upb_fielddef_defaultdouble
double upb_fielddef_defaultdouble(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1658
ruby_to_Map
Map * ruby_to_Map(VALUE _self)
Definition: ruby/ext/google/protobuf_c/map.c:139
ALLOC
#define ALLOC(class_name)
Definition: php/ext/google/protobuf/protobuf.h:1477
upb_oneofdef
Definition: php/ext/google/protobuf/upb.c:1176
UPB_TYPE_UINT32
@ UPB_TYPE_UINT32
Definition: php/ext/google/protobuf/upb.h:416
MessageField::hasbit
size_t hasbit
Definition: ruby/ext/google/protobuf_c/protobuf.h:501
upb_fielddef_defaultfloat
float upb_fielddef_defaultfloat(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1653
UPB_SYNTAX_PROTO3
@ UPB_SYNTAX_PROTO3
Definition: php/ext/google/protobuf/upb.h:3141
ONEOF_CASE_NONE
#define ONEOF_CASE_NONE
Definition: php/ext/google/protobuf/protobuf.h:1188
create_layout
MessageLayout * create_layout(const upb_msgdef *msgdef)
Definition: ruby/ext/google/protobuf_c/storage.c:463
layout_deep_copy
void layout_deep_copy(MessageLayout *layout, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:947
ALLOC_N
#define ALLOC_N(class_name, n)
Definition: php/ext/google/protobuf/protobuf.h:1479
map_entry_value
const upb_fielddef * map_entry_value(const upb_msgdef *msgdef)
Definition: ruby/ext/google/protobuf_c/storage.c:442
upb_inttable_iter
Definition: php/ext/google/protobuf/upb.h:3088
offset
GLintptr offset
Definition: glcorearb.h:2944
kRubyStringUtf8Encoding
rb_encoding * kRubyStringUtf8Encoding
Definition: ruby/ext/google/protobuf_c/protobuf.c:67
MESSAGE_FIELD_NO_HASBIT
#define MESSAGE_FIELD_NO_HASBIT
Definition: ruby/ext/google/protobuf_c/protobuf.h:496
MessageLayout::fields
MessageField * fields
Definition: php/ext/google/protobuf/protobuf.h:929
update_failure_list.str
str
Definition: update_failure_list.py:41
upb_fielddef_containingoneof
const upb_oneofdef * upb_fielddef_containingoneof(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1619
upb_msg_oneof_begin
void upb_msg_oneof_begin(upb_msg_oneof_iter *iter, const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1846
native_slot_mark
void native_slot_mark(upb_fieldtype_t type, void *memory)
Definition: ruby/ext/google/protobuf_c/storage.c:346
UPB_TYPE_DOUBLE
@ UPB_TYPE_DOUBLE
Definition: php/ext/google/protobuf/upb.h:423
UPB_TYPE_STRING
@ UPB_TYPE_STRING
Definition: php/ext/google/protobuf/upb.h:419
size
#define size
Definition: glcorearb.h:2944
upb_fielddef_name
const char * upb_fielddef_name(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1568
native_slot_set_value_and_case
void native_slot_set_value_and_case(const char *name, upb_fieldtype_t type, VALUE type_class, void *memory, VALUE value, uint32_t *case_memory, uint32_t case_number)
Definition: ruby/ext/google/protobuf_c/storage.c:120
upb_fielddef
Definition: php/ext/google/protobuf/upb.c:1118
upb_fielddef_defaultint32
int32_t upb_fielddef_defaultint32(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1633
kRubyString8bitEncoding
rb_encoding * kRubyString8bitEncoding
Definition: ruby/ext/google/protobuf_c/protobuf.c:69
layout_hash
VALUE layout_hash(MessageLayout *layout, void *storage)
Definition: ruby/ext/google/protobuf_c/storage.c:1023
upb_msg_oneof_done
bool upb_msg_oneof_done(const upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1863
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:421
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
native_slot_deep_copy
void native_slot_deep_copy(upb_fieldtype_t type, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:362
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:417
Map_eq
VALUE Map_eq(VALUE _self, VALUE _other)
Definition: ruby/ext/google/protobuf_c/map.c:582
map_entry_key
const upb_fielddef * map_entry_key(const upb_msgdef *msgdef)
Definition: ruby/ext/google/protobuf_c/storage.c:436
UPB_TYPE_UINT64
@ UPB_TYPE_UINT64
Definition: php/ext/google/protobuf/upb.h:425
upb_oneof_next
void upb_oneof_next(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1915
is_map_field
bool is_map_field(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:417
upb_msg_iter_field
upb_fielddef * upb_msg_iter_field(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1833
upb_fielddef_type
upb_fieldtype_t upb_fielddef_type(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1505
upb_fielddef_defaultbool
bool upb_fielddef_defaultbool(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1648
layout_set
void layout_set(MessageLayout *layout, void *storage, const upb_fielddef *field, VALUE val)
Definition: ruby/ext/google/protobuf_c/storage.c:834
type
GLenum type
Definition: glcorearb.h:2695
upb_oneof_iter_field
upb_fielddef * upb_oneof_iter_field(const upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1923
native_slot_set
void native_slot_set(const char *name, upb_fieldtype_t type, VALUE type_class, void *memory, VALUE value)
Definition: ruby/ext/google/protobuf_c/storage.c:114
RepeatedField_dup
VALUE RepeatedField_dup(VALUE _self)
Definition: repeated_field.c:340
upb_oneof_begin
void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o)
Definition: php/ext/google/protobuf/upb.c:1911
tryget_map_entry_msgdef
const upb_msgdef * tryget_map_entry_msgdef(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:401
is_ruby_num
static bool is_ruby_num(VALUE value)
Definition: ruby/ext/google/protobuf_c/storage.c:62
upb_fielddef_msgsubdef
const upb_msgdef * upb_fielddef_msgsubdef(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1677
layout_dup
void layout_dup(MessageLayout *layout, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:915
upb_msg_field_next
void upb_msg_field_next(upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1827
cTypeError
VALUE cTypeError
Definition: ruby/ext/google/protobuf_c/protobuf.c:44
upb_enumdef
Definition: php/ext/google/protobuf/upb.c:1168
MessageLayout::msgdef
const upb_msgdef * msgdef
Definition: php/ext/google/protobuf/protobuf.h:928
UPB_LABEL_REPEATED
@ UPB_LABEL_REPEATED
Definition: php/ext/google/protobuf/upb.h:432
get_def_obj
PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void *def)
Definition: php/ext/google/protobuf/protobuf.c:112
field_contains_hasbit
bool field_contains_hasbit(MessageLayout *layout, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:452
slot_is_hasbit_set
static bool slot_is_hasbit_set(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:628
upb_msgdef_numfields
int upb_msgdef_numfields(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1799
fieldtype_to_ruby
VALUE fieldtype_to_ruby(upb_fieldtype_t type)
Definition: defs.c:752
RepeatedField_type
const rb_data_type_t RepeatedField_type
Definition: repeated_field.c:37
Descriptor_msgclass
VALUE Descriptor_msgclass(VALUE _self)
Definition: defs.c:493
NATIVE_SLOT_MAX_SIZE
#define NATIVE_SLOT_MAX_SIZE
Definition: php/ext/google/protobuf/protobuf.h:1021
size
GLsizeiptr size
Definition: glcorearb.h:2943
DEREF
#define DEREF(memory, type)
Definition: ruby/ext/google/protobuf_c/storage.c:43
upb_msg_field_done
bool upb_msg_field_done(const upb_msg_field_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1829
upb_msgdef_itof
const upb_fielddef * upb_msgdef_itof(const upb_msgdef *m, uint32_t i)
Definition: php/ext/google/protobuf/upb.c:1757
map_field_key
const upb_fielddef * map_field_key(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:426
Message_deep_copy
VALUE Message_deep_copy(VALUE _self)
Definition: ruby/ext/google/protobuf_c/message.c:515
MESSAGE_FIELD_NO_CASE
#define MESSAGE_FIELD_NO_CASE
Definition: php/ext/google/protobuf/protobuf.h:918
RepeatedField_eq
VALUE RepeatedField_eq(VALUE _self, VALUE _other)
Definition: repeated_field.c:412
UPB_TYPE_BYTES
@ UPB_TYPE_BYTES
Definition: php/ext/google/protobuf/upb.h:420
ruby_to_RepeatedField
RepeatedField * ruby_to_RepeatedField(VALUE value)
Definition: repeated_field.c:44
upb_fielddef_number
uint32_t upb_fielddef_number(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1552
first
GLint first
Definition: glcorearb.h:2830
upb_fielddef_label
upb_label_t upb_fielddef_label(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1548
TYPE
#define TYPE(u, l)
Definition: php/ext/google/protobuf/upb.c:8510
layout_clear
void layout_clear(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:647
free_layout
void free_layout(MessageLayout *layout)
Definition: ruby/ext/google/protobuf_c/storage.c:577
UPB_TYPE_INT64
@ UPB_TYPE_INT64
Definition: php/ext/google/protobuf/upb.h:424
upb_oneof_done
bool upb_oneof_done(upb_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1919
DEREF_OFFSET
#define DEREF_OFFSET(msg, ofs, type)
Definition: ruby/ext/google/protobuf_c/storage.c:42
native_slot_init
void native_slot_init(upb_fieldtype_t type, void *memory)
Definition: ruby/ext/google/protobuf_c/storage.c:308
MessageLayout
Definition: php/ext/google/protobuf/protobuf.h:927
map_entry_msgdef
const upb_msgdef * map_entry_msgdef(const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:411
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
Map_type
const rb_data_type_t Map_type
Definition: ruby/ext/google/protobuf_c/map.c:132
layout_get
VALUE layout_get(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:743
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
MAP_KEY_FIELD
#define MAP_KEY_FIELD
Definition: php/ext/google/protobuf/protobuf.h:1093
RepeatedField_deep_copy
VALUE RepeatedField_deep_copy(VALUE _self)
Definition: repeated_field.c:359
slot_oneof_case
static uint32_t * slot_oneof_case(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:604
upb_strtable_iter
Definition: php/ext/google/protobuf/upb.h:3061
upb_msg_oneof_next
void upb_msg_oneof_next(upb_msg_oneof_iter *iter)
Definition: php/ext/google/protobuf/upb.c:1855
enum_lookup
VALUE enum_lookup(VALUE self, VALUE number)
Definition: ruby/ext/google/protobuf_c/message.c:760
upb_msgdef_syntax
upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m)
Definition: php/ext/google/protobuf/upb.c:1745
enumdef
const upb_enumdef * enumdef
Definition: php/ext/google/protobuf/protobuf.h:830
native_slot_dup
void native_slot_dup(upb_fieldtype_t type, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:358
UPB_TYPE_BOOL
@ UPB_TYPE_BOOL
Definition: php/ext/google/protobuf/upb.h:412
MAP_VALUE_FIELD
#define MAP_VALUE_FIELD
Definition: php/ext/google/protobuf/protobuf.h:1094
layout_has
VALUE layout_has(MessageLayout *layout, const void *storage, const upb_fielddef *field)
Definition: ruby/ext/google/protobuf_c/storage.c:640
MessageField::case_offset
size_t case_offset
Definition: php/ext/google/protobuf/protobuf.h:924
upb_fielddef_index
uint32_t upb_fielddef_index(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1544
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
native_slot_get
VALUE native_slot_get(upb_fieldtype_t type, VALUE type_class, const void *memory)
Definition: ruby/ext/google/protobuf_c/storage.c:272
upb_msgdef
Definition: php/ext/google/protobuf/upb.c:1146
upb_fielddef_haspresence
bool upb_fielddef_haspresence(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1713
upb_fieldtype_t
upb_fieldtype_t
Definition: php/ext/google/protobuf/upb.h:410
h
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:4147
upb_fielddef_defaultuint32
uint32_t upb_fielddef_defaultuint32(const upb_fielddef *f)
Definition: php/ext/google/protobuf/upb.c:1643
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
upb_fielddef_defaultstr
const char * upb_fielddef_defaultstr(const upb_fielddef *f, size_t *len)
Definition: php/ext/google/protobuf/upb.c:1663
Map_deep_copy
VALUE Map_deep_copy(VALUE _self)
Definition: ruby/ext/google/protobuf_c/map.c:542
RepeatedField
Definition: ruby/ext/google/protobuf_c/protobuf.h:395


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:59