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 +4 -4
- data/ext/google/protobuf_c/map.c +5 -3
- data/ext/google/protobuf_c/map.h +2 -1
- data/ext/google/protobuf_c/message.c +12 -4
- data/ext/google/protobuf_c/protobuf.c +10 -0
- data/ext/google/protobuf_c/protobuf.h +4 -0
- data/ext/google/protobuf_c/repeated_field.c +4 -2
- data/ext/google/protobuf_c/repeated_field.h +2 -1
- data/ext/google/protobuf_c/ruby-upb.c +756 -812
- data/ext/google/protobuf_c/ruby-upb.h +288 -329
- data/lib/google/2.3/protobuf_c.so +0 -0
- data/lib/google/2.4/protobuf_c.so +0 -0
- data/lib/google/2.5/protobuf_c.so +0 -0
- data/lib/google/2.6/protobuf_c.so +0 -0
- data/lib/google/2.7/protobuf_c.so +0 -0
- data/lib/google/3.0/protobuf_c.so +0 -0
- data/tests/basic.rb +7 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 959b565c78f77dbcde28d1db46164ab5b8575cfa757ee2ba827c8a5d2ec7944c
|
4
|
+
data.tar.gz: ea5e298ef9f1f1a87ad00fd09d817f1e71c37d4b504157e149194198050ece0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e16842901e10a17a63a726cac510413107c78d18fd94a7625e54fe903d7c8d8fe03b3a189504a849073c50032d5f609cfff0275b6a533ed74d88bb6fdb497c52
|
7
|
+
data.tar.gz: 7094846c4925b7eed0859b0165db60d017439057d8e7b91aede3f68e54c9e923065cb3c15cd970744c49c320547ca78a0cef25f22f57295e12f7c4ae38b2ead2
|
data/ext/google/protobuf_c/map.c
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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);
|
data/ext/google/protobuf_c/map.h
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
*
|
5
|
-
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
*
|
17
|
-
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
23
|
-
*
|
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
|
-
#
|
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
|
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.
|
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->
|
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
|
-
|
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
|
-
|
1643
|
-
|
1644
|
-
|
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
|
-
|
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 *
|
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 =
|
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
|
-
|
1725
|
-
|
1726
|
-
|
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,
|
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 =
|
1815
|
+
t->entries = upb_arena_malloc(a, bytes);
|
1743
1816
|
if (!t->entries) return false;
|
1744
|
-
memset(
|
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 =
|
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,
|
1975
|
+
static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) {
|
1907
1976
|
uint32_t len = (uint32_t) k2.str.len;
|
1908
|
-
char *str =
|
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
|
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
|
-
|
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
|
-
|
1965
|
-
|
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
|
1974
|
-
|
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
|
2002
|
-
upb_value *val
|
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
|
-
|
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
|
-
|
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 =
|
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
|
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
|
-
|
2136
|
-
|
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
|
-
|
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
|
-
|
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->
|
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->
|
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 (!
|
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
|
-
(*
|
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
|
-
|
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
|
-
|
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
|
2622
|
-
//
|
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
|
-
/*
|
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(
|
2655
|
-
|
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
|
-
|
2662
|
-
return fastdecode_tagdispatch(
|
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(
|
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
|
-
|
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
|
-
|
2682
|
-
return fastdecode_tagdispatch(
|
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(
|
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
|
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
|
-
|
2957
|
-
|
2958
|
-
|
2959
|
-
|
2960
|
-
|
2961
|
-
|
2962
|
-
|
2963
|
-
|
2964
|
-
|
2965
|
-
|
2966
|
-
|
2967
|
-
|
2968
|
-
|
2969
|
-
|
2970
|
-
}
|
2971
|
-
|
2972
|
-
|
2973
|
-
|
2974
|
-
|
2975
|
-
|
2976
|
-
|
2977
|
-
|
2978
|
-
|
2979
|
-
|
2980
|
-
|
2981
|
-
|
2982
|
-
|
2983
|
-
|
2984
|
-
|
2985
|
-
|
2986
|
-
|
2987
|
-
|
2988
|
-
|
2989
|
-
|
2990
|
-
|
2991
|
-
|
2992
|
-
|
2993
|
-
|
2994
|
-
|
2995
|
-
|
2996
|
-
|
2997
|
-
|
2998
|
-
|
2999
|
-
|
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
|
-
|
3036
|
-
|
3037
|
-
|
3038
|
-
|
3039
|
-
|
3040
|
-
|
3041
|
-
|
3042
|
-
|
3043
|
-
|
3044
|
-
|
3045
|
-
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
|
3050
|
-
|
3051
|
-
|
3052
|
-
|
3053
|
-
|
3054
|
-
|
3055
|
-
|
3056
|
-
|
3057
|
-
|
3058
|
-
if (
|
3059
|
-
|
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
|
-
|
3090
|
-
|
3091
|
-
|
3092
|
-
|
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
|
-
|
3125
|
-
|
3126
|
-
|
3127
|
-
|
3128
|
-
|
3129
|
-
|
3130
|
-
|
3131
|
-
|
3132
|
-
|
3133
|
-
|
3134
|
-
|
3135
|
-
|
3136
|
-
|
3137
|
-
|
3138
|
-
|
3139
|
-
|
3140
|
-
if (card == CARD_r) {
|
3141
|
-
|
3142
|
-
|
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
|
-
|
3238
|
-
|
3239
|
-
|
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,
|
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(
|
3274
|
-
}
|
3275
|
-
|
3276
|
-
|
3277
|
-
|
3278
|
-
|
3279
|
-
|
3280
|
-
|
3281
|
-
|
3282
|
-
|
3283
|
-
ptr
|
3284
|
-
|
3285
|
-
|
3286
|
-
}
|
3287
|
-
|
3288
|
-
if (
|
3289
|
-
dst->
|
3290
|
-
|
3291
|
-
}
|
3292
|
-
|
3293
|
-
|
3294
|
-
|
3295
|
-
|
3296
|
-
|
3297
|
-
|
3298
|
-
|
3299
|
-
|
3300
|
-
|
3301
|
-
|
3302
|
-
|
3303
|
-
|
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
|
-
|
3316
|
-
|
3317
|
-
|
3318
|
-
|
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
|
-
|
3327
|
-
|
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
|
-
|
3341
|
-
|
3342
|
-
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3346
|
-
size_t
|
3347
|
-
|
3348
|
-
|
3349
|
-
|
3350
|
-
UPB_ASSERT(
|
3351
|
-
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
3355
|
-
|
3356
|
-
|
3357
|
-
|
3358
|
-
|
3359
|
-
|
3360
|
-
|
3361
|
-
|
3362
|
-
|
3363
|
-
|
3364
|
-
|
3365
|
-
|
3366
|
-
|
3367
|
-
|
3368
|
-
|
3369
|
-
|
3370
|
-
|
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))
|
3376
|
-
|
3377
|
-
|
3378
|
-
|
3379
|
-
|
3380
|
-
|
3381
|
-
|
3382
|
-
|
3383
|
-
|
3384
|
-
|
3385
|
-
|
3386
|
-
|
3387
|
-
|
3388
|
-
|
3389
|
-
|
3390
|
-
|
3391
|
-
|
3392
|
-
|
3393
|
-
|
3394
|
-
|
3395
|
-
|
3396
|
-
|
3397
|
-
dst
|
3398
|
-
|
3399
|
-
|
3400
|
-
|
3401
|
-
|
3402
|
-
|
3403
|
-
|
3404
|
-
|
3405
|
-
|
3406
|
-
|
3407
|
-
|
3408
|
-
}
|
3409
|
-
|
3410
|
-
|
3411
|
-
|
3412
|
-
|
3413
|
-
|
3414
|
-
|
3415
|
-
|
3416
|
-
|
3417
|
-
|
3418
|
-
|
3419
|
-
|
3420
|
-
|
3421
|
-
|
3422
|
-
|
3423
|
-
|
3424
|
-
|
3425
|
-
|
3426
|
-
|
3427
|
-
|
3428
|
-
|
3429
|
-
|
3430
|
-
|
3431
|
-
|
3432
|
-
|
3433
|
-
if (UPB_UNLIKELY(!
|
3434
|
-
|
3435
|
-
}
|
3436
|
-
|
3437
|
-
|
3438
|
-
|
3439
|
-
|
3440
|
-
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
3444
|
-
|
3445
|
-
|
3446
|
-
|
3447
|
-
|
3448
|
-
|
3449
|
-
|
3450
|
-
|
3451
|
-
|
3452
|
-
|
3453
|
-
|
3454
|
-
|
3455
|
-
|
3456
|
-
|
3457
|
-
|
3458
|
-
|
3459
|
-
|
3460
|
-
|
3461
|
-
|
3462
|
-
|
3463
|
-
|
3464
|
-
|
3465
|
-
|
3466
|
-
|
3467
|
-
|
3468
|
-
|
3469
|
-
|
3470
|
-
|
3471
|
-
|
3472
|
-
|
3473
|
-
|
3474
|
-
|
3475
|
-
|
3476
|
-
|
3477
|
-
|
3478
|
-
|
3479
|
-
|
3480
|
-
|
3481
|
-
|
3482
|
-
|
3483
|
-
|
3484
|
-
|
3485
|
-
|
3486
|
-
|
3487
|
-
|
3488
|
-
|
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
|
-
|
3501
|
-
|
3502
|
-
}
|
3503
|
-
const char *upb_p##card##type##_##tagbytes##bt(UPB_PARSE_PARAMS) {
|
3504
|
-
|
3505
|
-
|
3506
|
-
|
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
|
-
|
3563
|
-
|
3564
|
-
|
3565
|
-
|
3566
|
-
|
3567
|
-
|
3568
|
-
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
3572
|
-
|
3573
|
-
|
3574
|
-
const upb_msglayout *
|
3575
|
-
|
3576
|
-
|
3577
|
-
|
3578
|
-
|
3579
|
-
|
3580
|
-
|
3581
|
-
|
3582
|
-
|
3583
|
-
|
3584
|
-
|
3585
|
-
|
3586
|
-
|
3587
|
-
|
3588
|
-
|
3589
|
-
|
3590
|
-
|
3591
|
-
|
3592
|
-
|
3593
|
-
|
3594
|
-
|
3595
|
-
|
3596
|
-
|
3597
|
-
|
3598
|
-
|
3599
|
-
|
3600
|
-
|
3601
|
-
|
3602
|
-
ptr
|
3603
|
-
|
3604
|
-
|
3605
|
-
|
3606
|
-
|
3607
|
-
|
3608
|
-
|
3609
|
-
|
3610
|
-
|
3611
|
-
|
3612
|
-
|
3613
|
-
|
3614
|
-
|
3615
|
-
|
3616
|
-
|
3617
|
-
|
3618
|
-
return fastdecode_tagdispatch(
|
3619
|
-
case FD_NEXT_ATLIMIT:
|
3620
|
-
d->depth++;
|
3621
|
-
return ptr;
|
3622
|
-
}
|
3623
|
-
}
|
3624
|
-
|
3625
|
-
d->depth++;
|
3626
|
-
return fastdecode_dispatch(
|
3627
|
-
|
3628
|
-
|
3629
|
-
|
3630
|
-
|
3631
|
-
|
3632
|
-
|
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
|
-
|
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
|
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
|
4701
|
-
|
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
|
4910
|
-
|
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 (!
|
5001
|
-
!
|
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 *
|
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->
|
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
|
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
|
-
|
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->
|
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(
|
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 '
|
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(
|
5518
|
+
CHK_OOM(upb_strtable_insert(&m->ntof, name.data, name.size, v, ctx->arena));
|
5553
5519
|
|
5554
|
-
CHK_OOM(
|
5555
|
-
CHK_OOM(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
5771
|
-
CHK_OOM(
|
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
|
-
|
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(
|
5845
|
-
CHK_OOM(
|
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(
|
5889
|
-
CHK_OOM(
|
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(
|
5884
|
+
CHK_OOM(upb_inttable_insert(&e->iton, num, v, ctx->arena));
|
5922
5885
|
}
|
5923
5886
|
}
|
5924
5887
|
|
5925
|
-
|
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(
|
5950
|
-
CHK_OOM(
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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
|
-
|
6262
|
-
|
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
|
-
|
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)
|
8242
|
-
|
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
|
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
|
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
|
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, "
|
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
|
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
|