google-protobuf 3.15.7 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -1,27 +1,54 @@
1
1
  /* Amalgamated source file */
2
2
  #include "ruby-upb.h"
3
3
  /*
4
- * This is where we define macros used across upb.
5
- *
6
- * All of these macros are undef'd in port_undef.inc to avoid leaking them to
7
- * users.
8
- *
9
- * The correct usage is:
10
- *
11
- * #include "upb/foobar.h"
12
- * #include "upb/baz.h"
13
- *
14
- * // MUST be last included header.
15
- * #include "upb/port_def.inc"
16
- *
17
- * // Code for this file.
18
- * // <...>
19
- *
20
- * // Can be omitted for .c files, required for .h.
21
- * #include "upb/port_undef.inc"
22
- *
23
- * This file is private and must not be included by users!
24
- */
4
+ * Copyright (c) 2009-2021, Google LLC
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
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 copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of Google LLC nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ /*
31
+ * This is where we define macros used across upb.
32
+ *
33
+ * All of these macros are undef'd in port_undef.inc to avoid leaking them to
34
+ * users.
35
+ *
36
+ * The correct usage is:
37
+ *
38
+ * #include "upb/foobar.h"
39
+ * #include "upb/baz.h"
40
+ *
41
+ * // MUST be last included header.
42
+ * #include "upb/port_def.inc"
43
+ *
44
+ * // Code for this file.
45
+ * // <...>
46
+ *
47
+ * // Can be omitted for .c files, required for .h.
48
+ * #include "upb/port_undef.inc"
49
+ *
50
+ * This file is private and must not be included by users!
51
+ */
25
52
 
26
53
  #if !((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
27
54
  (defined(__cplusplus) && __cplusplus >= 201103L) || \
@@ -137,9 +164,40 @@
137
164
  #define UPB_LONGJMP(buf, val) longjmp(buf, val)
138
165
  #endif
139
166
 
167
+ /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
168
+ #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
169
+
140
170
  /* Configure whether fasttable is switched on or not. *************************/
141
171
 
142
- #if defined(__x86_64__) && defined(__GNUC__)
172
+ #ifdef __has_attribute
173
+ #define UPB_HAS_ATTRIBUTE(x) __has_attribute(x)
174
+ #else
175
+ #define UPB_HAS_ATTRIBUTE(x) 0
176
+ #endif
177
+
178
+ #if UPB_HAS_ATTRIBUTE(musttail)
179
+ #define UPB_MUSTTAIL __attribute__((musttail))
180
+ #else
181
+ #define UPB_MUSTTAIL
182
+ #endif
183
+
184
+ #undef UPB_HAS_ATTRIBUTE
185
+
186
+ /* This check is not fully robust: it does not require that we have "musttail"
187
+ * support available. We need tail calls to avoid consuming arbitrary amounts
188
+ * of stack space.
189
+ *
190
+ * GCC/Clang can mostly be trusted to generate tail calls as long as
191
+ * optimization is enabled, but, debug builds will not generate tail calls
192
+ * unless "musttail" is available.
193
+ *
194
+ * We should probably either:
195
+ * 1. require that the compiler supports musttail.
196
+ * 2. add some fallback code for when musttail isn't available (ie. return
197
+ * instead of tail calling). This is safe and portable, but this comes at
198
+ * a CPU cost.
199
+ */
200
+ #if (defined(__x86_64__) || defined(__aarch64__)) && defined(__GNUC__)
143
201
  #define UPB_FASTTABLE_SUPPORTED 1
144
202
  #else
145
203
  #define UPB_FASTTABLE_SUPPORTED 0
@@ -150,7 +208,7 @@
150
208
  * for example for testing or benchmarking. */
151
209
  #if defined(UPB_ENABLE_FASTTABLE)
152
210
  #if !UPB_FASTTABLE_SUPPORTED
153
- #error fasttable is x86-64 + Clang/GCC only
211
+ #error fasttable is x86-64/ARM64 only and requires GCC or Clang.
154
212
  #endif
155
213
  #define UPB_FASTTABLE 1
156
214
  /* Define UPB_TRY_ENABLE_FASTTABLE to use fasttable if possible.
@@ -194,8 +252,9 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
194
252
  ((void)(addr), (void)(size))
195
253
  #define UPB_UNPOISON_MEMORY_REGION(addr, size) \
196
254
  ((void)(addr), (void)(size))
197
- #endif
255
+ #endif
198
256
 
257
+ /** upb/decode.c ************************************************************/
199
258
 
200
259
  #include <setjmp.h>
201
260
  #include <string.h>
@@ -465,24 +524,43 @@ static void decode_munge(int type, wireval *val) {
465
524
  }
466
525
 
467
526
  static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
468
- uint32_t field_number) {
527
+ uint32_t field_number,
528
+ int *last_field_index) {
469
529
  static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
470
530
 
471
- /* Lots of optimization opportunities here. */
472
- int i;
473
531
  if (l == NULL) return &none;
474
- for (i = 0; i < l->field_count; i++) {
475
- if (l->fields[i].number == field_number) {
476
- return &l->fields[i];
532
+
533
+ size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
534
+ if (idx < l->dense_below) {
535
+ goto found;
536
+ }
537
+
538
+ /* Resume scanning from last_field_index since fields are usually in order. */
539
+ int last = *last_field_index;
540
+ for (idx = last; idx < l->field_count; idx++) {
541
+ if (l->fields[idx].number == field_number) {
542
+ goto found;
543
+ }
544
+ }
545
+
546
+ for (idx = 0; idx < last; idx++) {
547
+ if (l->fields[idx].number == field_number) {
548
+ goto found;
477
549
  }
478
550
  }
479
551
 
480
552
  return &none; /* Unknown field. */
553
+
554
+ found:
555
+ UPB_ASSERT(l->fields[idx].number == field_number);
556
+ *last_field_index = idx;
557
+ return &l->fields[idx];
481
558
  }
482
559
 
483
- static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
560
+ static upb_msg *decode_newsubmsg(upb_decstate *d,
561
+ upb_msglayout const *const *submsgs,
484
562
  const upb_msglayout_field *field) {
485
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
563
+ const upb_msglayout *subl = submsgs[field->submsg_index];
486
564
  return _upb_msg_new_inl(subl, &d->arena);
487
565
  }
488
566
 
@@ -512,9 +590,10 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
512
590
 
513
591
  UPB_FORCEINLINE
514
592
  static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
515
- upb_msg *submsg, const upb_msglayout *layout,
593
+ upb_msg *submsg,
594
+ upb_msglayout const *const *submsgs,
516
595
  const upb_msglayout_field *field, int size) {
517
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
596
+ const upb_msglayout *subl = submsgs[field->submsg_index];
518
597
  int saved_delta = decode_pushlimit(d, ptr, size);
519
598
  if (--d->depth < 0) decode_err(d);
520
599
  if (!decode_isdone(d, &ptr)) {
@@ -543,15 +622,17 @@ static const char *decode_group(upb_decstate *d, const char *ptr,
543
622
 
544
623
  UPB_FORCEINLINE
545
624
  static const char *decode_togroup(upb_decstate *d, const char *ptr,
546
- upb_msg *submsg, const upb_msglayout *layout,
625
+ upb_msg *submsg,
626
+ upb_msglayout const *const *submsgs,
547
627
  const upb_msglayout_field *field) {
548
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
628
+ const upb_msglayout *subl = submsgs[field->submsg_index];
549
629
  return decode_group(d, ptr, submsg, subl, field->number);
550
630
  }
551
631
 
552
632
  static const char *decode_toarray(upb_decstate *d, const char *ptr,
553
- upb_msg *msg, const upb_msglayout *layout,
554
- const upb_msglayout_field *field, wireval val,
633
+ upb_msg *msg,
634
+ upb_msglayout const *const *submsgs,
635
+ const upb_msglayout_field *field, wireval *val,
555
636
  int op) {
556
637
  upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
557
638
  upb_array *arr = *arrp;
@@ -573,27 +654,27 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
573
654
  /* Append scalar value. */
574
655
  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
575
656
  arr->len++;
576
- memcpy(mem, &val, 1 << op);
657
+ memcpy(mem, val, 1 << op);
577
658
  return ptr;
578
659
  case OP_STRING:
579
- decode_verifyutf8(d, ptr, val.size);
660
+ decode_verifyutf8(d, ptr, val->size);
580
661
  /* Fallthrough. */
581
662
  case OP_BYTES: {
582
663
  /* Append bytes. */
583
664
  upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len;
584
665
  arr->len++;
585
- return decode_readstr(d, ptr, val.size, str);
666
+ return decode_readstr(d, ptr, val->size, str);
586
667
  }
587
668
  case OP_SUBMSG: {
588
669
  /* Append submessage / group. */
589
- upb_msg *submsg = decode_newsubmsg(d, layout, field);
670
+ upb_msg *submsg = decode_newsubmsg(d, submsgs, field);
590
671
  *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
591
672
  submsg;
592
673
  arr->len++;
593
674
  if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
594
- return decode_togroup(d, ptr, submsg, layout, field);
675
+ return decode_togroup(d, ptr, submsg, submsgs, field);
595
676
  } else {
596
- return decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
677
+ return decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
597
678
  }
598
679
  }
599
680
  case OP_FIXPCK_LG2(2):
@@ -601,15 +682,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
601
682
  /* Fixed packed. */
602
683
  int lg2 = op - OP_FIXPCK_LG2(0);
603
684
  int mask = (1 << lg2) - 1;
604
- size_t count = val.size >> lg2;
605
- if ((val.size & mask) != 0) {
685
+ size_t count = val->size >> lg2;
686
+ if ((val->size & mask) != 0) {
606
687
  decode_err(d); /* Length isn't a round multiple of elem size. */
607
688
  }
608
689
  decode_reserve(d, arr, count);
609
690
  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
610
691
  arr->len += count;
611
- memcpy(mem, ptr, val.size); /* XXX: ptr boundary. */
612
- return ptr + val.size;
692
+ memcpy(mem, ptr, val->size); /* XXX: ptr boundary. */
693
+ return ptr + val->size;
613
694
  }
614
695
  case OP_VARPCK_LG2(0):
615
696
  case OP_VARPCK_LG2(2):
@@ -617,7 +698,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
617
698
  /* Varint packed. */
618
699
  int lg2 = op - OP_VARPCK_LG2(0);
619
700
  int scale = 1 << lg2;
620
- int saved_limit = decode_pushlimit(d, ptr, val.size);
701
+ int saved_limit = decode_pushlimit(d, ptr, val->size);
621
702
  char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
622
703
  while (!decode_isdone(d, &ptr)) {
623
704
  wireval elem;
@@ -639,16 +720,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
639
720
  }
640
721
 
641
722
  static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
642
- const upb_msglayout *layout,
643
- const upb_msglayout_field *field, wireval val) {
723
+ upb_msglayout const *const *submsgs,
724
+ const upb_msglayout_field *field, wireval *val) {
644
725
  upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
645
726
  upb_map *map = *map_p;
646
727
  upb_map_entry ent;
647
- const upb_msglayout *entry = layout->submsgs[field->submsg_index];
728
+ const upb_msglayout *entry = submsgs[field->submsg_index];
648
729
 
649
730
  if (!map) {
650
731
  /* Lazily create map. */
651
- const upb_msglayout *entry = layout->submsgs[field->submsg_index];
652
732
  const upb_msglayout_field *key_field = &entry->fields[0];
653
733
  const upb_msglayout_field *val_field = &entry->fields[1];
654
734
  char key_size = desctype_to_mapsize[key_field->descriptortype];
@@ -668,28 +748,28 @@ static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
668
748
  ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
669
749
  }
670
750
 
671
- ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size);
751
+ ptr = decode_tosubmsg(d, ptr, &ent.k, submsgs, field, val->size);
672
752
  _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
673
753
  return ptr;
674
754
  }
675
755
 
676
756
  static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
677
- const upb_msglayout *layout,
678
- const upb_msglayout_field *field, wireval val,
757
+ upb_msglayout const *const *submsgs,
758
+ const upb_msglayout_field *field, wireval *val,
679
759
  int op) {
680
760
  void *mem = UPB_PTR_AT(msg, field->offset, void);
681
761
  int type = field->descriptortype;
682
762
 
683
763
  /* Set presence if necessary. */
684
- if (field->presence < 0) {
764
+ if (field->presence > 0) {
765
+ _upb_sethas_field(msg, field);
766
+ } else if (field->presence < 0) {
685
767
  /* Oneof case */
686
768
  uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
687
769
  if (op == OP_SUBMSG && *oneof_case != field->number) {
688
770
  memset(mem, 0, sizeof(void*));
689
771
  }
690
772
  *oneof_case = field->number;
691
- } else if (field->presence > 0) {
692
- _upb_sethas_field(msg, field);
693
773
  }
694
774
 
695
775
  /* Store into message. */
@@ -698,29 +778,29 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
698
778
  upb_msg **submsgp = mem;
699
779
  upb_msg *submsg = *submsgp;
700
780
  if (!submsg) {
701
- submsg = decode_newsubmsg(d, layout, field);
781
+ submsg = decode_newsubmsg(d, submsgs, field);
702
782
  *submsgp = submsg;
703
783
  }
704
784
  if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
705
- ptr = decode_togroup(d, ptr, submsg, layout, field);
785
+ ptr = decode_togroup(d, ptr, submsg, submsgs, field);
706
786
  } else {
707
- ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
787
+ ptr = decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
708
788
  }
709
789
  break;
710
790
  }
711
791
  case OP_STRING:
712
- decode_verifyutf8(d, ptr, val.size);
792
+ decode_verifyutf8(d, ptr, val->size);
713
793
  /* Fallthrough. */
714
794
  case OP_BYTES:
715
- return decode_readstr(d, ptr, val.size, mem);
795
+ return decode_readstr(d, ptr, val->size, mem);
716
796
  case OP_SCALAR_LG2(3):
717
- memcpy(mem, &val, 8);
797
+ memcpy(mem, val, 8);
718
798
  break;
719
799
  case OP_SCALAR_LG2(2):
720
- memcpy(mem, &val, 4);
800
+ memcpy(mem, val, 4);
721
801
  break;
722
802
  case OP_SCALAR_LG2(0):
723
- memcpy(mem, &val, 1);
803
+ memcpy(mem, val, 1);
724
804
  break;
725
805
  default:
726
806
  UPB_UNREACHABLE();
@@ -746,6 +826,7 @@ static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr,
746
826
  UPB_NOINLINE
747
827
  static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
748
828
  const upb_msglayout *layout) {
829
+ int last_field_index = 0;
749
830
  while (true) {
750
831
  uint32_t tag;
751
832
  const upb_msglayout_field *field;
@@ -760,7 +841,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
760
841
  field_number = tag >> 3;
761
842
  wire_type = tag & 7;
762
843
 
763
- field = upb_find_field(layout, field_number);
844
+ field = upb_find_field(layout, field_number, &last_field_index);
764
845
 
765
846
  switch (wire_type) {
766
847
  case UPB_WIRE_TYPE_VARINT:
@@ -785,7 +866,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
785
866
  case UPB_WIRE_TYPE_DELIMITED: {
786
867
  int ndx = field->descriptortype;
787
868
  uint64_t size;
788
- if (_upb_isrepeated(field)) ndx += 18;
869
+ if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18;
789
870
  ptr = decode_varint64(d, ptr, &size);
790
871
  if (size >= INT32_MAX ||
791
872
  ptr - d->end + (int32_t)size > d->limit) {
@@ -809,17 +890,18 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
809
890
 
810
891
  if (op >= 0) {
811
892
  /* Parse, using op for dispatch. */
812
- switch (field->label) {
813
- case UPB_LABEL_REPEATED:
814
- case _UPB_LABEL_PACKED:
815
- ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
893
+ switch (_upb_getmode(field)) {
894
+ case _UPB_MODE_ARRAY:
895
+ ptr = decode_toarray(d, ptr, msg, layout->submsgs, field, &val, op);
816
896
  break;
817
- case _UPB_LABEL_MAP:
818
- ptr = decode_tomap(d, ptr, msg, layout, field, val);
897
+ case _UPB_MODE_MAP:
898
+ ptr = decode_tomap(d, ptr, msg, layout->submsgs, field, &val);
819
899
  break;
820
- default:
821
- ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
900
+ case _UPB_MODE_SCALAR:
901
+ ptr = decode_tomsg(d, ptr, msg, layout->submsgs, field, &val, op);
822
902
  break;
903
+ default:
904
+ UPB_UNREACHABLE();
823
905
  }
824
906
  } else {
825
907
  unknown:
@@ -865,7 +947,8 @@ static bool decode_top(struct upb_decstate *d, const char *buf, void *msg,
865
947
  }
866
948
 
867
949
  bool _upb_decode(const char *buf, size_t size, void *msg,
868
- const upb_msglayout *l, upb_arena *arena, int options) {
950
+ const upb_msglayout *l, const upb_extreg *extreg, int options,
951
+ upb_arena *arena) {
869
952
  bool ok;
870
953
  upb_decstate state;
871
954
  unsigned depth = (unsigned)options >> 16;
@@ -891,7 +974,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
891
974
  state.end_group = DECODE_NOGROUP;
892
975
  state.arena.head = arena->head;
893
976
  state.arena.last_size = arena->last_size;
894
- state.arena.cleanups = arena->cleanups;
977
+ state.arena.cleanup_metadata = arena->cleanup_metadata;
895
978
  state.arena.parent = arena;
896
979
 
897
980
  if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
@@ -902,7 +985,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
902
985
 
903
986
  arena->head.ptr = state.arena.head.ptr;
904
987
  arena->head.end = state.arena.head.end;
905
- arena->cleanups = state.arena.cleanups;
988
+ arena->cleanup_metadata = state.arena.cleanup_metadata;
906
989
  return ok;
907
990
  }
908
991
 
@@ -911,6 +994,8 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
911
994
  #undef OP_VARPCK_LG2
912
995
  #undef OP_STRING
913
996
  #undef OP_SUBMSG
997
+
998
+ /** upb/encode.c ************************************************************/
914
999
  /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
915
1000
 
916
1001
 
@@ -1065,7 +1150,7 @@ static void encode_fixedarray(upb_encstate *e, const upb_array *arr,
1065
1150
  }
1066
1151
  }
1067
1152
 
1068
- static void encode_message(upb_encstate *e, const char *msg,
1153
+ static void encode_message(upb_encstate *e, const upb_msg *msg,
1069
1154
  const upb_msglayout *m, size_t *size);
1070
1155
 
1071
1156
  static void encode_scalar(upb_encstate *e, const void *_field_mem,
@@ -1157,10 +1242,10 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
1157
1242
  encode_tag(e, f->number, wire_type);
1158
1243
  }
1159
1244
 
1160
- static void encode_array(upb_encstate *e, const char *field_mem,
1245
+ static void encode_array(upb_encstate *e, const upb_msg *msg,
1161
1246
  const upb_msglayout *m, const upb_msglayout_field *f) {
1162
- const upb_array *arr = *(const upb_array**)field_mem;
1163
- bool packed = f->label == _UPB_LABEL_PACKED;
1247
+ const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*);
1248
+ bool packed = f->mode & _UPB_MODE_IS_PACKED;
1164
1249
  size_t pre_len = e->limit - e->ptr;
1165
1250
 
1166
1251
  if (arr == NULL || arr->len == 0) {
@@ -1276,9 +1361,9 @@ static void encode_mapentry(upb_encstate *e, uint32_t number,
1276
1361
  encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED);
1277
1362
  }
1278
1363
 
1279
- static void encode_map(upb_encstate *e, const char *field_mem,
1364
+ static void encode_map(upb_encstate *e, const upb_msg *msg,
1280
1365
  const upb_msglayout *m, const upb_msglayout_field *f) {
1281
- const upb_map *map = *(const upb_map**)field_mem;
1366
+ const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*);
1282
1367
  const upb_msglayout *layout = m->submsgs[f->submsg_index];
1283
1368
  UPB_ASSERT(layout->field_count == 2);
1284
1369
 
@@ -1324,7 +1409,7 @@ static void encode_scalarfield(upb_encstate *e, const char *msg,
1324
1409
  encode_scalar(e, msg + f->offset, m, f, skip_empty);
1325
1410
  }
1326
1411
 
1327
- static void encode_message(upb_encstate *e, const char *msg,
1412
+ static void encode_message(upb_encstate *e, const upb_msg *msg,
1328
1413
  const upb_msglayout *m, size_t *size) {
1329
1414
  size_t pre_len = e->limit - e->ptr;
1330
1415
  const upb_msglayout_field *f = &m->fields[m->field_count];
@@ -1341,12 +1426,18 @@ static void encode_message(upb_encstate *e, const char *msg,
1341
1426
 
1342
1427
  while (f != first) {
1343
1428
  f--;
1344
- if (_upb_isrepeated(f)) {
1345
- encode_array(e, msg + f->offset, m, f);
1346
- } else if (f->label == _UPB_LABEL_MAP) {
1347
- encode_map(e, msg + f->offset, m, f);
1348
- } else {
1349
- encode_scalarfield(e, msg, m, f);
1429
+ switch (_upb_getmode(f)) {
1430
+ case _UPB_MODE_ARRAY:
1431
+ encode_array(e, msg, m, f);
1432
+ break;
1433
+ case _UPB_MODE_MAP:
1434
+ encode_map(e, msg, m, f);
1435
+ break;
1436
+ case _UPB_MODE_SCALAR:
1437
+ encode_scalarfield(e, msg, m, f);
1438
+ break;
1439
+ default:
1440
+ UPB_UNREACHABLE();
1350
1441
  }
1351
1442
  }
1352
1443
 
@@ -1386,12 +1477,12 @@ char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
1386
1477
  return ret;
1387
1478
  }
1388
1479
 
1389
-
1480
+ /** upb/msg.c ************************************************************/
1390
1481
 
1391
1482
 
1392
1483
  /** upb_msg *******************************************************************/
1393
1484
 
1394
- static const size_t overhead = sizeof(upb_msg_internal);
1485
+ static const size_t overhead = sizeof(upb_msg_internaldata);
1395
1486
 
1396
1487
  static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
1397
1488
  ptrdiff_t size = sizeof(upb_msg_internal);
@@ -1407,49 +1498,107 @@ void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) {
1407
1498
  memset(mem, 0, upb_msg_sizeof(l));
1408
1499
  }
1409
1500
 
1501
+ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) {
1502
+ upb_msg_internal *in = upb_msg_getinternal(msg);
1503
+ if (!in->internal) {
1504
+ /* No internal data, allocate from scratch. */
1505
+ size_t size = UPB_MAX(128, _upb_lg2ceilsize(need + overhead));
1506
+ upb_msg_internaldata *internal = upb_arena_malloc(arena, size);
1507
+ if (!internal) return false;
1508
+ internal->size = size;
1509
+ internal->unknown_end = overhead;
1510
+ internal->ext_begin = size;
1511
+ in->internal = internal;
1512
+ } else if (in->internal->ext_begin - in->internal->unknown_end < need) {
1513
+ /* Internal data is too small, reallocate. */
1514
+ size_t new_size = _upb_lg2ceilsize(in->internal->size + need);
1515
+ size_t ext_bytes = in->internal->size - in->internal->ext_begin;
1516
+ size_t new_ext_begin = new_size - ext_bytes;
1517
+ upb_msg_internaldata *internal =
1518
+ upb_arena_realloc(arena, in->internal, in->internal->size, new_size);
1519
+ if (!internal) return false;
1520
+ if (ext_bytes) {
1521
+ /* Need to move extension data to the end. */
1522
+ char *ptr = (char*)internal;
1523
+ memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes);
1524
+ }
1525
+ internal->ext_begin = new_ext_begin;
1526
+ internal->size = new_size;
1527
+ in->internal = internal;
1528
+ }
1529
+ UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need);
1530
+ return true;
1531
+ }
1532
+
1410
1533
  bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1411
1534
  upb_arena *arena) {
1412
-
1535
+ if (!realloc_internal(msg, len, arena)) return false;
1413
1536
  upb_msg_internal *in = upb_msg_getinternal(msg);
1414
- if (!in->unknown) {
1415
- size_t size = 128;
1416
- while (size < len) size *= 2;
1417
- in->unknown = upb_arena_malloc(arena, size + overhead);
1418
- if (!in->unknown) return false;
1419
- in->unknown->size = size;
1420
- in->unknown->len = 0;
1421
- } else if (in->unknown->size - in->unknown->len < len) {
1422
- size_t need = in->unknown->len + len;
1423
- size_t size = in->unknown->size;
1424
- while (size < need) size *= 2;
1425
- in->unknown = upb_arena_realloc(
1426
- arena, in->unknown, in->unknown->size + overhead, size + overhead);
1427
- if (!in->unknown) return false;
1428
- in->unknown->size = size;
1429
- }
1430
- memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len);
1431
- in->unknown->len += len;
1537
+ memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len);
1538
+ in->internal->unknown_end += len;
1432
1539
  return true;
1433
1540
  }
1434
1541
 
1435
1542
  void _upb_msg_discardunknown_shallow(upb_msg *msg) {
1436
1543
  upb_msg_internal *in = upb_msg_getinternal(msg);
1437
- if (in->unknown) {
1438
- in->unknown->len = 0;
1544
+ if (in->internal) {
1545
+ in->internal->unknown_end = overhead;
1439
1546
  }
1440
1547
  }
1441
1548
 
1442
1549
  const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1443
1550
  const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1444
- if (in->unknown) {
1445
- *len = in->unknown->len;
1446
- return (char*)(in->unknown + 1);
1551
+ if (in->internal) {
1552
+ *len = in->internal->unknown_end - overhead;
1553
+ return (char*)(in->internal + 1);
1447
1554
  } else {
1448
1555
  *len = 0;
1449
1556
  return NULL;
1450
1557
  }
1451
1558
  }
1452
1559
 
1560
+ const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) {
1561
+ const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1562
+ if (in->internal) {
1563
+ *count =
1564
+ (in->internal->size - in->internal->ext_begin) / sizeof(upb_msg_ext);
1565
+ return UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1566
+ } else {
1567
+ *count = 0;
1568
+ return NULL;
1569
+ }
1570
+ }
1571
+
1572
+ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg,
1573
+ const upb_msglayout_ext *e) {
1574
+ size_t n;
1575
+ const upb_msg_ext *ext = _upb_msg_getexts(msg, &n);
1576
+
1577
+ /* For now we use linear search exclusively to find extensions. If this
1578
+ * becomes an issue due to messages with lots of extensions, we can introduce
1579
+ * a table of some sort. */
1580
+ for (size_t i = 0; i < n; i++) {
1581
+ if (ext[i].ext == e) {
1582
+ return &ext[i];
1583
+ }
1584
+ }
1585
+
1586
+ return NULL;
1587
+ }
1588
+
1589
+ upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e,
1590
+ upb_arena *arena) {
1591
+ upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, e);
1592
+ if (ext) return ext;
1593
+ if (!realloc_internal(msg, sizeof(upb_msg_ext), arena)) return NULL;
1594
+ upb_msg_internal *in = upb_msg_getinternal(msg);
1595
+ in->internal->ext_begin -= sizeof(upb_msg_ext);
1596
+ ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1597
+ memset(ext, 0, sizeof(upb_msg_ext));
1598
+ ext->ext = e;
1599
+ return ext;
1600
+ }
1601
+
1453
1602
  /** upb_array *****************************************************************/
1454
1603
 
1455
1604
  bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
@@ -1517,7 +1666,7 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1517
1666
  return NULL;
1518
1667
  }
1519
1668
 
1520
- upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a));
1669
+ upb_strtable_init(&map->table, 4, a);
1521
1670
  map->key_size = key_size;
1522
1671
  map->val_size = value_size;
1523
1672
 
@@ -1638,15 +1787,73 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
1638
1787
  qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
1639
1788
  return true;
1640
1789
  }
1790
+
1791
+ /** upb_extreg ****************************************************************/
1792
+
1793
+ struct upb_extreg {
1794
+ upb_arena *arena;
1795
+ upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */
1796
+ };
1797
+
1798
+ #define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t))
1799
+
1800
+ static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) {
1801
+ memcpy(buf, &l, sizeof(l));
1802
+ memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
1803
+ }
1804
+
1805
+ upb_extreg *upb_extreg_new(upb_arena *arena) {
1806
+ upb_extreg *r = upb_arena_malloc(arena, sizeof(*r));
1807
+ if (!r) return NULL;
1808
+ r->arena = arena;
1809
+ if (!upb_strtable_init(&r->exts, 8, arena)) return NULL;
1810
+ return r;
1811
+ }
1812
+
1813
+ bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) {
1814
+ char buf[EXTREG_KEY_SIZE];
1815
+ const upb_msglayout_ext *start = e;
1816
+ const upb_msglayout_ext *end = e + count;
1817
+ for (; e < end; e++) {
1818
+ extreg_key(buf, e->extendee, e->field.number);
1819
+ if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
1820
+ upb_value_constptr(e), r->arena)) {
1821
+ goto failure;
1822
+ }
1823
+ }
1824
+ return true;
1825
+
1826
+ failure:
1827
+ /* Back out the entries previously added. */
1828
+ for (end = e, e = start; e < end; e++) {
1829
+ extreg_key(buf, e->extendee, e->field.number);
1830
+ upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
1831
+ }
1832
+ return false;
1833
+ }
1834
+
1835
+ const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r,
1836
+ const upb_msglayout *l,
1837
+ uint32_t num) {
1838
+ char buf[EXTREG_KEY_SIZE];
1839
+ upb_value v;
1840
+ extreg_key(buf, l, num);
1841
+ if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
1842
+ return upb_value_getconstptr(v);
1843
+ } else {
1844
+ return NULL;
1845
+ }
1846
+ }
1847
+
1848
+ /** upb/table.c ************************************************************/
1641
1849
  /*
1642
- ** upb_table Implementation
1643
- **
1644
- ** Implementation is heavily inspired by Lua's ltable.c.
1645
- */
1850
+ * upb_table Implementation
1851
+ *
1852
+ * Implementation is heavily inspired by Lua's ltable.c.
1853
+ */
1646
1854
 
1647
1855
  #include <string.h>
1648
1856
 
1649
- #include "third_party/wyhash/wyhash.h"
1650
1857
 
1651
1858
  /* Must be last. */
1652
1859
 
@@ -1663,9 +1870,15 @@ static const double MAX_LOAD = 0.85;
1663
1870
  * cache effects). The lower this is, the more memory we'll use. */
1664
1871
  static const double MIN_DENSITY = 0.1;
1665
1872
 
1666
- bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1873
+ static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1667
1874
 
1668
- int log2ceil(uint64_t v) {
1875
+ static upb_value _upb_value_val(uint64_t val) {
1876
+ upb_value ret;
1877
+ _upb_value_setval(&ret, val);
1878
+ return ret;
1879
+ }
1880
+
1881
+ static int log2ceil(uint64_t v) {
1669
1882
  int ret = 0;
1670
1883
  bool pow2 = is_pow2(v);
1671
1884
  while (v >>= 1) ret++;
@@ -1673,11 +1886,7 @@ int log2ceil(uint64_t v) {
1673
1886
  return UPB_MIN(UPB_MAXARRSIZE, ret);
1674
1887
  }
1675
1888
 
1676
- char *upb_strdup(const char *s, upb_alloc *a) {
1677
- return upb_strdup2(s, strlen(s), a);
1678
- }
1679
-
1680
- char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
1889
+ char *upb_strdup2(const char *s, size_t len, upb_arena *a) {
1681
1890
  size_t n;
1682
1891
  char *p;
1683
1892
 
@@ -1686,7 +1895,7 @@ char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
1686
1895
  /* Always null-terminate, even if binary data; but don't rely on the input to
1687
1896
  * have a null-terminating byte since it may be a raw binary buffer. */
1688
1897
  n = len + 1;
1689
- p = upb_malloc(a, n);
1898
+ p = upb_arena_malloc(a, n);
1690
1899
  if (p) {
1691
1900
  memcpy(p, s, len);
1692
1901
  p[len] = 0;
@@ -1721,16 +1930,24 @@ typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
1721
1930
 
1722
1931
  /* Base table (shared code) ***************************************************/
1723
1932
 
1724
- /* For when we need to cast away const. */
1725
- static upb_tabent *mutable_entries(upb_table *t) {
1726
- return (upb_tabent*)t->entries;
1933
+ static uint32_t upb_inthash(uintptr_t key) {
1934
+ return (uint32_t)key;
1935
+ }
1936
+
1937
+ static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) {
1938
+ return t->entries + (hash & t->mask);
1727
1939
  }
1728
1940
 
1941
+ static bool upb_arrhas(upb_tabval key) {
1942
+ return key.val != (uint64_t)-1;
1943
+ }
1944
+
1945
+
1729
1946
  static bool isfull(upb_table *t) {
1730
1947
  return t->count == t->max_count;
1731
1948
  }
1732
1949
 
1733
- static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1950
+ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) {
1734
1951
  size_t bytes;
1735
1952
 
1736
1953
  t->count = 0;
@@ -1739,21 +1956,17 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1739
1956
  t->max_count = upb_table_size(t) * MAX_LOAD;
1740
1957
  bytes = upb_table_size(t) * sizeof(upb_tabent);
1741
1958
  if (bytes > 0) {
1742
- t->entries = upb_malloc(a, bytes);
1959
+ t->entries = upb_arena_malloc(a, bytes);
1743
1960
  if (!t->entries) return false;
1744
- memset(mutable_entries(t), 0, bytes);
1961
+ memset(t->entries, 0, bytes);
1745
1962
  } else {
1746
1963
  t->entries = NULL;
1747
1964
  }
1748
1965
  return true;
1749
1966
  }
1750
1967
 
1751
- static void uninit(upb_table *t, upb_alloc *a) {
1752
- upb_free(a, mutable_entries(t));
1753
- }
1754
-
1755
1968
  static upb_tabent *emptyent(upb_table *t, upb_tabent *e) {
1756
- upb_tabent *begin = mutable_entries(t);
1969
+ upb_tabent *begin = t->entries;
1757
1970
  upb_tabent *end = begin + upb_table_size(t);
1758
1971
  for (e = e + 1; e < end; e++) {
1759
1972
  if (upb_tabent_isempty(e)) return e;
@@ -1903,9 +2116,9 @@ static size_t begin(const upb_table *t) {
1903
2116
 
1904
2117
  /* A simple "subclass" of upb_table that only adds a hash function for strings. */
1905
2118
 
1906
- static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
2119
+ static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) {
1907
2120
  uint32_t len = (uint32_t) k2.str.len;
1908
- char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
2121
+ char *str = upb_arena_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
1909
2122
  if (str == NULL) return 0;
1910
2123
  memcpy(str, &len, sizeof(uint32_t));
1911
2124
  if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
@@ -1913,8 +2126,143 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
1913
2126
  return (uintptr_t)str;
1914
2127
  }
1915
2128
 
2129
+ /* Adapted from ABSL's wyhash. */
2130
+
2131
+ static uint64_t UnalignedLoad64(const void *p) {
2132
+ uint64_t val;
2133
+ memcpy(&val, p, 8);
2134
+ return val;
2135
+ }
2136
+
2137
+ static uint32_t UnalignedLoad32(const void *p) {
2138
+ uint32_t val;
2139
+ memcpy(&val, p, 4);
2140
+ return val;
2141
+ }
2142
+
2143
+ #if defined(_MSC_VER) && defined(_M_X64)
2144
+ #include <intrin.h>
2145
+ #endif
2146
+
2147
+ /* Computes a * b, returning the low 64 bits of the result and storing the high
2148
+ * 64 bits in |*high|. */
2149
+ static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) {
2150
+ #ifdef __SIZEOF_INT128__
2151
+ __uint128_t p = v0;
2152
+ p *= v1;
2153
+ *out_high = (uint64_t)(p >> 64);
2154
+ return (uint64_t)p;
2155
+ #elif defined(_MSC_VER) && defined(_M_X64)
2156
+ return _umul128(v0, v1, out_high);
2157
+ #else
2158
+ uint64_t a32 = v0 >> 32;
2159
+ uint64_t a00 = v0 & 0xffffffff;
2160
+ uint64_t b32 = v1 >> 32;
2161
+ uint64_t b00 = v1 & 0xffffffff;
2162
+ uint64_t high = a32 * b32;
2163
+ uint64_t low = a00 * b00;
2164
+ uint64_t mid1 = a32 * b00;
2165
+ uint64_t mid2 = a00 * b32;
2166
+ low += (mid1 << 32) + (mid2 << 32);
2167
+ // Omit carry bit, for mixing we do not care about exact numerical precision.
2168
+ high += (mid1 >> 32) + (mid2 >> 32);
2169
+ *out_high = high;
2170
+ return low;
2171
+ #endif
2172
+ }
2173
+
2174
+ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) {
2175
+ uint64_t high;
2176
+ uint64_t low = upb_umul128(v0, v1, &high);
2177
+ return low ^ high;
2178
+ }
2179
+
2180
+ uint64_t Wyhash(const void *data, size_t len, uint64_t seed,
2181
+ const uint64_t salt[]) {
2182
+ const uint8_t* ptr = (const uint8_t*)data;
2183
+ uint64_t starting_length = (uint64_t)len;
2184
+ uint64_t current_state = seed ^ salt[0];
2185
+
2186
+ if (len > 64) {
2187
+ // If we have more than 64 bytes, we're going to handle chunks of 64
2188
+ // bytes at a time. We're going to build up two separate hash states
2189
+ // which we will then hash together.
2190
+ uint64_t duplicated_state = current_state;
2191
+
2192
+ do {
2193
+ uint64_t a = UnalignedLoad64(ptr);
2194
+ uint64_t b = UnalignedLoad64(ptr + 8);
2195
+ uint64_t c = UnalignedLoad64(ptr + 16);
2196
+ uint64_t d = UnalignedLoad64(ptr + 24);
2197
+ uint64_t e = UnalignedLoad64(ptr + 32);
2198
+ uint64_t f = UnalignedLoad64(ptr + 40);
2199
+ uint64_t g = UnalignedLoad64(ptr + 48);
2200
+ uint64_t h = UnalignedLoad64(ptr + 56);
2201
+
2202
+ uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state);
2203
+ uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state);
2204
+ current_state = (cs0 ^ cs1);
2205
+
2206
+ uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state);
2207
+ uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state);
2208
+ duplicated_state = (ds0 ^ ds1);
2209
+
2210
+ ptr += 64;
2211
+ len -= 64;
2212
+ } while (len > 64);
2213
+
2214
+ current_state = current_state ^ duplicated_state;
2215
+ }
2216
+
2217
+ // We now have a data `ptr` with at most 64 bytes and the current state
2218
+ // of the hashing state machine stored in current_state.
2219
+ while (len > 16) {
2220
+ uint64_t a = UnalignedLoad64(ptr);
2221
+ uint64_t b = UnalignedLoad64(ptr + 8);
2222
+
2223
+ current_state = WyhashMix(a ^ salt[1], b ^ current_state);
2224
+
2225
+ ptr += 16;
2226
+ len -= 16;
2227
+ }
2228
+
2229
+ // We now have a data `ptr` with at most 16 bytes.
2230
+ uint64_t a = 0;
2231
+ uint64_t b = 0;
2232
+ if (len > 8) {
2233
+ // When we have at least 9 and at most 16 bytes, set A to the first 64
2234
+ // bits of the input and B to the last 64 bits of the input. Yes, they will
2235
+ // overlap in the middle if we are working with less than the full 16
2236
+ // bytes.
2237
+ a = UnalignedLoad64(ptr);
2238
+ b = UnalignedLoad64(ptr + len - 8);
2239
+ } else if (len > 3) {
2240
+ // If we have at least 4 and at most 8 bytes, set A to the first 32
2241
+ // bits and B to the last 32 bits.
2242
+ a = UnalignedLoad32(ptr);
2243
+ b = UnalignedLoad32(ptr + len - 4);
2244
+ } else if (len > 0) {
2245
+ // If we have at least 1 and at most 3 bytes, read all of the provided
2246
+ // bits into A, with some adjustments.
2247
+ a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]);
2248
+ b = 0;
2249
+ } else {
2250
+ a = 0;
2251
+ b = 0;
2252
+ }
2253
+
2254
+ uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state);
2255
+ uint64_t z = salt[1] ^ starting_length;
2256
+ return WyhashMix(w, z);
2257
+ }
2258
+
2259
+ const uint64_t kWyhashSalt[5] = {
2260
+ 0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL,
2261
+ 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL,
2262
+ };
2263
+
1916
2264
  static uint32_t table_hash(const char *p, size_t n) {
1917
- return wyhash(p, n, 0, _wyp);
2265
+ return Wyhash(p, n, 0, kWyhashSalt);
1918
2266
  }
1919
2267
 
1920
2268
  static uint32_t strhash(upb_tabkey key) {
@@ -1929,9 +2277,7 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
1929
2277
  return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
1930
2278
  }
1931
2279
 
1932
- bool upb_strtable_init2(upb_strtable *t, upb_ctype_t ctype,
1933
- size_t expected_size, upb_alloc *a) {
1934
- UPB_UNUSED(ctype); /* TODO(haberman): rm */
2280
+ bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a) {
1935
2281
  // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator.
1936
2282
  size_t need_entries = (expected_size + 1) * 1204 / 1024;
1937
2283
  UPB_ASSERT(need_entries >= expected_size * 0.85);
@@ -1945,14 +2291,7 @@ void upb_strtable_clear(upb_strtable *t) {
1945
2291
  memset((char*)t->t.entries, 0, bytes);
1946
2292
  }
1947
2293
 
1948
- void upb_strtable_uninit2(upb_strtable *t, upb_alloc *a) {
1949
- size_t i;
1950
- for (i = 0; i < upb_table_size(&t->t); i++)
1951
- upb_free(a, (void*)t->t.entries[i].key);
1952
- uninit(&t->t, a);
1953
- }
1954
-
1955
- bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
2294
+ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) {
1956
2295
  upb_strtable new_table;
1957
2296
  upb_strtable_iter i;
1958
2297
 
@@ -1961,17 +2300,15 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
1961
2300
  upb_strtable_begin(&i, t);
1962
2301
  for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1963
2302
  upb_strview key = upb_strtable_iter_key(&i);
1964
- upb_strtable_insert3(
1965
- &new_table, key.data, key.size,
1966
- upb_strtable_iter_value(&i), a);
2303
+ upb_strtable_insert(&new_table, key.data, key.size,
2304
+ upb_strtable_iter_value(&i), a);
1967
2305
  }
1968
- upb_strtable_uninit2(t, a);
1969
2306
  *t = new_table;
1970
2307
  return true;
1971
2308
  }
1972
2309
 
1973
- bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
1974
- upb_value v, upb_alloc *a) {
2310
+ bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len,
2311
+ upb_value v, upb_arena *a) {
1975
2312
  lookupkey_t key;
1976
2313
  upb_tabkey tabkey;
1977
2314
  uint32_t hash;
@@ -1998,19 +2335,11 @@ bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
1998
2335
  return lookup(&t->t, strkey2(key, len), v, hash, &streql);
1999
2336
  }
2000
2337
 
2001
- bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
2002
- upb_value *val, upb_alloc *alloc) {
2338
+ bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len,
2339
+ upb_value *val) {
2003
2340
  uint32_t hash = table_hash(key, len);
2004
2341
  upb_tabkey tabkey;
2005
- if (rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql)) {
2006
- if (alloc) {
2007
- /* Arena-based allocs don't need to free and won't pass this. */
2008
- upb_free(alloc, (void*)tabkey);
2009
- }
2010
- return true;
2011
- } else {
2012
- return false;
2013
- }
2342
+ return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql);
2014
2343
  }
2015
2344
 
2016
2345
  /* Iteration */
@@ -2108,7 +2437,7 @@ static void check(upb_inttable *t) {
2108
2437
  }
2109
2438
 
2110
2439
  bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2111
- upb_alloc *a) {
2440
+ upb_arena *a) {
2112
2441
  size_t array_bytes;
2113
2442
 
2114
2443
  if (!init(&t->t, hsize_lg2, a)) return false;
@@ -2117,9 +2446,8 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2117
2446
  t->array_size = UPB_MAX(1, asize);
2118
2447
  t->array_count = 0;
2119
2448
  array_bytes = t->array_size * sizeof(upb_value);
2120
- t->array = upb_malloc(a, array_bytes);
2449
+ t->array = upb_arena_malloc(a, array_bytes);
2121
2450
  if (!t->array) {
2122
- uninit(&t->t, a);
2123
2451
  return false;
2124
2452
  }
2125
2453
  memset(mutable_array(t), 0xff, array_bytes);
@@ -2127,18 +2455,12 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2127
2455
  return true;
2128
2456
  }
2129
2457
 
2130
- bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
2131
- UPB_UNUSED(ctype); /* TODO(haberman): rm */
2458
+ bool upb_inttable_init(upb_inttable *t, upb_arena *a) {
2132
2459
  return upb_inttable_sizedinit(t, 0, 4, a);
2133
2460
  }
2134
2461
 
2135
- void upb_inttable_uninit2(upb_inttable *t, upb_alloc *a) {
2136
- uninit(&t->t, a);
2137
- upb_free(a, mutable_array(t));
2138
- }
2139
-
2140
- bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
2141
- upb_alloc *a) {
2462
+ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val,
2463
+ upb_arena *a) {
2142
2464
  upb_tabval tabval;
2143
2465
  tabval.val = val.val;
2144
2466
  UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
@@ -2169,7 +2491,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
2169
2491
 
2170
2492
  UPB_ASSERT(t->t.count == new_table.count);
2171
2493
 
2172
- uninit(&t->t, a);
2173
2494
  t->t = new_table;
2174
2495
  }
2175
2496
  insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
@@ -2213,21 +2534,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
2213
2534
  return success;
2214
2535
  }
2215
2536
 
2216
- bool upb_inttable_insertptr2(upb_inttable *t, const void *key, upb_value val,
2217
- upb_alloc *a) {
2218
- return upb_inttable_insert2(t, (uintptr_t)key, val, a);
2219
- }
2220
-
2221
- bool upb_inttable_lookupptr(const upb_inttable *t, const void *key,
2222
- upb_value *v) {
2223
- return upb_inttable_lookup(t, (uintptr_t)key, v);
2224
- }
2225
-
2226
- bool upb_inttable_removeptr(upb_inttable *t, const void *key, upb_value *val) {
2227
- return upb_inttable_remove(t, (uintptr_t)key, val);
2228
- }
2229
-
2230
- void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
2537
+ void upb_inttable_compact(upb_inttable *t, upb_arena *a) {
2231
2538
  /* A power-of-two histogram of the table keys. */
2232
2539
  size_t counts[UPB_MAXARRSIZE + 1] = {0};
2233
2540
 
@@ -2275,12 +2582,11 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
2275
2582
  upb_inttable_begin(&i, t);
2276
2583
  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2277
2584
  uintptr_t k = upb_inttable_iter_key(&i);
2278
- upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
2585
+ upb_inttable_insert(&new_t, k, upb_inttable_iter_value(&i), a);
2279
2586
  }
2280
2587
  UPB_ASSERT(new_t.array_size == arr_size);
2281
2588
  UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
2282
2589
  }
2283
- upb_inttable_uninit2(t, a);
2284
2590
  *t = new_t;
2285
2591
  }
2286
2592
 
@@ -2354,6 +2660,7 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
2354
2660
  i1->array_part == i2->array_part;
2355
2661
  }
2356
2662
 
2663
+ /** upb/upb.c ************************************************************/
2357
2664
 
2358
2665
  #include <errno.h>
2359
2666
  #include <stdarg.h>
@@ -2420,6 +2727,19 @@ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
2420
2727
  }
2421
2728
  }
2422
2729
 
2730
+ static uint32_t *upb_cleanup_pointer(uintptr_t cleanup_metadata) {
2731
+ return (uint32_t *)(cleanup_metadata & ~0x1);
2732
+ }
2733
+
2734
+ static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) {
2735
+ return cleanup_metadata & 0x1;
2736
+ }
2737
+
2738
+ static uintptr_t upb_cleanup_metadata(uint32_t *cleanup,
2739
+ bool has_initial_block) {
2740
+ return (uintptr_t)cleanup | has_initial_block;
2741
+ }
2742
+
2423
2743
  upb_alloc upb_alloc_global = {&upb_global_allocfunc};
2424
2744
 
2425
2745
  /* upb_arena ******************************************************************/
@@ -2465,7 +2785,8 @@ static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr,
2465
2785
 
2466
2786
  a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
2467
2787
  a->head.end = UPB_PTR_AT(block, size, char);
2468
- a->cleanups = &block->cleanups;
2788
+ a->cleanup_metadata = upb_cleanup_metadata(
2789
+ &block->cleanups, upb_cleanup_has_initial_block(a->cleanup_metadata));
2469
2790
 
2470
2791
  UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
2471
2792
  }
@@ -2513,6 +2834,7 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
2513
2834
  a->refcount = 1;
2514
2835
  a->freelist = NULL;
2515
2836
  a->freelist_tail = NULL;
2837
+ a->cleanup_metadata = upb_cleanup_metadata(NULL, false);
2516
2838
 
2517
2839
  upb_arena_addblock(a, a, mem, n);
2518
2840
 
@@ -2540,7 +2862,7 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
2540
2862
  a->head.ptr = mem;
2541
2863
  a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
2542
2864
  a->freelist = NULL;
2543
- a->cleanups = NULL;
2865
+ a->cleanup_metadata = upb_cleanup_metadata(NULL, true);
2544
2866
 
2545
2867
  return a;
2546
2868
  }
@@ -2575,15 +2897,17 @@ void upb_arena_free(upb_arena *a) {
2575
2897
 
2576
2898
  bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2577
2899
  cleanup_ent *ent;
2900
+ uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2578
2901
 
2579
- if (!a->cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
2902
+ if (!cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
2580
2903
  if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
2581
2904
  UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent));
2905
+ cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2582
2906
  }
2583
2907
 
2584
2908
  a->head.end -= sizeof(cleanup_ent);
2585
2909
  ent = (cleanup_ent*)a->head.end;
2586
- (*a->cleanups)++;
2910
+ (*cleanups)++;
2587
2911
  UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
2588
2912
 
2589
2913
  ent->cleanup = func;
@@ -2592,11 +2916,18 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2592
2916
  return true;
2593
2917
  }
2594
2918
 
2595
- void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2919
+ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2596
2920
  upb_arena *r1 = arena_findroot(a1);
2597
2921
  upb_arena *r2 = arena_findroot(a2);
2598
2922
 
2599
- if (r1 == r2) return; /* Already fused. */
2923
+ if (r1 == r2) return true; /* Already fused. */
2924
+
2925
+ /* Do not fuse initial blocks since we cannot lifetime extend them. */
2926
+ if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false;
2927
+ if (upb_cleanup_has_initial_block(r2->cleanup_metadata)) return false;
2928
+
2929
+ /* Only allow fuse with a common allocator */
2930
+ if (r1->block_alloc != r2->block_alloc) return false;
2600
2931
 
2601
2932
  /* We want to join the smaller tree to the larger tree.
2602
2933
  * So swap first if they are backwards. */
@@ -2614,12 +2945,15 @@ void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2614
2945
  r1->freelist = r2->freelist;
2615
2946
  }
2616
2947
  r2->parent = r1;
2948
+ return true;
2617
2949
  }
2618
- // Fast decoder: ~3x the speed of decode.c, but x86-64 specific.
2950
+
2951
+ /** upb/decode_fast.c ************************************************************/
2952
+ // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64.
2619
2953
  // Also the table size grows by 2x.
2620
2954
  //
2621
- // Could potentially be ported to ARM64 or other 64-bit archs that pass at
2622
- // least six arguments in registers.
2955
+ // Could potentially be ported to other 64-bit archs that pass at least six
2956
+ // arguments in registers and have 8 unused high bits in pointers.
2623
2957
  //
2624
2958
  // The overall design is to create specialized functions for every possible
2625
2959
  // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
@@ -2639,8 +2973,10 @@ void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2639
2973
 
2640
2974
  #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
2641
2975
 
2642
- #define RETURN_GENERIC(m) \
2643
- /* fprintf(stderr, m); */ \
2976
+ #define RETURN_GENERIC(m) \
2977
+ /* Uncomment either of these for debugging purposes. */ \
2978
+ /* fprintf(stderr, m); */ \
2979
+ /*__builtin_trap(); */ \
2644
2980
  return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
2645
2981
 
2646
2982
  typedef enum {
@@ -2651,21 +2987,18 @@ typedef enum {
2651
2987
  } upb_card;
2652
2988
 
2653
2989
  UPB_NOINLINE
2654
- static const char *fastdecode_isdonefallback(upb_decstate *d, const char *ptr,
2655
- upb_msg *msg, intptr_t table,
2656
- uint64_t hasbits, int overrun) {
2990
+ static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
2991
+ int overrun = data;
2657
2992
  ptr = decode_isdonefallback_inl(d, ptr, overrun);
2658
2993
  if (ptr == NULL) {
2659
2994
  return fastdecode_err(d);
2660
2995
  }
2661
- uint16_t tag = fastdecode_loadtag(ptr);
2662
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
2996
+ data = fastdecode_loadtag(ptr);
2997
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
2663
2998
  }
2664
2999
 
2665
3000
  UPB_FORCEINLINE
2666
- static const char *fastdecode_dispatch(upb_decstate *d, const char *ptr,
2667
- upb_msg *msg, intptr_t table,
2668
- uint64_t hasbits) {
3001
+ static const char *fastdecode_dispatch(UPB_PARSE_PARAMS) {
2669
3002
  if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
2670
3003
  int overrun = ptr - d->end;
2671
3004
  if (UPB_LIKELY(overrun == d->limit)) {
@@ -2673,21 +3006,22 @@ static const char *fastdecode_dispatch(upb_decstate *d, const char *ptr,
2673
3006
  *(uint32_t*)msg |= hasbits; // Sync hasbits.
2674
3007
  return ptr;
2675
3008
  } else {
2676
- return fastdecode_isdonefallback(d, ptr, msg, table, hasbits, overrun);
3009
+ data = overrun;
3010
+ UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS);
2677
3011
  }
2678
3012
  }
2679
3013
 
2680
3014
  // Read two bytes of tag data (for a one-byte tag, the high byte is junk).
2681
- uint16_t tag = fastdecode_loadtag(ptr);
2682
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
3015
+ data = fastdecode_loadtag(ptr);
3016
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
2683
3017
  }
2684
3018
 
2685
3019
  UPB_FORCEINLINE
2686
- static bool fastdecode_checktag(uint64_t data, int tagbytes) {
3020
+ static bool fastdecode_checktag(uint16_t data, int tagbytes) {
2687
3021
  if (tagbytes == 1) {
2688
3022
  return (data & 0xff) == 0;
2689
3023
  } else {
2690
- return (data & 0xffff) == 0;
3024
+ return data == 0;
2691
3025
  }
2692
3026
  }
2693
3027
 
@@ -2911,6 +3245,14 @@ static bool fastdecode_flippacked(uint64_t *data, int tagbytes) {
2911
3245
  return fastdecode_checktag(*data, tagbytes);
2912
3246
  }
2913
3247
 
3248
+ #define FASTDECODE_CHECKPACKED(tagbytes, card, func) \
3249
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3250
+ if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \
3251
+ UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \
3252
+ } \
3253
+ RETURN_GENERIC("packed check tag mismatch\n"); \
3254
+ }
3255
+
2914
3256
  /* varint fields **************************************************************/
2915
3257
 
2916
3258
  UPB_FORCEINLINE
@@ -2953,57 +3295,50 @@ done:
2953
3295
  return ptr;
2954
3296
  }
2955
3297
 
2956
- UPB_FORCEINLINE
2957
- static const char *fastdecode_unpackedvarint(UPB_PARSE_PARAMS, int tagbytes,
2958
- int valbytes, upb_card card,
2959
- bool zigzag,
2960
- _upb_field_parser *packed) {
2961
- uint64_t val;
2962
- void *dst;
2963
- fastdecode_arr farr;
2964
-
2965
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
2966
- if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
2967
- return packed(UPB_PARSE_ARGS);
2968
- }
2969
- RETURN_GENERIC("varint field tag mismatch\n");
2970
- }
2971
-
2972
- dst =
2973
- fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
2974
- if (card == CARD_r) {
2975
- if (UPB_UNLIKELY(!dst)) {
2976
- RETURN_GENERIC("need array resize\n");
2977
- }
2978
- }
2979
-
2980
- again:
2981
- if (card == CARD_r) {
2982
- dst = fastdecode_resizearr(d, dst, &farr, valbytes);
2983
- }
2984
-
2985
- ptr += tagbytes;
2986
- ptr = fastdecode_varint64(ptr, &val);
2987
- if (ptr == NULL) return fastdecode_err(d);
2988
- val = fastdecode_munge(val, valbytes, zigzag);
2989
- memcpy(dst, &val, valbytes);
2990
-
2991
- if (card == CARD_r) {
2992
- fastdecode_nextret ret =
2993
- fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
2994
- switch (ret.next) {
2995
- case FD_NEXT_SAMEFIELD:
2996
- dst = ret.dst;
2997
- goto again;
2998
- case FD_NEXT_OTHERFIELD:
2999
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3000
- case FD_NEXT_ATLIMIT:
3001
- return ptr;
3002
- }
3003
- }
3004
-
3005
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3006
- }
3298
+ #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3299
+ valbytes, card, zigzag, packed) \
3300
+ uint64_t val; \
3301
+ void *dst; \
3302
+ fastdecode_arr farr; \
3303
+ \
3304
+ FASTDECODE_CHECKPACKED(tagbytes, card, packed); \
3305
+ \
3306
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3307
+ card); \
3308
+ if (card == CARD_r) { \
3309
+ if (UPB_UNLIKELY(!dst)) { \
3310
+ RETURN_GENERIC("need array resize\n"); \
3311
+ } \
3312
+ } \
3313
+ \
3314
+ again: \
3315
+ if (card == CARD_r) { \
3316
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3317
+ } \
3318
+ \
3319
+ ptr += tagbytes; \
3320
+ ptr = fastdecode_varint64(ptr, &val); \
3321
+ if (ptr == NULL) \
3322
+ return fastdecode_err(d); \
3323
+ val = fastdecode_munge(val, valbytes, zigzag); \
3324
+ memcpy(dst, &val, valbytes); \
3325
+ \
3326
+ if (card == CARD_r) { \
3327
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3328
+ d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3329
+ switch (ret.next) { \
3330
+ case FD_NEXT_SAMEFIELD: \
3331
+ dst = ret.dst; \
3332
+ goto again; \
3333
+ case FD_NEXT_OTHERFIELD: \
3334
+ data = ret.tag; \
3335
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3336
+ case FD_NEXT_ATLIMIT: \
3337
+ return ptr; \
3338
+ } \
3339
+ } \
3340
+ \
3341
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3007
3342
 
3008
3343
  typedef struct {
3009
3344
  uint8_t valbytes;
@@ -3032,50 +3367,37 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr,
3032
3367
  return ptr;
3033
3368
  }
3034
3369
 
3035
- UPB_FORCEINLINE
3036
- static const char *fastdecode_packedvarint(UPB_PARSE_PARAMS, int tagbytes,
3037
- int valbytes, bool zigzag,
3038
- _upb_field_parser *unpacked) {
3039
- fastdecode_varintdata ctx = {valbytes, zigzag};
3040
-
3041
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
3042
- if (fastdecode_flippacked(&data, tagbytes)) {
3043
- return unpacked(UPB_PARSE_ARGS);
3044
- } else {
3045
- RETURN_GENERIC("varint field tag mismatch\n");
3046
- }
3047
- }
3048
-
3049
- ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr,
3050
- valbytes, CARD_r);
3051
- if (UPB_UNLIKELY(!ctx.dst)) {
3052
- RETURN_GENERIC("need array resize\n");
3370
+ #define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3371
+ valbytes, zigzag, unpacked) \
3372
+ fastdecode_varintdata ctx = {valbytes, zigzag}; \
3373
+ \
3374
+ FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \
3375
+ \
3376
+ ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \
3377
+ valbytes, CARD_r); \
3378
+ if (UPB_UNLIKELY(!ctx.dst)) { \
3379
+ RETURN_GENERIC("need array resize\n"); \
3380
+ } \
3381
+ \
3382
+ ptr += tagbytes; \
3383
+ ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
3384
+ \
3385
+ if (UPB_UNLIKELY(ptr == NULL)) { \
3386
+ return fastdecode_err(d); \
3387
+ } \
3388
+ \
3389
+ UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
3390
+
3391
+ #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3392
+ valbytes, card, zigzag, unpacked, packed) \
3393
+ if (card == CARD_p) { \
3394
+ FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3395
+ valbytes, zigzag, unpacked); \
3396
+ } else { \
3397
+ FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3398
+ valbytes, card, zigzag, packed); \
3053
3399
  }
3054
3400
 
3055
- ptr += tagbytes;
3056
- ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx);
3057
-
3058
- if (UPB_UNLIKELY(ptr == NULL)) {
3059
- return fastdecode_err(d);
3060
- }
3061
-
3062
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3063
- }
3064
-
3065
- UPB_FORCEINLINE
3066
- static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
3067
- int valbytes, upb_card card, bool zigzag,
3068
- _upb_field_parser *unpacked,
3069
- _upb_field_parser *packed) {
3070
- if (card == CARD_p) {
3071
- return fastdecode_packedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, zigzag,
3072
- unpacked);
3073
- } else {
3074
- return fastdecode_unpackedvarint(UPB_PARSE_ARGS, tagbytes, valbytes, card,
3075
- zigzag, packed);
3076
- }
3077
- }
3078
-
3079
3401
  #define z_ZZ true
3080
3402
  #define b_ZZ false
3081
3403
  #define v_ZZ false
@@ -3086,10 +3408,10 @@ static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
3086
3408
  #define F(card, type, valbytes, tagbytes) \
3087
3409
  UPB_NOINLINE \
3088
3410
  const char *upb_p##card##type##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3089
- return fastdecode_varint(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card, \
3090
- type##_ZZ, \
3091
- &upb_pr##type##valbytes##_##tagbytes##bt, \
3092
- &upb_pp##type##valbytes##_##tagbytes##bt); \
3411
+ FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3412
+ CARD_##card, type##_ZZ, \
3413
+ upb_pr##type##valbytes##_##tagbytes##bt, \
3414
+ upb_pp##type##valbytes##_##tagbytes##bt); \
3093
3415
  }
3094
3416
 
3095
3417
  #define TYPES(card, tagbytes) \
@@ -3117,126 +3439,110 @@ TAGBYTES(p)
3117
3439
  #undef F
3118
3440
  #undef TYPES
3119
3441
  #undef TAGBYTES
3442
+ #undef FASTDECODE_UNPACKEDVARINT
3443
+ #undef FASTDECODE_PACKEDVARINT
3444
+ #undef FASTDECODE_VARINT
3120
3445
 
3121
3446
 
3122
3447
  /* fixed fields ***************************************************************/
3123
3448
 
3124
- UPB_FORCEINLINE
3125
- static const char *fastdecode_unpackedfixed(UPB_PARSE_PARAMS, int tagbytes,
3126
- int valbytes, upb_card card,
3127
- _upb_field_parser *packed) {
3128
- void *dst;
3129
- fastdecode_arr farr;
3130
-
3131
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
3132
- if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) {
3133
- return packed(UPB_PARSE_ARGS);
3134
- }
3135
- RETURN_GENERIC("fixed field tag mismatch\n");
3136
- }
3137
-
3138
- dst =
3139
- fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, card);
3140
- if (card == CARD_r) {
3141
- if (UPB_UNLIKELY(!dst)) {
3142
- RETURN_GENERIC("couldn't allocate array in arena\n");
3143
- }
3144
- }
3145
-
3146
-
3147
- again:
3148
- if (card == CARD_r) {
3149
- dst = fastdecode_resizearr(d, dst, &farr, valbytes);
3150
- }
3151
-
3152
- ptr += tagbytes;
3153
- memcpy(dst, ptr, valbytes);
3154
- ptr += valbytes;
3155
-
3156
- if (card == CARD_r) {
3157
- fastdecode_nextret ret =
3158
- fastdecode_nextrepeated(d, dst, &ptr, &farr, data, tagbytes, valbytes);
3159
- switch (ret.next) {
3160
- case FD_NEXT_SAMEFIELD:
3161
- dst = ret.dst;
3162
- goto again;
3163
- case FD_NEXT_OTHERFIELD:
3164
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3165
- case FD_NEXT_ATLIMIT:
3166
- return ptr;
3167
- }
3168
- }
3169
-
3170
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3171
- }
3172
-
3173
- UPB_FORCEINLINE
3174
- static const char *fastdecode_packedfixed(UPB_PARSE_PARAMS, int tagbytes,
3175
- int valbytes,
3176
- _upb_field_parser *unpacked) {
3177
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
3178
- if (fastdecode_flippacked(&data, tagbytes)) {
3179
- return unpacked(UPB_PARSE_ARGS);
3180
- } else {
3181
- RETURN_GENERIC("varint field tag mismatch\n");
3182
- }
3183
- }
3184
-
3185
- ptr += tagbytes;
3186
- int size = (uint8_t)ptr[0];
3187
- ptr++;
3188
- if (size & 0x80) {
3189
- ptr = fastdecode_longsize(ptr, &size);
3190
- }
3191
-
3192
- if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr)) ||
3193
- (size % valbytes) != 0) {
3194
- return fastdecode_err(d);
3195
- }
3196
-
3197
- upb_array **arr_p = fastdecode_fieldmem(msg, data);
3198
- upb_array *arr = *arr_p;
3199
- uint8_t elem_size_lg2 = __builtin_ctz(valbytes);
3200
- int elems = size / valbytes;
3201
-
3202
- if (UPB_LIKELY(!arr)) {
3203
- *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2);
3204
- if (!arr) {
3205
- return fastdecode_err(d);
3206
- }
3207
- } else {
3208
- _upb_array_resize(arr, elems, &d->arena);
3449
+ #define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3450
+ valbytes, card, packed) \
3451
+ void *dst; \
3452
+ fastdecode_arr farr; \
3453
+ \
3454
+ FASTDECODE_CHECKPACKED(tagbytes, card, packed) \
3455
+ \
3456
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3457
+ card); \
3458
+ if (card == CARD_r) { \
3459
+ if (UPB_UNLIKELY(!dst)) { \
3460
+ RETURN_GENERIC("couldn't allocate array in arena\n"); \
3461
+ } \
3462
+ } \
3463
+ \
3464
+ again: \
3465
+ if (card == CARD_r) { \
3466
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3467
+ } \
3468
+ \
3469
+ ptr += tagbytes; \
3470
+ memcpy(dst, ptr, valbytes); \
3471
+ ptr += valbytes; \
3472
+ \
3473
+ if (card == CARD_r) { \
3474
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3475
+ d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3476
+ switch (ret.next) { \
3477
+ case FD_NEXT_SAMEFIELD: \
3478
+ dst = ret.dst; \
3479
+ goto again; \
3480
+ case FD_NEXT_OTHERFIELD: \
3481
+ data = ret.tag; \
3482
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3483
+ case FD_NEXT_ATLIMIT: \
3484
+ return ptr; \
3485
+ } \
3486
+ } \
3487
+ \
3488
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3489
+
3490
+ #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3491
+ valbytes, unpacked) \
3492
+ FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked) \
3493
+ \
3494
+ ptr += tagbytes; \
3495
+ int size = (uint8_t)ptr[0]; \
3496
+ ptr++; \
3497
+ if (size & 0x80) { \
3498
+ ptr = fastdecode_longsize(ptr, &size); \
3499
+ } \
3500
+ \
3501
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
3502
+ (size % valbytes) != 0)) { \
3503
+ return fastdecode_err(d); \
3504
+ } \
3505
+ \
3506
+ upb_array **arr_p = fastdecode_fieldmem(msg, data); \
3507
+ upb_array *arr = *arr_p; \
3508
+ uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \
3509
+ int elems = size / valbytes; \
3510
+ \
3511
+ if (UPB_LIKELY(!arr)) { \
3512
+ *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \
3513
+ if (!arr) { \
3514
+ return fastdecode_err(d); \
3515
+ } \
3516
+ } else { \
3517
+ _upb_array_resize(arr, elems, &d->arena); \
3518
+ } \
3519
+ \
3520
+ char *dst = _upb_array_ptr(arr); \
3521
+ memcpy(dst, ptr, size); \
3522
+ arr->len = elems; \
3523
+ \
3524
+ ptr += size; \
3525
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3526
+
3527
+ #define FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3528
+ valbytes, card, unpacked, packed) \
3529
+ if (card == CARD_p) { \
3530
+ FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3531
+ valbytes, unpacked); \
3532
+ } else { \
3533
+ FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3534
+ valbytes, card, packed); \
3209
3535
  }
3210
3536
 
3211
- char *dst = _upb_array_ptr(arr);
3212
- memcpy(dst, ptr, size);
3213
- arr->len = elems;
3214
-
3215
- return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
3216
- }
3217
-
3218
- UPB_FORCEINLINE
3219
- static const char *fastdecode_fixed(UPB_PARSE_PARAMS, int tagbytes,
3220
- int valbytes, upb_card card,
3221
- _upb_field_parser *unpacked,
3222
- _upb_field_parser *packed) {
3223
- if (card == CARD_p) {
3224
- return fastdecode_packedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, unpacked);
3225
- } else {
3226
- return fastdecode_unpackedfixed(UPB_PARSE_ARGS, tagbytes, valbytes, card,
3227
- packed);
3228
- }
3229
- }
3230
-
3231
3537
  /* Generate all combinations:
3232
3538
  * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
3233
3539
 
3234
- #define F(card, valbytes, tagbytes) \
3235
- UPB_NOINLINE \
3236
- const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3237
- return fastdecode_fixed(UPB_PARSE_ARGS, tagbytes, valbytes, CARD_##card, \
3238
- &upb_ppf##valbytes##_##tagbytes##bt, \
3239
- &upb_prf##valbytes##_##tagbytes##bt); \
3540
+ #define F(card, valbytes, tagbytes) \
3541
+ UPB_NOINLINE \
3542
+ const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3543
+ FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3544
+ CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \
3545
+ upb_prf##valbytes##_##tagbytes##bt); \
3240
3546
  }
3241
3547
 
3242
3548
  #define TYPES(card, tagbytes) \
@@ -3255,6 +3561,8 @@ TAGBYTES(p)
3255
3561
  #undef F
3256
3562
  #undef TYPES
3257
3563
  #undef TAGBYTES
3564
+ #undef FASTDECODE_UNPACKEDFIXED
3565
+ #undef FASTDECODE_PACKEDFIXED
3258
3566
 
3259
3567
  /* string fields **************************************************************/
3260
3568
 
@@ -3266,56 +3574,54 @@ typedef const char *fastdecode_copystr_func(struct upb_decstate *d,
3266
3574
  UPB_NOINLINE
3267
3575
  static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr,
3268
3576
  upb_msg *msg, intptr_t table,
3269
- uint64_t hasbits, upb_strview *dst) {
3577
+ uint64_t hasbits, uint64_t data) {
3578
+ upb_strview *dst = (upb_strview*)data;
3270
3579
  if (!decode_verifyutf8_inl(dst->data, dst->size)) {
3271
3580
  return fastdecode_err(d);
3272
3581
  }
3273
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3274
- }
3275
-
3276
- UPB_FORCEINLINE
3277
- static const char *fastdecode_longstring(struct upb_decstate *d,
3278
- const char *ptr, upb_msg *msg,
3279
- intptr_t table, uint64_t hasbits,
3280
- upb_strview *dst,
3281
- bool validate_utf8) {
3282
- int size = (uint8_t)ptr[0]; // Could plumb through hasbits.
3283
- ptr++;
3284
- if (size & 0x80) {
3285
- ptr = fastdecode_longsize(ptr, &size);
3286
- }
3287
-
3288
- if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) {
3289
- dst->size = 0;
3290
- return fastdecode_err(d);
3291
- }
3292
-
3293
- if (d->alias) {
3294
- dst->data = ptr;
3295
- dst->size = size;
3296
- } else {
3297
- char *data = upb_arena_malloc(&d->arena, size);
3298
- if (!data) {
3299
- return fastdecode_err(d);
3300
- }
3301
- memcpy(data, ptr, size);
3302
- dst->data = data;
3303
- dst->size = size;
3304
- }
3305
-
3306
- if (validate_utf8) {
3307
- return fastdecode_verifyutf8(d, ptr + size, msg, table, hasbits, dst);
3308
- } else {
3309
- return fastdecode_dispatch(d, ptr + size, msg, table, hasbits);
3582
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3583
+ }
3584
+
3585
+ #define FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, validate_utf8) \
3586
+ int size = (uint8_t)ptr[0]; /* Could plumb through hasbits. */ \
3587
+ ptr++; \
3588
+ if (size & 0x80) { \
3589
+ ptr = fastdecode_longsize(ptr, &size); \
3590
+ } \
3591
+ \
3592
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
3593
+ dst->size = 0; \
3594
+ return fastdecode_err(d); \
3595
+ } \
3596
+ \
3597
+ if (d->alias) { \
3598
+ dst->data = ptr; \
3599
+ dst->size = size; \
3600
+ } else { \
3601
+ char *data = upb_arena_malloc(&d->arena, size); \
3602
+ if (!data) { \
3603
+ return fastdecode_err(d); \
3604
+ } \
3605
+ memcpy(data, ptr, size); \
3606
+ dst->data = data; \
3607
+ dst->size = size; \
3608
+ } \
3609
+ \
3610
+ ptr += size; \
3611
+ if (validate_utf8) { \
3612
+ data = (uint64_t)dst; \
3613
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3614
+ } else { \
3615
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3310
3616
  }
3311
- }
3312
3617
 
3313
3618
  UPB_NOINLINE
3314
3619
  static const char *fastdecode_longstring_utf8(struct upb_decstate *d,
3315
- const char *ptr, upb_msg *msg,
3316
- intptr_t table, uint64_t hasbits,
3317
- upb_strview *dst) {
3318
- return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, true);
3620
+ const char *ptr, upb_msg *msg,
3621
+ intptr_t table, uint64_t hasbits,
3622
+ uint64_t data) {
3623
+ upb_strview *dst = (upb_strview*)data;
3624
+ FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true);
3319
3625
  }
3320
3626
 
3321
3627
  UPB_NOINLINE
@@ -3323,8 +3629,9 @@ static const char *fastdecode_longstring_noutf8(struct upb_decstate *d,
3323
3629
  const char *ptr, upb_msg *msg,
3324
3630
  intptr_t table,
3325
3631
  uint64_t hasbits,
3326
- upb_strview *dst) {
3327
- return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, false);
3632
+ uint64_t data) {
3633
+ upb_strview *dst = (upb_strview*)data;
3634
+ FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false);
3328
3635
  }
3329
3636
 
3330
3637
  UPB_FORCEINLINE
@@ -3337,156 +3644,165 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size,
3337
3644
  UPB_POISON_MEMORY_REGION(data + size, copy - size);
3338
3645
  }
3339
3646
 
3340
- UPB_FORCEINLINE
3341
- static const char *fastdecode_copystring(UPB_PARSE_PARAMS, int tagbytes,
3342
- upb_card card, bool validate_utf8) {
3343
- upb_strview *dst;
3344
- fastdecode_arr farr;
3345
- int64_t size;
3346
- size_t arena_has;
3347
- size_t common_has;
3348
- char *buf;
3349
-
3350
- UPB_ASSERT(!d->alias);
3351
- UPB_ASSERT(fastdecode_checktag(data, tagbytes));
3352
-
3353
- dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
3354
- sizeof(upb_strview), card);
3355
-
3356
- again:
3357
- if (card == CARD_r) {
3358
- dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
3359
- }
3360
-
3361
- size = (uint8_t)ptr[tagbytes];
3362
- ptr += tagbytes + 1;
3363
- dst->size = size;
3364
-
3365
- buf = d->arena.head.ptr;
3366
- arena_has = _upb_arenahas(&d->arena);
3367
- common_has = UPB_MIN(arena_has, (d->end - ptr) + 16);
3368
-
3369
- if (UPB_LIKELY(size <= 15 - tagbytes)) {
3370
- if (arena_has < 16) goto longstr;
3371
- d->arena.head.ptr += 16;
3372
- memcpy(buf, ptr - tagbytes - 1, 16);
3373
- dst->data = buf + tagbytes + 1;
3374
- } else if (UPB_LIKELY(size <= 32)) {
3375
- if (UPB_UNLIKELY(common_has < 32)) goto longstr;
3376
- fastdecode_docopy(d, ptr, size, 32, buf, dst);
3377
- } else if (UPB_LIKELY(size <= 64)) {
3378
- if (UPB_UNLIKELY(common_has < 64)) goto longstr;
3379
- fastdecode_docopy(d, ptr, size, 64, buf, dst);
3380
- } else if (UPB_LIKELY(size < 128)) {
3381
- if (UPB_UNLIKELY(common_has < 128)) goto longstr;
3382
- fastdecode_docopy(d, ptr, size, 128, buf, dst);
3383
- } else {
3384
- goto longstr;
3385
- }
3386
-
3387
- ptr += size;
3388
-
3389
- if (card == CARD_r) {
3390
- if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
3391
- return fastdecode_err(d);
3392
- }
3393
- fastdecode_nextret ret = fastdecode_nextrepeated(
3394
- d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
3395
- switch (ret.next) {
3396
- case FD_NEXT_SAMEFIELD:
3397
- dst = ret.dst;
3398
- goto again;
3399
- case FD_NEXT_OTHERFIELD:
3400
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3401
- case FD_NEXT_ATLIMIT:
3402
- return ptr;
3403
- }
3404
- }
3405
-
3406
- if (card != CARD_r && validate_utf8) {
3407
- return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
3408
- }
3409
-
3410
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3411
-
3412
- longstr:
3413
- ptr--;
3414
- if (validate_utf8) {
3415
- return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
3416
- } else {
3417
- return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
3418
- }
3419
- }
3420
-
3421
- UPB_FORCEINLINE
3422
- static const char *fastdecode_string(UPB_PARSE_PARAMS, int tagbytes,
3423
- upb_card card, _upb_field_parser *copyfunc,
3424
- bool validate_utf8) {
3425
- upb_strview *dst;
3426
- fastdecode_arr farr;
3427
- int64_t size;
3428
-
3429
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
3430
- RETURN_GENERIC("string field tag mismatch\n");
3431
- }
3432
-
3433
- if (UPB_UNLIKELY(!d->alias)) {
3434
- return copyfunc(UPB_PARSE_ARGS);
3435
- }
3436
-
3437
- dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
3438
- sizeof(upb_strview), card);
3439
-
3440
- again:
3441
- if (card == CARD_r) {
3442
- dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview));
3443
- }
3444
-
3445
- size = (int8_t)ptr[tagbytes];
3446
- ptr += tagbytes + 1;
3447
- dst->data = ptr;
3448
- dst->size = size;
3449
-
3450
- if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) {
3451
- ptr--;
3452
- if (validate_utf8) {
3453
- return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, dst);
3454
- } else {
3455
- return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, dst);
3456
- }
3457
- }
3458
-
3459
- ptr += size;
3460
-
3461
- if (card == CARD_r) {
3462
- if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) {
3463
- return fastdecode_err(d);
3464
- }
3465
- fastdecode_nextret ret = fastdecode_nextrepeated(
3466
- d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview));
3467
- switch (ret.next) {
3468
- case FD_NEXT_SAMEFIELD:
3469
- dst = ret.dst;
3470
- if (UPB_UNLIKELY(!d->alias)) {
3471
- // Buffer flipped and we can't alias any more. Bounce to copyfunc(),
3472
- // but via dispatch since we need to reload table data also.
3473
- fastdecode_commitarr(dst, &farr, sizeof(upb_strview));
3474
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3475
- }
3476
- goto again;
3477
- case FD_NEXT_OTHERFIELD:
3478
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3479
- case FD_NEXT_ATLIMIT:
3480
- return ptr;
3481
- }
3482
- }
3483
-
3484
- if (card != CARD_r && validate_utf8) {
3485
- return fastdecode_verifyutf8(d, ptr, msg, table, hasbits, dst);
3486
- }
3487
-
3488
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3489
- }
3647
+ #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3648
+ card, validate_utf8) \
3649
+ upb_strview *dst; \
3650
+ fastdecode_arr farr; \
3651
+ int64_t size; \
3652
+ size_t arena_has; \
3653
+ size_t common_has; \
3654
+ char *buf; \
3655
+ \
3656
+ UPB_ASSERT(!d->alias); \
3657
+ UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \
3658
+ \
3659
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3660
+ sizeof(upb_strview), card); \
3661
+ \
3662
+ again: \
3663
+ if (card == CARD_r) { \
3664
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3665
+ } \
3666
+ \
3667
+ size = (uint8_t)ptr[tagbytes]; \
3668
+ ptr += tagbytes + 1; \
3669
+ dst->size = size; \
3670
+ \
3671
+ buf = d->arena.head.ptr; \
3672
+ arena_has = _upb_arenahas(&d->arena); \
3673
+ common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \
3674
+ \
3675
+ if (UPB_LIKELY(size <= 15 - tagbytes)) { \
3676
+ if (arena_has < 16) \
3677
+ goto longstr; \
3678
+ d->arena.head.ptr += 16; \
3679
+ memcpy(buf, ptr - tagbytes - 1, 16); \
3680
+ dst->data = buf + tagbytes + 1; \
3681
+ } else if (UPB_LIKELY(size <= 32)) { \
3682
+ if (UPB_UNLIKELY(common_has < 32)) \
3683
+ goto longstr; \
3684
+ fastdecode_docopy(d, ptr, size, 32, buf, dst); \
3685
+ } else if (UPB_LIKELY(size <= 64)) { \
3686
+ if (UPB_UNLIKELY(common_has < 64)) \
3687
+ goto longstr; \
3688
+ fastdecode_docopy(d, ptr, size, 64, buf, dst); \
3689
+ } else if (UPB_LIKELY(size < 128)) { \
3690
+ if (UPB_UNLIKELY(common_has < 128)) \
3691
+ goto longstr; \
3692
+ fastdecode_docopy(d, ptr, size, 128, buf, dst); \
3693
+ } else { \
3694
+ goto longstr; \
3695
+ } \
3696
+ \
3697
+ ptr += size; \
3698
+ \
3699
+ if (card == CARD_r) { \
3700
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3701
+ return fastdecode_err(d); \
3702
+ } \
3703
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3704
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3705
+ switch (ret.next) { \
3706
+ case FD_NEXT_SAMEFIELD: \
3707
+ dst = ret.dst; \
3708
+ goto again; \
3709
+ case FD_NEXT_OTHERFIELD: \
3710
+ data = ret.tag; \
3711
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3712
+ case FD_NEXT_ATLIMIT: \
3713
+ return ptr; \
3714
+ } \
3715
+ } \
3716
+ \
3717
+ if (card != CARD_r && validate_utf8) { \
3718
+ data = (uint64_t)dst; \
3719
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3720
+ } \
3721
+ \
3722
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3723
+ \
3724
+ longstr: \
3725
+ ptr--; \
3726
+ if (validate_utf8) { \
3727
+ UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \
3728
+ hasbits, (uint64_t)dst); \
3729
+ } else { \
3730
+ UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \
3731
+ hasbits, (uint64_t)dst); \
3732
+ }
3733
+
3734
+ #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \
3735
+ copyfunc, validate_utf8) \
3736
+ upb_strview *dst; \
3737
+ fastdecode_arr farr; \
3738
+ int64_t size; \
3739
+ \
3740
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3741
+ RETURN_GENERIC("string field tag mismatch\n"); \
3742
+ } \
3743
+ \
3744
+ if (UPB_UNLIKELY(!d->alias)) { \
3745
+ UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \
3746
+ } \
3747
+ \
3748
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3749
+ sizeof(upb_strview), card); \
3750
+ \
3751
+ again: \
3752
+ if (card == CARD_r) { \
3753
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3754
+ } \
3755
+ \
3756
+ size = (int8_t)ptr[tagbytes]; \
3757
+ ptr += tagbytes + 1; \
3758
+ dst->data = ptr; \
3759
+ dst->size = size; \
3760
+ \
3761
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) { \
3762
+ ptr--; \
3763
+ if (validate_utf8) { \
3764
+ return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, \
3765
+ (uint64_t)dst); \
3766
+ } else { \
3767
+ return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, \
3768
+ (uint64_t)dst); \
3769
+ } \
3770
+ } \
3771
+ \
3772
+ ptr += size; \
3773
+ \
3774
+ if (card == CARD_r) { \
3775
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3776
+ return fastdecode_err(d); \
3777
+ } \
3778
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3779
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3780
+ switch (ret.next) { \
3781
+ case FD_NEXT_SAMEFIELD: \
3782
+ dst = ret.dst; \
3783
+ if (UPB_UNLIKELY(!d->alias)) { \
3784
+ /* Buffer flipped and we can't alias any more. Bounce to */ \
3785
+ /* copyfunc(), but via dispatch since we need to reload table */ \
3786
+ /* data also. */ \
3787
+ fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \
3788
+ data = ret.tag; \
3789
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3790
+ } \
3791
+ goto again; \
3792
+ case FD_NEXT_OTHERFIELD: \
3793
+ data = ret.tag; \
3794
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3795
+ case FD_NEXT_ATLIMIT: \
3796
+ return ptr; \
3797
+ } \
3798
+ } \
3799
+ \
3800
+ if (card != CARD_r && validate_utf8) { \
3801
+ data = (uint64_t)dst; \
3802
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3803
+ } \
3804
+ \
3805
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3490
3806
 
3491
3807
  /* Generate all combinations:
3492
3808
  * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
@@ -3494,16 +3810,16 @@ again:
3494
3810
  #define s_VALIDATE true
3495
3811
  #define b_VALIDATE false
3496
3812
 
3497
- #define F(card, tagbytes, type) \
3498
- UPB_NOINLINE \
3499
- const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3500
- return fastdecode_copystring(UPB_PARSE_ARGS, tagbytes, CARD_##card, \
3501
- type##_VALIDATE); \
3502
- } \
3503
- const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3504
- return fastdecode_string(UPB_PARSE_ARGS, tagbytes, CARD_##card, \
3505
- &upb_c##card##type##_##tagbytes##bt, \
3506
- type##_VALIDATE); \
3813
+ #define F(card, tagbytes, type) \
3814
+ UPB_NOINLINE \
3815
+ const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3816
+ FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3817
+ CARD_##card, type##_VALIDATE); \
3818
+ } \
3819
+ const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3820
+ FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3821
+ CARD_##card, upb_c##card##type##_##tagbytes##bt, \
3822
+ type##_VALIDATE); \
3507
3823
  }
3508
3824
 
3509
3825
  #define UTF8(card, tagbytes) \
@@ -3522,6 +3838,9 @@ TAGBYTES(r)
3522
3838
  #undef b_VALIDATE
3523
3839
  #undef F
3524
3840
  #undef TAGBYTES
3841
+ #undef FASTDECODE_LONGSTRING
3842
+ #undef FASTDECODE_COPYSTRING
3843
+ #undef FASTDECODE_STRING
3525
3844
 
3526
3845
  /* message fields *************************************************************/
3527
3846
 
@@ -3554,82 +3873,82 @@ UPB_FORCEINLINE
3554
3873
  static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr,
3555
3874
  void *ctx) {
3556
3875
  fastdecode_submsgdata *submsg = ctx;
3557
- ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0);
3876
+ ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0);
3558
3877
  UPB_ASSUME(ptr != NULL);
3559
3878
  return ptr;
3560
3879
  }
3561
3880
 
3562
- UPB_FORCEINLINE
3563
- static const char *fastdecode_submsg(UPB_PARSE_PARAMS, int tagbytes,
3564
- int msg_ceil_bytes, upb_card card) {
3565
-
3566
- if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) {
3567
- RETURN_GENERIC("submessage field tag mismatch\n");
3568
- }
3569
-
3570
- if (--d->depth == 0) return fastdecode_err(d);
3571
-
3572
- upb_msg **dst;
3573
- uint32_t submsg_idx = (data >> 16) & 0xff;
3574
- const upb_msglayout *tablep = decode_totablep(table);
3575
- const upb_msglayout *subtablep = tablep->submsgs[submsg_idx];
3576
- fastdecode_submsgdata submsg = {decode_totable(subtablep)};
3577
- fastdecode_arr farr;
3578
-
3579
- if (subtablep->table_mask == (uint8_t)-1) {
3580
- RETURN_GENERIC("submessage doesn't have fast tables.");
3581
- }
3582
-
3583
- dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr,
3584
- sizeof(upb_msg *), card);
3585
-
3586
- if (card == CARD_s) {
3587
- *(uint32_t*)msg |= hasbits;
3588
- hasbits = 0;
3589
- }
3590
-
3591
- again:
3592
- if (card == CARD_r) {
3593
- dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg*));
3594
- }
3595
-
3596
- submsg.msg = *dst;
3597
-
3598
- if (card == CARD_r || UPB_LIKELY(!submsg.msg)) {
3599
- *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes);
3600
- }
3601
-
3602
- ptr += tagbytes;
3603
- ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg);
3604
-
3605
- if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) {
3606
- return fastdecode_err(d);
3607
- }
3608
-
3609
- if (card == CARD_r) {
3610
- fastdecode_nextret ret = fastdecode_nextrepeated(
3611
- d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *));
3612
- switch (ret.next) {
3613
- case FD_NEXT_SAMEFIELD:
3614
- dst = ret.dst;
3615
- goto again;
3616
- case FD_NEXT_OTHERFIELD:
3617
- d->depth++;
3618
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, ret.tag);
3619
- case FD_NEXT_ATLIMIT:
3620
- d->depth++;
3621
- return ptr;
3622
- }
3623
- }
3624
-
3625
- d->depth++;
3626
- return fastdecode_dispatch(d, ptr, msg, table, hasbits);
3627
- }
3628
-
3629
- #define F(card, tagbytes, size_ceil, ceil_arg) \
3630
- const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
3631
- UPB_PARSE_PARAMS) { \
3632
- return fastdecode_submsg(UPB_PARSE_ARGS, tagbytes, ceil_arg, CARD_##card); \
3881
+ #define FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, \
3882
+ msg_ceil_bytes, card) \
3883
+ \
3884
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3885
+ RETURN_GENERIC("submessage field tag mismatch\n"); \
3886
+ } \
3887
+ \
3888
+ if (--d->depth == 0) return fastdecode_err(d); \
3889
+ \
3890
+ upb_msg **dst; \
3891
+ uint32_t submsg_idx = (data >> 16) & 0xff; \
3892
+ const upb_msglayout *tablep = decode_totablep(table); \
3893
+ const upb_msglayout *subtablep = tablep->submsgs[submsg_idx]; \
3894
+ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
3895
+ fastdecode_arr farr; \
3896
+ \
3897
+ if (subtablep->table_mask == (uint8_t)-1) { \
3898
+ RETURN_GENERIC("submessage doesn't have fast tables."); \
3899
+ } \
3900
+ \
3901
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3902
+ sizeof(upb_msg *), card); \
3903
+ \
3904
+ if (card == CARD_s) { \
3905
+ *(uint32_t *)msg |= hasbits; \
3906
+ hasbits = 0; \
3907
+ } \
3908
+ \
3909
+ again: \
3910
+ if (card == CARD_r) { \
3911
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg *)); \
3912
+ } \
3913
+ \
3914
+ submsg.msg = *dst; \
3915
+ \
3916
+ if (card == CARD_r || UPB_LIKELY(!submsg.msg)) { \
3917
+ *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes); \
3918
+ } \
3919
+ \
3920
+ ptr += tagbytes; \
3921
+ ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
3922
+ \
3923
+ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
3924
+ return fastdecode_err(d); \
3925
+ } \
3926
+ \
3927
+ if (card == CARD_r) { \
3928
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3929
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *)); \
3930
+ switch (ret.next) { \
3931
+ case FD_NEXT_SAMEFIELD: \
3932
+ dst = ret.dst; \
3933
+ goto again; \
3934
+ case FD_NEXT_OTHERFIELD: \
3935
+ d->depth++; \
3936
+ data = ret.tag; \
3937
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3938
+ case FD_NEXT_ATLIMIT: \
3939
+ d->depth++; \
3940
+ return ptr; \
3941
+ } \
3942
+ } \
3943
+ \
3944
+ d->depth++; \
3945
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3946
+
3947
+ #define F(card, tagbytes, size_ceil, ceil_arg) \
3948
+ const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
3949
+ UPB_PARSE_PARAMS) { \
3950
+ FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \
3951
+ CARD_##card); \
3633
3952
  }
3634
3953
 
3635
3954
  #define SIZES(card, tagbytes) \
@@ -3650,9 +3969,11 @@ TAGBYTES(r)
3650
3969
  #undef TAGBYTES
3651
3970
  #undef SIZES
3652
3971
  #undef F
3972
+ #undef FASTDECODE_SUBMSG
3653
3973
 
3654
3974
  #endif /* UPB_FASTTABLE */
3655
- /* This file was generated by upbc (the upb compiler) from the input
3975
+
3976
+ /** bazel-out/k8-fastbuild/bin/external/com_google_protobuf/google/protobuf/descriptor.upb.c ************************************************************//* This file was generated by upbc (the upb compiler) from the input
3656
3977
  * file:
3657
3978
  *
3658
3979
  * google/protobuf/descriptor.proto
@@ -3668,13 +3989,13 @@ static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] =
3668
3989
  };
3669
3990
 
3670
3991
  static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
3671
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
3992
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3672
3993
  };
3673
3994
 
3674
3995
  const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
3675
3996
  &google_protobuf_FileDescriptorSet_submsgs[0],
3676
3997
  &google_protobuf_FileDescriptorSet__fields[0],
3677
- UPB_SIZE(8, 8), 1, false, 255,
3998
+ UPB_SIZE(8, 8), 1, false, 1, 255,
3678
3999
  };
3679
4000
 
3680
4001
  static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
@@ -3687,24 +4008,24 @@ static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6]
3687
4008
  };
3688
4009
 
3689
4010
  static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
3690
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3691
- {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
3692
- {3, UPB_SIZE(36, 72), 0, 0, 12, 3},
3693
- {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
3694
- {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
3695
- {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
3696
- {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
3697
- {8, UPB_SIZE(28, 56), 3, 3, 11, 1},
3698
- {9, UPB_SIZE(32, 64), 4, 5, 11, 1},
3699
- {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
3700
- {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
3701
- {12, UPB_SIZE(20, 40), 5, 0, 12, 1},
4011
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4012
+ {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4013
+ {3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY},
4014
+ {4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4015
+ {5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY},
4016
+ {6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY},
4017
+ {7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY},
4018
+ {8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR},
4019
+ {9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR},
4020
+ {10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY},
4021
+ {11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY},
4022
+ {12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR},
3702
4023
  };
3703
4024
 
3704
4025
  const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
3705
4026
  &google_protobuf_FileDescriptorProto_submsgs[0],
3706
4027
  &google_protobuf_FileDescriptorProto__fields[0],
3707
- UPB_SIZE(64, 128), 12, false, 255,
4028
+ UPB_SIZE(64, 128), 12, false, 12, 255,
3708
4029
  };
3709
4030
 
3710
4031
  static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
@@ -3718,22 +4039,22 @@ static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
3718
4039
  };
3719
4040
 
3720
4041
  static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
3721
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3722
- {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
3723
- {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
3724
- {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
3725
- {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
3726
- {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
3727
- {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
3728
- {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
3729
- {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
3730
- {10, UPB_SIZE(44, 88), 0, 0, 12, 3},
4042
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4043
+ {2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY},
4044
+ {3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4045
+ {4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY},
4046
+ {5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY},
4047
+ {6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY},
4048
+ {7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR},
4049
+ {8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY},
4050
+ {9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY},
4051
+ {10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY},
3731
4052
  };
3732
4053
 
3733
4054
  const upb_msglayout google_protobuf_DescriptorProto_msginit = {
3734
4055
  &google_protobuf_DescriptorProto_submsgs[0],
3735
4056
  &google_protobuf_DescriptorProto__fields[0],
3736
- UPB_SIZE(48, 96), 10, false, 255,
4057
+ UPB_SIZE(48, 96), 10, false, 10, 255,
3737
4058
  };
3738
4059
 
3739
4060
  static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@@ -3741,26 +4062,26 @@ static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange
3741
4062
  };
3742
4063
 
3743
4064
  static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
3744
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3745
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
3746
- {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
4065
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4066
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
4067
+ {3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR},
3747
4068
  };
3748
4069
 
3749
4070
  const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
3750
4071
  &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
3751
4072
  &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
3752
- UPB_SIZE(16, 24), 3, false, 255,
4073
+ UPB_SIZE(16, 24), 3, false, 3, 255,
3753
4074
  };
3754
4075
 
3755
4076
  static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
3756
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3757
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
4077
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4078
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
3758
4079
  };
3759
4080
 
3760
4081
  const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
3761
4082
  NULL,
3762
4083
  &google_protobuf_DescriptorProto_ReservedRange__fields[0],
3763
- UPB_SIZE(16, 16), 2, false, 255,
4084
+ UPB_SIZE(16, 16), 2, false, 2, 255,
3764
4085
  };
3765
4086
 
3766
4087
  static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@@ -3768,13 +4089,13 @@ static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[
3768
4089
  };
3769
4090
 
3770
4091
  static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
3771
- {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
4092
+ {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3772
4093
  };
3773
4094
 
3774
4095
  const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
3775
4096
  &google_protobuf_ExtensionRangeOptions_submsgs[0],
3776
4097
  &google_protobuf_ExtensionRangeOptions__fields[0],
3777
- UPB_SIZE(8, 8), 1, false, 255,
4098
+ UPB_SIZE(8, 8), 1, false, 0, 255,
3778
4099
  };
3779
4100
 
3780
4101
  static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
@@ -3782,23 +4103,23 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
3782
4103
  };
3783
4104
 
3784
4105
  static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
3785
- {1, UPB_SIZE(24, 24), 1, 0, 12, 1},
3786
- {2, UPB_SIZE(32, 40), 2, 0, 12, 1},
3787
- {3, UPB_SIZE(12, 12), 3, 0, 5, 1},
3788
- {4, UPB_SIZE(4, 4), 4, 0, 14, 1},
3789
- {5, UPB_SIZE(8, 8), 5, 0, 14, 1},
3790
- {6, UPB_SIZE(40, 56), 6, 0, 12, 1},
3791
- {7, UPB_SIZE(48, 72), 7, 0, 12, 1},
3792
- {8, UPB_SIZE(64, 104), 8, 0, 11, 1},
3793
- {9, UPB_SIZE(16, 16), 9, 0, 5, 1},
3794
- {10, UPB_SIZE(56, 88), 10, 0, 12, 1},
3795
- {17, UPB_SIZE(20, 20), 11, 0, 8, 1},
4106
+ {1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4107
+ {2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4108
+ {3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR},
4109
+ {4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR},
4110
+ {5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4111
+ {6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR},
4112
+ {7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR},
4113
+ {8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR},
4114
+ {9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR},
4115
+ {10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR},
4116
+ {17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR},
3796
4117
  };
3797
4118
 
3798
4119
  const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
3799
4120
  &google_protobuf_FieldDescriptorProto_submsgs[0],
3800
4121
  &google_protobuf_FieldDescriptorProto__fields[0],
3801
- UPB_SIZE(72, 112), 11, false, 255,
4122
+ UPB_SIZE(72, 112), 11, false, 10, 255,
3802
4123
  };
3803
4124
 
3804
4125
  static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -3806,14 +4127,14 @@ static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1
3806
4127
  };
3807
4128
 
3808
4129
  static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
3809
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3810
- {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
4130
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4131
+ {2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR},
3811
4132
  };
3812
4133
 
3813
4134
  const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
3814
4135
  &google_protobuf_OneofDescriptorProto_submsgs[0],
3815
4136
  &google_protobuf_OneofDescriptorProto__fields[0],
3816
- UPB_SIZE(16, 32), 2, false, 255,
4137
+ UPB_SIZE(16, 32), 2, false, 2, 255,
3817
4138
  };
3818
4139
 
3819
4140
  static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
@@ -3823,28 +4144,28 @@ static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3]
3823
4144
  };
3824
4145
 
3825
4146
  static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
3826
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3827
- {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
3828
- {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
3829
- {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
3830
- {5, UPB_SIZE(24, 48), 0, 0, 12, 3},
4147
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4148
+ {2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY},
4149
+ {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
4150
+ {4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4151
+ {5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY},
3831
4152
  };
3832
4153
 
3833
4154
  const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
3834
4155
  &google_protobuf_EnumDescriptorProto_submsgs[0],
3835
4156
  &google_protobuf_EnumDescriptorProto__fields[0],
3836
- UPB_SIZE(32, 64), 5, false, 255,
4157
+ UPB_SIZE(32, 64), 5, false, 5, 255,
3837
4158
  };
3838
4159
 
3839
4160
  static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
3840
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3841
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
4161
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4162
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
3842
4163
  };
3843
4164
 
3844
4165
  const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
3845
4166
  NULL,
3846
4167
  &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
3847
- UPB_SIZE(16, 16), 2, false, 255,
4168
+ UPB_SIZE(16, 16), 2, false, 2, 255,
3848
4169
  };
3849
4170
 
3850
4171
  static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@@ -3852,15 +4173,15 @@ static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_subms
3852
4173
  };
3853
4174
 
3854
4175
  static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
3855
- {1, UPB_SIZE(8, 8), 1, 0, 12, 1},
3856
- {2, UPB_SIZE(4, 4), 2, 0, 5, 1},
3857
- {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
4176
+ {1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4177
+ {2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4178
+ {3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR},
3858
4179
  };
3859
4180
 
3860
4181
  const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
3861
4182
  &google_protobuf_EnumValueDescriptorProto_submsgs[0],
3862
4183
  &google_protobuf_EnumValueDescriptorProto__fields[0],
3863
- UPB_SIZE(24, 32), 3, false, 255,
4184
+ UPB_SIZE(24, 32), 3, false, 3, 255,
3864
4185
  };
3865
4186
 
3866
4187
  static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@@ -3869,15 +4190,15 @@ static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs
3869
4190
  };
3870
4191
 
3871
4192
  static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
3872
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3873
- {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
3874
- {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
4193
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4194
+ {2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY},
4195
+ {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
3875
4196
  };
3876
4197
 
3877
4198
  const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
3878
4199
  &google_protobuf_ServiceDescriptorProto_submsgs[0],
3879
4200
  &google_protobuf_ServiceDescriptorProto__fields[0],
3880
- UPB_SIZE(24, 48), 3, false, 255,
4201
+ UPB_SIZE(24, 48), 3, false, 3, 255,
3881
4202
  };
3882
4203
 
3883
4204
  static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
@@ -3885,18 +4206,18 @@ static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[
3885
4206
  };
3886
4207
 
3887
4208
  static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
3888
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3889
- {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
3890
- {3, UPB_SIZE(20, 40), 3, 0, 12, 1},
3891
- {4, UPB_SIZE(28, 56), 4, 0, 11, 1},
3892
- {5, UPB_SIZE(1, 1), 5, 0, 8, 1},
3893
- {6, UPB_SIZE(2, 2), 6, 0, 8, 1},
4209
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4210
+ {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4211
+ {3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR},
4212
+ {4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR},
4213
+ {5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR},
4214
+ {6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR},
3894
4215
  };
3895
4216
 
3896
4217
  const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
3897
4218
  &google_protobuf_MethodDescriptorProto_submsgs[0],
3898
4219
  &google_protobuf_MethodDescriptorProto__fields[0],
3899
- UPB_SIZE(32, 64), 6, false, 255,
4220
+ UPB_SIZE(32, 64), 6, false, 6, 255,
3900
4221
  };
3901
4222
 
3902
4223
  static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
@@ -3904,33 +4225,33 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
3904
4225
  };
3905
4226
 
3906
4227
  static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
3907
- {1, UPB_SIZE(20, 24), 1, 0, 12, 1},
3908
- {8, UPB_SIZE(28, 40), 2, 0, 12, 1},
3909
- {9, UPB_SIZE(4, 4), 3, 0, 14, 1},
3910
- {10, UPB_SIZE(8, 8), 4, 0, 8, 1},
3911
- {11, UPB_SIZE(36, 56), 5, 0, 12, 1},
3912
- {16, UPB_SIZE(9, 9), 6, 0, 8, 1},
3913
- {17, UPB_SIZE(10, 10), 7, 0, 8, 1},
3914
- {18, UPB_SIZE(11, 11), 8, 0, 8, 1},
3915
- {20, UPB_SIZE(12, 12), 9, 0, 8, 1},
3916
- {23, UPB_SIZE(13, 13), 10, 0, 8, 1},
3917
- {27, UPB_SIZE(14, 14), 11, 0, 8, 1},
3918
- {31, UPB_SIZE(15, 15), 12, 0, 8, 1},
3919
- {36, UPB_SIZE(44, 72), 13, 0, 12, 1},
3920
- {37, UPB_SIZE(52, 88), 14, 0, 12, 1},
3921
- {39, UPB_SIZE(60, 104), 15, 0, 12, 1},
3922
- {40, UPB_SIZE(68, 120), 16, 0, 12, 1},
3923
- {41, UPB_SIZE(76, 136), 17, 0, 12, 1},
3924
- {42, UPB_SIZE(16, 16), 18, 0, 8, 1},
3925
- {44, UPB_SIZE(84, 152), 19, 0, 12, 1},
3926
- {45, UPB_SIZE(92, 168), 20, 0, 12, 1},
3927
- {999, UPB_SIZE(100, 184), 0, 0, 11, 3},
4228
+ {1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4229
+ {8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4230
+ {9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR},
4231
+ {10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR},
4232
+ {11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR},
4233
+ {16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR},
4234
+ {17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR},
4235
+ {18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR},
4236
+ {20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR},
4237
+ {23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR},
4238
+ {27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR},
4239
+ {31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR},
4240
+ {36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR},
4241
+ {37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR},
4242
+ {39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR},
4243
+ {40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR},
4244
+ {41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR},
4245
+ {42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR},
4246
+ {44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR},
4247
+ {45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR},
4248
+ {999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY},
3928
4249
  };
3929
4250
 
3930
4251
  const upb_msglayout google_protobuf_FileOptions_msginit = {
3931
4252
  &google_protobuf_FileOptions_submsgs[0],
3932
4253
  &google_protobuf_FileOptions__fields[0],
3933
- UPB_SIZE(104, 192), 21, false, 255,
4254
+ UPB_SIZE(104, 192), 21, false, 1, 255,
3934
4255
  };
3935
4256
 
3936
4257
  static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
@@ -3938,17 +4259,17 @@ static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
3938
4259
  };
3939
4260
 
3940
4261
  static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
3941
- {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
3942
- {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
3943
- {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
3944
- {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
3945
- {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
4262
+ {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4263
+ {2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4264
+ {3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR},
4265
+ {7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR},
4266
+ {999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY},
3946
4267
  };
3947
4268
 
3948
4269
  const upb_msglayout google_protobuf_MessageOptions_msginit = {
3949
4270
  &google_protobuf_MessageOptions_submsgs[0],
3950
4271
  &google_protobuf_MessageOptions__fields[0],
3951
- UPB_SIZE(16, 16), 5, false, 255,
4272
+ UPB_SIZE(16, 16), 5, false, 3, 255,
3952
4273
  };
3953
4274
 
3954
4275
  static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
@@ -3956,19 +4277,19 @@ static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
3956
4277
  };
3957
4278
 
3958
4279
  static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
3959
- {1, UPB_SIZE(4, 4), 1, 0, 14, 1},
3960
- {2, UPB_SIZE(12, 12), 2, 0, 8, 1},
3961
- {3, UPB_SIZE(13, 13), 3, 0, 8, 1},
3962
- {5, UPB_SIZE(14, 14), 4, 0, 8, 1},
3963
- {6, UPB_SIZE(8, 8), 5, 0, 14, 1},
3964
- {10, UPB_SIZE(15, 15), 6, 0, 8, 1},
3965
- {999, UPB_SIZE(16, 16), 0, 0, 11, 3},
4280
+ {1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR},
4281
+ {2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR},
4282
+ {3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR},
4283
+ {5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR},
4284
+ {6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4285
+ {10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR},
4286
+ {999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY},
3966
4287
  };
3967
4288
 
3968
4289
  const upb_msglayout google_protobuf_FieldOptions_msginit = {
3969
4290
  &google_protobuf_FieldOptions_submsgs[0],
3970
4291
  &google_protobuf_FieldOptions__fields[0],
3971
- UPB_SIZE(24, 24), 7, false, 255,
4292
+ UPB_SIZE(24, 24), 7, false, 3, 255,
3972
4293
  };
3973
4294
 
3974
4295
  static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
@@ -3976,13 +4297,13 @@ static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
3976
4297
  };
3977
4298
 
3978
4299
  static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
3979
- {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
4300
+ {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3980
4301
  };
3981
4302
 
3982
4303
  const upb_msglayout google_protobuf_OneofOptions_msginit = {
3983
4304
  &google_protobuf_OneofOptions_submsgs[0],
3984
4305
  &google_protobuf_OneofOptions__fields[0],
3985
- UPB_SIZE(8, 8), 1, false, 255,
4306
+ UPB_SIZE(8, 8), 1, false, 0, 255,
3986
4307
  };
3987
4308
 
3988
4309
  static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
@@ -3990,15 +4311,15 @@ static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
3990
4311
  };
3991
4312
 
3992
4313
  static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
3993
- {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
3994
- {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
3995
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4314
+ {2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4315
+ {3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4316
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
3996
4317
  };
3997
4318
 
3998
4319
  const upb_msglayout google_protobuf_EnumOptions_msginit = {
3999
4320
  &google_protobuf_EnumOptions_submsgs[0],
4000
4321
  &google_protobuf_EnumOptions__fields[0],
4001
- UPB_SIZE(8, 16), 3, false, 255,
4322
+ UPB_SIZE(8, 16), 3, false, 0, 255,
4002
4323
  };
4003
4324
 
4004
4325
  static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
@@ -4006,14 +4327,14 @@ static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] =
4006
4327
  };
4007
4328
 
4008
4329
  static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
4009
- {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
4010
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4330
+ {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4331
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4011
4332
  };
4012
4333
 
4013
4334
  const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
4014
4335
  &google_protobuf_EnumValueOptions_submsgs[0],
4015
4336
  &google_protobuf_EnumValueOptions__fields[0],
4016
- UPB_SIZE(8, 16), 2, false, 255,
4337
+ UPB_SIZE(8, 16), 2, false, 1, 255,
4017
4338
  };
4018
4339
 
4019
4340
  static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
@@ -4021,14 +4342,14 @@ static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
4021
4342
  };
4022
4343
 
4023
4344
  static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
4024
- {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
4025
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4345
+ {33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4346
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4026
4347
  };
4027
4348
 
4028
4349
  const upb_msglayout google_protobuf_ServiceOptions_msginit = {
4029
4350
  &google_protobuf_ServiceOptions_submsgs[0],
4030
4351
  &google_protobuf_ServiceOptions__fields[0],
4031
- UPB_SIZE(8, 16), 2, false, 255,
4352
+ UPB_SIZE(8, 16), 2, false, 0, 255,
4032
4353
  };
4033
4354
 
4034
4355
  static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
@@ -4036,15 +4357,15 @@ static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
4036
4357
  };
4037
4358
 
4038
4359
  static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
4039
- {33, UPB_SIZE(8, 8), 1, 0, 8, 1},
4040
- {34, UPB_SIZE(4, 4), 2, 0, 14, 1},
4041
- {999, UPB_SIZE(12, 16), 0, 0, 11, 3},
4360
+ {33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR},
4361
+ {34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR},
4362
+ {999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY},
4042
4363
  };
4043
4364
 
4044
4365
  const upb_msglayout google_protobuf_MethodOptions_msginit = {
4045
4366
  &google_protobuf_MethodOptions_submsgs[0],
4046
4367
  &google_protobuf_MethodOptions__fields[0],
4047
- UPB_SIZE(16, 24), 3, false, 255,
4368
+ UPB_SIZE(16, 24), 3, false, 0, 255,
4048
4369
  };
4049
4370
 
4050
4371
  static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
@@ -4052,30 +4373,30 @@ static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
4052
4373
  };
4053
4374
 
4054
4375
  static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
4055
- {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
4056
- {3, UPB_SIZE(32, 32), 1, 0, 12, 1},
4057
- {4, UPB_SIZE(8, 8), 2, 0, 4, 1},
4058
- {5, UPB_SIZE(16, 16), 3, 0, 3, 1},
4059
- {6, UPB_SIZE(24, 24), 4, 0, 1, 1},
4060
- {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
4061
- {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
4376
+ {2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4377
+ {3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR},
4378
+ {4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR},
4379
+ {5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR},
4380
+ {6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR},
4381
+ {7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR},
4382
+ {8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR},
4062
4383
  };
4063
4384
 
4064
4385
  const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
4065
4386
  &google_protobuf_UninterpretedOption_submsgs[0],
4066
4387
  &google_protobuf_UninterpretedOption__fields[0],
4067
- UPB_SIZE(64, 96), 7, false, 255,
4388
+ UPB_SIZE(64, 96), 7, false, 0, 255,
4068
4389
  };
4069
4390
 
4070
4391
  static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
4071
- {1, UPB_SIZE(4, 8), 1, 0, 12, 2},
4072
- {2, UPB_SIZE(1, 1), 2, 0, 8, 2},
4392
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4393
+ {2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR},
4073
4394
  };
4074
4395
 
4075
4396
  const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
4076
4397
  NULL,
4077
4398
  &google_protobuf_UninterpretedOption_NamePart__fields[0],
4078
- UPB_SIZE(16, 32), 2, false, 255,
4399
+ UPB_SIZE(16, 32), 2, false, 2, 255,
4079
4400
  };
4080
4401
 
4081
4402
  static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
@@ -4083,27 +4404,27 @@ static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
4083
4404
  };
4084
4405
 
4085
4406
  static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
4086
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
4407
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4087
4408
  };
4088
4409
 
4089
4410
  const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
4090
4411
  &google_protobuf_SourceCodeInfo_submsgs[0],
4091
4412
  &google_protobuf_SourceCodeInfo__fields[0],
4092
- UPB_SIZE(8, 8), 1, false, 255,
4413
+ UPB_SIZE(8, 8), 1, false, 1, 255,
4093
4414
  };
4094
4415
 
4095
4416
  static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
4096
- {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
4097
- {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
4098
- {3, UPB_SIZE(4, 8), 1, 0, 12, 1},
4099
- {4, UPB_SIZE(12, 24), 2, 0, 12, 1},
4100
- {6, UPB_SIZE(28, 56), 0, 0, 12, 3},
4417
+ {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4418
+ {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4419
+ {3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4420
+ {4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4421
+ {6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY},
4101
4422
  };
4102
4423
 
4103
4424
  const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
4104
4425
  NULL,
4105
4426
  &google_protobuf_SourceCodeInfo_Location__fields[0],
4106
- UPB_SIZE(32, 64), 5, false, 255,
4427
+ UPB_SIZE(32, 64), 5, false, 4, 255,
4107
4428
  };
4108
4429
 
4109
4430
  static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@@ -4111,30 +4432,31 @@ static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] =
4111
4432
  };
4112
4433
 
4113
4434
  static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
4114
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
4435
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4115
4436
  };
4116
4437
 
4117
4438
  const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
4118
4439
  &google_protobuf_GeneratedCodeInfo_submsgs[0],
4119
4440
  &google_protobuf_GeneratedCodeInfo__fields[0],
4120
- UPB_SIZE(8, 8), 1, false, 255,
4441
+ UPB_SIZE(8, 8), 1, false, 1, 255,
4121
4442
  };
4122
4443
 
4123
4444
  static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
4124
- {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
4125
- {2, UPB_SIZE(12, 16), 1, 0, 12, 1},
4126
- {3, UPB_SIZE(4, 4), 2, 0, 5, 1},
4127
- {4, UPB_SIZE(8, 8), 3, 0, 5, 1},
4445
+ {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4446
+ {2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR},
4447
+ {3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4448
+ {4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR},
4128
4449
  };
4129
4450
 
4130
4451
  const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
4131
4452
  NULL,
4132
4453
  &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
4133
- UPB_SIZE(24, 48), 4, false, 255,
4454
+ UPB_SIZE(24, 48), 4, false, 4, 255,
4134
4455
  };
4135
4456
 
4136
4457
 
4137
4458
 
4459
+ /** upb/def.c ************************************************************/
4138
4460
 
4139
4461
  #include <ctype.h>
4140
4462
  #include <errno.h>
@@ -4172,7 +4494,6 @@ struct upb_fielddef {
4172
4494
  uint32_t number_;
4173
4495
  uint16_t index_;
4174
4496
  uint16_t layout_index;
4175
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
4176
4497
  bool is_extension_;
4177
4498
  bool lazy_;
4178
4499
  bool packed_;
@@ -4185,8 +4506,6 @@ struct upb_msgdef {
4185
4506
  const upb_msglayout *layout;
4186
4507
  const upb_filedef *file;
4187
4508
  const char *full_name;
4188
- uint32_t selector_count;
4189
- uint32_t submsg_field_count;
4190
4509
 
4191
4510
  /* Tables for looking up fields by number and name. */
4192
4511
  upb_inttable itof;
@@ -4316,30 +4635,6 @@ int cmp_fields(const void *p1, const void *p2) {
4316
4635
  return field_rank(f1) - field_rank(f2);
4317
4636
  }
4318
4637
 
4319
- /* A few implementation details of handlers. We put these here to avoid
4320
- * a def -> handlers dependency. */
4321
-
4322
- #define UPB_STATIC_SELECTOR_COUNT 3 /* Warning: also in upb/handlers.h. */
4323
-
4324
- static uint32_t upb_handlers_selectorbaseoffset(const upb_fielddef *f) {
4325
- return upb_fielddef_isseq(f) ? 2 : 0;
4326
- }
4327
-
4328
- static uint32_t upb_handlers_selectorcount(const upb_fielddef *f) {
4329
- uint32_t ret = 1;
4330
- if (upb_fielddef_isseq(f)) ret += 2; /* STARTSEQ/ENDSEQ */
4331
- if (upb_fielddef_isstring(f)) ret += 2; /* [STRING]/STARTSTR/ENDSTR */
4332
- if (upb_fielddef_issubmsg(f)) {
4333
- /* ENDSUBMSG (STARTSUBMSG is at table beginning) */
4334
- ret += 0;
4335
- if (upb_fielddef_lazy(f)) {
4336
- /* STARTSTR/ENDSTR/STRING (for lazy) */
4337
- ret += 3;
4338
- }
4339
- }
4340
- return ret;
4341
- }
4342
-
4343
4638
  static void upb_status_setoom(upb_status *status) {
4344
4639
  upb_status_seterrmsg(status, "out of memory");
4345
4640
  }
@@ -4431,8 +4726,7 @@ bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
4431
4726
 
4432
4727
  const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
4433
4728
  upb_value v;
4434
- return upb_inttable_lookup32(&def->iton, num, &v) ?
4435
- upb_value_getcstr(v) : NULL;
4729
+ return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getcstr(v) : NULL;
4436
4730
  }
4437
4731
 
4438
4732
  const char *upb_enum_iter_name(upb_enum_iter *iter) {
@@ -4521,10 +4815,6 @@ const char *upb_fielddef_jsonname(const upb_fielddef *f) {
4521
4815
  return f->json_name;
4522
4816
  }
4523
4817
 
4524
- uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
4525
- return f->selector_base;
4526
- }
4527
-
4528
4818
  const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
4529
4819
  return f->file;
4530
4820
  }
@@ -4687,18 +4977,10 @@ upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
4687
4977
  return m->file->syntax;
4688
4978
  }
4689
4979
 
4690
- size_t upb_msgdef_selectorcount(const upb_msgdef *m) {
4691
- return m->selector_count;
4692
- }
4693
-
4694
- uint32_t upb_msgdef_submsgfieldcount(const upb_msgdef *m) {
4695
- return m->submsg_field_count;
4696
- }
4697
-
4698
4980
  const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
4699
4981
  upb_value val;
4700
- return upb_inttable_lookup32(&m->itof, i, &val) ?
4701
- upb_value_getconstptr(val) : NULL;
4982
+ return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val)
4983
+ : NULL;
4702
4984
  }
4703
4985
 
4704
4986
  const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
@@ -4906,8 +5188,8 @@ const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
4906
5188
 
4907
5189
  const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
4908
5190
  upb_value val;
4909
- return upb_inttable_lookup32(&o->itof, num, &val) ?
4910
- upb_value_getptr(val) : NULL;
5191
+ return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val)
5192
+ : NULL;
4911
5193
  }
4912
5194
 
4913
5195
  void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
@@ -4987,7 +5269,6 @@ void upb_symtab_free(upb_symtab *s) {
4987
5269
 
4988
5270
  upb_symtab *upb_symtab_new(void) {
4989
5271
  upb_symtab *s = upb_gmalloc(sizeof(*s));
4990
- upb_alloc *alloc;
4991
5272
 
4992
5273
  if (!s) {
4993
5274
  return NULL;
@@ -4995,10 +5276,9 @@ upb_symtab *upb_symtab_new(void) {
4995
5276
 
4996
5277
  s->arena = upb_arena_new();
4997
5278
  s->bytes_loaded = 0;
4998
- alloc = upb_arena_alloc(s->arena);
4999
5279
 
5000
- if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) ||
5001
- !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) {
5280
+ if (!upb_strtable_init(&s->syms, 32, s->arena) ||
5281
+ !upb_strtable_init(&s->files, 4, s->arena)) {
5002
5282
  upb_arena_free(s->arena);
5003
5283
  upb_gfree(s);
5004
5284
  s = NULL;
@@ -5054,8 +5334,7 @@ int upb_symtab_filecount(const upb_symtab *s) {
5054
5334
  typedef struct {
5055
5335
  upb_symtab *symtab;
5056
5336
  upb_filedef *file; /* File we are building. */
5057
- upb_arena *file_arena; /* Allocate defs here. */
5058
- upb_alloc *alloc; /* Alloc of file_arena, for tables. */
5337
+ upb_arena *arena; /* Allocate defs here. */
5059
5338
  const upb_msglayout **layouts; /* NULL if we should build layouts. */
5060
5339
  upb_status *status; /* Record errors here. */
5061
5340
  jmp_buf err; /* longjmp() on error. */
@@ -5077,7 +5356,7 @@ static void symtab_oomerr(symtab_addctx *ctx) {
5077
5356
  }
5078
5357
 
5079
5358
  void *symtab_alloc(symtab_addctx *ctx, size_t bytes) {
5080
- void *ret = upb_arena_malloc(ctx->file_arena, bytes);
5359
+ void *ret = upb_arena_malloc(ctx->arena, bytes);
5081
5360
  if (!ret) symtab_oomerr(ctx);
5082
5361
  return ret;
5083
5362
  }
@@ -5167,13 +5446,44 @@ static int field_number_cmp(const void *p1, const void *p2) {
5167
5446
  return f1->number - f2->number;
5168
5447
  }
5169
5448
 
5170
- static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fields) {
5449
+ static void assign_layout_indices(const upb_msgdef *m, upb_msglayout *l,
5450
+ upb_msglayout_field *fields) {
5171
5451
  int i;
5172
5452
  int n = upb_msgdef_numfields(m);
5453
+ int dense_below = 0;
5173
5454
  for (i = 0; i < n; i++) {
5174
5455
  upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number);
5175
5456
  UPB_ASSERT(f);
5176
5457
  f->layout_index = i;
5458
+ if (i < UINT8_MAX && fields[i].number == i + 1 &&
5459
+ (i == 0 || fields[i-1].number == i)) {
5460
+ dense_below = i + 1;
5461
+ }
5462
+ }
5463
+ l->dense_below = dense_below;
5464
+ }
5465
+
5466
+ static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f) {
5467
+ field->number = upb_fielddef_number(f);
5468
+ field->descriptortype = upb_fielddef_descriptortype(f);
5469
+
5470
+ if (field->descriptortype == UPB_DTYPE_STRING &&
5471
+ f->file->syntax == UPB_SYNTAX_PROTO2) {
5472
+ /* See TableDescriptorType() in upbc/generator.cc for details and
5473
+ * rationale. */
5474
+ field->descriptortype = UPB_DTYPE_BYTES;
5475
+ }
5476
+
5477
+ if (upb_fielddef_ismap(f)) {
5478
+ field->mode = _UPB_MODE_MAP;
5479
+ } else if (upb_fielddef_isseq(f)) {
5480
+ field->mode = _UPB_MODE_ARRAY;
5481
+ } else {
5482
+ field->mode = _UPB_MODE_SCALAR;
5483
+ }
5484
+
5485
+ if (upb_fielddef_packed(f)) {
5486
+ field->mode |= _UPB_MODE_IS_PACKED;
5177
5487
  }
5178
5488
  }
5179
5489
 
@@ -5184,13 +5494,21 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5184
5494
  upb_msg_field_iter it;
5185
5495
  upb_msg_oneof_iter oit;
5186
5496
  size_t hasbit;
5187
- size_t submsg_count = m->submsg_field_count;
5497
+ size_t field_count = upb_msgdef_numfields(m);
5498
+ size_t submsg_count = 0;
5188
5499
  const upb_msglayout **submsgs;
5189
5500
  upb_msglayout_field *fields;
5190
5501
 
5191
5502
  memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
5192
5503
 
5193
- fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields));
5504
+ /* Count sub-messages. */
5505
+ for (size_t i = 0; i < field_count; i++) {
5506
+ if (upb_fielddef_issubmsg(&m->fields[i])) {
5507
+ submsg_count++;
5508
+ }
5509
+ }
5510
+
5511
+ fields = symtab_alloc(ctx, field_count * sizeof(*fields));
5194
5512
  submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
5195
5513
 
5196
5514
  l->field_count = upb_msgdef_numfields(m);
@@ -5210,8 +5528,8 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5210
5528
  const upb_fielddef *val = upb_msgdef_itof(m, 2);
5211
5529
  fields[0].number = 1;
5212
5530
  fields[1].number = 2;
5213
- fields[0].label = UPB_LABEL_OPTIONAL;
5214
- fields[1].label = UPB_LABEL_OPTIONAL;
5531
+ fields[0].mode = _UPB_MODE_SCALAR;
5532
+ fields[1].mode = _UPB_MODE_SCALAR;
5215
5533
  fields[0].presence = 0;
5216
5534
  fields[1].presence = 0;
5217
5535
  fields[0].descriptortype = upb_fielddef_descriptortype(key);
@@ -5247,22 +5565,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5247
5565
  upb_fielddef* f = upb_msg_iter_field(&it);
5248
5566
  upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
5249
5567
 
5250
- field->number = upb_fielddef_number(f);
5251
- field->descriptortype = upb_fielddef_descriptortype(f);
5252
- field->label = upb_fielddef_label(f);
5253
-
5254
- if (field->descriptortype == UPB_DTYPE_STRING &&
5255
- f->file->syntax == UPB_SYNTAX_PROTO2) {
5256
- /* See TableDescriptorType() in upbc/generator.cc for details and
5257
- * rationale. */
5258
- field->descriptortype = UPB_DTYPE_BYTES;
5259
- }
5260
-
5261
- if (upb_fielddef_ismap(f)) {
5262
- field->label = _UPB_LABEL_MAP;
5263
- } else if (upb_fielddef_packed(f)) {
5264
- field->label = _UPB_LABEL_PACKED;
5265
- }
5568
+ fill_fieldlayout(field, f);
5266
5569
 
5267
5570
  if (upb_fielddef_issubmsg(f)) {
5268
5571
  const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
@@ -5338,54 +5641,11 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5338
5641
 
5339
5642
  /* Sort fields by number. */
5340
5643
  qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp);
5341
- assign_layout_indices(m, fields);
5342
- }
5343
-
5344
- static void assign_msg_indices(symtab_addctx *ctx, upb_msgdef *m) {
5345
- /* Sort fields. upb internally relies on UPB_TYPE_MESSAGE fields having the
5346
- * lowest indexes, but we do not publicly guarantee this. */
5347
- upb_msg_field_iter j;
5348
- int i;
5349
- uint32_t selector;
5350
- int n = upb_msgdef_numfields(m);
5351
- upb_fielddef **fields;
5352
-
5353
- if (n == 0) {
5354
- m->selector_count = UPB_STATIC_SELECTOR_COUNT;
5355
- m->submsg_field_count = 0;
5356
- return;
5357
- }
5358
-
5359
- fields = upb_gmalloc(n * sizeof(*fields));
5360
-
5361
- m->submsg_field_count = 0;
5362
- for(i = 0, upb_msg_field_begin(&j, m);
5363
- !upb_msg_field_done(&j);
5364
- upb_msg_field_next(&j), i++) {
5365
- upb_fielddef *f = upb_msg_iter_field(&j);
5366
- UPB_ASSERT(f->msgdef == m);
5367
- if (upb_fielddef_issubmsg(f)) {
5368
- m->submsg_field_count++;
5369
- }
5370
- fields[i] = f;
5371
- }
5372
-
5373
- qsort(fields, n, sizeof(*fields), cmp_fields);
5374
-
5375
- selector = UPB_STATIC_SELECTOR_COUNT + m->submsg_field_count;
5376
- for (i = 0; i < n; i++) {
5377
- upb_fielddef *f = fields[i];
5378
- f->index_ = i;
5379
- f->selector_base = selector + upb_handlers_selectorbaseoffset(f);
5380
- selector += upb_handlers_selectorcount(f);
5381
- }
5382
- m->selector_count = selector;
5383
-
5384
- upb_gfree(fields);
5644
+ assign_layout_indices(m, l, fields);
5385
5645
  }
5386
5646
 
5387
5647
  static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
5388
- return upb_strdup2(view.data, view.size, ctx->alloc);
5648
+ return upb_strdup2(view.data, view.size, ctx->arena);
5389
5649
  }
5390
5650
 
5391
5651
  static bool streql2(const char *a, size_t n, const char *b) {
@@ -5496,9 +5756,9 @@ static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) {
5496
5756
  if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
5497
5757
  symtab_errf(ctx, "duplicate symbol '%s'", name);
5498
5758
  }
5499
- upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena);
5500
5759
  size_t len = strlen(name);
5501
- CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc));
5760
+ CHK_OOM(upb_strtable_insert(&ctx->symtab->syms, name, len, v,
5761
+ ctx->symtab->arena));
5502
5762
  }
5503
5763
 
5504
5764
  /* Given a symbol and the base symbol inside which it is defined, find the
@@ -5531,7 +5791,8 @@ static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f,
5531
5791
  }
5532
5792
 
5533
5793
  notfound:
5534
- symtab_errf(ctx, "couldn't resolve name '%s'", sym.data);
5794
+ symtab_errf(ctx, "couldn't resolve name '" UPB_STRVIEW_FORMAT "'",
5795
+ UPB_STRVIEW_ARGS(sym));
5535
5796
  }
5536
5797
 
5537
5798
  static void create_oneofdef(
@@ -5549,10 +5810,10 @@ static void create_oneofdef(
5549
5810
 
5550
5811
  v = pack_def(o, UPB_DEFTYPE_ONEOF);
5551
5812
  symtab_add(ctx, o->full_name, v);
5552
- CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
5813
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
5553
5814
 
5554
- CHK_OOM(upb_inttable_init2(&o->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
5555
- CHK_OOM(upb_strtable_init2(&o->ntof, UPB_CTYPE_CONSTPTR, 4, ctx->alloc));
5815
+ CHK_OOM(upb_inttable_init(&o->itof, ctx->arena));
5816
+ CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena));
5556
5817
  }
5557
5818
 
5558
5819
  static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) {
@@ -5608,8 +5869,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5608
5869
  break;
5609
5870
  }
5610
5871
  case UPB_TYPE_INT64: {
5611
- /* XXX: Need to write our own strtoll, since it's not available in c89. */
5612
- int64_t val = strtol(str, &end, 0);
5872
+ long long val = strtoll(str, &end, 0);
5613
5873
  if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
5614
5874
  goto invalid;
5615
5875
  }
@@ -5625,8 +5885,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5625
5885
  break;
5626
5886
  }
5627
5887
  case UPB_TYPE_UINT64: {
5628
- /* XXX: Need to write our own strtoull, since it's not available in c89. */
5629
- uint64_t val = strtoul(str, &end, 0);
5888
+ unsigned long long val = strtoull(str, &end, 0);
5630
5889
  if (val > UINT64_MAX || errno == ERANGE || *end) {
5631
5890
  goto invalid;
5632
5891
  }
@@ -5642,8 +5901,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5642
5901
  break;
5643
5902
  }
5644
5903
  case UPB_TYPE_FLOAT: {
5645
- /* XXX: Need to write our own strtof, since it's not available in c89. */
5646
- float val = strtod(str, &end);
5904
+ float val = strtof(str, &end);
5647
5905
  if (errno == ERANGE || *end) {
5648
5906
  goto invalid;
5649
5907
  }
@@ -5709,7 +5967,6 @@ static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) {
5709
5967
  static void create_fielddef(
5710
5968
  symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
5711
5969
  const google_protobuf_FieldDescriptorProto *field_proto) {
5712
- upb_alloc *alloc = ctx->alloc;
5713
5970
  upb_fielddef *f;
5714
5971
  const google_protobuf_FieldOptions *options;
5715
5972
  upb_strview name;
@@ -5745,7 +6002,8 @@ static void create_fielddef(
5745
6002
  upb_value v, field_v, json_v;
5746
6003
  size_t json_size;
5747
6004
 
5748
- f = (upb_fielddef*)&m->fields[m->field_count++];
6005
+ f = (upb_fielddef*)&m->fields[m->field_count];
6006
+ f->index_ = m->field_count++;
5749
6007
  f->msgdef = m;
5750
6008
  f->is_extension_ = false;
5751
6009
 
@@ -5766,12 +6024,12 @@ static void create_fielddef(
5766
6024
  v = upb_value_constptr(f);
5767
6025
  json_size = strlen(json_name);
5768
6026
 
5769
- CHK_OOM(
5770
- upb_strtable_insert3(&m->ntof, name.data, name.size, field_v, alloc));
5771
- CHK_OOM(upb_inttable_insert2(&m->itof, field_number, v, alloc));
6027
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v,
6028
+ ctx->arena));
6029
+ CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena));
5772
6030
 
5773
6031
  if (strcmp(shortname, json_name) != 0) {
5774
- upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc);
6032
+ upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena);
5775
6033
  }
5776
6034
 
5777
6035
  if (ctx->layouts) {
@@ -5834,15 +6092,16 @@ static void create_fielddef(
5834
6092
  symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
5835
6093
  }
5836
6094
 
5837
- oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
6095
+ oneof = (upb_oneofdef *)&m->oneofs[oneof_index];
5838
6096
  f->oneof = oneof;
5839
6097
 
5840
6098
  oneof->field_count++;
5841
6099
  if (f->proto3_optional_) {
5842
6100
  oneof->synthetic = true;
5843
6101
  }
5844
- CHK_OOM(upb_inttable_insert2(&oneof->itof, f->number_, v, alloc));
5845
- CHK_OOM(upb_strtable_insert3(&oneof->ntof, name.data, name.size, v, alloc));
6102
+ CHK_OOM(upb_inttable_insert(&oneof->itof, f->number_, v, ctx->arena));
6103
+ CHK_OOM(
6104
+ upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena));
5846
6105
  } else {
5847
6106
  f->oneof = NULL;
5848
6107
  if (f->proto3_optional_) {
@@ -5885,8 +6144,8 @@ static void create_enumdef(
5885
6144
  symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
5886
6145
 
5887
6146
  values = google_protobuf_EnumDescriptorProto_value(enum_proto, &n);
5888
- CHK_OOM(upb_strtable_init2(&e->ntoi, UPB_CTYPE_INT32, n, ctx->alloc));
5889
- CHK_OOM(upb_inttable_init2(&e->iton, UPB_CTYPE_CSTR, ctx->alloc));
6147
+ CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena));
6148
+ CHK_OOM(upb_inttable_init(&e->iton, ctx->arena));
5890
6149
 
5891
6150
  e->file = ctx->file;
5892
6151
  e->defaultval = 0;
@@ -5913,16 +6172,15 @@ static void create_enumdef(
5913
6172
  }
5914
6173
 
5915
6174
  CHK_OOM(name2)
5916
- CHK_OOM(
5917
- upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
6175
+ CHK_OOM(upb_strtable_insert(&e->ntoi, name2, strlen(name2), v, ctx->arena));
5918
6176
 
5919
6177
  if (!upb_inttable_lookup(&e->iton, num, NULL)) {
5920
6178
  upb_value v = upb_value_cstr(name2);
5921
- CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
6179
+ CHK_OOM(upb_inttable_insert(&e->iton, num, v, ctx->arena));
5922
6180
  }
5923
6181
  }
5924
6182
 
5925
- upb_inttable_compact2(&e->iton, ctx->alloc);
6183
+ upb_inttable_compact(&e->iton, ctx->arena);
5926
6184
  }
5927
6185
 
5928
6186
  static void create_msgdef(symtab_addctx *ctx, const char *prefix,
@@ -5946,9 +6204,8 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
5946
6204
  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
5947
6205
  fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
5948
6206
 
5949
- CHK_OOM(upb_inttable_init2(&m->itof, UPB_CTYPE_CONSTPTR, ctx->alloc));
5950
- CHK_OOM(upb_strtable_init2(&m->ntof, UPB_CTYPE_CONSTPTR, n_oneof + n_field,
5951
- ctx->alloc));
6207
+ CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
6208
+ CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
5952
6209
 
5953
6210
  m->file = ctx->file;
5954
6211
  m->map_entry = false;
@@ -5980,10 +6237,9 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
5980
6237
  create_fielddef(ctx, m->full_name, m, fields[i]);
5981
6238
  }
5982
6239
 
5983
- assign_msg_indices(ctx, m);
5984
6240
  finalize_oneofs(ctx, m);
5985
6241
  assign_msg_wellknowntype(m);
5986
- upb_inttable_compact2(&m->itof, ctx->alloc);
6242
+ upb_inttable_compact(&m->itof, ctx->arena);
5987
6243
 
5988
6244
  /* This message is built. Now build nested messages and enums. */
5989
6245
 
@@ -6095,13 +6351,18 @@ static void build_filedef(
6095
6351
  const upb_strview* strs;
6096
6352
  size_t i, n;
6097
6353
 
6098
- count_types_in_file(file_proto, file);
6354
+ file->symtab = ctx->symtab;
6099
6355
 
6356
+ /* One pass to count and allocate. */
6357
+ file->msg_count = 0;
6358
+ file->enum_count = 0;
6359
+ file->ext_count = 0;
6360
+ count_types_in_file(file_proto, file);
6100
6361
  file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count);
6101
6362
  file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
6102
6363
  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
6103
6364
 
6104
- /* We increment these as defs are added. */
6365
+ /* In the second pass we increment these as defs are added. */
6105
6366
  file->msg_count = 0;
6106
6367
  file->enum_count = 0;
6107
6368
  file->ext_count = 0;
@@ -6212,61 +6473,61 @@ static void build_filedef(
6212
6473
  }
6213
6474
 
6214
6475
  static void remove_filedef(upb_symtab *s, upb_filedef *file) {
6215
- upb_alloc *alloc = upb_arena_alloc(s->arena);
6216
6476
  int i;
6217
6477
  for (i = 0; i < file->msg_count; i++) {
6218
6478
  const char *name = file->msgs[i].full_name;
6219
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6479
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6220
6480
  }
6221
6481
  for (i = 0; i < file->enum_count; i++) {
6222
6482
  const char *name = file->enums[i].full_name;
6223
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6483
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6224
6484
  }
6225
6485
  for (i = 0; i < file->ext_count; i++) {
6226
6486
  const char *name = file->exts[i].full_name;
6227
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6487
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6228
6488
  }
6229
6489
  }
6230
6490
 
6231
6491
  static const upb_filedef *_upb_symtab_addfile(
6232
6492
  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
6233
6493
  const upb_msglayout **layouts, upb_status *status) {
6234
- upb_arena *file_arena = upb_arena_new();
6235
- upb_filedef *file;
6236
6494
  symtab_addctx ctx;
6495
+ upb_strview name = google_protobuf_FileDescriptorProto_name(file_proto);
6237
6496
 
6238
- if (!file_arena) return NULL;
6239
-
6240
- file = upb_arena_malloc(file_arena, sizeof(*file));
6241
- if (!file) goto done;
6497
+ if (upb_strtable_lookup2(&s->files, name.data, name.size, NULL)) {
6498
+ upb_status_seterrf(status, "duplicate file name (%.*s)",
6499
+ UPB_STRVIEW_ARGS(name));
6500
+ return NULL;
6501
+ }
6242
6502
 
6243
- ctx.file = file;
6244
6503
  ctx.symtab = s;
6245
- ctx.file_arena = file_arena;
6246
- ctx.alloc = upb_arena_alloc(file_arena);
6247
6504
  ctx.layouts = layouts;
6248
6505
  ctx.status = status;
6506
+ ctx.file = NULL;
6507
+ ctx.arena = upb_arena_new();
6249
6508
 
6250
- file->msg_count = 0;
6251
- file->enum_count = 0;
6252
- file->ext_count = 0;
6253
- file->symtab = s;
6509
+ if (!ctx.arena) {
6510
+ upb_status_setoom(status);
6511
+ return NULL;
6512
+ }
6254
6513
 
6255
6514
  if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
6256
6515
  UPB_ASSERT(!upb_ok(status));
6257
- remove_filedef(s, file);
6258
- file = NULL;
6516
+ if (ctx.file) {
6517
+ remove_filedef(s, ctx.file);
6518
+ ctx.file = NULL;
6519
+ }
6259
6520
  } else {
6260
- build_filedef(&ctx, file, file_proto);
6261
- upb_strtable_insert3(&s->files, file->name, strlen(file->name),
6262
- upb_value_constptr(file), ctx.alloc);
6521
+ ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file));
6522
+ build_filedef(&ctx, ctx.file, file_proto);
6523
+ upb_strtable_insert(&s->files, name.data, name.size,
6524
+ upb_value_constptr(ctx.file), ctx.arena);
6263
6525
  UPB_ASSERT(upb_ok(status));
6264
- upb_arena_fuse(s->arena, file_arena);
6526
+ upb_arena_fuse(s->arena, ctx.arena);
6265
6527
  }
6266
6528
 
6267
- done:
6268
- upb_arena_free(file_arena);
6269
- return file;
6529
+ upb_arena_free(ctx.arena);
6530
+ return ctx.file;
6270
6531
  }
6271
6532
 
6272
6533
  const upb_filedef *upb_symtab_addfile(
@@ -6299,7 +6560,8 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
6299
6560
  }
6300
6561
 
6301
6562
  file = google_protobuf_FileDescriptorProto_parse_ex(
6302
- init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS);
6563
+ init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS,
6564
+ arena);
6303
6565
  s->bytes_loaded += init->descriptor.size;
6304
6566
 
6305
6567
  if (!file) {
@@ -6333,6 +6595,7 @@ upb_arena *_upb_symtab_arena(const upb_symtab *s) {
6333
6595
 
6334
6596
  #undef CHK_OOM
6335
6597
 
6598
+ /** upb/reflection.c ************************************************************/
6336
6599
 
6337
6600
  #include <string.h>
6338
6601
 
@@ -6443,40 +6706,7 @@ upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
6443
6706
  if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
6444
6707
  return _upb_msg_getraw(msg, f);
6445
6708
  } else {
6446
- /* TODO(haberman): change upb_fielddef to not require this switch(). */
6447
- upb_msgval val = {0};
6448
- switch (upb_fielddef_type(f)) {
6449
- case UPB_TYPE_INT32:
6450
- case UPB_TYPE_ENUM:
6451
- val.int32_val = upb_fielddef_defaultint32(f);
6452
- break;
6453
- case UPB_TYPE_INT64:
6454
- val.int64_val = upb_fielddef_defaultint64(f);
6455
- break;
6456
- case UPB_TYPE_UINT32:
6457
- val.uint32_val = upb_fielddef_defaultuint32(f);
6458
- break;
6459
- case UPB_TYPE_UINT64:
6460
- val.uint64_val = upb_fielddef_defaultuint64(f);
6461
- break;
6462
- case UPB_TYPE_FLOAT:
6463
- val.float_val = upb_fielddef_defaultfloat(f);
6464
- break;
6465
- case UPB_TYPE_DOUBLE:
6466
- val.double_val = upb_fielddef_defaultdouble(f);
6467
- break;
6468
- case UPB_TYPE_BOOL:
6469
- val.bool_val = upb_fielddef_defaultbool(f);
6470
- break;
6471
- case UPB_TYPE_STRING:
6472
- case UPB_TYPE_BYTES:
6473
- val.str_val.data = upb_fielddef_defaultstr(f, &val.str_val.size);
6474
- break;
6475
- case UPB_TYPE_MESSAGE:
6476
- val.msg_val = NULL;
6477
- break;
6478
- }
6479
- return val;
6709
+ return upb_fielddef_default(f);
6480
6710
  }
6481
6711
  }
6482
6712
 
@@ -6736,6 +6966,7 @@ upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
6736
6966
 
6737
6967
  /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
6738
6968
 
6969
+ /** upb/json_decode.c ************************************************************/
6739
6970
 
6740
6971
  #include <errno.h>
6741
6972
  #include <float.h>
@@ -7646,17 +7877,17 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7646
7877
  return;
7647
7878
  }
7648
7879
 
7649
- if (upb_fielddef_realcontainingoneof(f) &&
7650
- upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
7651
- jsondec_err(d, "More than one field for this oneof.");
7652
- }
7653
-
7654
7880
  if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
7655
7881
  /* JSON "null" indicates a default value, so no need to set anything. */
7656
7882
  jsondec_null(d);
7657
7883
  return;
7658
7884
  }
7659
7885
 
7886
+ if (upb_fielddef_realcontainingoneof(f) &&
7887
+ upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
7888
+ jsondec_err(d, "More than one field for this oneof.");
7889
+ }
7890
+
7660
7891
  preserved = d->debug_field;
7661
7892
  d->debug_field = f;
7662
7893
 
@@ -8160,6 +8391,9 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
8160
8391
  const upb_msgdef *m, const upb_symtab *any_pool,
8161
8392
  int options, upb_arena *arena, upb_status *status) {
8162
8393
  jsondec d;
8394
+
8395
+ if (size == 0) return true;
8396
+
8163
8397
  d.ptr = buf;
8164
8398
  d.end = buf + size;
8165
8399
  d.arena = arena;
@@ -8178,6 +8412,7 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
8178
8412
  return true;
8179
8413
  }
8180
8414
 
8415
+ /** upb/json_encode.c ************************************************************/
8181
8416
 
8182
8417
  #include <ctype.h>
8183
8418
  #include <float.h>
@@ -8207,7 +8442,7 @@ static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f);
8207
8442
  static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
8208
8443
  const upb_msgdef *m);
8209
8444
  static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8210
- const upb_msgdef *m);
8445
+ const upb_msgdef *m, bool first);
8211
8446
  static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
8212
8447
 
8213
8448
  UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
@@ -8238,8 +8473,10 @@ static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) {
8238
8473
  memcpy(e->ptr, data, len);
8239
8474
  e->ptr += len;
8240
8475
  } else {
8241
- if (have) memcpy(e->ptr, data, have);
8242
- e->ptr += have;
8476
+ if (have) {
8477
+ memcpy(e->ptr, data, have);
8478
+ e->ptr += have;
8479
+ }
8243
8480
  e->overflow += (len - have);
8244
8481
  }
8245
8482
  }
@@ -8261,7 +8498,7 @@ static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
8261
8498
  if (UPB_LIKELY(have > n)) {
8262
8499
  e->ptr += n;
8263
8500
  } else {
8264
- e->ptr += have;
8501
+ e->ptr = UPB_PTRADD(e->ptr, have);
8265
8502
  e->overflow += (n - have);
8266
8503
  }
8267
8504
  }
@@ -8365,7 +8602,7 @@ static void jsonenc_bytes(jsonenc *e, upb_strview str) {
8365
8602
  static const char base64[] =
8366
8603
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8367
8604
  const unsigned char *ptr = (unsigned char*)str.data;
8368
- const unsigned char *end = ptr + str.size;
8605
+ const unsigned char *end = UPB_PTRADD(ptr, str.size);
8369
8606
  char buf[4];
8370
8607
 
8371
8608
  jsonenc_putstr(e, "\"");
@@ -8401,7 +8638,7 @@ static void jsonenc_bytes(jsonenc *e, upb_strview str) {
8401
8638
 
8402
8639
  static void jsonenc_stringbody(jsonenc *e, upb_strview str) {
8403
8640
  const char *ptr = str.data;
8404
- const char *end = ptr + str.size;
8641
+ const char *end = UPB_PTRADD(ptr, str.size);
8405
8642
 
8406
8643
  while (ptr < end) {
8407
8644
  switch (*ptr) {
@@ -8454,7 +8691,17 @@ static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
8454
8691
  } else if (val != val) {
8455
8692
  jsonenc_putstr(e, "\"NaN\"");
8456
8693
  } else {
8694
+ char *p = e->ptr;
8457
8695
  jsonenc_printf(e, fmt, val);
8696
+
8697
+ /* printf() is dependent on locales; sadly there is no easy and portable way
8698
+ * to avoid this. This little post-processing step will translate 1,2 -> 1.2
8699
+ * since JSON needs the latter. Arguably a hack, but it is simple and the
8700
+ * alternatives are far more complicated, platform-dependent, and/or larger
8701
+ * in code size. */
8702
+ for (char *end = e->ptr; p < end; p++) {
8703
+ if (*p == ',') *p = '.';
8704
+ }
8458
8705
  }
8459
8706
  }
8460
8707
 
@@ -8517,14 +8764,13 @@ static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8517
8764
 
8518
8765
  jsonenc_putstr(e, "{\"@type\":");
8519
8766
  jsonenc_string(e, type_url);
8520
- jsonenc_putstr(e, ",");
8521
8767
 
8522
8768
  if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) {
8523
8769
  /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
8524
- jsonenc_msgfields(e, any, any_m);
8770
+ jsonenc_msgfields(e, any, any_m, false);
8525
8771
  } else {
8526
8772
  /* Well-known type: {"@type": "...","value": <well-known encoding>} */
8527
- jsonenc_putstr(e, "\"value\":");
8773
+ jsonenc_putstr(e, ",\"value\":");
8528
8774
  jsonenc_msgfield(e, any, any_m);
8529
8775
  }
8530
8776
 
@@ -8827,10 +9073,9 @@ static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
8827
9073
  }
8828
9074
 
8829
9075
  static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8830
- const upb_msgdef *m) {
9076
+ const upb_msgdef *m, bool first) {
8831
9077
  upb_msgval val;
8832
9078
  const upb_fielddef *f;
8833
- bool first = true;
8834
9079
 
8835
9080
  if (e->options & UPB_JSONENC_EMITDEFAULTS) {
8836
9081
  /* Iterate over all fields. */
@@ -8853,7 +9098,7 @@ static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8853
9098
 
8854
9099
  static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8855
9100
  jsonenc_putstr(e, "{");
8856
- jsonenc_msgfields(e, msg, m);
9101
+ jsonenc_msgfields(e, msg, m, true);
8857
9102
  jsonenc_putstr(e, "}");
8858
9103
  }
8859
9104
 
@@ -8875,7 +9120,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
8875
9120
 
8876
9121
  e.buf = buf;
8877
9122
  e.ptr = buf;
8878
- e.end = buf + size;
9123
+ e.end = UPB_PTRADD(buf, size);
8879
9124
  e.overflow = 0;
8880
9125
  e.options = options;
8881
9126
  e.ext_pool = ext_pool;
@@ -8888,27 +9133,39 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
8888
9133
  if (e.arena) upb_arena_free(e.arena);
8889
9134
  return jsonenc_nullz(&e, size);
8890
9135
  }
9136
+
9137
+ /** upb/port_undef.inc ************************************************************/
8891
9138
  /* See port_def.inc. This should #undef all macros #defined there. */
8892
9139
 
8893
- #undef UPB_MAPTYPE_STRING
8894
9140
  #undef UPB_SIZE
8895
9141
  #undef UPB_PTR_AT
8896
9142
  #undef UPB_READ_ONEOF
8897
9143
  #undef UPB_WRITE_ONEOF
9144
+ #undef UPB_MAPTYPE_STRING
8898
9145
  #undef UPB_INLINE
8899
9146
  #undef UPB_ALIGN_UP
8900
9147
  #undef UPB_ALIGN_DOWN
8901
9148
  #undef UPB_ALIGN_MALLOC
8902
9149
  #undef UPB_ALIGN_OF
9150
+ #undef UPB_LIKELY
9151
+ #undef UPB_UNLIKELY
8903
9152
  #undef UPB_FORCEINLINE
8904
9153
  #undef UPB_NOINLINE
8905
9154
  #undef UPB_NORETURN
9155
+ #undef UPB_PRINTF
8906
9156
  #undef UPB_MAX
8907
9157
  #undef UPB_MIN
8908
9158
  #undef UPB_UNUSED
8909
9159
  #undef UPB_ASSUME
8910
9160
  #undef UPB_ASSERT
8911
9161
  #undef UPB_UNREACHABLE
9162
+ #undef UPB_SETJMP
9163
+ #undef UPB_LONGJMP
9164
+ #undef UPB_PTRADD
9165
+ #undef UPB_MUSTTAIL
9166
+ #undef UPB_FASTTABLE_SUPPORTED
9167
+ #undef UPB_FASTTABLE
9168
+ #undef UPB_FASTTABLE_INIT
8912
9169
  #undef UPB_POISON_MEMORY_REGION
8913
9170
  #undef UPB_UNPOISON_MEMORY_REGION
8914
9171
  #undef UPB_ASAN