google-protobuf 4.34.0.rc.2-java → 4.35.0.rc.1-java
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 +407 -242
- data/ext/google/protobuf_c/ruby-upb.h +150 -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/protobuf/descriptor_pb.rb +1 -1
- data/lib/google/protobuf_java.jar +0 -0
- metadata +6 -6
|
@@ -1962,7 +1962,7 @@ const upb_MiniTable google__protobuf__GeneratedCodeInfo__Annotation_msg_init = {
|
|
|
1962
1962
|
|
|
1963
1963
|
const upb_MiniTableEnum google__protobuf__Edition_enum_init = {
|
|
1964
1964
|
64,
|
|
1965
|
-
|
|
1965
|
+
11,
|
|
1966
1966
|
{
|
|
1967
1967
|
0x7,
|
|
1968
1968
|
0x0,
|
|
@@ -1971,6 +1971,7 @@ const upb_MiniTableEnum google__protobuf__Edition_enum_init = {
|
|
|
1971
1971
|
0x3e7,
|
|
1972
1972
|
0x3e8,
|
|
1973
1973
|
0x3e9,
|
|
1974
|
+
0x3ea,
|
|
1974
1975
|
0x270f,
|
|
1975
1976
|
0x1869d,
|
|
1976
1977
|
0x1869e,
|
|
@@ -1992,7 +1993,7 @@ const upb_MiniTableEnum google__protobuf__FeatureSet__EnforceNamingStyle_enum_in
|
|
|
1992
1993
|
64,
|
|
1993
1994
|
0,
|
|
1994
1995
|
{
|
|
1995
|
-
|
|
1996
|
+
0xf,
|
|
1996
1997
|
0x0,
|
|
1997
1998
|
},
|
|
1998
1999
|
};
|
|
@@ -2338,10 +2339,15 @@ static int log2ceil(uint64_t v) {
|
|
|
2338
2339
|
return UPB_MIN(UPB_MAXARRSIZE, ret);
|
|
2339
2340
|
}
|
|
2340
2341
|
|
|
2341
|
-
/* A type to represent the lookup key of either a strtable
|
|
2342
|
+
/* A type to represent the lookup key of either a strtable, inttable or
|
|
2343
|
+
* exttable. */
|
|
2342
2344
|
typedef union {
|
|
2343
2345
|
uintptr_t num;
|
|
2344
2346
|
upb_StringView str;
|
|
2347
|
+
struct {
|
|
2348
|
+
const void* ptr;
|
|
2349
|
+
uint32_t ext_num;
|
|
2350
|
+
} ext;
|
|
2345
2351
|
} lookupkey_t;
|
|
2346
2352
|
|
|
2347
2353
|
static lookupkey_t strkey2(const char* str, size_t len) {
|
|
@@ -2350,16 +2356,24 @@ static lookupkey_t strkey2(const char* str, size_t len) {
|
|
|
2350
2356
|
|
|
2351
2357
|
static lookupkey_t intkey(uintptr_t key) { return (lookupkey_t){.num = key}; }
|
|
2352
2358
|
|
|
2353
|
-
|
|
2354
|
-
|
|
2359
|
+
static lookupkey_t extkey(const void* ptr, uint32_t ext_num) {
|
|
2360
|
+
return (lookupkey_t){.ext = {ptr, ext_num}};
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// Conceptually the hash and equal functions should only take the key, not the
|
|
2364
|
+
// value, but the extension table stores part of its logical key in the value
|
|
2365
|
+
// slot. This is a sign that we have outgrown the original architecture.
|
|
2366
|
+
typedef uint32_t hashfunc_t(upb_key key, upb_value val);
|
|
2367
|
+
typedef bool eqlfunc_t(upb_key k1, upb_value v1, lookupkey_t k2);
|
|
2355
2368
|
|
|
2356
2369
|
/* Base table (shared code) ***************************************************/
|
|
2357
2370
|
|
|
2358
2371
|
static uint32_t upb_inthash(uintptr_t key) {
|
|
2372
|
+
UPB_STATIC_ASSERT(sizeof(uintptr_t) == 4 || sizeof(uintptr_t) == 8,
|
|
2373
|
+
"Pointers don't fit");
|
|
2359
2374
|
if (sizeof(uintptr_t) == 8) {
|
|
2360
2375
|
return (uint32_t)key ^ (uint32_t)(key >> 32);
|
|
2361
2376
|
} else {
|
|
2362
|
-
UPB_ASSERT(sizeof(uintptr_t) == 4);
|
|
2363
2377
|
return (uint32_t)key;
|
|
2364
2378
|
}
|
|
2365
2379
|
}
|
|
@@ -2420,7 +2434,7 @@ static const upb_tabent* findentry(const upb_table* t, lookupkey_t key,
|
|
|
2420
2434
|
e = upb_getentry(t, hash);
|
|
2421
2435
|
if (upb_tabent_isempty(e)) return NULL;
|
|
2422
2436
|
while (1) {
|
|
2423
|
-
if (eql(e->key, key)) return e;
|
|
2437
|
+
if (eql(e->key, e->val, key)) return e;
|
|
2424
2438
|
if ((e = e->next) == NULL) return NULL;
|
|
2425
2439
|
}
|
|
2426
2440
|
}
|
|
@@ -2460,7 +2474,8 @@ static void insert(upb_table* t, lookupkey_t key, upb_key tabkey, upb_value val,
|
|
|
2460
2474
|
/* Collision. */
|
|
2461
2475
|
upb_tabent* new_e = emptyent(t, mainpos_e);
|
|
2462
2476
|
/* Head of collider's chain. */
|
|
2463
|
-
upb_tabent* chain =
|
|
2477
|
+
upb_tabent* chain =
|
|
2478
|
+
getentry_mutable(t, hashfunc(mainpos_e->key, mainpos_e->val));
|
|
2464
2479
|
if (chain == mainpos_e) {
|
|
2465
2480
|
/* Existing ent is in its main position (it has the same hash as us, and
|
|
2466
2481
|
* is the head of our chain). Insert to new ent and append to this chain.
|
|
@@ -2491,7 +2506,7 @@ static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash,
|
|
|
2491
2506
|
eqlfunc_t* eql) {
|
|
2492
2507
|
upb_tabent* chain = getentry_mutable(t, hash);
|
|
2493
2508
|
if (upb_tabent_isempty(chain)) return false;
|
|
2494
|
-
if (eql(chain->key, key)) {
|
|
2509
|
+
if (eql(chain->key, chain->val, key)) {
|
|
2495
2510
|
/* Element to remove is at the head of its chain. */
|
|
2496
2511
|
t->count--;
|
|
2497
2512
|
if (val) *val = chain->val;
|
|
@@ -2506,7 +2521,7 @@ static bool rm(upb_table* t, lookupkey_t key, upb_value* val, uint32_t hash,
|
|
|
2506
2521
|
} else {
|
|
2507
2522
|
/* Element to remove is either in a non-head position or not in the
|
|
2508
2523
|
* table. */
|
|
2509
|
-
while (chain->next && !eql(chain->next->key, key)) {
|
|
2524
|
+
while (chain->next && !eql(chain->next->key, chain->next->val, key)) {
|
|
2510
2525
|
chain = (upb_tabent*)chain->next;
|
|
2511
2526
|
}
|
|
2512
2527
|
if (chain->next) {
|
|
@@ -2705,11 +2720,13 @@ static uint32_t _upb_Hash_NoSeed(const char* p, size_t n) {
|
|
|
2705
2720
|
return _upb_Hash(p, n, _upb_Seed());
|
|
2706
2721
|
}
|
|
2707
2722
|
|
|
2708
|
-
static uint32_t strhash(upb_key key) {
|
|
2723
|
+
static uint32_t strhash(upb_key key, upb_value val) {
|
|
2724
|
+
UPB_UNUSED(val);
|
|
2709
2725
|
return _upb_Hash_NoSeed(key.str->data, key.str->size);
|
|
2710
2726
|
}
|
|
2711
2727
|
|
|
2712
|
-
static bool streql(upb_key k1, lookupkey_t k2) {
|
|
2728
|
+
static bool streql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
2729
|
+
UPB_UNUSED(v1);
|
|
2713
2730
|
const upb_SizePrefixString* k1s = k1.str;
|
|
2714
2731
|
const upb_StringView k2s = k2.str;
|
|
2715
2732
|
return k1s->size == k2s.size &&
|
|
@@ -2873,6 +2890,96 @@ void upb_strtable_setentryvalue(upb_strtable* t, intptr_t iter, upb_value v) {
|
|
|
2873
2890
|
t->t.entries[iter].val = v;
|
|
2874
2891
|
}
|
|
2875
2892
|
|
|
2893
|
+
/* upb_exttable ***************************************************************/
|
|
2894
|
+
|
|
2895
|
+
static uint32_t _upb_exttable_hash(const void* ptr, uint32_t ext_num) {
|
|
2896
|
+
uint64_t a = (uintptr_t)ptr;
|
|
2897
|
+
uint64_t b = ext_num;
|
|
2898
|
+
return (uint32_t)WyhashMix(a ^ kWyhashSalt[1], b ^ _upb_Seed());
|
|
2899
|
+
}
|
|
2900
|
+
|
|
2901
|
+
static uint32_t exthash(upb_key key, upb_value val) {
|
|
2902
|
+
const void* ptr = (const void*)key.num;
|
|
2903
|
+
uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(val);
|
|
2904
|
+
return _upb_exttable_hash(ptr, ext_num);
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
static bool exteql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
2908
|
+
if ((const void*)k1.num == k2.ext.ptr) {
|
|
2909
|
+
uint32_t ext_num1 = *(const uint32_t*)upb_value_getconstptr(v1);
|
|
2910
|
+
return ext_num1 == k2.ext.ext_num;
|
|
2911
|
+
}
|
|
2912
|
+
return false;
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
bool upb_exttable_init(upb_exttable* t, size_t expected_size, upb_Arena* a) {
|
|
2916
|
+
int size_lg2 = upb_Log2Ceiling(_upb_entries_needed_for(expected_size));
|
|
2917
|
+
return init(&t->t, size_lg2, a);
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
void upb_exttable_clear(upb_exttable* t) {
|
|
2921
|
+
size_t bytes = upb_table_size(&t->t) * sizeof(upb_tabent);
|
|
2922
|
+
t->t.count = 0;
|
|
2923
|
+
memset((char*)t->t.entries, 0, bytes);
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
bool upb_exttable_resize(upb_exttable* t, size_t size_lg2, upb_Arena* a) {
|
|
2927
|
+
upb_exttable new_table;
|
|
2928
|
+
if (!init(&new_table.t, size_lg2, a)) return false;
|
|
2929
|
+
|
|
2930
|
+
size_t i;
|
|
2931
|
+
for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
|
|
2932
|
+
const upb_tabent* e = &t->t.entries[i];
|
|
2933
|
+
uint32_t hash = exthash(e->key, e->val);
|
|
2934
|
+
uint32_t ext_num = *(const uint32_t*)upb_value_getconstptr(e->val);
|
|
2935
|
+
lookupkey_t lookupkey = extkey((const void*)e->key.num, ext_num);
|
|
2936
|
+
insert(&new_table.t, lookupkey, e->key, e->val, hash, &exthash, &exteql);
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
*t = new_table;
|
|
2940
|
+
return true;
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2943
|
+
bool upb_exttable_insert(upb_exttable* t, const void* k, const uint32_t* v,
|
|
2944
|
+
upb_Arena* a) {
|
|
2945
|
+
UPB_ASSERT(k != NULL);
|
|
2946
|
+
UPB_ASSERT(v != NULL);
|
|
2947
|
+
UPB_ASSERT(*v != 0);
|
|
2948
|
+
|
|
2949
|
+
if (isfull(&t->t)) {
|
|
2950
|
+
if (!upb_exttable_resize(t, _upb_log2_table_size(&t->t) + 1, a)) {
|
|
2951
|
+
return false;
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2955
|
+
lookupkey_t lookupkey = extkey(k, *v);
|
|
2956
|
+
upb_key key = {.num = (uintptr_t)k};
|
|
2957
|
+
upb_value val = upb_value_constptr(v);
|
|
2958
|
+
uint32_t hash = _upb_exttable_hash(k, *v);
|
|
2959
|
+
insert(&t->t, lookupkey, key, val, hash, &exthash, &exteql);
|
|
2960
|
+
return true;
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
const uint32_t* upb_exttable_lookup(const upb_exttable* t, const void* k,
|
|
2964
|
+
uint32_t ext_number) {
|
|
2965
|
+
uint32_t hash = _upb_exttable_hash(k, ext_number);
|
|
2966
|
+
upb_value val;
|
|
2967
|
+
if (lookup(&t->t, extkey(k, ext_number), &val, hash, &exteql)) {
|
|
2968
|
+
return (const uint32_t*)upb_value_getconstptr(val);
|
|
2969
|
+
}
|
|
2970
|
+
return NULL;
|
|
2971
|
+
}
|
|
2972
|
+
|
|
2973
|
+
const uint32_t* upb_exttable_remove(upb_exttable* t, const void* k,
|
|
2974
|
+
uint32_t ext_number) {
|
|
2975
|
+
uint32_t hash = _upb_exttable_hash(k, ext_number);
|
|
2976
|
+
upb_value val;
|
|
2977
|
+
if (rm(&t->t, extkey(k, ext_number), &val, hash, &exteql)) {
|
|
2978
|
+
return (const uint32_t*)upb_value_getconstptr(val);
|
|
2979
|
+
}
|
|
2980
|
+
return NULL;
|
|
2981
|
+
}
|
|
2982
|
+
|
|
2876
2983
|
/* upb_inttable ***************************************************************/
|
|
2877
2984
|
|
|
2878
2985
|
/* For inttables we use a hybrid structure where small keys are kept in an
|
|
@@ -2887,9 +2994,15 @@ static uint32_t presence_mask_arr_size(uint32_t array_size) {
|
|
|
2887
2994
|
return (array_size + 7) / 8; // sizeof(uint8_t) is always 1.
|
|
2888
2995
|
}
|
|
2889
2996
|
|
|
2890
|
-
static uint32_t inthash(upb_key key
|
|
2997
|
+
static uint32_t inthash(upb_key key, upb_value val) {
|
|
2998
|
+
UPB_UNUSED(val);
|
|
2999
|
+
return upb_inthash(key.num);
|
|
3000
|
+
}
|
|
2891
3001
|
|
|
2892
|
-
static bool inteql(upb_key k1, lookupkey_t k2) {
|
|
3002
|
+
static bool inteql(upb_key k1, upb_value v1, lookupkey_t k2) {
|
|
3003
|
+
UPB_UNUSED(v1);
|
|
3004
|
+
return k1.num == k2.num;
|
|
3005
|
+
}
|
|
2893
3006
|
|
|
2894
3007
|
static upb_value* mutable_array(upb_inttable* t) {
|
|
2895
3008
|
return (upb_value*)t->array;
|
|
@@ -2995,8 +3108,8 @@ bool upb_inttable_insert(upb_inttable* t, uintptr_t key, upb_value val,
|
|
|
2995
3108
|
|
|
2996
3109
|
for (i = begin(&t->t); i < upb_table_size(&t->t); i = next(&t->t, i)) {
|
|
2997
3110
|
const upb_tabent* e = &t->t.entries[i];
|
|
2998
|
-
insert(&new_table, intkey(e->key.num), e->key, e->val,
|
|
2999
|
-
&inthash, &inteql);
|
|
3111
|
+
insert(&new_table, intkey(e->key.num), e->key, e->val,
|
|
3112
|
+
inthash(e->key, e->val), &inthash, &inteql);
|
|
3000
3113
|
}
|
|
3001
3114
|
|
|
3002
3115
|
UPB_ASSERT(t->t.count == new_table.count);
|
|
@@ -5655,24 +5768,33 @@ static int GetLocaleRadix(char *data, size_t capacity) {
|
|
|
5655
5768
|
const int size = snprintf(temp, sizeof(temp), "%.1f", 1.5);
|
|
5656
5769
|
UPB_ASSERT(temp[0] == '1');
|
|
5657
5770
|
UPB_ASSERT(temp[size - 1] == '5');
|
|
5658
|
-
|
|
5771
|
+
if (size < capacity) {
|
|
5772
|
+
return 0;
|
|
5773
|
+
}
|
|
5659
5774
|
temp[size - 1] = '\0';
|
|
5660
|
-
|
|
5775
|
+
strncpy(data, temp + 1, size);
|
|
5661
5776
|
return size - 2;
|
|
5662
5777
|
}
|
|
5663
5778
|
|
|
5664
5779
|
// Populates a string identical to *input except that the character pointed to
|
|
5665
5780
|
// by pos (which should be '.') is replaced with the locale-specific radix.
|
|
5666
5781
|
|
|
5667
|
-
static void LocalizeRadix(const char *input, const char *pos, char *output
|
|
5782
|
+
static void LocalizeRadix(const char *input, const char *pos, char *output,
|
|
5783
|
+
int output_size) {
|
|
5668
5784
|
const int len1 = pos - input;
|
|
5669
5785
|
|
|
5670
5786
|
char radix[8];
|
|
5671
5787
|
const int len2 = GetLocaleRadix(radix, sizeof(radix));
|
|
5672
5788
|
|
|
5789
|
+
const int n = output_size - len1 - len2 - 1;
|
|
5790
|
+
if (n < 0) {
|
|
5791
|
+
return;
|
|
5792
|
+
}
|
|
5793
|
+
|
|
5673
5794
|
memcpy(output, input, len1);
|
|
5674
5795
|
memcpy(output + len1, radix, len2);
|
|
5675
|
-
|
|
5796
|
+
strncpy(output + len1 + len2, input + len1 + 1, n);
|
|
5797
|
+
output[output_size - 1] = '\0';
|
|
5676
5798
|
}
|
|
5677
5799
|
|
|
5678
5800
|
double _upb_NoLocaleStrtod(const char *str, char **endptr) {
|
|
@@ -5692,7 +5814,7 @@ double _upb_NoLocaleStrtod(const char *str, char **endptr) {
|
|
|
5692
5814
|
// try again.
|
|
5693
5815
|
|
|
5694
5816
|
char localized[80];
|
|
5695
|
-
LocalizeRadix(str, temp_endptr, localized);
|
|
5817
|
+
LocalizeRadix(str, temp_endptr, localized, sizeof localized);
|
|
5696
5818
|
char *localized_endptr;
|
|
5697
5819
|
result = strtod(localized, &localized_endptr);
|
|
5698
5820
|
if ((localized_endptr - &localized[0]) > (temp_endptr - str)) {
|
|
@@ -5774,6 +5896,7 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc};
|
|
|
5774
5896
|
static UPB_ATOMIC(size_t) g_max_block_size = UPB_DEFAULT_MAX_BLOCK_SIZE;
|
|
5775
5897
|
|
|
5776
5898
|
void upb_Arena_SetMaxBlockSize(size_t max) {
|
|
5899
|
+
UPB_ASSERT(max <= UINT32_MAX);
|
|
5777
5900
|
upb_Atomic_Store(&g_max_block_size, max, memory_order_relaxed);
|
|
5778
5901
|
}
|
|
5779
5902
|
|
|
@@ -5810,8 +5933,14 @@ typedef struct upb_ArenaInternal {
|
|
|
5810
5933
|
UPB_ATOMIC(const upb_ArenaRef*) refs;
|
|
5811
5934
|
#endif
|
|
5812
5935
|
|
|
5813
|
-
//
|
|
5814
|
-
|
|
5936
|
+
// Size of the last block we allocated in the normal exponential scheme.
|
|
5937
|
+
uint32_t last_block_size;
|
|
5938
|
+
|
|
5939
|
+
// A hint that grows whenever we perform a "one-off" allocation into a a
|
|
5940
|
+
// dedicated block. This helps us determine if these outlier blocks are
|
|
5941
|
+
// actually common enough that we should switch back to the normal exponential
|
|
5942
|
+
// scheme at the larger size.
|
|
5943
|
+
uint32_t size_hint;
|
|
5815
5944
|
|
|
5816
5945
|
// All non atomic members used during allocation must be above this point, and
|
|
5817
5946
|
// are used by _SwapIn/_SwapOut
|
|
@@ -6107,23 +6236,60 @@ bool upb_Arena_HasRefChain(const upb_Arena* from, const upb_Arena* to) {
|
|
|
6107
6236
|
|
|
6108
6237
|
#endif
|
|
6109
6238
|
|
|
6110
|
-
|
|
6111
|
-
|
|
6112
|
-
|
|
6239
|
+
static upb_MemBlock* _upb_Arena_AllocBlockInternal(upb_alloc* alloc,
|
|
6240
|
+
size_t size) {
|
|
6241
|
+
UPB_ASSERT(size >= kUpb_MemblockReserve);
|
|
6242
|
+
upb_SizedPtr alloc_result = upb_SizeReturningMalloc(alloc, size);
|
|
6243
|
+
if (!alloc_result.p) return NULL;
|
|
6244
|
+
upb_MemBlock* block = alloc_result.p;
|
|
6245
|
+
block->size = alloc_result.n;
|
|
6246
|
+
return block;
|
|
6247
|
+
}
|
|
6248
|
+
|
|
6249
|
+
static upb_MemBlock* _upb_Arena_AllocBlock(upb_Arena* a, size_t size) {
|
|
6250
|
+
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6251
|
+
return _upb_Arena_AllocBlockInternal(_upb_ArenaInternal_BlockAlloc(ai), size);
|
|
6252
|
+
}
|
|
6253
|
+
|
|
6254
|
+
static void _upb_Arena_AddBlock(upb_Arena* a, upb_MemBlock* block) {
|
|
6113
6255
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6114
|
-
upb_MemBlock* block = ptr;
|
|
6115
6256
|
|
|
6116
|
-
|
|
6117
|
-
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6257
|
+
// Atomic add not required here, as threads won't race allocating blocks, plus
|
|
6258
|
+
// atomic fetch-add is slower than load/add/store on arm devices compiled
|
|
6259
|
+
// targeting pre-v8.1. Relaxed order is safe as nothing depends on order of
|
|
6260
|
+
// size allocated.
|
|
6261
|
+
uintptr_t old_space_allocated =
|
|
6262
|
+
upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed);
|
|
6263
|
+
upb_Atomic_Store(&ai->space_allocated, old_space_allocated + block->size,
|
|
6264
|
+
memory_order_relaxed);
|
|
6265
|
+
|
|
6266
|
+
block->next = ai->blocks;
|
|
6121
6267
|
ai->blocks = block;
|
|
6122
|
-
|
|
6268
|
+
}
|
|
6269
|
+
|
|
6270
|
+
static void _upb_Arena_UseBlockInternal(upb_Arena* a, upb_MemBlock* block,
|
|
6271
|
+
size_t offset) {
|
|
6272
|
+
size_t block_size = block->size;
|
|
6273
|
+
char* start = UPB_PTR_AT(block, kUpb_MemblockReserve + offset, char);
|
|
6123
6274
|
a->UPB_PRIVATE(ptr) = start;
|
|
6124
6275
|
a->UPB_PRIVATE(end) = UPB_PTR_AT(block, block_size, char);
|
|
6125
6276
|
UPB_PRIVATE(upb_Xsan_PoisonRegion)(start, a->UPB_PRIVATE(end) - start);
|
|
6126
|
-
|
|
6277
|
+
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(a));
|
|
6278
|
+
UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >=
|
|
6279
|
+
block_size - kUpb_MemblockReserve - offset);
|
|
6280
|
+
}
|
|
6281
|
+
|
|
6282
|
+
static void _upb_Arena_UseBlock(upb_Arena* a, upb_MemBlock* block) {
|
|
6283
|
+
_upb_Arena_UseBlockInternal(a, block, 0);
|
|
6284
|
+
}
|
|
6285
|
+
|
|
6286
|
+
static bool _upb_Arena_WouldReduceFreeSpace(upb_Arena* a, size_t size,
|
|
6287
|
+
size_t block_size) {
|
|
6288
|
+
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6289
|
+
size_t current_free =
|
|
6290
|
+
ai->blocks ? a->UPB_PRIVATE(end) - a->UPB_PRIVATE(ptr) : 0;
|
|
6291
|
+
size_t future_free = block_size - kUpb_MemblockReserve - size;
|
|
6292
|
+
return current_free >= future_free;
|
|
6127
6293
|
}
|
|
6128
6294
|
|
|
6129
6295
|
// Fulfills the allocation request by allocating a new block. Returns NULL on
|
|
@@ -6131,84 +6297,60 @@ static void _upb_Arena_AddBlock(upb_Arena* a, void* ptr, size_t offset,
|
|
|
6131
6297
|
void* UPB_PRIVATE(_upb_Arena_SlowMalloc)(upb_Arena* a, size_t size) {
|
|
6132
6298
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6133
6299
|
if (!ai->block_alloc) return NULL;
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6300
|
+
|
|
6301
|
+
// Whether to satisfy the allocation from a one-off block which is right-sized
|
|
6302
|
+
// for the current allocation. We do this if we suspect that the current
|
|
6303
|
+
// allocation is an outlier that does not represent the typical size of
|
|
6304
|
+
// allocations from this arena, or if we would reduce free space by
|
|
6305
|
+
// using exponential growth.
|
|
6306
|
+
bool one_off = false;
|
|
6141
6307
|
|
|
6142
6308
|
// Relaxed order is safe here as we don't need any ordering with the setter.
|
|
6143
6309
|
size_t max_block_size =
|
|
6144
6310
|
upb_Atomic_Load(&g_max_block_size, memory_order_relaxed);
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
target_size < max_block_size) {
|
|
6155
|
-
last_size = ai->size_hint;
|
|
6156
|
-
// Recalculate sizes with possibly larger last_size
|
|
6157
|
-
target_size = UPB_MIN(last_size * 2, max_block_size);
|
|
6158
|
-
future_free = UPB_MAX(size, target_size - kUpb_MemblockReserve) - size;
|
|
6159
|
-
}
|
|
6160
|
-
bool insert_after_head = false;
|
|
6161
|
-
// Only insert after head if an allocated block is present; we don't want to
|
|
6162
|
-
// continue allocating out of the initial block because we'll have no way of
|
|
6163
|
-
// restoring the size of our allocated block if we add another.
|
|
6164
|
-
if (last_block && current_free >= future_free) {
|
|
6165
|
-
// If we're still going to net reduce free space with this new block, then
|
|
6166
|
-
// only allocate the precise size requested and keep the current last block
|
|
6167
|
-
// as the active block for future allocations.
|
|
6168
|
-
insert_after_head = true;
|
|
6169
|
-
target_size = size + kUpb_MemblockReserve;
|
|
6170
|
-
// Add something to our previous size each time, so that eventually we
|
|
6171
|
-
// will reach the max block size. Allocations larger than the max block size
|
|
6172
|
-
// will always get their own backing allocation, so don't include them.
|
|
6173
|
-
if (target_size <= max_block_size) {
|
|
6174
|
-
ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1);
|
|
6311
|
+
size_t block_size = UPB_MIN(ai->last_block_size * 2, max_block_size);
|
|
6312
|
+
|
|
6313
|
+
if (size + kUpb_MemblockReserve > block_size) {
|
|
6314
|
+
// A regular doubling would not yield a large enough block. Does size_hint
|
|
6315
|
+
// indicate that we have consistently needed large blocks?
|
|
6316
|
+
block_size = UPB_MIN(ai->size_hint * 2, max_block_size);
|
|
6317
|
+
if (size + kUpb_MemblockReserve > block_size) {
|
|
6318
|
+
// Even size_hint is not large enough, we will have to do a one-off.
|
|
6319
|
+
one_off = true;
|
|
6175
6320
|
}
|
|
6176
6321
|
}
|
|
6177
|
-
// We may need to exceed the max block size if the user requested a large
|
|
6178
|
-
// allocation.
|
|
6179
|
-
size_t block_size = UPB_MAX(kUpb_MemblockReserve + size, target_size);
|
|
6180
|
-
upb_alloc* block_alloc = _upb_ArenaInternal_BlockAlloc(ai);
|
|
6181
|
-
upb_SizedPtr alloc_result = upb_SizeReturningMalloc(block_alloc, block_size);
|
|
6182
6322
|
|
|
6183
|
-
|
|
6323
|
+
// If switching to a block of this size would *reduce* available free space,
|
|
6324
|
+
// we might as well make a one-off block instead.
|
|
6325
|
+
one_off = one_off || _upb_Arena_WouldReduceFreeSpace(a, size, block_size);
|
|
6184
6326
|
|
|
6185
|
-
|
|
6186
|
-
|
|
6327
|
+
if (one_off) {
|
|
6328
|
+
// Note: this may exceed the max block size, but that's okay.
|
|
6329
|
+
block_size = size + kUpb_MemblockReserve;
|
|
6330
|
+
}
|
|
6187
6331
|
|
|
6188
|
-
|
|
6189
|
-
|
|
6190
|
-
// targetting pre-v8.1. Relaxed order is safe as nothing depends on order of
|
|
6191
|
-
// size allocated.
|
|
6332
|
+
upb_MemBlock* block = _upb_Arena_AllocBlock(a, block_size);
|
|
6333
|
+
if (!block) return NULL;
|
|
6192
6334
|
|
|
6193
|
-
|
|
6194
|
-
upb_Atomic_Load(&ai->space_allocated, memory_order_relaxed);
|
|
6195
|
-
upb_Atomic_Store(&ai->space_allocated,
|
|
6196
|
-
old_space_allocated + actual_block_size,
|
|
6197
|
-
memory_order_relaxed);
|
|
6198
|
-
if (UPB_UNLIKELY(insert_after_head)) {
|
|
6199
|
-
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6200
|
-
block->size = actual_block_size;
|
|
6201
|
-
upb_MemBlock* head = ai->blocks;
|
|
6202
|
-
block->next = head->next;
|
|
6203
|
-
head->next = block;
|
|
6335
|
+
_upb_Arena_AddBlock(a, block);
|
|
6204
6336
|
|
|
6337
|
+
// Recheck size, in case the allocator gave us a much larger block than we
|
|
6338
|
+
// requested and we want to make it the new allocating region.
|
|
6339
|
+
if (UPB_UNLIKELY(one_off) &&
|
|
6340
|
+
_upb_Arena_WouldReduceFreeSpace(a, size, block->size)) {
|
|
6341
|
+
// Increase size_hint, so that a series of one-off allocations will
|
|
6342
|
+
// eventually convince us to switch to exponential growth at the larger
|
|
6343
|
+
// size.
|
|
6344
|
+
ai->size_hint = UPB_MIN(ai->size_hint + (size >> 1), max_block_size >> 1);
|
|
6205
6345
|
char* allocated = UPB_PTR_AT(block, kUpb_MemblockReserve, char);
|
|
6206
|
-
|
|
6207
|
-
|
|
6346
|
+
char* poison_start = allocated + size - UPB_PRIVATE(kUpb_Asan_GuardSize);
|
|
6347
|
+
UPB_PRIVATE(upb_Xsan_PoisonRegion)(
|
|
6348
|
+
poison_start, UPB_PTR_AT(block, block->size, char) - poison_start);
|
|
6208
6349
|
return allocated;
|
|
6209
6350
|
} else {
|
|
6210
|
-
ai->
|
|
6211
|
-
|
|
6351
|
+
ai->last_block_size = UPB_MIN(block->size, UINT32_MAX);
|
|
6352
|
+
ai->size_hint = ai->last_block_size;
|
|
6353
|
+
_upb_Arena_UseBlock(a, block);
|
|
6212
6354
|
UPB_ASSERT(UPB_PRIVATE(_upb_ArenaHas)(a) >= size);
|
|
6213
6355
|
return upb_Arena_Malloc(a, size - UPB_PRIVATE(kUpb_Asan_GuardSize));
|
|
6214
6356
|
}
|
|
@@ -6219,27 +6361,26 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6219
6361
|
UPB_ALIGN_MALLOC(kUpb_MemblockReserve + sizeof(upb_ArenaState));
|
|
6220
6362
|
upb_ArenaState* a;
|
|
6221
6363
|
|
|
6222
|
-
|
|
6364
|
+
if (!alloc) return NULL;
|
|
6223
6365
|
|
|
6366
|
+
// We need to malloc the initial block.
|
|
6224
6367
|
size_t block_size =
|
|
6225
6368
|
first_block_overhead + UPB_MAX(256, UPB_ALIGN_MALLOC(first_size) +
|
|
6226
6369
|
UPB_PRIVATE(kUpb_Asan_GuardSize));
|
|
6227
|
-
|
|
6228
|
-
if (!
|
|
6229
|
-
!(alloc_result = upb_SizeReturningMalloc(alloc, block_size)).p) {
|
|
6230
|
-
return NULL;
|
|
6231
|
-
}
|
|
6232
|
-
char* mem = alloc_result.p;
|
|
6233
|
-
size_t actual_block_size = alloc_result.n;
|
|
6370
|
+
upb_MemBlock* block = _upb_Arena_AllocBlockInternal(alloc, block_size);
|
|
6371
|
+
if (!block) return NULL;
|
|
6234
6372
|
|
|
6235
|
-
|
|
6373
|
+
// Initialize the arena state in the first block. We "borrow" the memory from
|
|
6374
|
+
// the block, because we can't yet call upb_Arena_Malloc.
|
|
6375
|
+
a = UPB_PTR_AT(block, kUpb_MemblockReserve, upb_ArenaState);
|
|
6236
6376
|
a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 0);
|
|
6237
|
-
a->body.
|
|
6377
|
+
a->body.last_block_size = UPB_MIN(block->size, UINT32_MAX);
|
|
6378
|
+
a->body.size_hint = UPB_MIN(block->size, UINT32_MAX);
|
|
6238
6379
|
upb_Atomic_Init(&a->body.parent_or_count, _upb_Arena_TaggedFromRefcount(1));
|
|
6239
6380
|
upb_Atomic_Init(&a->body.next, NULL);
|
|
6240
6381
|
upb_Atomic_Init(&a->body.previous_or_tail,
|
|
6241
6382
|
_upb_Arena_TaggedFromTail(&a->body));
|
|
6242
|
-
upb_Atomic_Init(&a->body.space_allocated,
|
|
6383
|
+
upb_Atomic_Init(&a->body.space_allocated, 0);
|
|
6243
6384
|
a->body.blocks = NULL;
|
|
6244
6385
|
#ifndef NDEBUG
|
|
6245
6386
|
a->body.refs = NULL;
|
|
@@ -6247,15 +6388,16 @@ static upb_Arena* _upb_Arena_InitSlow(upb_alloc* alloc, size_t first_size) {
|
|
|
6247
6388
|
a->body.upb_alloc_cleanup = NULL;
|
|
6248
6389
|
UPB_PRIVATE(upb_Xsan_Init)(UPB_XSAN(&a->body));
|
|
6249
6390
|
|
|
6250
|
-
_upb_Arena_AddBlock(&a->head,
|
|
6391
|
+
_upb_Arena_AddBlock(&a->head, block);
|
|
6392
|
+
_upb_Arena_UseBlockInternal(&a->head, block,
|
|
6393
|
+
UPB_ALIGN_MALLOC(sizeof(upb_ArenaState)));
|
|
6251
6394
|
|
|
6252
6395
|
return &a->head;
|
|
6253
6396
|
}
|
|
6254
6397
|
|
|
6255
6398
|
upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
|
|
6256
|
-
UPB_STATIC_ASSERT(
|
|
6257
|
-
|
|
6258
|
-
"Need to update UPB_ARENA_SIZE_HACK");
|
|
6399
|
+
UPB_STATIC_ASSERT(UPB_ARENA_SIZE_HACK >= sizeof(upb_ArenaState),
|
|
6400
|
+
"Need to update UPB_ARENA_SIZE_HACK");
|
|
6259
6401
|
upb_ArenaState* a;
|
|
6260
6402
|
|
|
6261
6403
|
if (mem) {
|
|
@@ -6285,6 +6427,7 @@ upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
|
|
|
6285
6427
|
a->body.refs = NULL;
|
|
6286
6428
|
#endif
|
|
6287
6429
|
a->body.size_hint = 128;
|
|
6430
|
+
a->body.last_block_size = 128;
|
|
6288
6431
|
a->body.upb_alloc_cleanup = NULL;
|
|
6289
6432
|
a->body.block_alloc = _upb_Arena_MakeBlockAlloc(alloc, 1);
|
|
6290
6433
|
a->head.UPB_PRIVATE(ptr) = (void*)UPB_ALIGN_MALLOC((uintptr_t)(a + 1));
|
|
@@ -6731,14 +6874,11 @@ void UPB_PRIVATE(_upb_Arena_SwapOut)(upb_Arena* des, const upb_Arena* src) {
|
|
|
6731
6874
|
bool _upb_Arena_WasLastAlloc(struct upb_Arena* a, void* ptr, size_t oldsize) {
|
|
6732
6875
|
upb_ArenaInternal* ai = upb_Arena_Internal(a);
|
|
6733
6876
|
upb_MemBlock* block = ai->blocks;
|
|
6734
|
-
if (block == NULL) return false;
|
|
6735
6877
|
// Skip any arena refs.
|
|
6736
6878
|
while (block != NULL && block->size == 0) {
|
|
6737
6879
|
block = block->next;
|
|
6738
6880
|
}
|
|
6739
6881
|
if (block == NULL) return false;
|
|
6740
|
-
block = block->next;
|
|
6741
|
-
if (block == NULL) return false;
|
|
6742
6882
|
char* start = UPB_PTR_AT(block, kUpb_MemblockReserve, char);
|
|
6743
6883
|
return UPB_PRIVATE(upb_Xsan_PtrEq)(ptr, start) &&
|
|
6744
6884
|
UPB_PRIVATE(_upb_Arena_AllocSpan)(oldsize) ==
|
|
@@ -6820,6 +6960,46 @@ bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
|
|
|
6820
6960
|
return true;
|
|
6821
6961
|
}
|
|
6822
6962
|
|
|
6963
|
+
bool upb_Array_Copy(upb_Array* dst, const upb_Array* src, upb_Arena* arena) {
|
|
6964
|
+
UPB_ASSERT(dst);
|
|
6965
|
+
UPB_ASSERT(src);
|
|
6966
|
+
UPB_ASSERT(!upb_Array_IsFrozen(dst));
|
|
6967
|
+
if (dst == src) return true;
|
|
6968
|
+
size_t len = upb_Array_Size(src);
|
|
6969
|
+
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) {
|
|
6970
|
+
return false;
|
|
6971
|
+
}
|
|
6972
|
+
if (len == 0) return true;
|
|
6973
|
+
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst);
|
|
6974
|
+
const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src);
|
|
6975
|
+
UPB_ASSERT(lg2 == src_lg2);
|
|
6976
|
+
char* dst_data = upb_Array_MutableDataPtr(dst);
|
|
6977
|
+
const char* src_data = upb_Array_DataPtr(src);
|
|
6978
|
+
memcpy(dst_data, src_data, len << lg2);
|
|
6979
|
+
return true;
|
|
6980
|
+
}
|
|
6981
|
+
|
|
6982
|
+
bool upb_Array_AppendAll(upb_Array* dst, const upb_Array* src,
|
|
6983
|
+
upb_Arena* arena) {
|
|
6984
|
+
UPB_ASSERT(!upb_Array_IsFrozen(dst));
|
|
6985
|
+
UPB_ASSERT(src);
|
|
6986
|
+
size_t src_len = upb_Array_Size(src);
|
|
6987
|
+
if (src_len == 0) return true;
|
|
6988
|
+
size_t dst_len = upb_Array_Size(dst);
|
|
6989
|
+
size_t len = dst_len + src_len;
|
|
6990
|
+
if (UPB_UNLIKELY(len < dst_len)) return false;
|
|
6991
|
+
if (!UPB_PRIVATE(_upb_Array_ResizeUninitialized)(dst, len, arena)) {
|
|
6992
|
+
return false;
|
|
6993
|
+
}
|
|
6994
|
+
const int lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(dst);
|
|
6995
|
+
const int src_lg2 = UPB_PRIVATE(_upb_Array_ElemSizeLg2)(src);
|
|
6996
|
+
UPB_ASSERT(lg2 == src_lg2);
|
|
6997
|
+
char* dst_data = upb_Array_MutableDataPtr(dst);
|
|
6998
|
+
const char* src_data = upb_Array_DataPtr(src);
|
|
6999
|
+
memcpy(dst_data + (dst_len << lg2), src_data, src_len << lg2);
|
|
7000
|
+
return true;
|
|
7001
|
+
}
|
|
7002
|
+
|
|
6823
7003
|
void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx,
|
|
6824
7004
|
size_t count) {
|
|
6825
7005
|
UPB_ASSERT(!upb_Array_IsFrozen(arr));
|
|
@@ -6880,9 +7060,17 @@ bool UPB_PRIVATE(_upb_Array_Realloc)(upb_Array* array, size_t min_capacity,
|
|
|
6880
7060
|
void* ptr = upb_Array_MutableDataPtr(array);
|
|
6881
7061
|
|
|
6882
7062
|
// Log2 ceiling of size.
|
|
6883
|
-
while (new_capacity < min_capacity)
|
|
7063
|
+
while (new_capacity < min_capacity) {
|
|
7064
|
+
if (upb_ShlOverflow(&new_capacity, 1)) {
|
|
7065
|
+
new_capacity = SIZE_MAX;
|
|
7066
|
+
break;
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
6884
7069
|
|
|
6885
|
-
|
|
7070
|
+
size_t new_bytes = new_capacity;
|
|
7071
|
+
if (upb_ShlOverflow(&new_bytes, lg2)) {
|
|
7072
|
+
return false;
|
|
7073
|
+
}
|
|
6886
7074
|
ptr = upb_Arena_Realloc(arena, ptr, old_bytes, new_bytes);
|
|
6887
7075
|
if (!ptr) return false;
|
|
6888
7076
|
|
|
@@ -7340,6 +7528,7 @@ UPB_NOINLINE bool UPB_PRIVATE(_upb_Message_AddUnknownSlowPath)(upb_Message* msg,
|
|
|
7340
7528
|
if (!view) return false;
|
|
7341
7529
|
view->data = data;
|
|
7342
7530
|
} else {
|
|
7531
|
+
if (SIZE_MAX - sizeof(upb_StringView) < len) return false;
|
|
7343
7532
|
view = upb_Arena_Malloc(arena, sizeof(upb_StringView) + len);
|
|
7344
7533
|
if (!view) return false;
|
|
7345
7534
|
char* copy = UPB_PTR_AT(view, sizeof(upb_StringView), char);
|
|
@@ -8116,7 +8305,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
|
|
|
8116
8305
|
case kUpb_CType_String:
|
|
8117
8306
|
case kUpb_CType_Bytes: {
|
|
8118
8307
|
upb_StringView source = *(upb_StringView*)value;
|
|
8119
|
-
|
|
8308
|
+
size_t size = source.size;
|
|
8120
8309
|
void* cloned_data = upb_Arena_Malloc(arena, size);
|
|
8121
8310
|
if (cloned_data == NULL) {
|
|
8122
8311
|
return false;
|
|
@@ -8496,8 +8685,15 @@ bool UPB_PRIVATE(_upb_Message_ReserveSlot)(struct upb_Message* msg,
|
|
|
8496
8685
|
in->capacity = capacity;
|
|
8497
8686
|
UPB_PRIVATE(_upb_Message_SetInternal)(msg, in);
|
|
8498
8687
|
} else if (in->capacity == in->size) {
|
|
8688
|
+
if (in->size == UINT32_MAX) return false;
|
|
8499
8689
|
// Internal data is too small, reallocate.
|
|
8500
|
-
|
|
8690
|
+
size_t needed_pow2 = upb_RoundUpToPowerOfTwo(in->size + 1);
|
|
8691
|
+
if (needed_pow2 > UINT32_MAX) return false;
|
|
8692
|
+
uint32_t new_capacity = needed_pow2;
|
|
8693
|
+
if (UPB_SIZEOF_FLEX_WOULD_OVERFLOW(upb_Message_Internal, aux_data,
|
|
8694
|
+
new_capacity)) {
|
|
8695
|
+
return false;
|
|
8696
|
+
}
|
|
8501
8697
|
in = upb_Arena_Realloc(a, in, _upb_Message_SizeOfInternal(in->capacity),
|
|
8502
8698
|
_upb_Message_SizeOfInternal(new_capacity));
|
|
8503
8699
|
if (!in) return false;
|
|
@@ -8702,7 +8898,6 @@ upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len,
|
|
|
8702
8898
|
|
|
8703
8899
|
|
|
8704
8900
|
#include <inttypes.h>
|
|
8705
|
-
#include <stdalign.h>
|
|
8706
8901
|
#include <stddef.h>
|
|
8707
8902
|
#include <stdint.h>
|
|
8708
8903
|
#include <stdlib.h>
|
|
@@ -10109,28 +10304,25 @@ char* upb_MtDataEncoder_EndEnum(upb_MtDataEncoder* e, char* ptr) {
|
|
|
10109
10304
|
|
|
10110
10305
|
// Must be last.
|
|
10111
10306
|
|
|
10112
|
-
#define EXTREG_KEY_SIZE (sizeof(upb_MiniTable*) + sizeof(uint32_t))
|
|
10113
|
-
|
|
10114
10307
|
struct upb_ExtensionRegistry {
|
|
10308
|
+
upb_exttable exts;
|
|
10115
10309
|
upb_Arena* arena;
|
|
10116
|
-
upb_strtable exts; // Key is upb_MiniTable* concatenated with fieldnum.
|
|
10117
10310
|
};
|
|
10118
10311
|
|
|
10119
|
-
static void extreg_key(char* buf, const upb_MiniTable* l, uint32_t fieldnum) {
|
|
10120
|
-
memcpy(buf, &l, sizeof(l));
|
|
10121
|
-
memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
|
|
10122
|
-
}
|
|
10123
|
-
|
|
10124
10312
|
upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) {
|
|
10125
10313
|
upb_ExtensionRegistry* r = upb_Arena_Malloc(arena, sizeof(*r));
|
|
10126
10314
|
if (!r) return NULL;
|
|
10127
10315
|
r->arena = arena;
|
|
10128
|
-
if (!
|
|
10316
|
+
if (!upb_exttable_init(&r->exts, 8, arena)) return NULL;
|
|
10129
10317
|
return r;
|
|
10130
10318
|
}
|
|
10131
10319
|
|
|
10132
10320
|
UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add(
|
|
10133
10321
|
upb_ExtensionRegistry* r, const upb_MiniTableExtension* e) {
|
|
10322
|
+
UPB_STATIC_ASSERT(
|
|
10323
|
+
offsetof(upb_MiniTableExtension,
|
|
10324
|
+
UPB_PRIVATE(field).UPB_PRIVATE(number)) == 0,
|
|
10325
|
+
"Extension must be first-member-of-struct convertable with uint32_t");
|
|
10134
10326
|
uint32_t fieldnum = upb_MiniTableExtension_Number(e);
|
|
10135
10327
|
const upb_MiniTable* extendee = upb_MiniTableExtension_Extendee(e);
|
|
10136
10328
|
|
|
@@ -10140,15 +10332,11 @@ UPB_API upb_ExtensionRegistryStatus upb_ExtensionRegistry_Add(
|
|
|
10140
10332
|
return kUpb_ExtensionRegistryStatus_InvalidExtension;
|
|
10141
10333
|
}
|
|
10142
10334
|
|
|
10143
|
-
|
|
10144
|
-
extreg_key(buf, extendee, fieldnum);
|
|
10145
|
-
|
|
10146
|
-
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) {
|
|
10335
|
+
if (upb_exttable_lookup(&r->exts, extendee, fieldnum) != NULL) {
|
|
10147
10336
|
return kUpb_ExtensionRegistryStatus_DuplicateEntry;
|
|
10148
10337
|
}
|
|
10149
10338
|
|
|
10150
|
-
if (!
|
|
10151
|
-
upb_value_constptr(e), r->arena)) {
|
|
10339
|
+
if (!upb_exttable_insert(&r->exts, extendee, (const uint32_t*)e, r->arena)) {
|
|
10152
10340
|
return kUpb_ExtensionRegistryStatus_OutOfMemory;
|
|
10153
10341
|
}
|
|
10154
10342
|
return kUpb_ExtensionRegistryStatus_Ok;
|
|
@@ -10169,10 +10357,8 @@ failure:
|
|
|
10169
10357
|
// Back out the entries previously added.
|
|
10170
10358
|
for (end = e, e = start; e < end; e++) {
|
|
10171
10359
|
const upb_MiniTableExtension* ext = *e;
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
upb_MiniTableExtension_Number(ext));
|
|
10175
|
-
upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
|
|
10360
|
+
upb_exttable_remove(&r->exts, upb_MiniTableExtension_Extendee(ext),
|
|
10361
|
+
upb_MiniTableExtension_Number(ext));
|
|
10176
10362
|
}
|
|
10177
10363
|
UPB_ASSERT(status != kUpb_ExtensionRegistryStatus_Ok);
|
|
10178
10364
|
return status;
|
|
@@ -10180,14 +10366,8 @@ failure:
|
|
|
10180
10366
|
|
|
10181
10367
|
const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
|
|
10182
10368
|
const upb_ExtensionRegistry* r, const upb_MiniTable* t, uint32_t num) {
|
|
10183
|
-
|
|
10184
|
-
|
|
10185
|
-
extreg_key(buf, t, num);
|
|
10186
|
-
if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
|
|
10187
|
-
return upb_value_getconstptr(v);
|
|
10188
|
-
} else {
|
|
10189
|
-
return NULL;
|
|
10190
|
-
}
|
|
10369
|
+
const uint32_t* v = upb_exttable_lookup(&r->exts, t, num);
|
|
10370
|
+
return (const upb_MiniTableExtension*)v;
|
|
10191
10371
|
}
|
|
10192
10372
|
|
|
10193
10373
|
|
|
@@ -10440,6 +10620,7 @@ struct upb_DefPool {
|
|
|
10440
10620
|
size_t scratch_size;
|
|
10441
10621
|
size_t bytes_loaded;
|
|
10442
10622
|
bool disable_closed_enum_checking;
|
|
10623
|
+
bool disable_implicit_field_presence;
|
|
10443
10624
|
};
|
|
10444
10625
|
|
|
10445
10626
|
void upb_DefPool_Free(upb_DefPool* s) {
|
|
@@ -10458,6 +10639,7 @@ upb_DefPool* upb_DefPool_New(void) {
|
|
|
10458
10639
|
s->arena = upb_Arena_New();
|
|
10459
10640
|
s->bytes_loaded = 0;
|
|
10460
10641
|
s->disable_closed_enum_checking = false;
|
|
10642
|
+
s->disable_implicit_field_presence = false;
|
|
10461
10643
|
|
|
10462
10644
|
s->scratch_size = 240;
|
|
10463
10645
|
s->scratch_data = upb_gmalloc(s->scratch_size);
|
|
@@ -10499,6 +10681,15 @@ bool upb_DefPool_ClosedEnumCheckingDisabled(const upb_DefPool* s) {
|
|
|
10499
10681
|
return s->disable_closed_enum_checking;
|
|
10500
10682
|
}
|
|
10501
10683
|
|
|
10684
|
+
void upb_DefPool_DisableImplicitFieldPresence(upb_DefPool* s) {
|
|
10685
|
+
UPB_ASSERT(upb_strtable_count(&s->files) == 0);
|
|
10686
|
+
s->disable_implicit_field_presence = true;
|
|
10687
|
+
}
|
|
10688
|
+
|
|
10689
|
+
bool upb_DefPool_ImplicitFieldPresenceDisabled(const upb_DefPool* s) {
|
|
10690
|
+
return s->disable_implicit_field_presence;
|
|
10691
|
+
}
|
|
10692
|
+
|
|
10502
10693
|
const google_protobuf_FeatureSetDefaults* upb_DefPool_FeatureSetDefaults(
|
|
10503
10694
|
const upb_DefPool* s) {
|
|
10504
10695
|
return s->feature_set_defaults;
|
|
@@ -10608,7 +10799,7 @@ void _upb_DefPool_SetPlatform(upb_DefPool* s, upb_MiniTablePlatform platform) {
|
|
|
10608
10799
|
|
|
10609
10800
|
const upb_MessageDef* upb_DefPool_FindMessageByName(const upb_DefPool* s,
|
|
10610
10801
|
const char* sym) {
|
|
10611
|
-
return
|
|
10802
|
+
return upb_DefPool_FindMessageByNameWithSize(s, sym, strlen(sym));
|
|
10612
10803
|
}
|
|
10613
10804
|
|
|
10614
10805
|
const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
|
|
@@ -10618,12 +10809,23 @@ const upb_MessageDef* upb_DefPool_FindMessageByNameWithSize(
|
|
|
10618
10809
|
|
|
10619
10810
|
const upb_EnumDef* upb_DefPool_FindEnumByName(const upb_DefPool* s,
|
|
10620
10811
|
const char* sym) {
|
|
10621
|
-
return
|
|
10812
|
+
return upb_DefPool_FindEnumByNameWithSize(s, sym, strlen(sym));
|
|
10813
|
+
}
|
|
10814
|
+
|
|
10815
|
+
const upb_EnumDef* upb_DefPool_FindEnumByNameWithSize(const upb_DefPool* s,
|
|
10816
|
+
const char* sym,
|
|
10817
|
+
size_t len) {
|
|
10818
|
+
return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUM);
|
|
10819
|
+
}
|
|
10820
|
+
|
|
10821
|
+
const upb_EnumValueDef* upb_DefPool_FindEnumValueByName(const upb_DefPool* s,
|
|
10822
|
+
const char* sym) {
|
|
10823
|
+
return upb_DefPool_FindEnumValueByNameWithSize(s, sym, strlen(sym));
|
|
10622
10824
|
}
|
|
10623
10825
|
|
|
10624
|
-
const upb_EnumValueDef*
|
|
10625
|
-
|
|
10626
|
-
return _upb_DefPool_Unpack(s, sym,
|
|
10826
|
+
const upb_EnumValueDef* upb_DefPool_FindEnumValueByNameWithSize(
|
|
10827
|
+
const upb_DefPool* s, const char* sym, size_t len) {
|
|
10828
|
+
return _upb_DefPool_Unpack(s, sym, len, UPB_DEFTYPE_ENUMVAL);
|
|
10627
10829
|
}
|
|
10628
10830
|
|
|
10629
10831
|
const upb_FileDef* upb_DefPool_FindFileByName(const upb_DefPool* s,
|
|
@@ -12240,7 +12442,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
|
|
|
12240
12442
|
|
|
12241
12443
|
f->has_presence =
|
|
12242
12444
|
(!upb_FieldDef_IsRepeated(f)) &&
|
|
12243
|
-
(f->is_extension ||
|
|
12445
|
+
(f->is_extension || _upb_FileDef_ImplicitFieldPresenceDisabled(f->file) ||
|
|
12244
12446
|
(f->type_ == kUpb_FieldType_Message ||
|
|
12245
12447
|
f->type_ == kUpb_FieldType_Group || upb_FieldDef_ContainingOneof(f) ||
|
|
12246
12448
|
google_protobuf_FeatureSet_field_presence(f->resolved_features) !=
|
|
@@ -12644,6 +12846,10 @@ bool _upb_FileDef_ClosedEnumCheckingDisabled(const upb_FileDef* f) {
|
|
|
12644
12846
|
return upb_DefPool_ClosedEnumCheckingDisabled(f->symtab);
|
|
12645
12847
|
}
|
|
12646
12848
|
|
|
12849
|
+
bool _upb_FileDef_ImplicitFieldPresenceDisabled(const upb_FileDef* f) {
|
|
12850
|
+
return upb_DefPool_ImplicitFieldPresenceDisabled(f->symtab);
|
|
12851
|
+
}
|
|
12852
|
+
|
|
12647
12853
|
int upb_FileDef_TopLevelEnumCount(const upb_FileDef* f) {
|
|
12648
12854
|
return f->top_lvl_enum_count;
|
|
12649
12855
|
}
|
|
@@ -14532,6 +14738,7 @@ static void create_method(upb_DefBuilder* ctx,
|
|
|
14532
14738
|
m->output_type = _upb_DefBuilder_Resolve(
|
|
14533
14739
|
ctx, m->full_name, m->full_name,
|
|
14534
14740
|
google_protobuf_MethodDescriptorProto_output_type(method_proto), UPB_DEFTYPE_MSG);
|
|
14741
|
+
_upb_ServiceDef_InsertMethod(ctx, s, m);
|
|
14535
14742
|
}
|
|
14536
14743
|
|
|
14537
14744
|
// Allocate and initialize an array of |n| method defs belonging to |s|.
|
|
@@ -14763,6 +14970,7 @@ struct upb_ServiceDef {
|
|
|
14763
14970
|
upb_MethodDef* methods;
|
|
14764
14971
|
int method_count;
|
|
14765
14972
|
int index;
|
|
14973
|
+
upb_strtable ntom;
|
|
14766
14974
|
};
|
|
14767
14975
|
|
|
14768
14976
|
upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) {
|
|
@@ -14807,13 +15015,18 @@ const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) {
|
|
|
14807
15015
|
|
|
14808
15016
|
const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s,
|
|
14809
15017
|
const char* name) {
|
|
14810
|
-
|
|
14811
|
-
|
|
14812
|
-
|
|
14813
|
-
|
|
14814
|
-
|
|
15018
|
+
return upb_ServiceDef_FindMethodByNameWithSize(s, name, strlen(name));
|
|
15019
|
+
}
|
|
15020
|
+
|
|
15021
|
+
const upb_MethodDef* upb_ServiceDef_FindMethodByNameWithSize(
|
|
15022
|
+
const upb_ServiceDef* s, const char* name, size_t len) {
|
|
15023
|
+
upb_value val;
|
|
15024
|
+
|
|
15025
|
+
if (!upb_strtable_lookup2(&s->ntom, name, len, &val)) {
|
|
15026
|
+
return NULL;
|
|
14815
15027
|
}
|
|
14816
|
-
|
|
15028
|
+
|
|
15029
|
+
return _upb_DefType_Unpack(val, UPB_DEFTYPE_METHOD);
|
|
14817
15030
|
}
|
|
14818
15031
|
|
|
14819
15032
|
static void create_service(upb_DefBuilder* ctx,
|
|
@@ -14838,6 +15051,8 @@ static void create_service(upb_DefBuilder* ctx,
|
|
|
14838
15051
|
const google_protobuf_MethodDescriptorProto* const* methods =
|
|
14839
15052
|
google_protobuf_ServiceDescriptorProto_method(svc_proto, &n);
|
|
14840
15053
|
s->method_count = n;
|
|
15054
|
+
bool ok = upb_strtable_init(&s->ntom, n, ctx->arena);
|
|
15055
|
+
if (!ok) _upb_DefBuilder_OomErr(ctx);
|
|
14841
15056
|
s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s);
|
|
14842
15057
|
}
|
|
14843
15058
|
|
|
@@ -14855,6 +15070,20 @@ upb_ServiceDef* _upb_ServiceDefs_New(
|
|
|
14855
15070
|
return s;
|
|
14856
15071
|
}
|
|
14857
15072
|
|
|
15073
|
+
void _upb_ServiceDef_InsertMethod(upb_DefBuilder* ctx, upb_ServiceDef* s,
|
|
15074
|
+
const upb_MethodDef* m) {
|
|
15075
|
+
const char* shortname = upb_MethodDef_Name(m);
|
|
15076
|
+
const size_t shortnamelen = strlen(shortname);
|
|
15077
|
+
upb_value existing_v;
|
|
15078
|
+
if (upb_strtable_lookup(&s->ntom, shortname, &existing_v)) {
|
|
15079
|
+
_upb_DefBuilder_Errf(ctx, "duplicate method name (%s)", shortname);
|
|
15080
|
+
}
|
|
15081
|
+
const upb_value method_v = _upb_DefType_Pack(m, UPB_DEFTYPE_METHOD);
|
|
15082
|
+
bool ok = upb_strtable_insert(&s->ntom, shortname, shortnamelen, method_v,
|
|
15083
|
+
ctx->arena);
|
|
15084
|
+
if (!ok) _upb_DefBuilder_OomErr(ctx);
|
|
15085
|
+
}
|
|
15086
|
+
|
|
14858
15087
|
|
|
14859
15088
|
#include <inttypes.h>
|
|
14860
15089
|
#include <math.h>
|
|
@@ -16168,9 +16397,13 @@ static void upb_Decoder_AddKnownMessageSetItem(
|
|
|
16168
16397
|
upb_Message* submsg = _upb_Decoder_NewSubMessage2(
|
|
16169
16398
|
d, ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg),
|
|
16170
16399
|
&ext->ext->UPB_PRIVATE(field), submsgp);
|
|
16400
|
+
// upb_Decode_LimitDepth() takes uint32_t, d->depth - 1 can not be negative.
|
|
16401
|
+
if (d->depth <= 1) {
|
|
16402
|
+
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_MaxDepthExceeded);
|
|
16403
|
+
}
|
|
16171
16404
|
upb_DecodeStatus status = upb_Decode(
|
|
16172
16405
|
data, size, submsg, upb_MiniTableExtension_GetSubMessage(item_mt),
|
|
16173
|
-
d->extreg, d->options, &d->arena);
|
|
16406
|
+
d->extreg, upb_Decode_LimitDepth(d->options, d->depth - 1), &d->arena);
|
|
16174
16407
|
if (status != kUpb_DecodeStatus_Ok) {
|
|
16175
16408
|
upb_ErrorHandler_ThrowError(&d->err, status);
|
|
16176
16409
|
}
|
|
@@ -16458,6 +16691,7 @@ const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
|
|
|
16458
16691
|
*op = kUpb_DecodeOp_UnknownField;
|
|
16459
16692
|
return ptr;
|
|
16460
16693
|
}
|
|
16694
|
+
_upb_Decoder_MungeInt32(val);
|
|
16461
16695
|
} else {
|
|
16462
16696
|
_upb_Decoder_Munge(field, val);
|
|
16463
16697
|
}
|
|
@@ -16500,7 +16734,6 @@ const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
|
|
|
16500
16734
|
UPB_FORCEINLINE
|
|
16501
16735
|
const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
|
|
16502
16736
|
upb_Message* msg,
|
|
16503
|
-
const upb_MiniTable* layout,
|
|
16504
16737
|
const upb_MiniTableField* field,
|
|
16505
16738
|
int op, wireval* val) {
|
|
16506
16739
|
uint8_t mode = field->UPB_PRIVATE(mode);
|
|
@@ -16529,67 +16762,13 @@ const char* _upb_Decoder_DecodeKnownField(upb_Decoder* d, const char* ptr,
|
|
|
16529
16762
|
}
|
|
16530
16763
|
}
|
|
16531
16764
|
|
|
16532
|
-
static const char* _upb_Decoder_FindFieldStart(upb_Decoder* d, const char* ptr,
|
|
16533
|
-
uint32_t field_number,
|
|
16534
|
-
uint32_t wire_type) {
|
|
16535
|
-
// Since unknown fields are the uncommon case, we do a little extra work here
|
|
16536
|
-
// to walk backwards through the buffer to find the field start. This frees
|
|
16537
|
-
// up a register in the fast paths (when the field is known), which leads to
|
|
16538
|
-
// significant speedups in benchmarks. Note that ptr may point into the slop
|
|
16539
|
-
// space, beyond the normal end of the input buffer.
|
|
16540
|
-
const char* start = ptr;
|
|
16541
|
-
|
|
16542
|
-
switch (wire_type) {
|
|
16543
|
-
case kUpb_WireType_Varint:
|
|
16544
|
-
case kUpb_WireType_Delimited:
|
|
16545
|
-
// Skip the last byte
|
|
16546
|
-
start--;
|
|
16547
|
-
// Skip bytes until we encounter the final byte of the tag varint.
|
|
16548
|
-
while (start[-1] & 0x80) start--;
|
|
16549
|
-
break;
|
|
16550
|
-
case kUpb_WireType_32Bit:
|
|
16551
|
-
start -= 4;
|
|
16552
|
-
break;
|
|
16553
|
-
case kUpb_WireType_64Bit:
|
|
16554
|
-
start -= 8;
|
|
16555
|
-
break;
|
|
16556
|
-
default:
|
|
16557
|
-
break;
|
|
16558
|
-
}
|
|
16559
|
-
assert(start == d->debug_valstart);
|
|
16560
|
-
|
|
16561
|
-
{
|
|
16562
|
-
// The varint parser does not enforce that integers are encoded with their
|
|
16563
|
-
// minimum size; for example the value 1 could be encoded with three
|
|
16564
|
-
// bytes: 0x81, 0x80, 0x00. These unnecessary trailing zeroes mean that we
|
|
16565
|
-
// cannot skip backwards by the minimum encoded size of the tag; and
|
|
16566
|
-
// unlike the loop for delimited or varint fields, we can't stop at a
|
|
16567
|
-
// sentinel value because anything can precede a tag. Instead, parse back
|
|
16568
|
-
// one byte at a time until we read the same tag value that was parsed
|
|
16569
|
-
// earlier.
|
|
16570
|
-
uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
|
|
16571
|
-
uint32_t seen = 0;
|
|
16572
|
-
do {
|
|
16573
|
-
start--;
|
|
16574
|
-
seen <<= 7;
|
|
16575
|
-
seen |= *start & 0x7f;
|
|
16576
|
-
} while (seen != tag);
|
|
16577
|
-
}
|
|
16578
|
-
assert(start == d->debug_tagstart);
|
|
16579
|
-
|
|
16580
|
-
return start;
|
|
16581
|
-
}
|
|
16582
|
-
|
|
16583
16765
|
static const char* _upb_Decoder_DecodeUnknownField(
|
|
16584
16766
|
upb_Decoder* d, const char* ptr, upb_Message* msg, uint32_t field_number,
|
|
16585
|
-
uint32_t wire_type, wireval val) {
|
|
16767
|
+
uint32_t wire_type, wireval val, const char* start) {
|
|
16586
16768
|
if (field_number == 0) {
|
|
16587
16769
|
upb_ErrorHandler_ThrowError(&d->err, kUpb_DecodeStatus_Malformed);
|
|
16588
16770
|
}
|
|
16589
16771
|
|
|
16590
|
-
const char* start =
|
|
16591
|
-
_upb_Decoder_FindFieldStart(d, ptr, field_number, wire_type);
|
|
16592
|
-
|
|
16593
16772
|
upb_EpsCopyInputStream_StartCapture(&d->input, start);
|
|
16594
16773
|
|
|
16595
16774
|
if (wire_type == kUpb_WireType_Delimited) {
|
|
@@ -16628,10 +16807,6 @@ UPB_FORCEINLINE
|
|
|
16628
16807
|
const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr,
|
|
16629
16808
|
uint32_t* field_number,
|
|
16630
16809
|
uint32_t* wire_type) {
|
|
16631
|
-
#ifndef NDEBUG
|
|
16632
|
-
d->debug_tagstart = ptr;
|
|
16633
|
-
#endif
|
|
16634
|
-
|
|
16635
16810
|
uint32_t tag;
|
|
16636
16811
|
UPB_ASSERT(ptr < d->input.limit_ptr);
|
|
16637
16812
|
ptr = upb_WireReader_ReadTag(ptr, &tag, EPS(d));
|
|
@@ -16641,15 +16816,9 @@ const char* _upb_Decoder_DecodeFieldTag(upb_Decoder* d, const char* ptr,
|
|
|
16641
16816
|
}
|
|
16642
16817
|
|
|
16643
16818
|
UPB_FORCEINLINE
|
|
16644
|
-
const char* _upb_Decoder_DecodeFieldData(
|
|
16645
|
-
|
|
16646
|
-
|
|
16647
|
-
uint32_t field_number,
|
|
16648
|
-
uint32_t wire_type) {
|
|
16649
|
-
#ifndef NDEBUG
|
|
16650
|
-
d->debug_valstart = ptr;
|
|
16651
|
-
#endif
|
|
16652
|
-
|
|
16819
|
+
const char* _upb_Decoder_DecodeFieldData(
|
|
16820
|
+
upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* mt,
|
|
16821
|
+
uint32_t field_number, uint32_t wire_type, const char* start) {
|
|
16653
16822
|
int op;
|
|
16654
16823
|
wireval val;
|
|
16655
16824
|
|
|
@@ -16658,12 +16827,12 @@ const char* _upb_Decoder_DecodeFieldData(upb_Decoder* d, const char* ptr,
|
|
|
16658
16827
|
ptr = _upb_Decoder_DecodeWireValue(d, ptr, mt, field, wire_type, &val, &op);
|
|
16659
16828
|
|
|
16660
16829
|
if (op >= 0) {
|
|
16661
|
-
return _upb_Decoder_DecodeKnownField(d, ptr, msg,
|
|
16830
|
+
return _upb_Decoder_DecodeKnownField(d, ptr, msg, field, op, &val);
|
|
16662
16831
|
} else {
|
|
16663
16832
|
switch (op) {
|
|
16664
16833
|
case kUpb_DecodeOp_UnknownField:
|
|
16665
16834
|
return _upb_Decoder_DecodeUnknownField(d, ptr, msg, field_number,
|
|
16666
|
-
wire_type, val);
|
|
16835
|
+
wire_type, val, start);
|
|
16667
16836
|
case kUpb_DecodeOp_MessageSetItem:
|
|
16668
16837
|
return upb_Decoder_DecodeMessageSetItem(d, ptr, msg, mt);
|
|
16669
16838
|
default:
|
|
@@ -16684,6 +16853,7 @@ const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr,
|
|
|
16684
16853
|
uint32_t field_number;
|
|
16685
16854
|
uint32_t wire_type;
|
|
16686
16855
|
|
|
16856
|
+
const char* start = ptr;
|
|
16687
16857
|
ptr = _upb_Decoder_DecodeFieldTag(d, ptr, &field_number, &wire_type);
|
|
16688
16858
|
|
|
16689
16859
|
if (wire_type == kUpb_WireType_EndGroup) {
|
|
@@ -16691,7 +16861,8 @@ const char* _upb_Decoder_DecodeFieldNoFast(upb_Decoder* d, const char* ptr,
|
|
|
16691
16861
|
return _upb_Decoder_EndMessage(d, ptr);
|
|
16692
16862
|
}
|
|
16693
16863
|
|
|
16694
|
-
ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type
|
|
16864
|
+
ptr = _upb_Decoder_DecodeFieldData(d, ptr, msg, mt, field_number, wire_type,
|
|
16865
|
+
start);
|
|
16695
16866
|
_upb_Decoder_Trace(d, 'M');
|
|
16696
16867
|
return ptr;
|
|
16697
16868
|
}
|
|
@@ -16910,14 +17081,6 @@ typedef struct {
|
|
|
16910
17081
|
_upb_mapsorter sorter;
|
|
16911
17082
|
} upb_encstate;
|
|
16912
17083
|
|
|
16913
|
-
static size_t upb_roundup_pow2(size_t bytes) {
|
|
16914
|
-
size_t ret = 128;
|
|
16915
|
-
while (ret < bytes) {
|
|
16916
|
-
ret *= 2;
|
|
16917
|
-
}
|
|
16918
|
-
return ret;
|
|
16919
|
-
}
|
|
16920
|
-
|
|
16921
17084
|
UPB_NORETURN static void encode_err(upb_encstate* e, upb_EncodeStatus s) {
|
|
16922
17085
|
UPB_ASSERT(s != kUpb_EncodeStatus_Ok);
|
|
16923
17086
|
e->status = s;
|
|
@@ -16933,7 +17096,9 @@ UPB_NOINLINE static char* encode_growbuffer(char* ptr, upb_encstate* e,
|
|
|
16933
17096
|
size_t bytes) {
|
|
16934
17097
|
size_t old_size = e->limit - e->buf;
|
|
16935
17098
|
size_t needed_size = bytes + (e->limit - ptr);
|
|
16936
|
-
|
|
17099
|
+
if (needed_size < bytes) encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
17100
|
+
size_t new_size = upb_RoundUpToPowerOfTwo(UPB_MAX(128, needed_size));
|
|
17101
|
+
if (new_size == old_size) encode_err(e, kUpb_EncodeStatus_OutOfMemory);
|
|
16937
17102
|
void* old_buf = e->buf == &initial_buf_sentinel ? NULL : (void*)e->buf;
|
|
16938
17103
|
char* new_buf = upb_Arena_Realloc(e->arena, old_buf, old_size, new_size);
|
|
16939
17104
|
|