google-protobuf 3.17.0-x64-mingw32 → 3.17.1-x64-mingw32

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3880048d2f39d377cc9e3ffcdd8f0f46c9f21606e18ef8764642e253f767dd90
4
- data.tar.gz: d0eed474cbbd100f8a5ac624941b3319aa3029b953805e064c5ad4653022fbb0
3
+ metadata.gz: 959b565c78f77dbcde28d1db46164ab5b8575cfa757ee2ba827c8a5d2ec7944c
4
+ data.tar.gz: ea5e298ef9f1f1a87ad00fd09d817f1e71c37d4b504157e149194198050ece0b
5
5
  SHA512:
6
- metadata.gz: 1fa29b9521b5d22a5137b5546808ec8aebfb6f7f3e21f7db137069e427c0dbc6e771aa40bc6e0eecbd0867534d78ca5e3d756374baacce8f867c38d28ab8a3ea
7
- data.tar.gz: d794445f84cfa7d3c79fd2e277ef513c82d6680961ec6e301509827f235ea36bb50b4e70dfbd8e1316acea73c1649f2f33eacc60ad583689278cfbeefd18eb49
6
+ metadata.gz: e16842901e10a17a63a726cac510413107c78d18fd94a7625e54fe903d7c8d8fe03b3a189504a849073c50032d5f609cfff0275b6a533ed74d88bb6fdb497c52
7
+ data.tar.gz: 7094846c4925b7eed0859b0165db60d017439057d8e7b91aede3f68e54c9e923065cb3c15cd970744c49c320547ca78a0cef25f22f57295e12f7c4ae38b2ead2
@@ -167,7 +167,8 @@ VALUE Map_deep_copy(VALUE obj) {
167
167
  new_arena_rb);
168
168
  }
169
169
 
170
- const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef *field) {
170
+ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field,
171
+ upb_arena* arena) {
171
172
  const upb_fielddef* key_field = map_field_key(field);
172
173
  const upb_fielddef* value_field = map_field_value(field);
173
174
  TypeInfo value_type_info = TypeInfo_get(value_field);
@@ -189,6 +190,7 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef *field) {
189
190
  rb_raise(cTypeError, "Map value type has wrong message/enum class");
190
191
  }
191
192
 
193
+ Arena_fuse(self->arena, arena);
192
194
  return self->map;
193
195
  }
194
196
 
@@ -236,7 +238,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
236
238
  upb_msg *self_msg = Map_GetMutable(_self);
237
239
  size_t iter = UPB_MAP_BEGIN;
238
240
 
239
- upb_arena_fuse(arena, Arena_get(other->arena));
241
+ Arena_fuse(other->arena, arena);
240
242
 
241
243
  if (self->key_type != other->key_type ||
242
244
  self->value_type_info.type != other->value_type_info.type ||
@@ -511,7 +513,7 @@ static VALUE Map_dup(VALUE _self) {
511
513
  upb_arena *arena = Arena_get(new_self->arena);
512
514
  upb_map *new_map = Map_GetMutable(new_map_rb);
513
515
 
514
- upb_arena_fuse(arena, Arena_get(self->arena));
516
+ Arena_fuse(self->arena, arena);
515
517
 
516
518
  while (upb_mapiter_next(self->map, &iter)) {
517
519
  upb_msgval key = upb_mapiter_key(self->map, iter);
@@ -44,7 +44,8 @@ VALUE Map_GetRubyWrapper(upb_map *map, upb_fieldtype_t key_type,
44
44
  // Gets the underlying upb_map for this Ruby map object, which must have
45
45
  // key/value type that match |field|. If this is not a map or the type doesn't
46
46
  // match, raises an exception.
47
- const upb_map *Map_GetUpbMap(VALUE val, const upb_fielddef *field);
47
+ const upb_map *Map_GetUpbMap(VALUE val, const upb_fielddef *field,
48
+ upb_arena *arena);
48
49
 
49
50
  // Implements #inspect for this map by appending its contents to |b|.
50
51
  void Map_Inspect(StringBuilder *b, const upb_map *map, upb_fieldtype_t key_type,
@@ -277,9 +277,9 @@ static void Message_setfield(upb_msg* msg, const upb_fielddef* f, VALUE val,
277
277
  upb_arena* arena) {
278
278
  upb_msgval msgval;
279
279
  if (upb_fielddef_ismap(f)) {
280
- msgval.map_val = Map_GetUpbMap(val, f);
280
+ msgval.map_val = Map_GetUpbMap(val, f, arena);
281
281
  } else if (upb_fielddef_isseq(f)) {
282
- msgval.array_val = RepeatedField_GetUpbArray(val, f);
282
+ msgval.array_val = RepeatedField_GetUpbArray(val, f, arena);
283
283
  } else {
284
284
  if (val == Qnil &&
285
285
  (upb_fielddef_issubmsg(f) || upb_fielddef_realcontainingoneof(f))) {
@@ -660,7 +660,7 @@ static VALUE Message_dup(VALUE _self) {
660
660
  // TODO(copy unknown fields?)
661
661
  // TODO(use official upb msg copy function)
662
662
  memcpy((upb_msg*)new_msg_self->msg, self->msg, size);
663
- upb_arena_fuse(Arena_get(new_msg_self->arena), Arena_get(self->arena));
663
+ Arena_fuse(self->arena, Arena_get(new_msg_self->arena));
664
664
  return new_msg;
665
665
  }
666
666
 
@@ -794,6 +794,14 @@ static VALUE Message_CreateHash(const upb_msg *msg, const upb_msgdef *m) {
794
794
  VALUE msg_value;
795
795
  VALUE msg_key;
796
796
 
797
+ if (!is_proto2 && upb_fielddef_issubmsg(field) &&
798
+ !upb_fielddef_isseq(field) && !upb_msg_has(msg, field)) {
799
+ // TODO: Legacy behavior, remove when we fix the is_proto2 differences.
800
+ msg_key = ID2SYM(rb_intern(upb_fielddef_name(field)));
801
+ rb_hash_aset(hash, msg_key, Qnil);
802
+ continue;
803
+ }
804
+
797
805
  // Do not include fields that are not present (oneof or optional fields).
798
806
  if (is_proto2 && upb_fielddef_haspresence(field) &&
799
807
  !upb_msg_has(msg, field)) {
@@ -1306,7 +1314,7 @@ const upb_msg* Message_GetUpbMessage(VALUE value, const upb_msgdef* m,
1306
1314
  }
1307
1315
 
1308
1316
  Message* self = ruby_to_Message(value);
1309
- upb_arena_fuse(arena, Arena_get(self->arena));
1317
+ Arena_fuse(self->arena, arena);
1310
1318
 
1311
1319
  return self->msg;
1312
1320
  }
@@ -204,6 +204,16 @@ upb_arena *Arena_get(VALUE _arena) {
204
204
  return arena->arena;
205
205
  }
206
206
 
207
+ void Arena_fuse(VALUE _arena, upb_arena *other) {
208
+ Arena *arena;
209
+ TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
210
+ if (!upb_arena_fuse(arena->arena, other)) {
211
+ rb_raise(rb_eRuntimeError,
212
+ "Unable to fuse arenas. This should never happen since Ruby does "
213
+ "not use initial blocks");
214
+ }
215
+ }
216
+
207
217
  VALUE Arena_new() {
208
218
  return Arena_alloc(cArena);
209
219
  }
@@ -55,6 +55,10 @@ const upb_fielddef* map_field_value(const upb_fielddef* field);
55
55
  VALUE Arena_new();
56
56
  upb_arena *Arena_get(VALUE arena);
57
57
 
58
+ // Fuses this arena to another, throwing a Ruby exception if this is not
59
+ // possible.
60
+ void Arena_fuse(VALUE arena, upb_arena *other);
61
+
58
62
  // Pins this Ruby object to the lifetime of this arena, so that as long as the
59
63
  // arena is alive this object will not be collected.
60
64
  //
@@ -149,7 +149,8 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
149
149
  return new_rptfield;
150
150
  }
151
151
 
152
- const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef *field) {
152
+ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field,
153
+ upb_arena* arena) {
153
154
  RepeatedField* self;
154
155
  TypeInfo type_info = TypeInfo_get(field);
155
156
 
@@ -167,6 +168,7 @@ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef *field)
167
168
  rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
168
169
  }
169
170
 
171
+ Arena_fuse(self->arena, arena);
170
172
  return self->array;
171
173
  }
172
174
 
@@ -412,7 +414,7 @@ static VALUE RepeatedField_dup(VALUE _self) {
412
414
  int size = upb_array_size(self->array);
413
415
  int i;
414
416
 
415
- upb_arena_fuse(arena, Arena_get(self->arena));
417
+ Arena_fuse(self->arena, arena);
416
418
 
417
419
  for (i = 0; i < size; i++) {
418
420
  upb_msgval msgval = upb_array_get(self->array, i);
@@ -44,7 +44,8 @@ VALUE RepeatedField_GetRubyWrapper(upb_array* msg, TypeInfo type_info,
44
44
  // Gets the underlying upb_array for this Ruby RepeatedField object, which must
45
45
  // have a type that matches |f|. If this is not a repeated field or the type
46
46
  // doesn't match, raises an exception.
47
- const upb_array* RepeatedField_GetUpbArray(VALUE value, const upb_fielddef* f);
47
+ const upb_array* RepeatedField_GetUpbArray(VALUE value, const upb_fielddef* f,
48
+ upb_arena* arena);
48
49
 
49
50
  // Implements #inspect for this repeated field by appending its contents to |b|.
50
51
  void RepeatedField_Inspect(StringBuilder* b, const upb_array* array,
@@ -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>
@@ -891,7 +950,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
891
950
  state.end_group = DECODE_NOGROUP;
892
951
  state.arena.head = arena->head;
893
952
  state.arena.last_size = arena->last_size;
894
- state.arena.cleanups = arena->cleanups;
953
+ state.arena.cleanup_metadata = arena->cleanup_metadata;
895
954
  state.arena.parent = arena;
896
955
 
897
956
  if (UPB_UNLIKELY(UPB_SETJMP(state.err))) {
@@ -902,7 +961,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
902
961
 
903
962
  arena->head.ptr = state.arena.head.ptr;
904
963
  arena->head.end = state.arena.head.end;
905
- arena->cleanups = state.arena.cleanups;
964
+ arena->cleanup_metadata = state.arena.cleanup_metadata;
906
965
  return ok;
907
966
  }
908
967
 
@@ -911,6 +970,8 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
911
970
  #undef OP_VARPCK_LG2
912
971
  #undef OP_STRING
913
972
  #undef OP_SUBMSG
973
+
974
+ /** upb/encode.c ************************************************************/
914
975
  /* We encode backwards, to avoid pre-computing lengths (one-pass encode). */
915
976
 
916
977
 
@@ -1386,7 +1447,7 @@ char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
1386
1447
  return ret;
1387
1448
  }
1388
1449
 
1389
-
1450
+ /** upb/msg.c ************************************************************/
1390
1451
 
1391
1452
 
1392
1453
  /** upb_msg *******************************************************************/
@@ -1517,7 +1578,7 @@ upb_map *_upb_map_new(upb_arena *a, size_t key_size, size_t value_size) {
1517
1578
  return NULL;
1518
1579
  }
1519
1580
 
1520
- upb_strtable_init2(&map->table, UPB_CTYPE_INT32, 4, upb_arena_alloc(a));
1581
+ upb_strtable_init(&map->table, 4, a);
1521
1582
  map->key_size = key_size;
1522
1583
  map->val_size = value_size;
1523
1584
 
@@ -1638,11 +1699,13 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
1638
1699
  qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar);
1639
1700
  return true;
1640
1701
  }
1702
+
1703
+ /** upb/table.c ************************************************************/
1641
1704
  /*
1642
- ** upb_table Implementation
1643
- **
1644
- ** Implementation is heavily inspired by Lua's ltable.c.
1645
- */
1705
+ * upb_table Implementation
1706
+ *
1707
+ * Implementation is heavily inspired by Lua's ltable.c.
1708
+ */
1646
1709
 
1647
1710
  #include <string.h>
1648
1711
 
@@ -1663,9 +1726,15 @@ static const double MAX_LOAD = 0.85;
1663
1726
  * cache effects). The lower this is, the more memory we'll use. */
1664
1727
  static const double MIN_DENSITY = 0.1;
1665
1728
 
1666
- bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1729
+ static bool is_pow2(uint64_t v) { return v == 0 || (v & (v - 1)) == 0; }
1667
1730
 
1668
- int log2ceil(uint64_t v) {
1731
+ static upb_value _upb_value_val(uint64_t val) {
1732
+ upb_value ret;
1733
+ _upb_value_setval(&ret, val);
1734
+ return ret;
1735
+ }
1736
+
1737
+ static int log2ceil(uint64_t v) {
1669
1738
  int ret = 0;
1670
1739
  bool pow2 = is_pow2(v);
1671
1740
  while (v >>= 1) ret++;
@@ -1673,11 +1742,7 @@ int log2ceil(uint64_t v) {
1673
1742
  return UPB_MIN(UPB_MAXARRSIZE, ret);
1674
1743
  }
1675
1744
 
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) {
1745
+ char *upb_strdup2(const char *s, size_t len, upb_arena *a) {
1681
1746
  size_t n;
1682
1747
  char *p;
1683
1748
 
@@ -1686,7 +1751,7 @@ char *upb_strdup2(const char *s, size_t len, upb_alloc *a) {
1686
1751
  /* Always null-terminate, even if binary data; but don't rely on the input to
1687
1752
  * have a null-terminating byte since it may be a raw binary buffer. */
1688
1753
  n = len + 1;
1689
- p = upb_malloc(a, n);
1754
+ p = upb_arena_malloc(a, n);
1690
1755
  if (p) {
1691
1756
  memcpy(p, s, len);
1692
1757
  p[len] = 0;
@@ -1721,16 +1786,24 @@ typedef bool eqlfunc_t(upb_tabkey k1, lookupkey_t k2);
1721
1786
 
1722
1787
  /* Base table (shared code) ***************************************************/
1723
1788
 
1724
- /* For when we need to cast away const. */
1725
- static upb_tabent *mutable_entries(upb_table *t) {
1726
- return (upb_tabent*)t->entries;
1789
+ static uint32_t upb_inthash(uintptr_t key) {
1790
+ return (uint32_t)key;
1791
+ }
1792
+
1793
+ static const upb_tabent *upb_getentry(const upb_table *t, uint32_t hash) {
1794
+ return t->entries + (hash & t->mask);
1795
+ }
1796
+
1797
+ static bool upb_arrhas(upb_tabval key) {
1798
+ return key.val != (uint64_t)-1;
1727
1799
  }
1728
1800
 
1801
+
1729
1802
  static bool isfull(upb_table *t) {
1730
1803
  return t->count == t->max_count;
1731
1804
  }
1732
1805
 
1733
- static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1806
+ static bool init(upb_table *t, uint8_t size_lg2, upb_arena *a) {
1734
1807
  size_t bytes;
1735
1808
 
1736
1809
  t->count = 0;
@@ -1739,21 +1812,17 @@ static bool init(upb_table *t, uint8_t size_lg2, upb_alloc *a) {
1739
1812
  t->max_count = upb_table_size(t) * MAX_LOAD;
1740
1813
  bytes = upb_table_size(t) * sizeof(upb_tabent);
1741
1814
  if (bytes > 0) {
1742
- t->entries = upb_malloc(a, bytes);
1815
+ t->entries = upb_arena_malloc(a, bytes);
1743
1816
  if (!t->entries) return false;
1744
- memset(mutable_entries(t), 0, bytes);
1817
+ memset(t->entries, 0, bytes);
1745
1818
  } else {
1746
1819
  t->entries = NULL;
1747
1820
  }
1748
1821
  return true;
1749
1822
  }
1750
1823
 
1751
- static void uninit(upb_table *t, upb_alloc *a) {
1752
- upb_free(a, mutable_entries(t));
1753
- }
1754
-
1755
1824
  static upb_tabent *emptyent(upb_table *t, upb_tabent *e) {
1756
- upb_tabent *begin = mutable_entries(t);
1825
+ upb_tabent *begin = t->entries;
1757
1826
  upb_tabent *end = begin + upb_table_size(t);
1758
1827
  for (e = e + 1; e < end; e++) {
1759
1828
  if (upb_tabent_isempty(e)) return e;
@@ -1903,9 +1972,9 @@ static size_t begin(const upb_table *t) {
1903
1972
 
1904
1973
  /* A simple "subclass" of upb_table that only adds a hash function for strings. */
1905
1974
 
1906
- static upb_tabkey strcopy(lookupkey_t k2, upb_alloc *a) {
1975
+ static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) {
1907
1976
  uint32_t len = (uint32_t) k2.str.len;
1908
- char *str = upb_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
1977
+ char *str = upb_arena_malloc(a, k2.str.len + sizeof(uint32_t) + 1);
1909
1978
  if (str == NULL) return 0;
1910
1979
  memcpy(str, &len, sizeof(uint32_t));
1911
1980
  if (k2.str.len) memcpy(str + sizeof(uint32_t), k2.str.str, k2.str.len);
@@ -1929,9 +1998,7 @@ static bool streql(upb_tabkey k1, lookupkey_t k2) {
1929
1998
  return len == k2.str.len && (len == 0 || memcmp(str, k2.str.str, len) == 0);
1930
1999
  }
1931
2000
 
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 */
2001
+ bool upb_strtable_init(upb_strtable *t, size_t expected_size, upb_arena *a) {
1935
2002
  // Multiply by approximate reciprocal of MAX_LOAD (0.85), with pow2 denominator.
1936
2003
  size_t need_entries = (expected_size + 1) * 1204 / 1024;
1937
2004
  UPB_ASSERT(need_entries >= expected_size * 0.85);
@@ -1945,14 +2012,7 @@ void upb_strtable_clear(upb_strtable *t) {
1945
2012
  memset((char*)t->t.entries, 0, bytes);
1946
2013
  }
1947
2014
 
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) {
2015
+ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_arena *a) {
1956
2016
  upb_strtable new_table;
1957
2017
  upb_strtable_iter i;
1958
2018
 
@@ -1961,17 +2021,15 @@ bool upb_strtable_resize(upb_strtable *t, size_t size_lg2, upb_alloc *a) {
1961
2021
  upb_strtable_begin(&i, t);
1962
2022
  for ( ; !upb_strtable_done(&i); upb_strtable_next(&i)) {
1963
2023
  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);
2024
+ upb_strtable_insert(&new_table, key.data, key.size,
2025
+ upb_strtable_iter_value(&i), a);
1967
2026
  }
1968
- upb_strtable_uninit2(t, a);
1969
2027
  *t = new_table;
1970
2028
  return true;
1971
2029
  }
1972
2030
 
1973
- bool upb_strtable_insert3(upb_strtable *t, const char *k, size_t len,
1974
- upb_value v, upb_alloc *a) {
2031
+ bool upb_strtable_insert(upb_strtable *t, const char *k, size_t len,
2032
+ upb_value v, upb_arena *a) {
1975
2033
  lookupkey_t key;
1976
2034
  upb_tabkey tabkey;
1977
2035
  uint32_t hash;
@@ -1998,19 +2056,11 @@ bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len,
1998
2056
  return lookup(&t->t, strkey2(key, len), v, hash, &streql);
1999
2057
  }
2000
2058
 
2001
- bool upb_strtable_remove3(upb_strtable *t, const char *key, size_t len,
2002
- upb_value *val, upb_alloc *alloc) {
2059
+ bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len,
2060
+ upb_value *val) {
2003
2061
  uint32_t hash = table_hash(key, len);
2004
2062
  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
- }
2063
+ return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql);
2014
2064
  }
2015
2065
 
2016
2066
  /* Iteration */
@@ -2108,7 +2158,7 @@ static void check(upb_inttable *t) {
2108
2158
  }
2109
2159
 
2110
2160
  bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2111
- upb_alloc *a) {
2161
+ upb_arena *a) {
2112
2162
  size_t array_bytes;
2113
2163
 
2114
2164
  if (!init(&t->t, hsize_lg2, a)) return false;
@@ -2117,9 +2167,8 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2117
2167
  t->array_size = UPB_MAX(1, asize);
2118
2168
  t->array_count = 0;
2119
2169
  array_bytes = t->array_size * sizeof(upb_value);
2120
- t->array = upb_malloc(a, array_bytes);
2170
+ t->array = upb_arena_malloc(a, array_bytes);
2121
2171
  if (!t->array) {
2122
- uninit(&t->t, a);
2123
2172
  return false;
2124
2173
  }
2125
2174
  memset(mutable_array(t), 0xff, array_bytes);
@@ -2127,18 +2176,12 @@ bool upb_inttable_sizedinit(upb_inttable *t, size_t asize, int hsize_lg2,
2127
2176
  return true;
2128
2177
  }
2129
2178
 
2130
- bool upb_inttable_init2(upb_inttable *t, upb_ctype_t ctype, upb_alloc *a) {
2131
- UPB_UNUSED(ctype); /* TODO(haberman): rm */
2179
+ bool upb_inttable_init(upb_inttable *t, upb_arena *a) {
2132
2180
  return upb_inttable_sizedinit(t, 0, 4, a);
2133
2181
  }
2134
2182
 
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) {
2183
+ bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val,
2184
+ upb_arena *a) {
2142
2185
  upb_tabval tabval;
2143
2186
  tabval.val = val.val;
2144
2187
  UPB_ASSERT(upb_arrhas(tabval)); /* This will reject (uint64_t)-1. Fix this. */
@@ -2169,7 +2212,6 @@ bool upb_inttable_insert2(upb_inttable *t, uintptr_t key, upb_value val,
2169
2212
 
2170
2213
  UPB_ASSERT(t->t.count == new_table.count);
2171
2214
 
2172
- uninit(&t->t, a);
2173
2215
  t->t = new_table;
2174
2216
  }
2175
2217
  insert(&t->t, intkey(key), key, val, upb_inthash(key), &inthash, &inteql);
@@ -2213,21 +2255,7 @@ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val) {
2213
2255
  return success;
2214
2256
  }
2215
2257
 
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) {
2258
+ void upb_inttable_compact(upb_inttable *t, upb_arena *a) {
2231
2259
  /* A power-of-two histogram of the table keys. */
2232
2260
  size_t counts[UPB_MAXARRSIZE + 1] = {0};
2233
2261
 
@@ -2275,12 +2303,11 @@ void upb_inttable_compact2(upb_inttable *t, upb_alloc *a) {
2275
2303
  upb_inttable_begin(&i, t);
2276
2304
  for (; !upb_inttable_done(&i); upb_inttable_next(&i)) {
2277
2305
  uintptr_t k = upb_inttable_iter_key(&i);
2278
- upb_inttable_insert2(&new_t, k, upb_inttable_iter_value(&i), a);
2306
+ upb_inttable_insert(&new_t, k, upb_inttable_iter_value(&i), a);
2279
2307
  }
2280
2308
  UPB_ASSERT(new_t.array_size == arr_size);
2281
2309
  UPB_ASSERT(new_t.t.size_lg2 == hashsize_lg2);
2282
2310
  }
2283
- upb_inttable_uninit2(t, a);
2284
2311
  *t = new_t;
2285
2312
  }
2286
2313
 
@@ -2354,6 +2381,7 @@ bool upb_inttable_iter_isequal(const upb_inttable_iter *i1,
2354
2381
  i1->array_part == i2->array_part;
2355
2382
  }
2356
2383
 
2384
+ /** upb/upb.c ************************************************************/
2357
2385
 
2358
2386
  #include <errno.h>
2359
2387
  #include <stdarg.h>
@@ -2420,6 +2448,19 @@ static void *upb_global_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
2420
2448
  }
2421
2449
  }
2422
2450
 
2451
+ static uint32_t *upb_cleanup_pointer(uintptr_t cleanup_metadata) {
2452
+ return (uint32_t *)(cleanup_metadata & ~0x1);
2453
+ }
2454
+
2455
+ static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) {
2456
+ return cleanup_metadata & 0x1;
2457
+ }
2458
+
2459
+ static uintptr_t upb_cleanup_metadata(uint32_t *cleanup,
2460
+ bool has_initial_block) {
2461
+ return (uintptr_t)cleanup | has_initial_block;
2462
+ }
2463
+
2423
2464
  upb_alloc upb_alloc_global = {&upb_global_allocfunc};
2424
2465
 
2425
2466
  /* upb_arena ******************************************************************/
@@ -2465,7 +2506,8 @@ static void upb_arena_addblock(upb_arena *a, upb_arena *root, void *ptr,
2465
2506
 
2466
2507
  a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
2467
2508
  a->head.end = UPB_PTR_AT(block, size, char);
2468
- a->cleanups = &block->cleanups;
2509
+ a->cleanup_metadata = upb_cleanup_metadata(
2510
+ &block->cleanups, upb_cleanup_has_initial_block(a->cleanup_metadata));
2469
2511
 
2470
2512
  UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
2471
2513
  }
@@ -2513,6 +2555,7 @@ upb_arena *arena_initslow(void *mem, size_t n, upb_alloc *alloc) {
2513
2555
  a->refcount = 1;
2514
2556
  a->freelist = NULL;
2515
2557
  a->freelist_tail = NULL;
2558
+ a->cleanup_metadata = upb_cleanup_metadata(NULL, false);
2516
2559
 
2517
2560
  upb_arena_addblock(a, a, mem, n);
2518
2561
 
@@ -2540,7 +2583,7 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) {
2540
2583
  a->head.ptr = mem;
2541
2584
  a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
2542
2585
  a->freelist = NULL;
2543
- a->cleanups = NULL;
2586
+ a->cleanup_metadata = upb_cleanup_metadata(NULL, true);
2544
2587
 
2545
2588
  return a;
2546
2589
  }
@@ -2575,15 +2618,17 @@ void upb_arena_free(upb_arena *a) {
2575
2618
 
2576
2619
  bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2577
2620
  cleanup_ent *ent;
2621
+ uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2578
2622
 
2579
- if (!a->cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
2623
+ if (!cleanups || _upb_arenahas(a) < sizeof(cleanup_ent)) {
2580
2624
  if (!upb_arena_allocblock(a, 128)) return false; /* Out of memory. */
2581
2625
  UPB_ASSERT(_upb_arenahas(a) >= sizeof(cleanup_ent));
2626
+ cleanups = upb_cleanup_pointer(a->cleanup_metadata);
2582
2627
  }
2583
2628
 
2584
2629
  a->head.end -= sizeof(cleanup_ent);
2585
2630
  ent = (cleanup_ent*)a->head.end;
2586
- (*a->cleanups)++;
2631
+ (*cleanups)++;
2587
2632
  UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
2588
2633
 
2589
2634
  ent->cleanup = func;
@@ -2592,11 +2637,18 @@ bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func) {
2592
2637
  return true;
2593
2638
  }
2594
2639
 
2595
- void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2640
+ bool upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2596
2641
  upb_arena *r1 = arena_findroot(a1);
2597
2642
  upb_arena *r2 = arena_findroot(a2);
2598
2643
 
2599
- if (r1 == r2) return; /* Already fused. */
2644
+ if (r1 == r2) return true; /* Already fused. */
2645
+
2646
+ /* Do not fuse initial blocks since we cannot lifetime extend them. */
2647
+ if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false;
2648
+ if (upb_cleanup_has_initial_block(r2->cleanup_metadata)) return false;
2649
+
2650
+ /* Only allow fuse with a common allocator */
2651
+ if (r1->block_alloc != r2->block_alloc) return false;
2600
2652
 
2601
2653
  /* We want to join the smaller tree to the larger tree.
2602
2654
  * So swap first if they are backwards. */
@@ -2614,12 +2666,15 @@ void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2614
2666
  r1->freelist = r2->freelist;
2615
2667
  }
2616
2668
  r2->parent = r1;
2669
+ return true;
2617
2670
  }
2618
- // Fast decoder: ~3x the speed of decode.c, but x86-64 specific.
2671
+
2672
+ /** upb/decode_fast.c ************************************************************/
2673
+ // Fast decoder: ~3x the speed of decode.c, but requires x86-64/ARM64.
2619
2674
  // Also the table size grows by 2x.
2620
2675
  //
2621
- // Could potentially be ported to ARM64 or other 64-bit archs that pass at
2622
- // least six arguments in registers.
2676
+ // Could potentially be ported to other 64-bit archs that pass at least six
2677
+ // arguments in registers and have 8 unused high bits in pointers.
2623
2678
  //
2624
2679
  // The overall design is to create specialized functions for every possible
2625
2680
  // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
@@ -2639,8 +2694,10 @@ void upb_arena_fuse(upb_arena *a1, upb_arena *a2) {
2639
2694
 
2640
2695
  #define UPB_PARSE_ARGS d, ptr, msg, table, hasbits, data
2641
2696
 
2642
- #define RETURN_GENERIC(m) \
2643
- /* fprintf(stderr, m); */ \
2697
+ #define RETURN_GENERIC(m) \
2698
+ /* Uncomment either of these for debugging purposes. */ \
2699
+ /* fprintf(stderr, m); */ \
2700
+ /*__builtin_trap(); */ \
2644
2701
  return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
2645
2702
 
2646
2703
  typedef enum {
@@ -2651,21 +2708,18 @@ typedef enum {
2651
2708
  } upb_card;
2652
2709
 
2653
2710
  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) {
2711
+ static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
2712
+ int overrun = data;
2657
2713
  ptr = decode_isdonefallback_inl(d, ptr, overrun);
2658
2714
  if (ptr == NULL) {
2659
2715
  return fastdecode_err(d);
2660
2716
  }
2661
- uint16_t tag = fastdecode_loadtag(ptr);
2662
- return fastdecode_tagdispatch(d, ptr, msg, table, hasbits, tag);
2717
+ data = fastdecode_loadtag(ptr);
2718
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
2663
2719
  }
2664
2720
 
2665
2721
  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) {
2722
+ static const char *fastdecode_dispatch(UPB_PARSE_PARAMS) {
2669
2723
  if (UPB_UNLIKELY(ptr >= d->limit_ptr)) {
2670
2724
  int overrun = ptr - d->end;
2671
2725
  if (UPB_LIKELY(overrun == d->limit)) {
@@ -2673,21 +2727,22 @@ static const char *fastdecode_dispatch(upb_decstate *d, const char *ptr,
2673
2727
  *(uint32_t*)msg |= hasbits; // Sync hasbits.
2674
2728
  return ptr;
2675
2729
  } else {
2676
- return fastdecode_isdonefallback(d, ptr, msg, table, hasbits, overrun);
2730
+ data = overrun;
2731
+ UPB_MUSTTAIL return fastdecode_isdonefallback(UPB_PARSE_ARGS);
2677
2732
  }
2678
2733
  }
2679
2734
 
2680
2735
  // 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);
2736
+ data = fastdecode_loadtag(ptr);
2737
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
2683
2738
  }
2684
2739
 
2685
2740
  UPB_FORCEINLINE
2686
- static bool fastdecode_checktag(uint64_t data, int tagbytes) {
2741
+ static bool fastdecode_checktag(uint16_t data, int tagbytes) {
2687
2742
  if (tagbytes == 1) {
2688
2743
  return (data & 0xff) == 0;
2689
2744
  } else {
2690
- return (data & 0xffff) == 0;
2745
+ return data == 0;
2691
2746
  }
2692
2747
  }
2693
2748
 
@@ -2911,6 +2966,14 @@ static bool fastdecode_flippacked(uint64_t *data, int tagbytes) {
2911
2966
  return fastdecode_checktag(*data, tagbytes);
2912
2967
  }
2913
2968
 
2969
+ #define FASTDECODE_CHECKPACKED(tagbytes, card, func) \
2970
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
2971
+ if (card == CARD_r && fastdecode_flippacked(&data, tagbytes)) { \
2972
+ UPB_MUSTTAIL return func(UPB_PARSE_ARGS); \
2973
+ } \
2974
+ RETURN_GENERIC("packed check tag mismatch\n"); \
2975
+ }
2976
+
2914
2977
  /* varint fields **************************************************************/
2915
2978
 
2916
2979
  UPB_FORCEINLINE
@@ -2953,57 +3016,50 @@ done:
2953
3016
  return ptr;
2954
3017
  }
2955
3018
 
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
- }
3019
+ #define FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3020
+ valbytes, card, zigzag, packed) \
3021
+ uint64_t val; \
3022
+ void *dst; \
3023
+ fastdecode_arr farr; \
3024
+ \
3025
+ FASTDECODE_CHECKPACKED(tagbytes, card, packed); \
3026
+ \
3027
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3028
+ card); \
3029
+ if (card == CARD_r) { \
3030
+ if (UPB_UNLIKELY(!dst)) { \
3031
+ RETURN_GENERIC("need array resize\n"); \
3032
+ } \
3033
+ } \
3034
+ \
3035
+ again: \
3036
+ if (card == CARD_r) { \
3037
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3038
+ } \
3039
+ \
3040
+ ptr += tagbytes; \
3041
+ ptr = fastdecode_varint64(ptr, &val); \
3042
+ if (ptr == NULL) \
3043
+ return fastdecode_err(d); \
3044
+ val = fastdecode_munge(val, valbytes, zigzag); \
3045
+ memcpy(dst, &val, valbytes); \
3046
+ \
3047
+ if (card == CARD_r) { \
3048
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3049
+ d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3050
+ switch (ret.next) { \
3051
+ case FD_NEXT_SAMEFIELD: \
3052
+ dst = ret.dst; \
3053
+ goto again; \
3054
+ case FD_NEXT_OTHERFIELD: \
3055
+ data = ret.tag; \
3056
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3057
+ case FD_NEXT_ATLIMIT: \
3058
+ return ptr; \
3059
+ } \
3060
+ } \
3061
+ \
3062
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3007
3063
 
3008
3064
  typedef struct {
3009
3065
  uint8_t valbytes;
@@ -3032,50 +3088,37 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr,
3032
3088
  return ptr;
3033
3089
  }
3034
3090
 
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");
3053
- }
3054
-
3055
- ptr += tagbytes;
3056
- ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx);
3057
-
3058
- if (UPB_UNLIKELY(ptr == NULL)) {
3059
- return fastdecode_err(d);
3091
+ #define FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3092
+ valbytes, zigzag, unpacked) \
3093
+ fastdecode_varintdata ctx = {valbytes, zigzag}; \
3094
+ \
3095
+ FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked); \
3096
+ \
3097
+ ctx.dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &ctx.farr, \
3098
+ valbytes, CARD_r); \
3099
+ if (UPB_UNLIKELY(!ctx.dst)) { \
3100
+ RETURN_GENERIC("need array resize\n"); \
3101
+ } \
3102
+ \
3103
+ ptr += tagbytes; \
3104
+ ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
3105
+ \
3106
+ if (UPB_UNLIKELY(ptr == NULL)) { \
3107
+ return fastdecode_err(d); \
3108
+ } \
3109
+ \
3110
+ UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
3111
+
3112
+ #define FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3113
+ valbytes, card, zigzag, unpacked, packed) \
3114
+ if (card == CARD_p) { \
3115
+ FASTDECODE_PACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3116
+ valbytes, zigzag, unpacked); \
3117
+ } else { \
3118
+ FASTDECODE_UNPACKEDVARINT(d, ptr, msg, table, hasbits, data, tagbytes, \
3119
+ valbytes, card, zigzag, packed); \
3060
3120
  }
3061
3121
 
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
3122
  #define z_ZZ true
3080
3123
  #define b_ZZ false
3081
3124
  #define v_ZZ false
@@ -3086,10 +3129,10 @@ static const char *fastdecode_varint(UPB_PARSE_PARAMS, int tagbytes,
3086
3129
  #define F(card, type, valbytes, tagbytes) \
3087
3130
  UPB_NOINLINE \
3088
3131
  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); \
3132
+ FASTDECODE_VARINT(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3133
+ CARD_##card, type##_ZZ, \
3134
+ upb_pr##type##valbytes##_##tagbytes##bt, \
3135
+ upb_pp##type##valbytes##_##tagbytes##bt); \
3093
3136
  }
3094
3137
 
3095
3138
  #define TYPES(card, tagbytes) \
@@ -3117,126 +3160,110 @@ TAGBYTES(p)
3117
3160
  #undef F
3118
3161
  #undef TYPES
3119
3162
  #undef TAGBYTES
3163
+ #undef FASTDECODE_UNPACKEDVARINT
3164
+ #undef FASTDECODE_PACKEDVARINT
3165
+ #undef FASTDECODE_VARINT
3120
3166
 
3121
3167
 
3122
3168
  /* fixed fields ***************************************************************/
3123
3169
 
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
- }
3170
+ #define FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3171
+ valbytes, card, packed) \
3172
+ void *dst; \
3173
+ fastdecode_arr farr; \
3174
+ \
3175
+ FASTDECODE_CHECKPACKED(tagbytes, card, packed) \
3176
+ \
3177
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, valbytes, \
3178
+ card); \
3179
+ if (card == CARD_r) { \
3180
+ if (UPB_UNLIKELY(!dst)) { \
3181
+ RETURN_GENERIC("couldn't allocate array in arena\n"); \
3182
+ } \
3183
+ } \
3184
+ \
3185
+ again: \
3186
+ if (card == CARD_r) { \
3187
+ dst = fastdecode_resizearr(d, dst, &farr, valbytes); \
3188
+ } \
3189
+ \
3190
+ ptr += tagbytes; \
3191
+ memcpy(dst, ptr, valbytes); \
3192
+ ptr += valbytes; \
3193
+ \
3194
+ if (card == CARD_r) { \
3195
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3196
+ d, dst, &ptr, &farr, data, tagbytes, valbytes); \
3197
+ switch (ret.next) { \
3198
+ case FD_NEXT_SAMEFIELD: \
3199
+ dst = ret.dst; \
3200
+ goto again; \
3201
+ case FD_NEXT_OTHERFIELD: \
3202
+ data = ret.tag; \
3203
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3204
+ case FD_NEXT_ATLIMIT: \
3205
+ return ptr; \
3206
+ } \
3207
+ } \
3208
+ \
3209
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3210
+
3211
+ #define FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3212
+ valbytes, unpacked) \
3213
+ FASTDECODE_CHECKPACKED(tagbytes, CARD_r, unpacked) \
3214
+ \
3215
+ ptr += tagbytes; \
3216
+ int size = (uint8_t)ptr[0]; \
3217
+ ptr++; \
3218
+ if (size & 0x80) { \
3219
+ ptr = fastdecode_longsize(ptr, &size); \
3220
+ } \
3221
+ \
3222
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
3223
+ (size % valbytes) != 0)) { \
3224
+ return fastdecode_err(d); \
3225
+ } \
3226
+ \
3227
+ upb_array **arr_p = fastdecode_fieldmem(msg, data); \
3228
+ upb_array *arr = *arr_p; \
3229
+ uint8_t elem_size_lg2 = __builtin_ctz(valbytes); \
3230
+ int elems = size / valbytes; \
3231
+ \
3232
+ if (UPB_LIKELY(!arr)) { \
3233
+ *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \
3234
+ if (!arr) { \
3235
+ return fastdecode_err(d); \
3236
+ } \
3237
+ } else { \
3238
+ _upb_array_resize(arr, elems, &d->arena); \
3239
+ } \
3240
+ \
3241
+ char *dst = _upb_array_ptr(arr); \
3242
+ memcpy(dst, ptr, size); \
3243
+ arr->len = elems; \
3244
+ \
3245
+ ptr += size; \
3246
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3247
+
3248
+ #define FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3249
+ valbytes, card, unpacked, packed) \
3250
+ if (card == CARD_p) { \
3251
+ FASTDECODE_PACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3252
+ valbytes, unpacked); \
3253
+ } else { \
3254
+ FASTDECODE_UNPACKEDFIXED(d, ptr, msg, table, hasbits, data, tagbytes, \
3255
+ valbytes, card, packed); \
3144
3256
  }
3145
3257
 
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);
3209
- }
3210
-
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
3258
  /* Generate all combinations:
3232
3259
  * {s,o,r,p} x {f4,f8} x {1bt,2bt} */
3233
3260
 
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); \
3261
+ #define F(card, valbytes, tagbytes) \
3262
+ UPB_NOINLINE \
3263
+ const char *upb_p##card##f##valbytes##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3264
+ FASTDECODE_FIXED(d, ptr, msg, table, hasbits, data, tagbytes, valbytes, \
3265
+ CARD_##card, upb_ppf##valbytes##_##tagbytes##bt, \
3266
+ upb_prf##valbytes##_##tagbytes##bt); \
3240
3267
  }
3241
3268
 
3242
3269
  #define TYPES(card, tagbytes) \
@@ -3255,6 +3282,8 @@ TAGBYTES(p)
3255
3282
  #undef F
3256
3283
  #undef TYPES
3257
3284
  #undef TAGBYTES
3285
+ #undef FASTDECODE_UNPACKEDFIXED
3286
+ #undef FASTDECODE_PACKEDFIXED
3258
3287
 
3259
3288
  /* string fields **************************************************************/
3260
3289
 
@@ -3266,56 +3295,54 @@ typedef const char *fastdecode_copystr_func(struct upb_decstate *d,
3266
3295
  UPB_NOINLINE
3267
3296
  static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr,
3268
3297
  upb_msg *msg, intptr_t table,
3269
- uint64_t hasbits, upb_strview *dst) {
3298
+ uint64_t hasbits, uint64_t data) {
3299
+ upb_strview *dst = (upb_strview*)data;
3270
3300
  if (!decode_verifyutf8_inl(dst->data, dst->size)) {
3271
3301
  return fastdecode_err(d);
3272
3302
  }
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;
3303
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3304
+ }
3305
+
3306
+ #define FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, validate_utf8) \
3307
+ int size = (uint8_t)ptr[0]; /* Could plumb through hasbits. */ \
3308
+ ptr++; \
3309
+ if (size & 0x80) { \
3310
+ ptr = fastdecode_longsize(ptr, &size); \
3311
+ } \
3312
+ \
3313
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
3314
+ dst->size = 0; \
3315
+ return fastdecode_err(d); \
3316
+ } \
3317
+ \
3318
+ if (d->alias) { \
3319
+ dst->data = ptr; \
3320
+ dst->size = size; \
3321
+ } else { \
3322
+ char *data = upb_arena_malloc(&d->arena, size); \
3323
+ if (!data) { \
3324
+ return fastdecode_err(d); \
3325
+ } \
3326
+ memcpy(data, ptr, size); \
3327
+ dst->data = data; \
3328
+ dst->size = size; \
3329
+ } \
3330
+ \
3331
+ ptr += size; \
3332
+ if (validate_utf8) { \
3333
+ data = (uint64_t)dst; \
3334
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3335
+ } else { \
3336
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3304
3337
  }
3305
3338
 
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);
3310
- }
3311
- }
3312
-
3313
3339
  UPB_NOINLINE
3314
3340
  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);
3341
+ const char *ptr, upb_msg *msg,
3342
+ intptr_t table, uint64_t hasbits,
3343
+ uint64_t data) {
3344
+ upb_strview *dst = (upb_strview*)data;
3345
+ FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, true);
3319
3346
  }
3320
3347
 
3321
3348
  UPB_NOINLINE
@@ -3323,8 +3350,9 @@ static const char *fastdecode_longstring_noutf8(struct upb_decstate *d,
3323
3350
  const char *ptr, upb_msg *msg,
3324
3351
  intptr_t table,
3325
3352
  uint64_t hasbits,
3326
- upb_strview *dst) {
3327
- return fastdecode_longstring(d, ptr, msg, table, hasbits, dst, false);
3353
+ uint64_t data) {
3354
+ upb_strview *dst = (upb_strview*)data;
3355
+ FASTDECODE_LONGSTRING(d, ptr, msg, table, hasbits, dst, false);
3328
3356
  }
3329
3357
 
3330
3358
  UPB_FORCEINLINE
@@ -3337,156 +3365,165 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size,
3337
3365
  UPB_POISON_MEMORY_REGION(data + size, copy - size);
3338
3366
  }
3339
3367
 
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
- }
3368
+ #define FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3369
+ card, validate_utf8) \
3370
+ upb_strview *dst; \
3371
+ fastdecode_arr farr; \
3372
+ int64_t size; \
3373
+ size_t arena_has; \
3374
+ size_t common_has; \
3375
+ char *buf; \
3376
+ \
3377
+ UPB_ASSERT(!d->alias); \
3378
+ UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \
3379
+ \
3380
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3381
+ sizeof(upb_strview), card); \
3382
+ \
3383
+ again: \
3384
+ if (card == CARD_r) { \
3385
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3386
+ } \
3387
+ \
3388
+ size = (uint8_t)ptr[tagbytes]; \
3389
+ ptr += tagbytes + 1; \
3390
+ dst->size = size; \
3391
+ \
3392
+ buf = d->arena.head.ptr; \
3393
+ arena_has = _upb_arenahas(&d->arena); \
3394
+ common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \
3395
+ \
3396
+ if (UPB_LIKELY(size <= 15 - tagbytes)) { \
3397
+ if (arena_has < 16) \
3398
+ goto longstr; \
3399
+ d->arena.head.ptr += 16; \
3400
+ memcpy(buf, ptr - tagbytes - 1, 16); \
3401
+ dst->data = buf + tagbytes + 1; \
3402
+ } else if (UPB_LIKELY(size <= 32)) { \
3403
+ if (UPB_UNLIKELY(common_has < 32)) \
3404
+ goto longstr; \
3405
+ fastdecode_docopy(d, ptr, size, 32, buf, dst); \
3406
+ } else if (UPB_LIKELY(size <= 64)) { \
3407
+ if (UPB_UNLIKELY(common_has < 64)) \
3408
+ goto longstr; \
3409
+ fastdecode_docopy(d, ptr, size, 64, buf, dst); \
3410
+ } else if (UPB_LIKELY(size < 128)) { \
3411
+ if (UPB_UNLIKELY(common_has < 128)) \
3412
+ goto longstr; \
3413
+ fastdecode_docopy(d, ptr, size, 128, buf, dst); \
3414
+ } else { \
3415
+ goto longstr; \
3416
+ } \
3417
+ \
3418
+ ptr += size; \
3419
+ \
3420
+ if (card == CARD_r) { \
3421
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3422
+ return fastdecode_err(d); \
3423
+ } \
3424
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3425
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3426
+ switch (ret.next) { \
3427
+ case FD_NEXT_SAMEFIELD: \
3428
+ dst = ret.dst; \
3429
+ goto again; \
3430
+ case FD_NEXT_OTHERFIELD: \
3431
+ data = ret.tag; \
3432
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3433
+ case FD_NEXT_ATLIMIT: \
3434
+ return ptr; \
3435
+ } \
3436
+ } \
3437
+ \
3438
+ if (card != CARD_r && validate_utf8) { \
3439
+ data = (uint64_t)dst; \
3440
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3441
+ } \
3442
+ \
3443
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); \
3444
+ \
3445
+ longstr: \
3446
+ ptr--; \
3447
+ if (validate_utf8) { \
3448
+ UPB_MUSTTAIL return fastdecode_longstring_utf8(d, ptr, msg, table, \
3449
+ hasbits, (uint64_t)dst); \
3450
+ } else { \
3451
+ UPB_MUSTTAIL return fastdecode_longstring_noutf8(d, ptr, msg, table, \
3452
+ hasbits, (uint64_t)dst); \
3453
+ }
3454
+
3455
+ #define FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, card, \
3456
+ copyfunc, validate_utf8) \
3457
+ upb_strview *dst; \
3458
+ fastdecode_arr farr; \
3459
+ int64_t size; \
3460
+ \
3461
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3462
+ RETURN_GENERIC("string field tag mismatch\n"); \
3463
+ } \
3464
+ \
3465
+ if (UPB_UNLIKELY(!d->alias)) { \
3466
+ UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \
3467
+ } \
3468
+ \
3469
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3470
+ sizeof(upb_strview), card); \
3471
+ \
3472
+ again: \
3473
+ if (card == CARD_r) { \
3474
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_strview)); \
3475
+ } \
3476
+ \
3477
+ size = (int8_t)ptr[tagbytes]; \
3478
+ ptr += tagbytes + 1; \
3479
+ dst->data = ptr; \
3480
+ dst->size = size; \
3481
+ \
3482
+ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->end))) { \
3483
+ ptr--; \
3484
+ if (validate_utf8) { \
3485
+ return fastdecode_longstring_utf8(d, ptr, msg, table, hasbits, \
3486
+ (uint64_t)dst); \
3487
+ } else { \
3488
+ return fastdecode_longstring_noutf8(d, ptr, msg, table, hasbits, \
3489
+ (uint64_t)dst); \
3490
+ } \
3491
+ } \
3492
+ \
3493
+ ptr += size; \
3494
+ \
3495
+ if (card == CARD_r) { \
3496
+ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
3497
+ return fastdecode_err(d); \
3498
+ } \
3499
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3500
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \
3501
+ switch (ret.next) { \
3502
+ case FD_NEXT_SAMEFIELD: \
3503
+ dst = ret.dst; \
3504
+ if (UPB_UNLIKELY(!d->alias)) { \
3505
+ /* Buffer flipped and we can't alias any more. Bounce to */ \
3506
+ /* copyfunc(), but via dispatch since we need to reload table */ \
3507
+ /* data also. */ \
3508
+ fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \
3509
+ data = ret.tag; \
3510
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3511
+ } \
3512
+ goto again; \
3513
+ case FD_NEXT_OTHERFIELD: \
3514
+ data = ret.tag; \
3515
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3516
+ case FD_NEXT_ATLIMIT: \
3517
+ return ptr; \
3518
+ } \
3519
+ } \
3520
+ \
3521
+ if (card != CARD_r && validate_utf8) { \
3522
+ data = (uint64_t)dst; \
3523
+ UPB_MUSTTAIL return fastdecode_verifyutf8(UPB_PARSE_ARGS); \
3524
+ } \
3525
+ \
3526
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3490
3527
 
3491
3528
  /* Generate all combinations:
3492
3529
  * {p,c} x {s,o,r} x {s, b} x {1bt,2bt} */
@@ -3494,16 +3531,16 @@ again:
3494
3531
  #define s_VALIDATE true
3495
3532
  #define b_VALIDATE false
3496
3533
 
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); \
3534
+ #define F(card, tagbytes, type) \
3535
+ UPB_NOINLINE \
3536
+ const char *upb_c##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3537
+ FASTDECODE_COPYSTRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3538
+ CARD_##card, type##_VALIDATE); \
3539
+ } \
3540
+ const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) { \
3541
+ FASTDECODE_STRING(d, ptr, msg, table, hasbits, data, tagbytes, \
3542
+ CARD_##card, upb_c##card##type##_##tagbytes##bt, \
3543
+ type##_VALIDATE); \
3507
3544
  }
3508
3545
 
3509
3546
  #define UTF8(card, tagbytes) \
@@ -3522,6 +3559,9 @@ TAGBYTES(r)
3522
3559
  #undef b_VALIDATE
3523
3560
  #undef F
3524
3561
  #undef TAGBYTES
3562
+ #undef FASTDECODE_LONGSTRING
3563
+ #undef FASTDECODE_COPYSTRING
3564
+ #undef FASTDECODE_STRING
3525
3565
 
3526
3566
  /* message fields *************************************************************/
3527
3567
 
@@ -3554,82 +3594,82 @@ UPB_FORCEINLINE
3554
3594
  static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr,
3555
3595
  void *ctx) {
3556
3596
  fastdecode_submsgdata *submsg = ctx;
3557
- ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0);
3597
+ ptr = fastdecode_dispatch(d, ptr, submsg->msg, submsg->table, 0, 0);
3558
3598
  UPB_ASSUME(ptr != NULL);
3559
3599
  return ptr;
3560
3600
  }
3561
3601
 
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); \
3602
+ #define FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, \
3603
+ msg_ceil_bytes, card) \
3604
+ \
3605
+ if (UPB_UNLIKELY(!fastdecode_checktag(data, tagbytes))) { \
3606
+ RETURN_GENERIC("submessage field tag mismatch\n"); \
3607
+ } \
3608
+ \
3609
+ if (--d->depth == 0) return fastdecode_err(d); \
3610
+ \
3611
+ upb_msg **dst; \
3612
+ uint32_t submsg_idx = (data >> 16) & 0xff; \
3613
+ const upb_msglayout *tablep = decode_totablep(table); \
3614
+ const upb_msglayout *subtablep = tablep->submsgs[submsg_idx]; \
3615
+ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
3616
+ fastdecode_arr farr; \
3617
+ \
3618
+ if (subtablep->table_mask == (uint8_t)-1) { \
3619
+ RETURN_GENERIC("submessage doesn't have fast tables."); \
3620
+ } \
3621
+ \
3622
+ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \
3623
+ sizeof(upb_msg *), card); \
3624
+ \
3625
+ if (card == CARD_s) { \
3626
+ *(uint32_t *)msg |= hasbits; \
3627
+ hasbits = 0; \
3628
+ } \
3629
+ \
3630
+ again: \
3631
+ if (card == CARD_r) { \
3632
+ dst = fastdecode_resizearr(d, dst, &farr, sizeof(upb_msg *)); \
3633
+ } \
3634
+ \
3635
+ submsg.msg = *dst; \
3636
+ \
3637
+ if (card == CARD_r || UPB_LIKELY(!submsg.msg)) { \
3638
+ *dst = submsg.msg = decode_newmsg_ceil(d, subtablep, msg_ceil_bytes); \
3639
+ } \
3640
+ \
3641
+ ptr += tagbytes; \
3642
+ ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
3643
+ \
3644
+ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
3645
+ return fastdecode_err(d); \
3646
+ } \
3647
+ \
3648
+ if (card == CARD_r) { \
3649
+ fastdecode_nextret ret = fastdecode_nextrepeated( \
3650
+ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_msg *)); \
3651
+ switch (ret.next) { \
3652
+ case FD_NEXT_SAMEFIELD: \
3653
+ dst = ret.dst; \
3654
+ goto again; \
3655
+ case FD_NEXT_OTHERFIELD: \
3656
+ d->depth++; \
3657
+ data = ret.tag; \
3658
+ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
3659
+ case FD_NEXT_ATLIMIT: \
3660
+ d->depth++; \
3661
+ return ptr; \
3662
+ } \
3663
+ } \
3664
+ \
3665
+ d->depth++; \
3666
+ UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
3667
+
3668
+ #define F(card, tagbytes, size_ceil, ceil_arg) \
3669
+ const char *upb_p##card##m_##tagbytes##bt_max##size_ceil##b( \
3670
+ UPB_PARSE_PARAMS) { \
3671
+ FASTDECODE_SUBMSG(d, ptr, msg, table, hasbits, data, tagbytes, ceil_arg, \
3672
+ CARD_##card); \
3633
3673
  }
3634
3674
 
3635
3675
  #define SIZES(card, tagbytes) \
@@ -3650,9 +3690,11 @@ TAGBYTES(r)
3650
3690
  #undef TAGBYTES
3651
3691
  #undef SIZES
3652
3692
  #undef F
3693
+ #undef FASTDECODE_SUBMSG
3653
3694
 
3654
3695
  #endif /* UPB_FASTTABLE */
3655
- /* This file was generated by upbc (the upb compiler) from the input
3696
+
3697
+ /** 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
3698
  * file:
3657
3699
  *
3658
3700
  * google/protobuf/descriptor.proto
@@ -4135,6 +4177,7 @@ const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
4135
4177
 
4136
4178
 
4137
4179
 
4180
+ /** upb/def.c ************************************************************/
4138
4181
 
4139
4182
  #include <ctype.h>
4140
4183
  #include <errno.h>
@@ -4172,7 +4215,6 @@ struct upb_fielddef {
4172
4215
  uint32_t number_;
4173
4216
  uint16_t index_;
4174
4217
  uint16_t layout_index;
4175
- uint32_t selector_base; /* Used to index into a upb::Handlers table. */
4176
4218
  bool is_extension_;
4177
4219
  bool lazy_;
4178
4220
  bool packed_;
@@ -4185,8 +4227,6 @@ struct upb_msgdef {
4185
4227
  const upb_msglayout *layout;
4186
4228
  const upb_filedef *file;
4187
4229
  const char *full_name;
4188
- uint32_t selector_count;
4189
- uint32_t submsg_field_count;
4190
4230
 
4191
4231
  /* Tables for looking up fields by number and name. */
4192
4232
  upb_inttable itof;
@@ -4316,30 +4356,6 @@ int cmp_fields(const void *p1, const void *p2) {
4316
4356
  return field_rank(f1) - field_rank(f2);
4317
4357
  }
4318
4358
 
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
4359
  static void upb_status_setoom(upb_status *status) {
4344
4360
  upb_status_seterrmsg(status, "out of memory");
4345
4361
  }
@@ -4431,8 +4447,7 @@ bool upb_enumdef_ntoi(const upb_enumdef *def, const char *name,
4431
4447
 
4432
4448
  const char *upb_enumdef_iton(const upb_enumdef *def, int32_t num) {
4433
4449
  upb_value v;
4434
- return upb_inttable_lookup32(&def->iton, num, &v) ?
4435
- upb_value_getcstr(v) : NULL;
4450
+ return upb_inttable_lookup(&def->iton, num, &v) ? upb_value_getcstr(v) : NULL;
4436
4451
  }
4437
4452
 
4438
4453
  const char *upb_enum_iter_name(upb_enum_iter *iter) {
@@ -4521,10 +4536,6 @@ const char *upb_fielddef_jsonname(const upb_fielddef *f) {
4521
4536
  return f->json_name;
4522
4537
  }
4523
4538
 
4524
- uint32_t upb_fielddef_selectorbase(const upb_fielddef *f) {
4525
- return f->selector_base;
4526
- }
4527
-
4528
4539
  const upb_filedef *upb_fielddef_file(const upb_fielddef *f) {
4529
4540
  return f->file;
4530
4541
  }
@@ -4687,18 +4698,10 @@ upb_syntax_t upb_msgdef_syntax(const upb_msgdef *m) {
4687
4698
  return m->file->syntax;
4688
4699
  }
4689
4700
 
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
4701
  const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i) {
4699
4702
  upb_value val;
4700
- return upb_inttable_lookup32(&m->itof, i, &val) ?
4701
- upb_value_getconstptr(val) : NULL;
4703
+ return upb_inttable_lookup(&m->itof, i, &val) ? upb_value_getconstptr(val)
4704
+ : NULL;
4702
4705
  }
4703
4706
 
4704
4707
  const upb_fielddef *upb_msgdef_ntof(const upb_msgdef *m, const char *name,
@@ -4906,8 +4909,8 @@ const upb_fielddef *upb_oneofdef_ntof(const upb_oneofdef *o,
4906
4909
 
4907
4910
  const upb_fielddef *upb_oneofdef_itof(const upb_oneofdef *o, uint32_t num) {
4908
4911
  upb_value val;
4909
- return upb_inttable_lookup32(&o->itof, num, &val) ?
4910
- upb_value_getptr(val) : NULL;
4912
+ return upb_inttable_lookup(&o->itof, num, &val) ? upb_value_getptr(val)
4913
+ : NULL;
4911
4914
  }
4912
4915
 
4913
4916
  void upb_oneof_begin(upb_oneof_iter *iter, const upb_oneofdef *o) {
@@ -4987,7 +4990,6 @@ void upb_symtab_free(upb_symtab *s) {
4987
4990
 
4988
4991
  upb_symtab *upb_symtab_new(void) {
4989
4992
  upb_symtab *s = upb_gmalloc(sizeof(*s));
4990
- upb_alloc *alloc;
4991
4993
 
4992
4994
  if (!s) {
4993
4995
  return NULL;
@@ -4995,10 +4997,9 @@ upb_symtab *upb_symtab_new(void) {
4995
4997
 
4996
4998
  s->arena = upb_arena_new();
4997
4999
  s->bytes_loaded = 0;
4998
- alloc = upb_arena_alloc(s->arena);
4999
5000
 
5000
- if (!upb_strtable_init2(&s->syms, UPB_CTYPE_CONSTPTR, 32, alloc) ||
5001
- !upb_strtable_init2(&s->files, UPB_CTYPE_CONSTPTR, 4, alloc)) {
5001
+ if (!upb_strtable_init(&s->syms, 32, s->arena) ||
5002
+ !upb_strtable_init(&s->files, 4, s->arena)) {
5002
5003
  upb_arena_free(s->arena);
5003
5004
  upb_gfree(s);
5004
5005
  s = NULL;
@@ -5054,8 +5055,7 @@ int upb_symtab_filecount(const upb_symtab *s) {
5054
5055
  typedef struct {
5055
5056
  upb_symtab *symtab;
5056
5057
  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. */
5058
+ upb_arena *arena; /* Allocate defs here. */
5059
5059
  const upb_msglayout **layouts; /* NULL if we should build layouts. */
5060
5060
  upb_status *status; /* Record errors here. */
5061
5061
  jmp_buf err; /* longjmp() on error. */
@@ -5077,7 +5077,7 @@ static void symtab_oomerr(symtab_addctx *ctx) {
5077
5077
  }
5078
5078
 
5079
5079
  void *symtab_alloc(symtab_addctx *ctx, size_t bytes) {
5080
- void *ret = upb_arena_malloc(ctx->file_arena, bytes);
5080
+ void *ret = upb_arena_malloc(ctx->arena, bytes);
5081
5081
  if (!ret) symtab_oomerr(ctx);
5082
5082
  return ret;
5083
5083
  }
@@ -5184,13 +5184,21 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5184
5184
  upb_msg_field_iter it;
5185
5185
  upb_msg_oneof_iter oit;
5186
5186
  size_t hasbit;
5187
- size_t submsg_count = m->submsg_field_count;
5187
+ size_t field_count = upb_msgdef_numfields(m);
5188
+ size_t submsg_count = 0;
5188
5189
  const upb_msglayout **submsgs;
5189
5190
  upb_msglayout_field *fields;
5190
5191
 
5191
5192
  memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
5192
5193
 
5193
- fields = symtab_alloc(ctx, upb_msgdef_numfields(m) * sizeof(*fields));
5194
+ /* Count sub-messages. */
5195
+ for (size_t i = 0; i < field_count; i++) {
5196
+ if (upb_fielddef_issubmsg(&m->fields[i])) {
5197
+ submsg_count++;
5198
+ }
5199
+ }
5200
+
5201
+ fields = symtab_alloc(ctx, field_count * sizeof(*fields));
5194
5202
  submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
5195
5203
 
5196
5204
  l->field_count = upb_msgdef_numfields(m);
@@ -5341,51 +5349,8 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5341
5349
  assign_layout_indices(m, fields);
5342
5350
  }
5343
5351
 
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);
5385
- }
5386
-
5387
5352
  static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
5388
- return upb_strdup2(view.data, view.size, ctx->alloc);
5353
+ return upb_strdup2(view.data, view.size, ctx->arena);
5389
5354
  }
5390
5355
 
5391
5356
  static bool streql2(const char *a, size_t n, const char *b) {
@@ -5496,9 +5461,9 @@ static void symtab_add(symtab_addctx *ctx, const char *name, upb_value v) {
5496
5461
  if (upb_strtable_lookup(&ctx->symtab->syms, name, NULL)) {
5497
5462
  symtab_errf(ctx, "duplicate symbol '%s'", name);
5498
5463
  }
5499
- upb_alloc *alloc = upb_arena_alloc(ctx->symtab->arena);
5500
5464
  size_t len = strlen(name);
5501
- CHK_OOM(upb_strtable_insert3(&ctx->symtab->syms, name, len, v, alloc));
5465
+ CHK_OOM(upb_strtable_insert(&ctx->symtab->syms, name, len, v,
5466
+ ctx->symtab->arena));
5502
5467
  }
5503
5468
 
5504
5469
  /* Given a symbol and the base symbol inside which it is defined, find the
@@ -5531,7 +5496,8 @@ static const void *symtab_resolve(symtab_addctx *ctx, const upb_fielddef *f,
5531
5496
  }
5532
5497
 
5533
5498
  notfound:
5534
- symtab_errf(ctx, "couldn't resolve name '%s'", sym.data);
5499
+ symtab_errf(ctx, "couldn't resolve name '" UPB_STRVIEW_FORMAT "'",
5500
+ UPB_STRVIEW_ARGS(sym));
5535
5501
  }
5536
5502
 
5537
5503
  static void create_oneofdef(
@@ -5549,10 +5515,10 @@ static void create_oneofdef(
5549
5515
 
5550
5516
  v = pack_def(o, UPB_DEFTYPE_ONEOF);
5551
5517
  symtab_add(ctx, o->full_name, v);
5552
- CHK_OOM(upb_strtable_insert3(&m->ntof, name.data, name.size, v, ctx->alloc));
5518
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
5553
5519
 
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));
5520
+ CHK_OOM(upb_inttable_init(&o->itof, ctx->arena));
5521
+ CHK_OOM(upb_strtable_init(&o->ntof, 4, ctx->arena));
5556
5522
  }
5557
5523
 
5558
5524
  static str_t *newstr(symtab_addctx *ctx, const char *data, size_t len) {
@@ -5608,8 +5574,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5608
5574
  break;
5609
5575
  }
5610
5576
  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);
5577
+ long long val = strtoll(str, &end, 0);
5613
5578
  if (val > INT64_MAX || val < INT64_MIN || errno == ERANGE || *end) {
5614
5579
  goto invalid;
5615
5580
  }
@@ -5625,8 +5590,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5625
5590
  break;
5626
5591
  }
5627
5592
  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);
5593
+ unsigned long long val = strtoull(str, &end, 0);
5630
5594
  if (val > UINT64_MAX || errno == ERANGE || *end) {
5631
5595
  goto invalid;
5632
5596
  }
@@ -5642,8 +5606,7 @@ static void parse_default(symtab_addctx *ctx, const char *str, size_t len,
5642
5606
  break;
5643
5607
  }
5644
5608
  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);
5609
+ float val = strtof(str, &end);
5647
5610
  if (errno == ERANGE || *end) {
5648
5611
  goto invalid;
5649
5612
  }
@@ -5709,7 +5672,6 @@ static void set_default_default(symtab_addctx *ctx, upb_fielddef *f) {
5709
5672
  static void create_fielddef(
5710
5673
  symtab_addctx *ctx, const char *prefix, upb_msgdef *m,
5711
5674
  const google_protobuf_FieldDescriptorProto *field_proto) {
5712
- upb_alloc *alloc = ctx->alloc;
5713
5675
  upb_fielddef *f;
5714
5676
  const google_protobuf_FieldOptions *options;
5715
5677
  upb_strview name;
@@ -5745,7 +5707,8 @@ static void create_fielddef(
5745
5707
  upb_value v, field_v, json_v;
5746
5708
  size_t json_size;
5747
5709
 
5748
- f = (upb_fielddef*)&m->fields[m->field_count++];
5710
+ f = (upb_fielddef*)&m->fields[m->field_count];
5711
+ f->index_ = m->field_count++;
5749
5712
  f->msgdef = m;
5750
5713
  f->is_extension_ = false;
5751
5714
 
@@ -5766,12 +5729,12 @@ static void create_fielddef(
5766
5729
  v = upb_value_constptr(f);
5767
5730
  json_size = strlen(json_name);
5768
5731
 
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));
5732
+ CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, field_v,
5733
+ ctx->arena));
5734
+ CHK_OOM(upb_inttable_insert(&m->itof, field_number, v, ctx->arena));
5772
5735
 
5773
5736
  if (strcmp(shortname, json_name) != 0) {
5774
- upb_strtable_insert3(&m->ntof, json_name, json_size, json_v, alloc);
5737
+ upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena);
5775
5738
  }
5776
5739
 
5777
5740
  if (ctx->layouts) {
@@ -5834,15 +5797,16 @@ static void create_fielddef(
5834
5797
  symtab_errf(ctx, "oneof_index out of range (%s)", f->full_name);
5835
5798
  }
5836
5799
 
5837
- oneof = (upb_oneofdef*)&m->oneofs[oneof_index];
5800
+ oneof = (upb_oneofdef *)&m->oneofs[oneof_index];
5838
5801
  f->oneof = oneof;
5839
5802
 
5840
5803
  oneof->field_count++;
5841
5804
  if (f->proto3_optional_) {
5842
5805
  oneof->synthetic = true;
5843
5806
  }
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));
5807
+ CHK_OOM(upb_inttable_insert(&oneof->itof, f->number_, v, ctx->arena));
5808
+ CHK_OOM(
5809
+ upb_strtable_insert(&oneof->ntof, name.data, name.size, v, ctx->arena));
5846
5810
  } else {
5847
5811
  f->oneof = NULL;
5848
5812
  if (f->proto3_optional_) {
@@ -5885,8 +5849,8 @@ static void create_enumdef(
5885
5849
  symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
5886
5850
 
5887
5851
  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));
5852
+ CHK_OOM(upb_strtable_init(&e->ntoi, n, ctx->arena));
5853
+ CHK_OOM(upb_inttable_init(&e->iton, ctx->arena));
5890
5854
 
5891
5855
  e->file = ctx->file;
5892
5856
  e->defaultval = 0;
@@ -5913,16 +5877,15 @@ static void create_enumdef(
5913
5877
  }
5914
5878
 
5915
5879
  CHK_OOM(name2)
5916
- CHK_OOM(
5917
- upb_strtable_insert3(&e->ntoi, name2, strlen(name2), v, ctx->alloc));
5880
+ CHK_OOM(upb_strtable_insert(&e->ntoi, name2, strlen(name2), v, ctx->arena));
5918
5881
 
5919
5882
  if (!upb_inttable_lookup(&e->iton, num, NULL)) {
5920
5883
  upb_value v = upb_value_cstr(name2);
5921
- CHK_OOM(upb_inttable_insert2(&e->iton, num, v, ctx->alloc));
5884
+ CHK_OOM(upb_inttable_insert(&e->iton, num, v, ctx->arena));
5922
5885
  }
5923
5886
  }
5924
5887
 
5925
- upb_inttable_compact2(&e->iton, ctx->alloc);
5888
+ upb_inttable_compact(&e->iton, ctx->arena);
5926
5889
  }
5927
5890
 
5928
5891
  static void create_msgdef(symtab_addctx *ctx, const char *prefix,
@@ -5946,9 +5909,8 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
5946
5909
  oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
5947
5910
  fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
5948
5911
 
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));
5912
+ CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
5913
+ CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
5952
5914
 
5953
5915
  m->file = ctx->file;
5954
5916
  m->map_entry = false;
@@ -5980,10 +5942,9 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
5980
5942
  create_fielddef(ctx, m->full_name, m, fields[i]);
5981
5943
  }
5982
5944
 
5983
- assign_msg_indices(ctx, m);
5984
5945
  finalize_oneofs(ctx, m);
5985
5946
  assign_msg_wellknowntype(m);
5986
- upb_inttable_compact2(&m->itof, ctx->alloc);
5947
+ upb_inttable_compact(&m->itof, ctx->arena);
5987
5948
 
5988
5949
  /* This message is built. Now build nested messages and enums. */
5989
5950
 
@@ -6212,19 +6173,18 @@ static void build_filedef(
6212
6173
  }
6213
6174
 
6214
6175
  static void remove_filedef(upb_symtab *s, upb_filedef *file) {
6215
- upb_alloc *alloc = upb_arena_alloc(s->arena);
6216
6176
  int i;
6217
6177
  for (i = 0; i < file->msg_count; i++) {
6218
6178
  const char *name = file->msgs[i].full_name;
6219
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6179
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6220
6180
  }
6221
6181
  for (i = 0; i < file->enum_count; i++) {
6222
6182
  const char *name = file->enums[i].full_name;
6223
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6183
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6224
6184
  }
6225
6185
  for (i = 0; i < file->ext_count; i++) {
6226
6186
  const char *name = file->exts[i].full_name;
6227
- upb_strtable_remove3(&s->syms, name, strlen(name), NULL, alloc);
6187
+ upb_strtable_remove(&s->syms, name, strlen(name), NULL);
6228
6188
  }
6229
6189
  }
6230
6190
 
@@ -6242,8 +6202,7 @@ static const upb_filedef *_upb_symtab_addfile(
6242
6202
 
6243
6203
  ctx.file = file;
6244
6204
  ctx.symtab = s;
6245
- ctx.file_arena = file_arena;
6246
- ctx.alloc = upb_arena_alloc(file_arena);
6205
+ ctx.arena = file_arena;
6247
6206
  ctx.layouts = layouts;
6248
6207
  ctx.status = status;
6249
6208
 
@@ -6258,8 +6217,8 @@ static const upb_filedef *_upb_symtab_addfile(
6258
6217
  file = NULL;
6259
6218
  } else {
6260
6219
  build_filedef(&ctx, file, file_proto);
6261
- upb_strtable_insert3(&s->files, file->name, strlen(file->name),
6262
- upb_value_constptr(file), ctx.alloc);
6220
+ upb_strtable_insert(&s->files, file->name, strlen(file->name),
6221
+ upb_value_constptr(file), ctx.arena);
6263
6222
  UPB_ASSERT(upb_ok(status));
6264
6223
  upb_arena_fuse(s->arena, file_arena);
6265
6224
  }
@@ -6333,6 +6292,7 @@ upb_arena *_upb_symtab_arena(const upb_symtab *s) {
6333
6292
 
6334
6293
  #undef CHK_OOM
6335
6294
 
6295
+ /** upb/reflection.c ************************************************************/
6336
6296
 
6337
6297
  #include <string.h>
6338
6298
 
@@ -6443,40 +6403,7 @@ upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
6443
6403
  if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
6444
6404
  return _upb_msg_getraw(msg, f);
6445
6405
  } 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;
6406
+ return upb_fielddef_default(f);
6480
6407
  }
6481
6408
  }
6482
6409
 
@@ -6736,6 +6663,7 @@ upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
6736
6663
 
6737
6664
  /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */
6738
6665
 
6666
+ /** upb/json_decode.c ************************************************************/
6739
6667
 
6740
6668
  #include <errno.h>
6741
6669
  #include <float.h>
@@ -7646,17 +7574,17 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
7646
7574
  return;
7647
7575
  }
7648
7576
 
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
7577
  if (jsondec_peek(d) == JD_NULL && !jsondec_isvalue(f)) {
7655
7578
  /* JSON "null" indicates a default value, so no need to set anything. */
7656
7579
  jsondec_null(d);
7657
7580
  return;
7658
7581
  }
7659
7582
 
7583
+ if (upb_fielddef_realcontainingoneof(f) &&
7584
+ upb_msg_whichoneof(msg, upb_fielddef_containingoneof(f))) {
7585
+ jsondec_err(d, "More than one field for this oneof.");
7586
+ }
7587
+
7660
7588
  preserved = d->debug_field;
7661
7589
  d->debug_field = f;
7662
7590
 
@@ -8160,6 +8088,9 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
8160
8088
  const upb_msgdef *m, const upb_symtab *any_pool,
8161
8089
  int options, upb_arena *arena, upb_status *status) {
8162
8090
  jsondec d;
8091
+
8092
+ if (size == 0) return true;
8093
+
8163
8094
  d.ptr = buf;
8164
8095
  d.end = buf + size;
8165
8096
  d.arena = arena;
@@ -8178,6 +8109,7 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
8178
8109
  return true;
8179
8110
  }
8180
8111
 
8112
+ /** upb/json_encode.c ************************************************************/
8181
8113
 
8182
8114
  #include <ctype.h>
8183
8115
  #include <float.h>
@@ -8207,7 +8139,7 @@ static void jsonenc_scalar(jsonenc *e, upb_msgval val, const upb_fielddef *f);
8207
8139
  static void jsonenc_msgfield(jsonenc *e, const upb_msg *msg,
8208
8140
  const upb_msgdef *m);
8209
8141
  static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8210
- const upb_msgdef *m);
8142
+ const upb_msgdef *m, bool first);
8211
8143
  static void jsonenc_value(jsonenc *e, const upb_msg *msg, const upb_msgdef *m);
8212
8144
 
8213
8145
  UPB_NORETURN static void jsonenc_err(jsonenc *e, const char *msg) {
@@ -8238,8 +8170,10 @@ static void jsonenc_putbytes(jsonenc *e, const void *data, size_t len) {
8238
8170
  memcpy(e->ptr, data, len);
8239
8171
  e->ptr += len;
8240
8172
  } else {
8241
- if (have) memcpy(e->ptr, data, have);
8242
- e->ptr += have;
8173
+ if (have) {
8174
+ memcpy(e->ptr, data, have);
8175
+ e->ptr += have;
8176
+ }
8243
8177
  e->overflow += (len - have);
8244
8178
  }
8245
8179
  }
@@ -8261,7 +8195,7 @@ static void jsonenc_printf(jsonenc *e, const char *fmt, ...) {
8261
8195
  if (UPB_LIKELY(have > n)) {
8262
8196
  e->ptr += n;
8263
8197
  } else {
8264
- e->ptr += have;
8198
+ e->ptr = UPB_PTRADD(e->ptr, have);
8265
8199
  e->overflow += (n - have);
8266
8200
  }
8267
8201
  }
@@ -8365,7 +8299,7 @@ static void jsonenc_bytes(jsonenc *e, upb_strview str) {
8365
8299
  static const char base64[] =
8366
8300
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8367
8301
  const unsigned char *ptr = (unsigned char*)str.data;
8368
- const unsigned char *end = ptr + str.size;
8302
+ const unsigned char *end = UPB_PTRADD(ptr, str.size);
8369
8303
  char buf[4];
8370
8304
 
8371
8305
  jsonenc_putstr(e, "\"");
@@ -8401,7 +8335,7 @@ static void jsonenc_bytes(jsonenc *e, upb_strview str) {
8401
8335
 
8402
8336
  static void jsonenc_stringbody(jsonenc *e, upb_strview str) {
8403
8337
  const char *ptr = str.data;
8404
- const char *end = ptr + str.size;
8338
+ const char *end = UPB_PTRADD(ptr, str.size);
8405
8339
 
8406
8340
  while (ptr < end) {
8407
8341
  switch (*ptr) {
@@ -8517,14 +8451,13 @@ static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8517
8451
 
8518
8452
  jsonenc_putstr(e, "{\"@type\":");
8519
8453
  jsonenc_string(e, type_url);
8520
- jsonenc_putstr(e, ",");
8521
8454
 
8522
8455
  if (upb_msgdef_wellknowntype(any_m) == UPB_WELLKNOWN_UNSPECIFIED) {
8523
8456
  /* Regular messages: {"@type": "...","foo": 1, "bar": 2} */
8524
- jsonenc_msgfields(e, any, any_m);
8457
+ jsonenc_msgfields(e, any, any_m, false);
8525
8458
  } else {
8526
8459
  /* Well-known type: {"@type": "...","value": <well-known encoding>} */
8527
- jsonenc_putstr(e, "\"value\":");
8460
+ jsonenc_putstr(e, ",\"value\":");
8528
8461
  jsonenc_msgfield(e, any, any_m);
8529
8462
  }
8530
8463
 
@@ -8827,10 +8760,9 @@ static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
8827
8760
  }
8828
8761
 
8829
8762
  static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8830
- const upb_msgdef *m) {
8763
+ const upb_msgdef *m, bool first) {
8831
8764
  upb_msgval val;
8832
8765
  const upb_fielddef *f;
8833
- bool first = true;
8834
8766
 
8835
8767
  if (e->options & UPB_JSONENC_EMITDEFAULTS) {
8836
8768
  /* Iterate over all fields. */
@@ -8853,7 +8785,7 @@ static void jsonenc_msgfields(jsonenc *e, const upb_msg *msg,
8853
8785
 
8854
8786
  static void jsonenc_msg(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) {
8855
8787
  jsonenc_putstr(e, "{");
8856
- jsonenc_msgfields(e, msg, m);
8788
+ jsonenc_msgfields(e, msg, m, true);
8857
8789
  jsonenc_putstr(e, "}");
8858
8790
  }
8859
8791
 
@@ -8875,7 +8807,7 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
8875
8807
 
8876
8808
  e.buf = buf;
8877
8809
  e.ptr = buf;
8878
- e.end = buf + size;
8810
+ e.end = UPB_PTRADD(buf, size);
8879
8811
  e.overflow = 0;
8880
8812
  e.options = options;
8881
8813
  e.ext_pool = ext_pool;
@@ -8888,27 +8820,39 @@ size_t upb_json_encode(const upb_msg *msg, const upb_msgdef *m,
8888
8820
  if (e.arena) upb_arena_free(e.arena);
8889
8821
  return jsonenc_nullz(&e, size);
8890
8822
  }
8823
+
8824
+ /** upb/port_undef.inc ************************************************************/
8891
8825
  /* See port_def.inc. This should #undef all macros #defined there. */
8892
8826
 
8893
- #undef UPB_MAPTYPE_STRING
8894
8827
  #undef UPB_SIZE
8895
8828
  #undef UPB_PTR_AT
8896
8829
  #undef UPB_READ_ONEOF
8897
8830
  #undef UPB_WRITE_ONEOF
8831
+ #undef UPB_MAPTYPE_STRING
8898
8832
  #undef UPB_INLINE
8899
8833
  #undef UPB_ALIGN_UP
8900
8834
  #undef UPB_ALIGN_DOWN
8901
8835
  #undef UPB_ALIGN_MALLOC
8902
8836
  #undef UPB_ALIGN_OF
8837
+ #undef UPB_LIKELY
8838
+ #undef UPB_UNLIKELY
8903
8839
  #undef UPB_FORCEINLINE
8904
8840
  #undef UPB_NOINLINE
8905
8841
  #undef UPB_NORETURN
8842
+ #undef UPB_PRINTF
8906
8843
  #undef UPB_MAX
8907
8844
  #undef UPB_MIN
8908
8845
  #undef UPB_UNUSED
8909
8846
  #undef UPB_ASSUME
8910
8847
  #undef UPB_ASSERT
8911
8848
  #undef UPB_UNREACHABLE
8849
+ #undef UPB_SETJMP
8850
+ #undef UPB_LONGJMP
8851
+ #undef UPB_PTRADD
8852
+ #undef UPB_MUSTTAIL
8853
+ #undef UPB_FASTTABLE_SUPPORTED
8854
+ #undef UPB_FASTTABLE
8855
+ #undef UPB_FASTTABLE_INIT
8912
8856
  #undef UPB_POISON_MEMORY_REGION
8913
8857
  #undef UPB_UNPOISON_MEMORY_REGION
8914
8858
  #undef UPB_ASAN