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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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