google-protobuf 4.34.2-aarch64-linux-gnu → 4.35.0-aarch64-linux-gnu
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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/message.c +1 -1
- data/ext/google/protobuf_c/message.h +1 -1
- data/ext/google/protobuf_c/ruby-upb.c +405 -242
- data/ext/google/protobuf_c/ruby-upb.h +152 -30
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +1 -1
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +2 -1
- data/lib/google/3.1/protobuf_c.so +0 -0
- data/lib/google/3.2/protobuf_c.so +0 -0
- data/lib/google/3.3/protobuf_c.so +0 -0
- data/lib/google/3.4/protobuf_c.so +0 -0
- data/lib/google/4.0/protobuf_c.so +0 -0
- data/lib/google/protobuf/descriptor_pb.rb +1 -1
- metadata +3 -3
|
@@ -1970,7 +1970,7 @@ const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init = {
|
|
|
1970
1970
|
|
|
1971
1971
|
const upb_MiniTableEnum google__protobuf__Edition_enum_init = {
|
|
1972
1972
|
64,
|
|
1973
|
-
|
|
1973
|
+
11,
|
|
1974
1974
|
{
|
|
1975
1975
|
0x7,
|
|
1976
1976
|
0x0,
|
|
@@ -1979,6 +1979,7 @@ const upb_MiniTableEnum google__protobuf__Edition_enum_init = {
|
|
|
1979
1979
|
0x3e7,
|
|
1980
1980
|
0x3e8,
|
|
1981
1981
|
0x3e9,
|
|
1982
|
+
0x3ea,
|
|
1982
1983
|
0x270f,
|
|
1983
1984
|
0x1869d,
|
|
1984
1985
|
0x1869e,
|
|
@@ -2000,7 +2001,7 @@ const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_in
|
|
|
2000
2001
|
64,
|
|
2001
2002
|
0,
|
|
2002
2003
|
{
|
|
2003
|
-
|
|
2004
|
+
0xf,
|
|
2004
2005
|
0x0,
|
|
2005
2006
|
},
|
|
2006
2007
|
};
|
|
@@ -2346,10 +2347,15 @@ static int log2ceil(uint64_t v) {
|
|
|
2346
2347
|
return UPB_MIN(UPB_MAXARRSIZE, ret);
|
|
2347
2348
|
}
|
|
2348
2349
|
|
|
2349
|
-
/* A type to represent the lookup key of either a strtable
|
|
2350
|
+
/* A type to represent the lookup key of either a strtable, inttable or
|
|
2351
|
+
* exttable. */
|
|
2350
2352
|
typedef union {
|
|
2351
2353
|
uintptr_t num;
|
|
2352
2354
|
upb_StringView str;
|
|
2355
|
+
struct {
|
|
2356
|
+
const void* ptr;
|
|
2357
|
+
uint32_t ext_num;
|
|
2358
|
+
} ext;
|
|
2353
2359
|
} lookupkey_t;
|
|
2354
2360
|
|
|
2355
2361
|
static lookupkey_t strkey2(const char* str, size_t len) {
|
|
@@ -2358,16 +2364,24 @@ static lookupkey_t strkey2(const char* str, size_t len) {
|
|
|
2358
2364
|
|
|
2359
2365
|
static lookupkey_t intkey(uintptr_t key) { return (lookupkey_t){.num = key}; }
|
|
2360
2366
|
|
|
2361
|
-
|
|
2362
|
-
|
|
2367
|
+
static lookupkey_t extkey(const void* ptr, uint32_t ext_num) {
|
|
2368
|
+
return (lookupkey_t){.ext = {ptr, ext_num}};
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
// Conceptually the hash and equal functions should only take the key, not the
|
|
2372
|
+
// value, but the extension table stores part of its logical key in the value
|
|
2373
|
+
// slot. This is a sign that we have outgrown the original architecture.
|
|
2374
|
+
typedef uint32_t hashfunc_t(upb_key key, upb_value val);
|
|
2375
|
+
typedef bool eqlfunc_t(upb_key k1, upb_value v1, lookupkey_t k2);
|
|
2363
2376
|
|
|
2364
2377
|
/* Base table (shared code) ***************************************************/
|
|
2365
2378
|
|
|
2366
2379
|
static uint32_t upb_inthash(uintptr_t key) {
|
|
2380
|
+
UPB_STATIC_ASSERT(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
|
|
2381
|
+
"Pointers don't fit");
|
|
2367
2382
|
if (sizeof(uintptr_t) == 8) {
|
|
2368
2383
|
return (uint32_t)key ^ (uint32_t)(key >> 32);
|
|
2369
2384
|
} else {
|
|
2370
|
-
UPB_ASSERT(sizeof(uintptr_t) == 4);
|
|
2371
2385
|
return (uint32_t)key;
|
|
2372
2386
|
}
|
|
2373
2387
|
}
|
|
@@ -2428,7 +2442,7 @@ static const upb_tabent* findentry(const upb_table* t, lookupkey_t key,
|
|
|
2428
2442
|
e = upb_getentry(t, hash);
|
|
2429
2443
|
if (upb_tabent_isempty(e)) return NULL;
|
|
2430
2444
|
while (1) {
|
|
2431
|
-
if (eql(e->key, key)) return e;
|
|
2445
|
+
if (eql(e->key, e->val, key)) return e;
|
|
2432
2446
|
if ((e = e->next) == NULL) return NULL;
|
|
2433
2447
|
}
|
|
2434
2448
|
}
|
|
@@ -2468,7 +2482,8 @@ static void insert(upb_table* t, lookupkey_t key, upb_key tabkey, upb_value val,
|
|
|
2468
2482
|
/* Collision. */
|
|
2469
2483
|
upb_tabent* new_e = emptyent(t, mainpos_e);
|
|
2470
2484
|
/* Head of collider's chain. */
|
|
2471
|
-
upb_tabent* chain =
|
|
2485
|
+
upb_tabent* chain =
|
|
2486
|
+
getentry_mutable(t, hashfunc(mainpos_e->key, mainpos_e->val));
|
|
2472
2487
|
if (chain == mainpos_e) {
|
|
2473
2488
|
/* Existing ent is in its main position (it has the same hash as us, and
|
|
2474
2489
|
* is the head of our chain). Insert to new ent and append to this chain.
|
|
@@ -2499,7 +2514,7 @@ static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash,
|
|
|
2499
2514
|
eqlfunc_t* eql) {
|
|
2500
2515
|
upb_tabent* chain = getentry_mutable(t, hash);
|
|
2501
2516
|
if (upb_tabent_isempty(chain)) return false;
|
|
2502
|
-
if (eql(chain->key, key)) {
|
|
2517
|
+
if (eql(chain->key, chain->val, key)) {
|
|
2503
2518
|
/* Element to remove is at the head of its chain. */
|
|
2504
2519
|
t->count--;
|
|
2505
2520
|
if (val) *val = chain->val;
|
|
@@ -2514,7 +2529,7 @@ static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash,
|
|
|
2514
2529
|
} else {
|
|
2515
2530
|
/* Element to remove is either in a non-head position or not in the
|
|
2516
2531
|
* table. */
|
|
2517
|
-
while (chain->next && !eql(chain->next->key, key)) {
|
|
2532
|
+
while (chain->next && !eql(chain->next->key, chain->next->val, key)) {
|
|
2518
2533
|
chain = (upb_tabent*)chain->next;
|
|
2519
2534
|
}
|
|
2520
2535
|
if (chain->next) {
|
|
@@ -2713,11 +2728,13 @@ static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) {
|
|
|
2713
2728
|
return _upb_Hash(p, n, _upb_Seed());
|
|
2714
2729
|
}
|
|
2715
2730
|
|
|
2716
|
-
static uint32_t strhash(upb_key key) {
|
|
2731
|
+
static uint32_t strhash(upb_key key, upb_value val) {
|
|
2732
|
+
UPB_UNUSED(val);
|
|
2717
2733
|
return _upb_Hash_NoSeed(key.str->data, key.str->size);
|
|
2718
2734
|
}
|
|
2719
2735
|
|
|
2720
|
-
static bool streql(upb_key k1, lookupkey_t k2) {
|
|
2736
|
+
static bool streql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
2737
|
+
UPB_UNUSED(v1);
|
|
2721
2738
|
const upb_SizePrefixString* k1s = k1.str;
|
|
2722
2739
|
const upb_StringView k2s = k2.str;
|
|
2723
2740
|
return k1s->size == k2s.size &&
|
|
@@ -2881,6 +2898,98 @@ void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) {
|
|
|
2881
2898
|
t->t.entries[iter].val = v;
|
|
2882
2899
|
}
|
|
2883
2900
|
|
|
2901
|
+
/* upb_exttable ***************************************************************/
|
|
2902
|
+
|
|
2903
|
+
static uint32_t _upb_exttable_hash(const void* ptr, uint32_t ext_num) {
|
|
2904
|
+
uint64_t a = (uintptr_t)ptr;
|
|
2905
|
+
uint64_t b = ext_num;
|
|
2906
|
+
return (uint32_t)WyhashMix(a ^ kWyhashSalt[1], b ^ _upb_Seed());
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2909
|
+
static uint32_t exthash(upb_key key, upb_value val) {
|
|
2910
|
+
const void* ptr = (const void*)key.num;
|
|
2911
|
+
uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(val);
|
|
2912
|
+
return _upb_exttable_hash(ptr, ext_num);
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
static bool exteql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
2916
|
+
if ((const void*)k1.num == k2.ext.ptr) {
|
|
2917
|
+
uint32_t ext_num1 = *(const uint32_t*)upb_value_getconstptr(v1);
|
|
2918
|
+
return ext_num1 == k2.ext.ext_num;
|
|
2919
|
+
}
|
|
2920
|
+
return false;
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2923
|
+
bool upb_exttable_init(upb_exttable* t, size_t expected_size, upb_Arena* a) {
|
|
2924
|
+
int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size));
|
|
2925
|
+
return init(&t->t, size_lg2, a);
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
void upb_exttable_clear(upb_exttable* t) {
|
|
2929
|
+
size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
|
|
2930
|
+
t->t.count = 0;
|
|
2931
|
+
memset((char*)t->t.entries, 0, bytes);
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
bool upb_exttable_resize(upb_exttable* t, size_t size_lg2, upb_Arena* a) {
|
|
2935
|
+
upb_exttable new_table;
|
|
2936
|
+
if (!init(&new_table.t, size_lg2, a)) return false;
|
|
2937
|
+
|
|
2938
|
+
size_t i;
|
|
2939
|
+
for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
|
|
2940
|
+
const upb_tabent* e = &t->t.entries[i];
|
|
2941
|
+
uint32_t hash = exthash(e->key, e->val);
|
|
2942
|
+
uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(e->val);
|
|
2943
|
+
lookupkey_t lookupkey = extkey((const void*)e->key.num, ext_num);
|
|
2944
|
+
insert(&new_table.t, lookupkey, e->key, e->val, hash, &exthash, &exteql);
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
*t = new_table;
|
|
2948
|
+
return true;
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2951
|
+
bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v,
|
|
2952
|
+
upb_Arena* a) {
|
|
2953
|
+
UPB_ASSERT(k != NULL);
|
|
2954
|
+
UPB_ASSERT(v != NULL);
|
|
2955
|
+
UPB_ASSERT(*v != 0);
|
|
2956
|
+
|
|
2957
|
+
if (isfull(&t->t)) {
|
|
2958
|
+
if (!upb_exttable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) {
|
|
2959
|
+
return false;
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
lookupkey_t lookupkey = extkey(k, *v);
|
|
2964
|
+
upb_key key = {.num = (uintptr_t)k};
|
|
2965
|
+
upb_value val = upb_value_constptr(v);
|
|
2966
|
+
uint32_t hash = _upb_exttable_hash(k, *v);
|
|
2967
|
+
insert(&t->t, lookupkey, key, val, hash, &exthash, &exteql);
|
|
2968
|
+
return true;
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k,
|
|
2972
|
+
uint32_t ext_number) {
|
|
2973
|
+
uint32_t hash = _upb_exttable_hash(k, ext_number);
|
|
2974
|
+
upb_value val;
|
|
2975
|
+
if (lookup(&t->t, extkey(k, ext_number), &val, hash, &exteql)) {
|
|
2976
|
+
return (const uint32_t*)upb_value_getconstptr(val);
|
|
2977
|
+
}
|
|
2978
|
+
return NULL;
|
|
2979
|
+
}
|
|
2980
|
+
|
|
2981
|
+
const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k,
|
|
2982
|
+
uint32_t ext_number) {
|
|
2983
|
+
uint32_t hash = _upb_exttable_hash(k, ext_number);
|
|
2984
|
+
upb_value val;
|
|
2985
|
+
if (rm(&t->t, extkey(k, ext_number), &val, hash, &exteql)) {
|
|
2986
|
+
return (const uint32_t*)upb_value_getconstptr(val);
|
|
2987
|
+
}
|
|
2988
|
+
return NULL;
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
size_t upb_exttable_size(const upb_exttable* t) { return t->t.count; }
|
|
2992
|
+
|
|
2884
2993
|
/* upb_inttable ***************************************************************/
|
|
2885
2994
|
|
|
2886
2995
|
/* For inttables we use a hybrid structure where small keys are kept in an
|
|
@@ -2895,9 +3004,15 @@ static uint32_t presence_mask_arr_size(uint32_t array_size) {
|
|
|
2895
3004
|
return (array_size + 7) / 8; // sizeof(uint8_t) is always 1.
|
|
2896
3005
|
}
|
|
2897
3006
|
|
|
2898
|
-
static uint32_t inthash(upb_key key
|
|
3007
|
+
static uint32_t inthash(upb_key key, upb_value val) {
|
|
3008
|
+
UPB_UNUSED(val);
|
|
3009
|
+
return upb_inthash(key.num);
|
|
3010
|
+
}
|
|
2899
3011
|
|
|
2900
|
-
static bool inteql(upb_key k1, lookupkey_t k2) {
|
|
3012
|
+
static bool inteql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
3013
|
+
UPB_UNUSED(v1);
|
|
3014
|
+
return k1.num == k2.num;
|
|
3015
|
+
}
|
|
2901
3016
|
|
|
2902
3017
|
static upb_value* mutable_array(upb_inttable* t) {
|
|
2903
3018
|
return (upb_value*)t->array;
|
|
@@ -3003,8 +3118,8 @@ bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val,
|
|
|
3003
3118
|
|
|
3004
3119
|
for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
|
|
3005
3120
|
const upb_tabent* e = &t->t.entries[i];
|
|
3006
|
-
insert(&new_table, intkey(e->key.num), e->key, e->val,
|
|
3007
|
-
&inthash, &inteql);
|
|
3121
|
+
insert(&new_table, intkey(e->key.num), e->key, e->val,
|
|
3122
|
+
inthash(e->key, e->val), &inthash, &inteql);
|
|
3008
3123
|
}
|
|
3009
3124
|
|
|
3010
3125
|
UPB_ASSERT(t->t.count == new_table.count);
|
|
@@ -5663,24 +5778,33 @@ static int GetLocaleRadix(char *data, size_t capacity) {
|
|
|
5663
5778
|
const int size = snprintf(temp, sizeof(temp), "%.1f", 1.5);
|
|
5664
5779
|
UPB_ASSERT(temp[0] == '1');
|
|
5665
5780
|
UPB_ASSERT(temp[size - 1] == '5');
|
|
5666
|
-
|
|
5781
|
+
if (size < capacity) {
|
|
5782
|
+
return 0;
|
|
5783
|
+
}
|
|
5667
5784
|
temp[size - 1] = '\0';
|
|
5668
|
-
|
|
5785
|
+
strncpy(data, temp + 1, size);
|
|
5669
5786
|
return size - 2;
|
|
5670
5787
|
}
|
|
5671
5788
|
|
|
5672
5789
|
// Populates a string identical to *input except that the character pointed to
|
|
5673
5790
|
// by pos (which should be '.') is replaced with the locale-specific radix.
|
|
5674
5791
|
|
|
5675
|
-
static void LocalizeRadix(const char *input, const char *pos, char *output
|
|
5792
|
+
static void LocalizeRadix(const char *input, const char *pos, char *output,
|
|
5793
|
+
int output_size) {
|
|
5676
5794
|
const int len1 = pos - input;
|
|
5677
5795
|
|
|
5678
5796
|
char radix[8];
|
|
5679
5797
|
const int len2 = GetLocaleRadix(radix, sizeof(radix));
|
|
5680
5798
|
|
|
5799
|
+
const int n = output_size - len1 - len2 - 1;
|
|
5800
|
+
if (n < 0) {
|
|
5801
|
+
return;
|
|
5802
|
+
}
|
|
5803
|
+
|
|
5681
5804
|
memcpy(output, input, len1);
|
|
5682
5805
|
memcpy(output + len1, radix, len2);
|
|
5683
|
-
|
|
5806
|
+
strncpy(output + len1 + len2, input + len1 + 1, n);
|
|
5807
|
+
output[output_size - 1] = '\0';
|
|
5684
5808
|
}
|
|
5685
5809
|
|
|
5686
5810
|
double _upb_NoLocaleStrtod(const char *str, char **endptr) {
|
|
@@ -5700,7 +5824,7 @@ double _upb_NoLocaleStrtod(const char *str, char **endptr) {
|
|
|
5700
5824
|
// try again.
|
|
5701
5825
|
|
|
5702
5826
|
char localized[80];
|
|
5703
|
-
LocalizeRadix(str, temp_endptr, localized);
|
|
5827
|
+
LocalizeRadix(str, temp_endptr, localized, sizeof localized);
|
|
5704
5828
|
char *localized_endptr;
|
|
5705
5829
|
result = strtod(localized, &localized_endptr);
|
|
5706
5830
|
if ((localized_endptr - &localized[0]) > (temp_endptr - str)) {
|
|
@@ -5782,6 +5906,7 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc};
|
|
|
5782
5906
|
static UPB_ATOMIC(size_t) g_max_block_size = UPB_DEFAULT_MAX_BLOCK_SIZE;
|
|
5783
5907
|
|
|
5784
5908
|
void upb_Arena_SetMaxBlockSize(size_t max) {
|
|
5909
|
+
UPB_ASSERT(max <= UINT32_MAX);
|
|
5785
5910
|
upb_Atomic_Store(&g_max_block_size, max, memory_order_relaxed);
|
|
5786
5911
|
}
|
|
5787
5912
|
|
|
@@ -5818,8 +5943,14 @@ typedef struct upb_ArenaInternal {
|
|
|
5818
5943
|
UPB_ATOMIC(const upb_ArenaRef*) refs;
|
|
5819
5944
|
#endif
|
|
5820
5945
|
|
|
5821
|
-
//
|
|
5822
|
-
|
|
5946
|
+
// Size of the last block we allocated in the normal exponential scheme.
|
|
5947
|
+
uint32_t last_block_size;
|
|
5948
|
+
|
|
5949
|
+
// A hint that grows whenever we perform a "one-off" allocation into a a
|
|
5950
|
+
// dedicated block. This helps us determine if these outlier blocks are
|
|
5951
|
+
// actually common enough that we should switch back to the normal exponential
|
|
5952
|
+
// scheme at the larger size.
|
|
5953
|
+
uint32_t size_hint;
|
|
5823
5954
|
|
|
5824
5955
|
// All non atomic members used during allocation must be above this point, and
|
|
5825
5956
|
// are used by _SwapIn/_SwapOut
|
|
@@ -6115,23 +6246,60 @@ bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to) {
|
|
|
6115
6246
|
|
|
6116
6247
|
#endif
|
|
6117
6248
|
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6249
|
+
static upb_MemBlock* _upb_Arena_AllocBlockInternal(upb_alloc* alloc,
|
|
6250
|
+
size_t size) {
|
|
6251
|
+
UPB_ASSERT(size >= kUpb_MemblockReserve);
|
|
6252
|
+
upb_SizedPtr alloc_result = upb_SizeReturningMalloc(alloc, size);
|
|
6253
|
+
if (!alloc_result.p) return NULL;
|
|
6254
|
+
upb_MemBlock* block = alloc_result.p;
|
|
6255
|
+
block->size = alloc_result.n;
|
|
6256
|
+
return block;
|
|
6257
|
+
}
|
|
6258
|
+
|
|
6259
|
+
static upb_MemBlock* _upb_Arena_AllocBlock(upb_Arena* a, size_t size) {
|
|
6260
|
+
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6261
|
+
return _upb_Arena_AllocBlockInternal(_upb_ArenaInternal_BlockAlloc(ai), size);
|
|
6262
|
+
}
|
|
6263
|
+
|
|
6264
|
+
static void _upb_Arena_AddBlock(upb_Arena* a, upb_MemBlock* block) {
|
|
6121
6265
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6122
|
-
upb_MemBlock* block = ptr;
|
|
6123
6266
|
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6267
|
+
// Atomic add not required here, as threads won't race allocating blocks, plus
|
|
6268
|
+
// atomic fetch-add is slower than load/add/store on arm devices compiled
|
|
6269
|
+
// targeting pre-v8.1. Relaxed order is safe as nothing depends on order of
|
|
6270
|
+
// size allocated.
|
|
6271
|
+
uintptr_t old_space_allocated =
|
|
6272
|
+
upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed);
|
|
6273
|
+
upb_Atomic_Store(&ai->space_allocated, old_space_allocated + block->size,
|
|
6274
|
+
memory_order_relaxed);
|
|
6275
|
+
|
|
6276
|
+
block->next = ai->blocks;
|
|
6129
6277
|
ai->blocks = block;
|
|
6130
|
-
|
|
6278
|
+
}
|
|
6279
|
+
|
|
6280
|
+
static void _upb_Arena_UseBlockInternal(upb_Arena* a, upb_MemBlock* block,
|
|
6281
|
+
size_t offset) {
|
|
6282
|
+
size_t block_size = block->size;
|
|
6283
|
+
char* start = UPB_PTR_AT(block, kUpb_MemblockReserve + offset, char);
|
|
6131
6284
|
a->UPB_PRIVATE(ptr) = start;
|
|
6132
6285
|
a->UPB_PRIVATE(end) = UPB_PTR_AT(block, block_size, char);
|
|
6133
6286
|
UPB_PRIVATE(upb_Xsan_PoisonRegion)(start, a->UPB_PRIVATE(end) - start);
|
|
6134
|
-
|
|
6287
|
+
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(a));
|
|
6288
|
+
UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >=
|
|
6289
|
+
block_size - kUpb_MemblockReserve - offset);
|
|
6290
|
+
}
|
|
6291
|
+
|
|
6292
|
+
static void _upb_Arena_UseBlock(upb_Arena* a, upb_MemBlock* block) {
|
|
6293
|
+
_upb_Arena_UseBlockInternal(a, block, 0);
|
|
6294
|
+
}
|
|
6295
|
+
|
|
6296
|
+
static bool _upb_Arena_WouldReduceFreeSpace(upb_Arena* a, size_t size,
|
|
6297
|
+
size_t block_size) {
|
|
6298
|
+
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6299
|
+
size_t current_free =
|
|
6300
|
+
ai->blocks ? a->UPB_PRIVATE(end) - a->UPB_PRIVATE(ptr) : 0;
|
|
6301
|
+
size_t future_free = block_size - kUpb_MemblockReserve - size;
|
|
6302
|
+
return current_free >= future_free;
|
|
6135
6303
|
}
|
|
6136
6304
|
|
|
6137
6305
|
// Fulfills the allocation request by allocating a new block. Returns NULL on
|
|
@@ -6139,84 +6307,60 @@ static void _upb_Arena_AddBlock(upb_Arena* a, void* ptr, size_t offset,
|
|
|
6139
6307
|
void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t size) {
|
|
6140
6308
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6141
6309
|
if (!ai->block_alloc) return NULL;
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6310
|
+
|
|
6311
|
+
// Whether to satisfy the allocation from a one-off block which is right-sized
|
|
6312
|
+
// for the current allocation. We do this if we suspect that the current
|
|
6313
|
+
// allocation is an outlier that does not represent the typical size of
|
|
6314
|
+
// allocations from this arena, or if we would reduce free space by
|
|
6315
|
+
// using exponential growth.
|
|
6316
|
+
bool one_off = false;
|
|
6149
6317
|
|
|
6150
6318
|
// Relaxed order is safe here as we don't need any ordering with the setter.
|
|
6151
6319
|
size_t max_block_size =
|
|
6152
6320
|
upb_Atomic_Load(&g_max_block_size, memory_order_relaxed);
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
target_size < max_block_size) {
|
|
6163
|
-
last_size = ai->size_hint;
|
|
6164
|
-
// Recalculate sizes with possibly larger last_size
|
|
6165
|
-
target_size = UPB_MIN(last_size * 2, max_block_size);
|
|
6166
|
-
future_free = UPB_MAX(size, target_size - kUpb_MemblockReserve) - size;
|
|
6167
|
-
}
|
|
6168
|
-
bool insert_after_head = false;
|
|
6169
|
-
// Only insert after head if an allocated block is present; we don't want to
|
|
6170
|
-
// continue allocating out of the initial block because we'll have no way of
|
|
6171
|
-
// restoring the size of our allocated block if we add another.
|
|
6172
|
-
if (last_block && current_free >= future_free) {
|
|
6173
|
-
// If we're still going to net reduce free space with this new block, then
|
|
6174
|
-
// only allocate the precise size requested and keep the current last block
|
|
6175
|
-
// as the active block for future allocations.
|
|
6176
|
-
insert_after_head = true;
|
|
6177
|
-
target_size = size + kUpb_MemblockReserve;
|
|
6178
|
-
// Add something to our previous size each time, so that eventually we
|
|
6179
|
-
// will reach the max block size. Allocations larger than the max block size
|
|
6180
|
-
// will always get their own backing allocation, so don't include them.
|
|
6181
|
-
if (target_size <= max_block_size) {
|
|
6182
|
-
ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1);
|
|
6321
|
+
size_t block_size = UPB_MIN(ai->last_block_size * 2, max_block_size);
|
|
6322
|
+
|
|
6323
|
+
if (size + kUpb_MemblockReserve > block_size) {
|
|
6324
|
+
// A regular doubling would not yield a large enough block. Does size_hint
|
|
6325
|
+
// indicate that we have consistently needed large blocks?
|
|
6326
|
+
block_size = UPB_MIN(ai->size_hint * 2, max_block_size);
|
|
6327
|
+
if (size + kUpb_MemblockReserve > block_size) {
|
|
6328
|
+
// Even size_hint is not large enough, we will have to do a one-off.
|
|
6329
|
+
one_off = true;
|
|
6183
6330
|
}
|
|
6184
6331
|
}
|
|
6185
|
-
// We may need to exceed the max block size if the user requested a large
|
|
6186
|
-
// allocation.
|
|
6187
|
-
size_t block_size = UPB_MAX(kUpb_MemblockReserve + size, target_size);
|
|
6188
|
-
upb_alloc* block_alloc = _upb_ArenaInternal_BlockAlloc(ai);
|
|
6189
|
-
upb_SizedPtr alloc_result = upb_SizeReturningMalloc(block_alloc, block_size);
|
|
6190
6332
|
|
|
6191
|
-
|
|
6333
|
+
// If switching to a block of this size would *reduce* available free space,
|
|
6334
|
+
// we might as well make a one-off block instead.
|
|
6335
|
+
one_off = one_off || _upb_Arena_WouldReduceFreeSpace(a, size, block_size);
|
|
6192
6336
|
|
|
6193
|
-
|
|
6194
|
-
|
|
6337
|
+
if (one_off) {
|
|
6338
|
+
// Note: this may exceed the max block size, but that's okay.
|
|
6339
|
+
block_size = size + kUpb_MemblockReserve;
|
|
6340
|
+
}
|
|
6195
6341
|
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
// targetting pre-v8.1. Relaxed order is safe as nothing depends on order of
|
|
6199
|
-
// size allocated.
|
|
6342
|
+
upb_MemBlock* block = _upb_Arena_AllocBlock(a, block_size);
|
|
6343
|
+
if (!block) return NULL;
|
|
6200
6344
|
|
|
6201
|
-
|
|
6202
|
-
upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed);
|
|
6203
|
-
upb_Atomic_Store(&ai->space_allocated,
|
|
6204
|
-
old_space_allocated + actual_block_size,
|
|
6205
|
-
memory_order_relaxed);
|
|
6206
|
-
if (UPB_UNLIKELY(insert_after_head)) {
|
|
6207
|
-
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6208
|
-
block->size = actual_block_size;
|
|
6209
|
-
upb_MemBlock* head = ai->blocks;
|
|
6210
|
-
block->next = head->next;
|
|
6211
|
-
head->next = block;
|
|
6345
|
+
_upb_Arena_AddBlock(a, block);
|
|
6212
6346
|
|
|
6347
|
+
// Recheck size, in case the allocator gave us a much larger block than we
|
|
6348
|
+
// requested and we want to make it the new allocating region.
|
|
6349
|
+
if (UPB_UNLIKELY(one_off) &&
|
|
6350
|
+
_upb_Arena_WouldReduceFreeSpace(a, size, block->size)) {
|
|
6351
|
+
// Increase size_hint, so that a series of one-off allocations will
|
|
6352
|
+
// eventually convince us to switch to exponential growth at the larger
|
|
6353
|
+
// size.
|
|
6354
|
+
ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1);
|
|
6213
6355
|
char* allocated = UPB_PTR_AT(block, kUpb_MemblockReserve, char);
|
|
6214
|
-
|
|
6215
|
-
|
|
6356
|
+
char* poison_start = allocated + size - UPB_PRIVATE(kUpb_Asan_GuardSize);
|
|
6357
|
+
UPB_PRIVATE(upb_Xsan_PoisonRegion)(
|
|
6358
|
+
poison_start, UPB_PTR_AT(block, block->size, char) - poison_start);
|
|
6216
6359
|
return allocated;
|
|
6217
6360
|
} else {
|
|
6218
|
-
ai->
|
|
6219
|
-
|
|
6361
|
+
ai->last_block_size = UPB_MIN(block->size, UINT32_MAX);
|
|
6362
|
+
ai->size_hint = ai->last_block_size;
|
|
6363
|
+
_upb_Arena_UseBlock(a, block);
|
|
6220
6364
|
UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= size);
|
|
6221
6365
|
return upb_Arena_Malloc(a, size - UPB_PRIVATE(kUpb_Asan_GuardSize));
|
|
6222
6366
|
}
|
|
@@ -6227,27 +6371,26 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6227
6371
|
UPB_ALIGN_MALLOC(kUpb_MemblockReserve + sizeof(upb_ArenaState));
|
|
6228
6372
|
upb_ArenaState* a;
|
|
6229
6373
|
|
|
6230
|
-
|
|
6374
|
+
if (!alloc) return NULL;
|
|
6231
6375
|
|
|
6376
|
+
// We need to malloc the initial block.
|
|
6232
6377
|
size_t block_size =
|
|
6233
6378
|
first_block_overhead + UPB_MAX(256, UPB_ALIGN_MALLOC(first_size) +
|
|
6234
6379
|
UPB_PRIVATE(kUpb_Asan_GuardSize));
|
|
6235
|
-
|
|
6236
|
-
if (!
|
|
6237
|
-
!(alloc_result = upb_SizeReturningMalloc(alloc, block_size)).p) {
|
|
6238
|
-
return NULL;
|
|
6239
|
-
}
|
|
6240
|
-
char* mem = alloc_result.p;
|
|
6241
|
-
size_t actual_block_size = alloc_result.n;
|
|
6380
|
+
upb_MemBlock* block = _upb_Arena_AllocBlockInternal(alloc, block_size);
|
|
6381
|
+
if (!block) return NULL;
|
|
6242
6382
|
|
|
6243
|
-
|
|
6383
|
+
// Initialize the arena state in the first block. We "borrow" the memory from
|
|
6384
|
+
// the block, because we can't yet call upb_Arena_Malloc.
|
|
6385
|
+
a = UPB_PTR_AT(block, kUpb_MemblockReserve, upb_ArenaState);
|
|
6244
6386
|
a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 0);
|
|
6245
|
-
a->body.
|
|
6387
|
+
a->body.last_block_size = UPB_MIN(block->size, UINT32_MAX);
|
|
6388
|
+
a->body.size_hint = UPB_MIN(block->size, UINT32_MAX);
|
|
6246
6389
|
upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1));
|
|
6247
6390
|
upb_Atomic_Init(&a->body.next, NULL);
|
|
6248
6391
|
upb_Atomic_Init(&a->body.previous_or_tail,
|
|
6249
6392
|
_upb_Arena_TaggedFromTail(&a->body));
|
|
6250
|
-
upb_Atomic_Init(&a->body.space_allocated,
|
|
6393
|
+
upb_Atomic_Init(&a->body.space_allocated, 0);
|
|
6251
6394
|
a->body.blocks = NULL;
|
|
6252
6395
|
#ifndef NDEBUG
|
|
6253
6396
|
a->body.refs = NULL;
|
|
@@ -6255,15 +6398,16 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6255
6398
|
a->body.upb_alloc_cleanup = NULL;
|
|
6256
6399
|
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body));
|
|
6257
6400
|
|
|
6258
|
-
_upb_Arena_AddBlock(&a->head,
|
|
6401
|
+
_upb_Arena_AddBlock(&a->head, block);
|
|
6402
|
+
_upb_Arena_UseBlockInternal(&a->head, block,
|
|
6403
|
+
UPB_ALIGN_MALLOC(sizeof(upb_ArenaState)));
|
|
6259
6404
|
|
|
6260
6405
|
return &a->head;
|
|
6261
6406
|
}
|
|
6262
6407
|
|
|
6263
6408
|
upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
|
|
6264
|
-
UPB_STATIC_ASSERT(
|
|
6265
|
-
|
|
6266
|
-
"Need to update UPB_ARENA_SIZE_HACK");
|
|
6409
|
+
UPB_STATIC_ASSERT(UPB_ARENA_SIZE_HACK >= sizeof(upb_ArenaState),
|
|
6410
|
+
"Need to update UPB_ARENA_SIZE_HACK");
|
|
6267
6411
|
upb_ArenaState* a;
|
|
6268
6412
|
|
|
6269
6413
|
if (mem) {
|
|
@@ -6293,6 +6437,7 @@ upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
|
|
|
6293
6437
|
a->body.refs = NULL;
|
|
6294
6438
|
#endif
|
|
6295
6439
|
a->body.size_hint = 128;
|
|
6440
|
+
a->body.last_block_size = 128;
|
|
6296
6441
|
a->body.upb_alloc_cleanup = NULL;
|
|
6297
6442
|
a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 1);
|
|
6298
6443
|
a->head.UPB_PRIVATE(ptr) = (void*)UPB_ALIGN_MALLOC((uintptr_t)(a + 1));
|
|
@@ -6739,14 +6884,11 @@ void UPB_PRIVATE(_upb_Arena_SwapOut)(upb_Arena* des, const upb_Arena* src) {
|
|
|
6739
6884
|
bool _upb_Arena_WasLastAlloc(struct upb_Arena* a, void* ptr, size_t oldsize) {
|
|
6740
6885
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6741
6886
|
upb_MemBlock* block = ai->blocks;
|
|
6742
|
-
if (block == NULL) return false;
|
|
6743
6887
|
// Skip any arena refs.
|
|
6744
6888
|
while (block != NULL && block->size == 0) {
|
|
6745
6889
|
block = block->next;
|
|
6746
6890
|
}
|
|
6747
6891
|
if (block == NULL) return false;
|
|
6748
|
-
block = block->next;
|
|
6749
|
-
if (block == NULL) return false;
|
|
6750
6892
|
char* start = UPB_PTR_AT(block, kUpb_MemblockReserve, char);
|
|
6751
6893
|
return UPB_PRIVATE(upb_Xsan_PtrEq)(ptr, start) &&
|
|
6752
6894
|
UPB_PRIVATE(_upb_Arena_AllocSpan)(oldsize) ==
|
|
@@ -6828,6 +6970,46 @@ bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
|
|
|
6828
6970
|
return true;
|
|
6829
6971
|
}
|
|
6830
6972
|
|
|
6973
|
+
bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, upb_Arena* arena) {
|
|
6974
|
+
UPB_ASSERT(dst);
|
|
6975
|
+
UPB_ASSERT(src);
|
|
6976
|
+
UPB_ASSERT(!upb_Array_IsFrozen(dst));
|
|
6977
|
+
if (dst == src) return true;
|
|
6978
|
+
size_t len = upb_Array_Size(src);
|
|
6979
|
+
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) {
|
|
6980
|
+
return false;
|
|
6981
|
+
}
|
|
6982
|
+
if (len == 0) return true;
|
|
6983
|
+
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst);
|
|
6984
|
+
const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src);
|
|
6985
|
+
UPB_ASSERT(lg2 == src_lg2);
|
|
6986
|
+
char* dst_data = upb_Array_MutableDataPtr(dst);
|
|
6987
|
+
const char* src_data = upb_Array_DataPtr(src);
|
|
6988
|
+
memcpy(dst_data, src_data, len << lg2);
|
|
6989
|
+
return true;
|
|
6990
|
+
}
|
|
6991
|
+
|
|
6992
|
+
bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src,
|
|
6993
|
+
upb_Arena* arena) {
|
|
6994
|
+
UPB_ASSERT(!upb_Array_IsFrozen(dst));
|
|
6995
|
+
UPB_ASSERT(src);
|
|
6996
|
+
size_t src_len = upb_Array_Size(src);
|
|
6997
|
+
if (src_len == 0) return true;
|
|
6998
|
+
size_t dst_len = upb_Array_Size(dst);
|
|
6999
|
+
size_t len = dst_len + src_len;
|
|
7000
|
+
if (UPB_UNLIKELY(len < dst_len)) return false;
|
|
7001
|
+
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) {
|
|
7002
|
+
return false;
|
|
7003
|
+
}
|
|
7004
|
+
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst);
|
|
7005
|
+
const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src);
|
|
7006
|
+
UPB_ASSERT(lg2 == src_lg2);
|
|
7007
|
+
char* dst_data = upb_Array_MutableDataPtr(dst);
|
|
7008
|
+
const char* src_data = upb_Array_DataPtr(src);
|
|
7009
|
+
memcpy(dst_data + (dst_len << lg2), src_data, src_len << lg2);
|
|
7010
|
+
return true;
|
|
7011
|
+
}
|
|
7012
|
+
|
|
6831
7013
|
void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx,
|
|
6832
7014
|
size_t count) {
|
|
6833
7015
|
UPB_ASSERT(!upb_Array_IsFrozen(arr));
|
|
@@ -6888,9 +7070,17 @@ bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity,
|
|
|
6888
7070
|
void* ptr = upb_Array_MutableDataPtr(array);
|
|
6889
7071
|
|
|
6890
7072
|
// Log2 ceiling of size.
|
|
6891
|
-
while (new_capacity < min_capacity)
|
|
7073
|
+
while (new_capacity < min_capacity) {
|
|
7074
|
+
if (upb_ShlOverflow(&new_capacity, 1)) {
|
|
7075
|
+
new_capacity = SIZE_MAX;
|
|
7076
|
+
break;
|
|
7077
|
+
}
|
|
7078
|
+
}
|
|
6892
7079
|
|
|
6893
|
-
|
|
7080
|
+
size_t new_bytes = new_capacity;
|
|
7081
|
+
if (upb_ShlOverflow(&new_bytes, lg2)) {
|
|
7082
|
+
return false;
|
|
7083
|
+
}
|
|
6894
7084
|
ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
|
|
6895
7085
|
if (!ptr) return false;
|
|
6896
7086
|
|
|
@@ -7348,6 +7538,7 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg,
|
|
|
7348
7538
|
if (!view) return false;
|
|
7349
7539
|
view->data = data;
|
|
7350
7540
|
} else {
|
|
7541
|
+
if (SIZE_MAX - sizeof(upb_StringView) < len) return false;
|
|
7351
7542
|
view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len);
|
|
7352
7543
|
if (!view) return false;
|
|
7353
7544
|
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char);
|
|
@@ -8124,7 +8315,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
|
|
|
8124
8315
|
case kUpb_CType_String:
|
|
8125
8316
|
case kUpb_CType_Bytes: {
|
|
8126
8317
|
upb_StringView source = *(upb_StringView*)value;
|
|
8127
|
-
|
|
8318
|
+
size_t size = source.size;
|
|
8128
8319
|
void* cloned_data = upb_Arena_Malloc(arena, size);
|
|
8129
8320
|
if (cloned_data == NULL) {
|
|
8130
8321
|
return false;
|
|
@@ -8504,8 +8695,15 @@ bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg,
|
|
|
8504
8695
|
in->capacity = capacity;
|
|
8505
8696
|
UPB_PRIVATE(_upb_Message_SetInternal)(msg, in);
|
|
8506
8697
|
} else if (in->capacity == in->size) {
|
|
8698
|
+
if (in->size == UINT32_MAX) return false;
|
|
8507
8699
|
// Internal data is too small, reallocate.
|
|
8508
|
-
|
|
8700
|
+
size_t needed_pow2 = upb_RoundUpToPowerOfTwo(in->size + 1);
|
|
8701
|
+
if (needed_pow2 > UINT32_MAX) return false;
|
|
8702
|
+
uint32_t new_capacity = needed_pow2;
|
|
8703
|
+
if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_Message_Internal, aux_data,
|
|
8704
|
+
new_capacity)) {
|
|
8705
|
+
return false;
|
|
8706
|
+
}
|
|
8509
8707
|
in = upb_Arena_Realloc(a, in, _upb_Message_SizeOfInternal(in->capacity),
|
|
8510
8708
|
_upb_Message_SizeOfInternal(new_capacity));
|
|
8511
8709
|
if (!in) return false;
|
|
@@ -8710,7 +8908,6 @@ upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len,
|
|
|
8710
8908
|
|
|
8711
8909
|
|
|
8712
8910
|
#include <inttypes.h>
|
|
8713
|
-
#include <stdalign.h>
|
|
8714
8911
|
#include <stddef.h>
|
|
8715
8912
|
#include <stdint.h>
|
|
8716
8913
|
#include <stdlib.h>
|
|
@@ -10117,28 +10314,25 @@ char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
|
|
|
10117
10314
|
|
|
10118
10315
|
// Must be last.
|
|
10119
10316
|
|
|
10120
|
-
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
|
|
10121
|
-
|
|
10122
10317
|
struct upb_ExtensionRegistry {
|
|
10318
|
+
upb_exttable exts;
|
|
10123
10319
|
upb_Arena* arena;
|
|
10124
|
-
upb_strtable exts; // Key is upb_MiniTable* concatenated with fieldnum.
|
|
10125
10320
|
};
|
|
10126
10321
|
|
|
10127
|
-
static void extreg_key(char* buf, const upb_MiniTable* l, uint32_t fieldnum) {
|
|
10128
|
-
memcpy(buf, &l, sizeof(l));
|
|
10129
|
-
memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
|
|
10130
|
-
}
|
|
10131
|
-
|
|
10132
10322
|
upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) {
|
|
10133
10323
|
upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r));
|
|
10134
10324
|
if (!r) return NULL;
|
|
10135
10325
|
r->arena = arena;
|
|
10136
|
-
if (!
|
|
10326
|
+
if (!upb_exttable_init(&r->exts, 8, arena)) return NULL;
|
|
10137
10327
|
return r;
|
|
10138
10328
|
}
|
|
10139
10329
|
|
|
10140
10330
|
UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add(
|
|
10141
10331
|
upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) {
|
|
10332
|
+
UPB_STATIC_ASSERT(
|
|
10333
|
+
offsetof(upb_MiniTableExtension,
|
|
10334
|
+
UPB_PRIVATE(field).UPB_PRIVATE(number)) == 0,
|
|
10335
|
+
"Extension must be first-member-of-struct convertable with uint32_t");
|
|
10142
10336
|
uint32_t fieldnum = upb_MiniTableExtension_Number(e);
|
|
10143
10337
|
const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(e);
|
|
10144
10338
|
|
|
@@ -10148,15 +10342,11 @@ UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add(
|
|
|
10148
10342
|
return kUpb_ExtensionRegistryStatus_InvalidExtension;
|
|
10149
10343
|
}
|
|
10150
10344
|
|
|
10151
|
-
|
|
10152
|
-
extreg_key(buf, extendee, fieldnum);
|
|
10153
|
-
|
|
10154
|
-
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) {
|
|
10345
|
+
if (upb_exttable_lookup(&r->exts, extendee, fieldnum) != NULL) {
|
|
10155
10346
|
return kUpb_ExtensionRegistryStatus_DuplicateEntry;
|
|
10156
10347
|
}
|
|
10157
10348
|
|
|
10158
|
-
if (!
|
|
10159
|
-
upb_value_constptr(e), r->arena)) {
|
|
10349
|
+
if (!upb_exttable_insert(&r->exts, extendee, (const uint32_t*)e, r->arena)) {
|
|
10160
10350
|
return kUpb_ExtensionRegistryStatus_OutOfMemory;
|
|
10161
10351
|
}
|
|
10162
10352
|
return kUpb_ExtensionRegistryStatus_Ok;
|
|
@@ -10177,10 +10367,8 @@ failure:
|
|
|
10177
10367
|
// Back out the entries previously added.
|
|
10178
10368
|
for (end = e, e = start; e < end; e++) {
|
|
10179
10369
|
const upb_MiniTableExtension* ext = *e;
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
upb_MiniTableExtension_Number(ext));
|
|
10183
|
-
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
|
|
10370
|
+
upb_exttable_remove(&r->exts, upb_MiniTableExtension_Extendee(ext),
|
|
10371
|
+
upb_MiniTableExtension_Number(ext));
|
|
10184
10372
|
}
|
|
10185
10373
|
UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok);
|
|
10186
10374
|
return status;
|
|
@@ -10188,18 +10376,12 @@ failure:
|
|
|
10188
10376
|
|
|
10189
10377
|
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
|
|
10190
10378
|
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
|
|
10191
|
-
|
|
10192
|
-
|
|
10193
|
-
extreg_key(buf, t, num);
|
|
10194
|
-
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
|
|
10195
|
-
return upb_value_getconstptr(v);
|
|
10196
|
-
} else {
|
|
10197
|
-
return NULL;
|
|
10198
|
-
}
|
|
10379
|
+
const uint32_t* v = upb_exttable_lookup(&r->exts, t, num);
|
|
10380
|
+
return (const upb_MiniTableExtension*)v;
|
|
10199
10381
|
}
|
|
10200
10382
|
|
|
10201
10383
|
size_t upb_ExtensionRegistry_Size(const upb_ExtensionRegistry* r) {
|
|
10202
|
-
return
|
|
10384
|
+
return upb_exttable_size(&r->exts);
|
|
10203
10385
|
}
|
|
10204
10386
|
|
|
10205
10387
|
|
|
@@ -10448,6 +10630,7 @@ struct upb_DefPool {
|
|
|
10448
10630
|
size_t scratch_size;
|
|
10449
10631
|
size_t bytes_loaded;
|
|
10450
10632
|
bool disable_closed_enum_checking;
|
|
10633
|
+
bool disable_implicit_field_presence;
|
|
10451
10634
|
};
|
|
10452
10635
|
|
|
10453
10636
|
void upb_DefPool_Free(upb_DefPool* s) {
|
|
@@ -10466,6 +10649,7 @@ upb_DefPool* upb_DefPool_New(void) {
|
|
|
10466
10649
|
s->arena = upb_Arena_New();
|
|
10467
10650
|
s->bytes_loaded = 0;
|
|
10468
10651
|
s->disable_closed_enum_checking = false;
|
|
10652
|
+
s->disable_implicit_field_presence = false;
|
|
10469
10653
|
|
|
10470
10654
|
s->scratch_size = 240;
|
|
10471
10655
|
s->scratch_data = upb_gmalloc(s->scratch_size);
|
|
@@ -10507,6 +10691,15 @@ bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s) {
|
|
|
10507
10691
|
return s->disable_closed_enum_checking;
|
|
10508
10692
|
}
|
|
10509
10693
|
|
|
10694
|
+
void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s) {
|
|
10695
|
+
UPB_ASSERT(upb_strtable_count(&s->files) == 0);
|
|
10696
|
+
s->disable_implicit_field_presence = true;
|
|
10697
|
+
}
|
|
10698
|
+
|
|
10699
|
+
bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s) {
|
|
10700
|
+
return s->disable_implicit_field_presence;
|
|
10701
|
+
}
|
|
10702
|
+
|
|
10510
10703
|
const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults(
|
|
10511
10704
|
const upb_DefPool* s) {
|
|
10512
10705
|
return s->feature_set_defaults;
|
|
@@ -10616,7 +10809,7 @@ void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform) {
|
|
|
10616
10809
|
|
|
10617
10810
|
const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s,
|
|
10618
10811
|
const char* sym) {
|
|
10619
|
-
return
|
|
10812
|
+
return upb_DefPool_FindMessageByNameWithSize(s, sym, strlen(sym));
|
|
10620
10813
|
}
|
|
10621
10814
|
|
|
10622
10815
|
const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
|
|
@@ -10626,12 +10819,23 @@ const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
|
|
|
10626
10819
|
|
|
10627
10820
|
const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
|
|
10628
10821
|
const char* sym) {
|
|
10629
|
-
return
|
|
10822
|
+
return upb_DefPool_FindEnumByNameWithSize(s, sym, strlen(sym));
|
|
10823
|
+
}
|
|
10824
|
+
|
|
10825
|
+
const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize(const upb_DefPool* s,
|
|
10826
|
+
const char* sym,
|
|
10827
|
+
size_t len) {
|
|
10828
|
+
return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUM);
|
|
10630
10829
|
}
|
|
10631
10830
|
|
|
10632
|
-
const upb_EnumValueDef*
|
|
10633
|
-
|
|
10634
|
-
return
|
|
10831
|
+
const upb_EnumValueDef* upb_DefPool_FindEnumValueByName(const upb_DefPool* s,
|
|
10832
|
+
const char* sym) {
|
|
10833
|
+
return upb_DefPool_FindEnumValueByNameWithSize(s, sym, strlen(sym));
|
|
10834
|
+
}
|
|
10835
|
+
|
|
10836
|
+
const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize(
|
|
10837
|
+
const upb_DefPool* s, const char* sym, size_t len) {
|
|
10838
|
+
return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUMVAL);
|
|
10635
10839
|
}
|
|
10636
10840
|
|
|
10637
10841
|
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
|
|
@@ -12248,7 +12452,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
|
|
|
12248
12452
|
|
|
12249
12453
|
f->has_presence =
|
|
12250
12454
|
(!upb_FieldDef_IsRepeated(f)) &&
|
|
12251
|
-
(f->is_extension ||
|
|
12455
|
+
(f->is_extension || _upb_FileDef_ImplicitFieldPresenceDisabled(f->file) ||
|
|
12252
12456
|
(f->type_ == kUpb_FieldType_Message ||
|
|
12253
12457
|
f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) ||
|
|
12254
12458
|
google_protobuf_FeatureSet_field_presence(f->resolved_features) !=
|
|
@@ -12652,6 +12856,10 @@ bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f) {
|
|
|
12652
12856
|
return upb_DefPool_ClosedEnumCheckingDisabled(f->symtab);
|
|
12653
12857
|
}
|
|
12654
12858
|
|
|
12859
|
+
bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f) {
|
|
12860
|
+
return upb_DefPool_ImplicitFieldPresenceDisabled(f->symtab);
|
|
12861
|
+
}
|
|
12862
|
+
|
|
12655
12863
|
int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) {
|
|
12656
12864
|
return f->top_lvl_enum_count;
|
|
12657
12865
|
}
|
|
@@ -14540,6 +14748,7 @@ static void create_method(upb_DefBuilder* ctx,
|
|
|
14540
14748
|
m->output_type = _upb_DefBuilder_Resolve(
|
|
14541
14749
|
ctx, m->full_name, m->full_name,
|
|
14542
14750
|
google_protobuf_MethodDescriptorProto_output_type(method_proto), UPB_DEFTYPE_MSG);
|
|
14751
|
+
_upb_ServiceDef_InsertMethod(ctx, s, m);
|
|
14543
14752
|
}
|
|
14544
14753
|
|
|
14545
14754
|
// Allocate and initialize an array of |n| method defs belonging to |s|.
|
|
@@ -14771,6 +14980,7 @@ struct upb_ServiceDef {
|
|
|
14771
14980
|
upb_MethodDef* methods;
|
|
14772
14981
|
int method_count;
|
|
14773
14982
|
int index;
|
|
14983
|
+
upb_strtable ntom;
|
|
14774
14984
|
};
|
|
14775
14985
|
|
|
14776
14986
|
upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) {
|
|
@@ -14815,13 +15025,18 @@ const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) {
|
|
|
14815
15025
|
|
|
14816
15026
|
const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s,
|
|
14817
15027
|
const char* name) {
|
|
14818
|
-
|
|
14819
|
-
|
|
14820
|
-
|
|
14821
|
-
|
|
14822
|
-
|
|
15028
|
+
return upb_ServiceDef_FindMethodByNameWithSize(s, name, strlen(name));
|
|
15029
|
+
}
|
|
15030
|
+
|
|
15031
|
+
const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize(
|
|
15032
|
+
const upb_ServiceDef* s, const char* name, size_t len) {
|
|
15033
|
+
upb_value val;
|
|
15034
|
+
|
|
15035
|
+
if (!upb_strtable_lookup2(&s->ntom, name, len, &val)) {
|
|
15036
|
+
return NULL;
|
|
14823
15037
|
}
|
|
14824
|
-
|
|
15038
|
+
|
|
15039
|
+
return _upb_DefType_Unpack(val, UPB_DEFTYPE_METHOD);
|
|
14825
15040
|
}
|
|
14826
15041
|
|
|
14827
15042
|
static void create_service(upb_DefBuilder* ctx,
|
|
@@ -14846,6 +15061,8 @@ static void create_service(upb_DefBuilder* ctx,
|
|
|
14846
15061
|
const google_protobuf_MethodDescriptorProto* const* methods =
|
|
14847
15062
|
google_protobuf_ServiceDescriptorProto_method(svc_proto, &n);
|
|
14848
15063
|
s->method_count = n;
|
|
15064
|
+
bool ok = upb_strtable_init(&s->ntom, n, ctx->arena);
|
|
15065
|
+
if (!ok) _upb_DefBuilder_OomErr(ctx);
|
|
14849
15066
|
s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s);
|
|
14850
15067
|
}
|
|
14851
15068
|
|
|
@@ -14863,6 +15080,20 @@ upb_ServiceDef* _upb_ServiceDefs_New(
|
|
|
14863
15080
|
return s;
|
|
14864
15081
|
}
|
|
14865
15082
|
|
|
15083
|
+
void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s,
|
|
15084
|
+
const upb_MethodDef* m) {
|
|
15085
|
+
const char* shortname = upb_MethodDef_Name(m);
|
|
15086
|
+
const size_t shortnamelen = strlen(shortname);
|
|
15087
|
+
upb_value existing_v;
|
|
15088
|
+
if (upb_strtable_lookup(&s->ntom, shortname, &existing_v)) {
|
|
15089
|
+
_upb_DefBuilder_Errf(ctx, "duplicate method name (%s)", shortname);
|
|
15090
|
+
}
|
|
15091
|
+
const upb_value method_v = _upb_DefType_Pack(m, UPB_DEFTYPE_METHOD);
|
|
15092
|
+
bool ok = upb_strtable_insert(&s->ntom, shortname, shortnamelen, method_v,
|
|
15093
|
+
ctx->arena);
|
|
15094
|
+
if (!ok) _upb_DefBuilder_OomErr(ctx);
|
|
15095
|
+
}
|
|
15096
|
+
|
|
14866
15097
|
|
|
14867
15098
|
#include <inttypes.h>
|
|
14868
15099
|
#include <math.h>
|
|
@@ -16470,6 +16701,7 @@ const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
|
|
|
16470
16701
|
*op = kUpb_DecodeOp_UnknownField;
|
|
16471
16702
|
return ptr;
|
|
16472
16703
|
}
|
|
16704
|
+
_upb_Decoder_MungeInt32(val);
|
|
16473
16705
|
} else {
|
|
16474
16706
|
_upb_Decoder_Munge(field, val);
|
|
16475
16707
|
}
|
|
@@ -16512,7 +16744,6 @@ const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
|
|
|
16512
16744
|
UPB_FORCEINLINE
|
|
16513
16745
|
const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
|
|
16514
16746
|
upb_Message* msg,
|
|
16515
|
-
const upb_MiniTable* layout,
|
|
16516
16747
|
const upb_MiniTableField* field,
|
|
16517
16748
|
int op, wireval* val) {
|
|
16518
16749
|
uint8_t mode = field->UPB_PRIVATE(mode);
|
|
@@ -16541,67 +16772,13 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
|
|
|
16541
16772
|
}
|
|
16542
16773
|
}
|
|
16543
16774
|
|
|
16544
|
-
static const char* _upb_Decoder_FindFieldStart(upb_Decoder* d, const char* ptr,
|
|
16545
|
-
uint32_t field_number,
|
|
16546
|
-
uint32_t wire_type) {
|
|
16547
|
-
// Since unknown fields are the uncommon case, we do a little extra work here
|
|
16548
|
-
// to walk backwards through the buffer to find the field start. This frees
|
|
16549
|
-
// up a register in the fast paths (when the field is known), which leads to
|
|
16550
|
-
// significant speedups in benchmarks. Note that ptr may point into the slop
|
|
16551
|
-
// space, beyond the normal end of the input buffer.
|
|
16552
|
-
const char* start = ptr;
|
|
16553
|
-
|
|
16554
|
-
switch (wire_type) {
|
|
16555
|
-
case kUpb_WireType_Varint:
|
|
16556
|
-
case kUpb_WireType_Delimited:
|
|
16557
|
-
// Skip the last byte
|
|
16558
|
-
start--;
|
|
16559
|
-
// Skip bytes until we encounter the final byte of the tag varint.
|
|
16560
|
-
while (start[-1] & 0x80) start--;
|
|
16561
|
-
break;
|
|
16562
|
-
case kUpb_WireType_32Bit:
|
|
16563
|
-
start -= 4;
|
|
16564
|
-
break;
|
|
16565
|
-
case kUpb_WireType_64Bit:
|
|
16566
|
-
start -= 8;
|
|
16567
|
-
break;
|
|
16568
|
-
default:
|
|
16569
|
-
break;
|
|
16570
|
-
}
|
|
16571
|
-
assert(start == d->debug_valstart);
|
|
16572
|
-
|
|
16573
|
-
{
|
|
16574
|
-
// The varint parser does not enforce that integers are encoded with their
|
|
16575
|
-
// minimum size; for example the value 1 could be encoded with three
|
|
16576
|
-
// bytes: 0x81, 0x80, 0x00. These unnecessary trailing zeroes mean that we
|
|
16577
|
-
// cannot skip backwards by the minimum encoded size of the tag; and
|
|
16578
|
-
// unlike the loop for delimited or varint fields, we can't stop at a
|
|
16579
|
-
// sentinel value because anything can precede a tag. Instead, parse back
|
|
16580
|
-
// one byte at a time until we read the same tag value that was parsed
|
|
16581
|
-
// earlier.
|
|
16582
|
-
uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
|
|
16583
|
-
uint32_t seen = 0;
|
|
16584
|
-
do {
|
|
16585
|
-
start--;
|
|
16586
|
-
seen <<= 7;
|
|
16587
|
-
seen |= *start & 0x7f;
|
|
16588
|
-
} while (seen != tag);
|
|
16589
|
-
}
|
|
16590
|
-
assert(start == d->debug_tagstart);
|
|
16591
|
-
|
|
16592
|
-
return start;
|
|
16593
|
-
}
|
|
16594
|
-
|
|
16595
16775
|
static const char* _upb_Decoder_DecodeUnknownField(
|
|
16596
16776
|
upb_Decoder* d, const char* ptr, upb_Message* msg, uint32_t field_number,
|
|
16597
|
-
uint32_t wire_type, wireval val) {
|
|
16777
|
+
uint32_t wire_type, wireval val, const char* start) {
|
|
16598
16778
|
if (field_number == 0) {
|
|
16599
16779
|
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
|
|
16600
16780
|
}
|
|
16601
16781
|
|
|
16602
|
-
const char* start =
|
|
16603
|
-
_upb_Decoder_FindFieldStart(d, ptr, field_number, wire_type);
|
|
16604
|
-
|
|
16605
16782
|
upb_EpsCopyInputStream_StartCapture(&d->input, start);
|
|
16606
16783
|
|
|
16607
16784
|
if (wire_type == kUpb_WireType_Delimited) {
|
|
@@ -16640,10 +16817,6 @@ UPB_FORCEINLINE
|
|
|
16640
16817
|
const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr,
|
|
16641
16818
|
uint32_t* field_number,
|
|
16642
16819
|
uint32_t* wire_type) {
|
|
16643
|
-
#ifndef NDEBUG
|
|
16644
|
-
d->debug_tagstart = ptr;
|
|
16645
|
-
#endif
|
|
16646
|
-
|
|
16647
16820
|
uint32_t tag;
|
|
16648
16821
|
UPB_ASSERT(ptr < d->input.limit_ptr);
|
|
16649
16822
|
ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d));
|
|
@@ -16653,15 +16826,9 @@ const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr,
|
|
|
16653
16826
|
}
|
|
16654
16827
|
|
|
16655
16828
|
UPB_FORCEINLINE
|
|
16656
|
-
const char* _upb_Decoder_DecodeFieldData(
|
|
16657
|
-
|
|
16658
|
-
|
|
16659
|
-
uint32_t field_number,
|
|
16660
|
-
uint32_t wire_type) {
|
|
16661
|
-
#ifndef NDEBUG
|
|
16662
|
-
d->debug_valstart = ptr;
|
|
16663
|
-
#endif
|
|
16664
|
-
|
|
16829
|
+
const char* _upb_Decoder_DecodeFieldData(
|
|
16830
|
+
upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* mt,
|
|
16831
|
+
uint32_t field_number, uint32_t wire_type, const char* start) {
|
|
16665
16832
|
int op;
|
|
16666
16833
|
wireval val;
|
|
16667
16834
|
|
|
@@ -16670,12 +16837,12 @@ const char* _upb_Decoder_DecodeFieldData(upb_Decoder* d, const char* ptr,
|
|
|
16670
16837
|
ptr = _upb_Decoder_DecodeWireValue(d, ptr, mt, field, wire_type, &val, &op);
|
|
16671
16838
|
|
|
16672
16839
|
if (op >= 0) {
|
|
16673
|
-
return _upb_Decoder_DecodeKnownField(d, ptr, msg,
|
|
16840
|
+
return _upb_Decoder_DecodeKnownField(d, ptr, msg, field, op, &val);
|
|
16674
16841
|
} else {
|
|
16675
16842
|
switch (op) {
|
|
16676
16843
|
case kUpb_DecodeOp_UnknownField:
|
|
16677
16844
|
return _upb_Decoder_DecodeUnknownField(d, ptr, msg, field_number,
|
|
16678
|
-
wire_type, val);
|
|
16845
|
+
wire_type, val, start);
|
|
16679
16846
|
case kUpb_DecodeOp_MessageSetItem:
|
|
16680
16847
|
return upb_Decoder_DecodeMessageSetItem(d, ptr, msg, mt);
|
|
16681
16848
|
default:
|
|
@@ -16696,6 +16863,7 @@ const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr,
|
|
|
16696
16863
|
uint32_t field_number;
|
|
16697
16864
|
uint32_t wire_type;
|
|
16698
16865
|
|
|
16866
|
+
const char* start = ptr;
|
|
16699
16867
|
ptr = _upb_Decoder_DecodeFieldTag(d, ptr, &field_number, &wire_type);
|
|
16700
16868
|
|
|
16701
16869
|
if (wire_type == kUpb_WireType_EndGroup) {
|
|
@@ -16703,7 +16871,8 @@ const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr,
|
|
|
16703
16871
|
return _upb_Decoder_EndMessage(d, ptr);
|
|
16704
16872
|
}
|
|
16705
16873
|
|
|
16706
|
-
ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type
|
|
16874
|
+
ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type,
|
|
16875
|
+
start);
|
|
16707
16876
|
_upb_Decoder_Trace(d, 'M');
|
|
16708
16877
|
return ptr;
|
|
16709
16878
|
}
|
|
@@ -16922,14 +17091,6 @@ typedef struct {
|
|
|
16922
17091
|
_upb_mapsorter sorter;
|
|
16923
17092
|
} upb_encstate;
|
|
16924
17093
|
|
|
16925
|
-
static size_t upb_roundup_pow2(size_t bytes) {
|
|
16926
|
-
size_t ret = 128;
|
|
16927
|
-
while (ret < bytes) {
|
|
16928
|
-
ret *= 2;
|
|
16929
|
-
}
|
|
16930
|
-
return ret;
|
|
16931
|
-
}
|
|
16932
|
-
|
|
16933
17094
|
UPB_NORETURN static void encode_err(upb_encstate* e, upb_EncodeStatus s) {
|
|
16934
17095
|
UPB_ASSERT(s != kUpb_EncodeStatus_Ok);
|
|
16935
17096
|
e->status = s;
|
|
@@ -16945,7 +17106,9 @@ UPB_NOINLINE static char* encode_growbuffer(char* ptr, upb_encstate* e,
|
|
|
16945
17106
|
size_t bytes) {
|
|
16946
17107
|
size_t old_size = e->limit - e->buf;
|
|
16947
17108
|
size_t needed_size = bytes + (e->limit - ptr);
|
|
16948
|
-
|
|
17109
|
+
if (needed_size < bytes) encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
17110
|
+
size_t new_size = upb_RoundUpToPowerOfTwo(UPB_MAX(128, needed_size));
|
|
17111
|
+
if (new_size == old_size) encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
16949
17112
|
void* old_buf = e->buf == &initial_buf_sentinel ? NULL : (void*)e->buf;
|
|
16950
17113
|
char* new_buf = upb_Arena_Realloc(e->arena, old_buf, old_size, new_size);
|
|
16951
17114
|
|