Updated decoder internal symbols to new naming scheme.

This is a naming change only, with no functional change.  We did replace one inline function that had only one caller, but the net effect should be a no-op.

I did remove several `return` statements for calls to certain `noreturn` functions.  These had no effect but were intended to improve readability.  However the unused "return" caused ClangTidy to throw warnings, so these have been removed.

PiperOrigin-RevId: 472619191
pull/13171/head
Joshua Haberman 2 years ago committed by Copybara-Service
parent 5a7644b2d0
commit ba7603b7c1
  1. 398
      upb/decode.c
  2. 72
      upb/decode_fast.c
  3. 7
      upb/decode_fast.h
  4. 2
      upb/def.c
  5. 34
      upb/internal/decode.h
  6. 4
      upbc/protoc-gen-upb.cc

@ -181,28 +181,31 @@ typedef union {
uint32_t size;
} wireval;
static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable* layout);
UPB_NORETURN static void* decode_err(upb_Decoder* d, upb_DecodeStatus status) {
UPB_NORETURN static void* _upb_Decoder_ErrorJmp(upb_Decoder* d,
upb_DecodeStatus status) {
assert(status != kUpb_DecodeStatus_Ok);
UPB_LONGJMP(d->err, status);
}
const char* fastdecode_err(upb_Decoder* d, int status) {
const char* _upb_FastDecoder_ErrorJmp(upb_Decoder* d, int status) {
assert(status != kUpb_DecodeStatus_Ok);
UPB_LONGJMP(d->err, status);
return NULL;
}
static void decode_verifyutf8(upb_Decoder* d, const char* buf, int len) {
if (!decode_verifyutf8_inl(buf, len))
decode_err(d, kUpb_DecodeStatus_BadUtf8);
static void _upb_Decoder_VerifyUtf8(upb_Decoder* d, const char* buf, int len) {
if (!_upb_Decoder_VerifyUtf8Inline(buf, len)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_BadUtf8);
}
}
static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
static bool _upb_Decoder_Reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
bool need_realloc = arr->capacity - arr->size < elem;
if (need_realloc && !_upb_array_realloc(arr, arr->size + elem, &d->arena)) {
decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
return need_realloc;
}
@ -210,11 +213,12 @@ static bool decode_reserve(upb_Decoder* d, upb_Array* arr, size_t elem) {
typedef struct {
const char* ptr;
uint64_t val;
} decode_vret;
} _upb_DecodeLongVarintReturn;
UPB_NOINLINE
static decode_vret decode_longvarint64(const char* ptr, uint64_t val) {
decode_vret ret = {NULL, 0};
static _upb_DecodeLongVarintReturn _upb_Decoder_DecodeLongVarint(
const char* ptr, uint64_t val) {
_upb_DecodeLongVarintReturn ret = {NULL, 0};
uint64_t byte;
int i;
for (i = 1; i < 10; i++) {
@ -230,31 +234,32 @@ static decode_vret decode_longvarint64(const char* ptr, uint64_t val) {
}
UPB_FORCEINLINE
static const char* decode_varint64(upb_Decoder* d, const char* ptr,
static const char* _upb_Decoder_DecodeVarint(upb_Decoder* d, const char* ptr,
uint64_t* val) {
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = byte;
return ptr + 1;
} else {
decode_vret res = decode_longvarint64(ptr, byte);
if (!res.ptr) return decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_DecodeLongVarintReturn res = _upb_Decoder_DecodeLongVarint(ptr, byte);
if (!res.ptr) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
*val = res.val;
return res.ptr;
}
}
UPB_FORCEINLINE
static const char* decode_tag(upb_Decoder* d, const char* ptr, uint32_t* val) {
static const char* _upb_Decoder_DecodeTag(upb_Decoder* d, const char* ptr,
uint32_t* val) {
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = byte;
return ptr + 1;
} else {
const char* start = ptr;
decode_vret res = decode_longvarint64(ptr, byte);
_upb_DecodeLongVarintReturn res = _upb_Decoder_DecodeLongVarint(ptr, byte);
if (!res.ptr || res.ptr - start > 5 || res.val > UINT32_MAX) {
return decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
*val = res.val;
return res.ptr;
@ -265,22 +270,22 @@ UPB_FORCEINLINE
static const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr,
uint32_t* size) {
uint64_t size64;
ptr = decode_varint64(d, ptr, &size64);
ptr = _upb_Decoder_DecodeVarint(d, ptr, &size64);
if (size64 >= INT32_MAX || ptr - d->end + (int)size64 > d->limit) {
decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
*size = size64;
return ptr;
}
static void decode_munge_int32(wireval* val) {
static void _upb_Decoder_MungeInt32(wireval* val) {
if (!_upb_IsLittleEndian()) {
/* The next stage will memcpy(dst, &val, 4) */
val->uint32_val = val->uint64_val;
}
}
static void decode_munge(int type, wireval* val) {
static void _upb_Decoder_Munge(int type, wireval* val) {
switch (type) {
case kUpb_FieldType_Bool:
val->bool_val = val->uint64_val != 0;
@ -298,38 +303,36 @@ static void decode_munge(int type, wireval* val) {
case kUpb_FieldType_Int32:
case kUpb_FieldType_UInt32:
case kUpb_FieldType_Enum:
decode_munge_int32(val);
_upb_Decoder_MungeInt32(val);
break;
}
}
static upb_Message* decode_newsubmsg(upb_Decoder* d,
const upb_MiniTable_Sub* subs,
static upb_Message* _upb_Decoder_NewSubMessage(
upb_Decoder* d, const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field) {
const upb_MiniTable* subl = subs[field->submsg_index].submsg;
upb_Message* msg = _upb_Message_New_inl(subl, &d->arena);
if (!msg) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
return msg;
}
UPB_NOINLINE
const char* decode_isdonefallback(upb_Decoder* d, const char* ptr,
const char* _upb_Decoder_IsDoneFallback(upb_Decoder* d, const char* ptr,
int overrun) {
int status;
ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
if (ptr == NULL) {
return decode_err(d, status);
}
ptr = _upb_Decoder_IsDoneFallbackInline(d, ptr, overrun, &status);
if (ptr == NULL) _upb_Decoder_ErrorJmp(d, status);
return ptr;
}
static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size,
upb_StringView* str) {
static const char* _upb_Decoder_ReadString(upb_Decoder* d, const char* ptr,
int size, upb_StringView* str) {
if (d->options & kUpb_DecodeOption_AliasString) {
str->data = ptr;
} else {
char* data = upb_Arena_Malloc(&d->arena, size);
if (!data) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
if (!data) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
memcpy(data, ptr, size);
str->data = data;
}
@ -338,50 +341,56 @@ static const char* decode_readstr(upb_Decoder* d, const char* ptr, int size,
}
UPB_FORCEINLINE
static const char* decode_tosubmsg2(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTable* subl, int size) {
int saved_delta = decode_pushlimit(d, ptr, size);
if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
ptr = decode_msg(d, ptr, submsg, subl);
if (d->end_group != DECODE_NOGROUP)
return decode_err(d, kUpb_DecodeStatus_Malformed);
decode_poplimit(d, ptr, saved_delta);
static const char* _upb_Decoder_DecodeSubMessage(
upb_Decoder* d, const char* ptr, upb_Message* submsg,
const upb_MiniTable_Sub* subs, const upb_MiniTable_Field* field, int size) {
int saved_delta = _upb_Decoder_PushLimit(d, ptr, size);
const upb_MiniTable* subl = subs[field->submsg_index].submsg;
if (--d->depth < 0) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_MaxDepthExceeded);
}
ptr = _upb_Decoder_DecodeMessage(d, ptr, submsg, subl);
if (d->end_group != DECODE_NOGROUP) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
_upb_Decoder_PopLimit(d, ptr, saved_delta);
d->depth++;
return ptr;
}
UPB_FORCEINLINE
static const char* decode_tosubmsg(upb_Decoder* d, const char* ptr,
static const char* _upb_Decoder_DoDecodeGroup(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field, int size) {
return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg,
size);
}
UPB_FORCEINLINE
static const char* decode_group(upb_Decoder* d, const char* ptr,
upb_Message* submsg, const upb_MiniTable* subl,
const upb_MiniTable* subl,
uint32_t number) {
if (--d->depth < 0) return decode_err(d, kUpb_DecodeStatus_MaxDepthExceeded);
if (decode_isdone(d, &ptr)) {
return decode_err(d, kUpb_DecodeStatus_Malformed);
if (--d->depth < 0) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_MaxDepthExceeded);
}
if (_upb_Decoder_IsDone(d, &ptr)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
ptr = _upb_Decoder_DecodeMessage(d, ptr, submsg, subl);
if (d->end_group != number) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
ptr = decode_msg(d, ptr, submsg, subl);
if (d->end_group != number) return decode_err(d, kUpb_DecodeStatus_Malformed);
d->end_group = DECODE_NOGROUP;
d->depth++;
return ptr;
}
UPB_FORCEINLINE
static const char* decode_togroup(upb_Decoder* d, const char* ptr,
upb_Message* submsg,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field) {
static const char* _upb_Decoder_DecodeUnknownGroup(upb_Decoder* d,
const char* ptr,
uint32_t number) {
return _upb_Decoder_DoDecodeGroup(d, ptr, NULL, NULL, number);
}
UPB_FORCEINLINE
static const char* _upb_Decoder_DecodeKnownGroup(
upb_Decoder* d, const char* ptr, upb_Message* submsg,
const upb_MiniTable_Sub* subs, const upb_MiniTable_Field* field) {
const upb_MiniTable* subl = subs[field->submsg_index].submsg;
return decode_group(d, ptr, submsg, subl, field->number);
return _upb_Decoder_DoDecodeGroup(d, ptr, submsg, subl, field->number);
}
static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) {
@ -394,7 +403,7 @@ static char* upb_Decoder_EncodeVarint32(uint32_t val, char* ptr) {
return ptr;
}
static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
static void _upb_Decoder_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
uint32_t val1, uint32_t val2) {
char buf[20];
char* end = buf;
@ -402,13 +411,14 @@ static void upb_Decode_AddUnknownVarints(upb_Decoder* d, upb_Message* msg,
end = upb_Decoder_EncodeVarint32(val2, end);
if (!_upb_Message_AddUnknown(msg, buf, end - buf, &d->arena)) {
decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
}
UPB_NOINLINE
static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr,
upb_Message* msg, const upb_MiniTable_Enum* e,
static bool _upb_Decoder_CheckEnumSlow(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable_Enum* e,
const upb_MiniTable_Field* field,
uint32_t v) {
// OPT: binary search long lists?
@ -423,29 +433,30 @@ static bool decode_checkenum_slow(upb_Decoder* d, const char* ptr,
uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Varint;
upb_Message* unknown_msg =
field->mode & kUpb_LabelFlags_IsExtension ? d->unknown_msg : msg;
upb_Decode_AddUnknownVarints(d, unknown_msg, tag, v);
_upb_Decoder_AddUnknownVarints(d, unknown_msg, tag, v);
return false;
}
UPB_FORCEINLINE
static bool decode_checkenum(upb_Decoder* d, const char* ptr, upb_Message* msg,
static bool _upb_Decoder_CheckEnum(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable_Enum* e,
const upb_MiniTable_Field* field, wireval* val) {
const upb_MiniTable_Field* field,
wireval* val) {
uint32_t v = val->uint32_val;
if (UPB_LIKELY(v < 64) && UPB_LIKELY(((1ULL << v) & e->mask))) return true;
return decode_checkenum_slow(d, ptr, msg, e, field, v);
return _upb_Decoder_CheckEnumSlow(d, ptr, msg, e, field, v);
}
UPB_NOINLINE
static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr,
upb_Message* msg, upb_Array* arr,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field,
static const char* _upb_Decoder_DecodeEnumArray(
upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
const upb_MiniTable_Sub* subs, const upb_MiniTable_Field* field,
wireval* val) {
const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
if (!decode_checkenum(d, ptr, msg, e, field, val)) return ptr;
if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr;
void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
arr->size++;
memcpy(mem, val, 4);
@ -453,17 +464,16 @@ static const char* decode_enum_toarray(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr,
upb_Array* arr, wireval* val,
const upb_MiniTable_Field* field,
int lg2) {
static const char* _upb_Decoder_DecodeFixedPacked(
upb_Decoder* d, const char* ptr, upb_Array* arr, wireval* val,
const upb_MiniTable_Field* field, int lg2) {
int mask = (1 << lg2) - 1;
size_t count = val->size >> lg2;
if ((val->size & mask) != 0) {
// Length isn't a round multiple of elem size.
return decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
decode_reserve(d, arr, count);
_upb_Decoder_Reserve(d, arr, count);
void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size << lg2, void);
arr->size += count;
// Note: if/when the decoder supports multi-buffer input, we will need to
@ -496,56 +506,54 @@ static const char* decode_fixed_packed(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static const char* decode_varint_packed(upb_Decoder* d, const char* ptr,
upb_Array* arr, wireval* val,
const upb_MiniTable_Field* field,
int lg2) {
static const char* _upb_Decoder_DecodeVarintPacked(
upb_Decoder* d, const char* ptr, upb_Array* arr, wireval* val,
const upb_MiniTable_Field* field, int lg2) {
int scale = 1 << lg2;
int saved_limit = decode_pushlimit(d, ptr, val->size);
int saved_limit = _upb_Decoder_PushLimit(d, ptr, val->size);
char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size << lg2, void);
while (!decode_isdone(d, &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
wireval elem;
ptr = decode_varint64(d, ptr, &elem.uint64_val);
decode_munge(field->descriptortype, &elem);
if (decode_reserve(d, arr, 1)) {
ptr = _upb_Decoder_DecodeVarint(d, ptr, &elem.uint64_val);
_upb_Decoder_Munge(field->descriptortype, &elem);
if (_upb_Decoder_Reserve(d, arr, 1)) {
out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size << lg2, void);
}
arr->size++;
memcpy(out, &elem, scale);
out += scale;
}
decode_poplimit(d, ptr, saved_limit);
_upb_Decoder_PopLimit(d, ptr, saved_limit);
return ptr;
}
UPB_NOINLINE
static const char* decode_enum_packed(upb_Decoder* d, const char* ptr,
upb_Message* msg, upb_Array* arr,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field,
static const char* _upb_Decoder_DecodeEnumPacked(
upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
const upb_MiniTable_Sub* subs, const upb_MiniTable_Field* field,
wireval* val) {
const upb_MiniTable_Enum* e = subs[field->submsg_index].subenum;
int saved_limit = decode_pushlimit(d, ptr, val->size);
int saved_limit = _upb_Decoder_PushLimit(d, ptr, val->size);
char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
while (!decode_isdone(d, &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
wireval elem;
ptr = decode_varint64(d, ptr, &elem.uint64_val);
decode_munge_int32(&elem);
if (!decode_checkenum(d, ptr, msg, e, field, &elem)) {
ptr = _upb_Decoder_DecodeVarint(d, ptr, &elem.uint64_val);
_upb_Decoder_MungeInt32(&elem);
if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, &elem)) {
continue;
}
if (decode_reserve(d, arr, 1)) {
if (_upb_Decoder_Reserve(d, arr, 1)) {
out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
}
arr->size++;
memcpy(out, &elem, 4);
out += 4;
}
decode_poplimit(d, ptr, saved_limit);
_upb_Decoder_PopLimit(d, ptr, saved_limit);
return ptr;
}
static const char* decode_toarray(upb_Decoder* d, const char* ptr,
static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field,
@ -555,11 +563,11 @@ static const char* decode_toarray(upb_Decoder* d, const char* ptr,
void* mem;
if (arr) {
decode_reserve(d, arr, 1);
_upb_Decoder_Reserve(d, arr, 1);
} else {
size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype];
arr = _upb_Array_New(&d->arena, 4, lg2);
if (!arr) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
if (!arr) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
*arrp = arr;
}
@ -573,46 +581,48 @@ static const char* decode_toarray(upb_Decoder* d, const char* ptr,
memcpy(mem, val, 1 << op);
return ptr;
case OP_STRING:
decode_verifyutf8(d, ptr, val->size);
_upb_Decoder_VerifyUtf8(d, ptr, val->size);
/* Fallthrough. */
case OP_BYTES: {
/* Append bytes. */
upb_StringView* str = (upb_StringView*)_upb_array_ptr(arr) + arr->size;
arr->size++;
return decode_readstr(d, ptr, val->size, str);
return _upb_Decoder_ReadString(d, ptr, val->size, str);
}
case OP_SUBMSG: {
/* Append submessage / group. */
upb_Message* submsg = decode_newsubmsg(d, subs, field);
upb_Message* submsg = _upb_Decoder_NewSubMessage(d, subs, field);
*UPB_PTR_AT(_upb_array_ptr(arr), arr->size * sizeof(void*),
upb_Message*) = submsg;
arr->size++;
if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) {
return decode_togroup(d, ptr, submsg, subs, field);
return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, subs, field);
} else {
return decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, subs, field,
val->size);
}
}
case OP_FIXPCK_LG2(2):
case OP_FIXPCK_LG2(3):
return decode_fixed_packed(d, ptr, arr, val, field,
return _upb_Decoder_DecodeFixedPacked(d, ptr, arr, val, field,
op - OP_FIXPCK_LG2(0));
case OP_VARPCK_LG2(0):
case OP_VARPCK_LG2(2):
case OP_VARPCK_LG2(3):
return decode_varint_packed(d, ptr, arr, val, field,
return _upb_Decoder_DecodeVarintPacked(d, ptr, arr, val, field,
op - OP_VARPCK_LG2(0));
case OP_ENUM:
return decode_enum_toarray(d, ptr, msg, arr, subs, field, val);
return _upb_Decoder_DecodeEnumArray(d, ptr, msg, arr, subs, field, val);
case OP_PACKED_ENUM:
return decode_enum_packed(d, ptr, msg, arr, subs, field, val);
return _upb_Decoder_DecodeEnumPacked(d, ptr, msg, arr, subs, field, val);
default:
UPB_UNREACHABLE();
}
}
static const char* decode_tomap(upb_Decoder* d, const char* ptr,
upb_Message* msg, const upb_MiniTable_Sub* subs,
static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field,
wireval* val) {
upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*);
@ -643,35 +653,35 @@ static const char* decode_tomap(upb_Decoder* d, const char* ptr,
}
const char* start = ptr;
ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size);
ptr = _upb_Decoder_DecodeSubMessage(d, ptr, &ent.k, subs, field, val->size);
// check if ent had any unknown fields
size_t size;
upb_Message_GetUnknown(&ent.k, &size);
if (size != 0) {
uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited;
upb_Decode_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start));
_upb_Decoder_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start));
if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
} else {
if (_upb_Map_Insert(map, &ent.k, map->key_size, &ent.v, map->val_size,
&d->arena) == _kUpb_MapInsertStatus_OutOfMemory) {
decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
}
return ptr;
}
static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
upb_Message* msg, const upb_MiniTable_Sub* subs,
const upb_MiniTable_Field* field, wireval* val,
int op) {
static const char* _upb_Decoder_DecodeToSubMessage(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTable_Sub* subs, const upb_MiniTable_Field* field,
wireval* val, int op) {
void* mem = UPB_PTR_AT(msg, field->offset, void);
int type = field->descriptortype;
if (UPB_UNLIKELY(op == OP_ENUM) &&
!decode_checkenum(d, ptr, msg, subs[field->submsg_index].subenum, field,
val)) {
!_upb_Decoder_CheckEnum(d, ptr, msg, subs[field->submsg_index].subenum,
field, val)) {
return ptr;
}
@ -693,21 +703,22 @@ static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
upb_Message** submsgp = mem;
upb_Message* submsg = *submsgp;
if (!submsg) {
submsg = decode_newsubmsg(d, subs, field);
submsg = _upb_Decoder_NewSubMessage(d, subs, field);
*submsgp = submsg;
}
if (UPB_UNLIKELY(type == kUpb_FieldType_Group)) {
ptr = decode_togroup(d, ptr, submsg, subs, field);
ptr = _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, subs, field);
} else {
ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
ptr = _upb_Decoder_DecodeSubMessage(d, ptr, submsg, subs, field,
val->size);
}
break;
}
case OP_STRING:
decode_verifyutf8(d, ptr, val->size);
_upb_Decoder_VerifyUtf8(d, ptr, val->size);
/* Fallthrough. */
case OP_BYTES:
return decode_readstr(d, ptr, val->size, mem);
return _upb_Decoder_ReadString(d, ptr, val->size, mem);
case OP_SCALAR_LG2(3):
memcpy(mem, val, 8);
break;
@ -726,7 +737,7 @@ static const char* decode_tomsg(upb_Decoder* d, const char* ptr,
}
UPB_NOINLINE
const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l) {
assert(l->required_count);
@ -743,14 +754,14 @@ const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
}
UPB_FORCEINLINE
static bool decode_tryfastdispatch(upb_Decoder* d, const char** ptr,
static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr,
upb_Message* msg,
const upb_MiniTable* layout) {
#if UPB_FASTTABLE
if (layout && layout->table_mask != (unsigned char)-1) {
uint16_t tag = fastdecode_loadtag(*ptr);
uint16_t tag = _upb_FastDecoder_LoadTag(*ptr);
intptr_t table = decode_totable(layout);
*ptr = fastdecode_tagdispatch(d, *ptr, msg, table, 0, tag);
*ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag);
return true;
}
#endif
@ -764,7 +775,7 @@ static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
switch (wire_type) {
case kUpb_WireType_Varint: {
uint64_t val;
return decode_varint64(d, ptr, &val);
return _upb_Decoder_DecodeVarint(d, ptr, &val);
}
case kUpb_WireType_64Bit:
return ptr + 8;
@ -776,9 +787,9 @@ static const char* upb_Decoder_SkipField(upb_Decoder* d, const char* ptr,
return ptr + size;
}
case kUpb_WireType_StartGroup:
return decode_group(d, ptr, NULL, NULL, field_number);
return _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
default:
decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
}
@ -794,12 +805,15 @@ static void upb_Decoder_AddKnownMessageSetItem(
const char* data, uint32_t size) {
upb_Message_Extension* ext =
_upb_Message_GetOrCreateExtension(msg, item_mt, &d->arena);
if (UPB_UNLIKELY(!ext)) decode_err(d, kUpb_DecodeStatus_OutOfMemory);
upb_Message* submsg = decode_newsubmsg(d, &ext->ext->sub, &ext->ext->field);
if (UPB_UNLIKELY(!ext)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
upb_Message* submsg =
_upb_Decoder_NewSubMessage(d, &ext->ext->sub, &ext->ext->field);
upb_DecodeStatus status = upb_Decode(data, size, submsg, item_mt->sub.submsg,
d->extreg, d->options, &d->arena);
memcpy(&ext->data, &submsg, sizeof(submsg));
if (status != kUpb_DecodeStatus_Ok) decode_err(d, status);
if (status != kUpb_DecodeStatus_Ok) _upb_Decoder_ErrorJmp(d, status);
}
static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d,
@ -822,7 +836,7 @@ static void upb_Decoder_AddUnknownMessageSetItem(upb_Decoder* d,
if (!_upb_Message_AddUnknown(msg, buf, split - buf, &d->arena) ||
!_upb_Message_AddUnknown(msg, message_data, message_size, &d->arena) ||
!_upb_Message_AddUnknown(msg, split, end - split, &d->arena)) {
decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
}
@ -849,15 +863,15 @@ static const char* upb_Decoder_DecodeMessageSetItem(
kUpb_HavePayload = 1 << 1,
} StateMask;
StateMask state_mask = 0;
while (!decode_isdone(d, &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
uint32_t tag;
ptr = decode_tag(d, ptr, &tag);
ptr = _upb_Decoder_DecodeTag(d, ptr, &tag);
switch (tag) {
case kEndItemTag:
return ptr;
case kTypeIdTag: {
uint64_t tmp;
ptr = decode_varint64(d, ptr, &tmp);
ptr = _upb_Decoder_DecodeVarint(d, ptr, &tmp);
if (state_mask & kUpb_HaveId) break; // Ignore dup.
state_mask |= kUpb_HaveId;
type_id = tmp;
@ -889,12 +903,11 @@ static const char* upb_Decoder_DecodeMessageSetItem(
break;
}
}
decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
static const upb_MiniTable_Field* decode_findfield(upb_Decoder* d,
const upb_MiniTable* l,
uint32_t field_number,
static const upb_MiniTable_Field* _upb_Decoder_FindField(
upb_Decoder* d, const upb_MiniTable* l, uint32_t field_number,
int* last_field_index) {
static upb_MiniTable_Field none = {0, 0, 0, 0, 0, 0};
if (l == NULL) return &none;
@ -948,14 +961,14 @@ found:
}
UPB_FORCEINLINE
static const char* decode_wireval(upb_Decoder* d, const char* ptr,
const upb_MiniTable_Field* field,
static const char* _upb_Decoder_DecodeWireValue(
upb_Decoder* d, const char* ptr, const upb_MiniTable_Field* field,
int wire_type, wireval* val, int* op) {
switch (wire_type) {
case kUpb_WireType_Varint:
ptr = decode_varint64(d, ptr, &val->uint64_val);
ptr = _upb_Decoder_DecodeVarint(d, ptr, &val->uint64_val);
*op = varint_ops[field->descriptortype];
decode_munge(field->descriptortype, val);
_upb_Decoder_Munge(field->descriptortype, val);
return ptr;
case kUpb_WireType_32Bit:
memcpy(&val->uint32_val, ptr, 4);
@ -993,13 +1006,13 @@ static const char* decode_wireval(upb_Decoder* d, const char* ptr,
default:
break;
}
return decode_err(d, kUpb_DecodeStatus_Malformed);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
}
UPB_FORCEINLINE
static const char* decode_known(upb_Decoder* d, const char* ptr,
upb_Message* msg, const upb_MiniTable* layout,
const upb_MiniTable_Field* field, int op,
static const char* _upb_Decoder_DecodeKnownField(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTable* layout, const upb_MiniTable_Field* field, int op,
wireval* val) {
const upb_MiniTable_Sub* subs = layout->subs;
uint8_t mode = field->mode;
@ -1009,7 +1022,9 @@ static const char* decode_known(upb_Decoder* d, const char* ptr,
(const upb_MiniTable_Extension*)field;
upb_Message_Extension* ext =
_upb_Message_GetOrCreateExtension(msg, ext_layout, &d->arena);
if (UPB_UNLIKELY(!ext)) return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
if (UPB_UNLIKELY(!ext)) {
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
d->unknown_msg = msg;
msg = &ext->data;
subs = &ext->ext->sub;
@ -1017,17 +1032,18 @@ static const char* decode_known(upb_Decoder* d, const char* ptr,
switch (mode & kUpb_FieldMode_Mask) {
case kUpb_FieldMode_Array:
return decode_toarray(d, ptr, msg, subs, field, val, op);
return _upb_Decoder_DecodeToArray(d, ptr, msg, subs, field, val, op);
case kUpb_FieldMode_Map:
return decode_tomap(d, ptr, msg, subs, field, val);
return _upb_Decoder_DecodeToMap(d, ptr, msg, subs, field, val);
case kUpb_FieldMode_Scalar:
return decode_tomsg(d, ptr, msg, subs, field, val, op);
return _upb_Decoder_DecodeToSubMessage(d, ptr, msg, subs, field, val, op);
default:
UPB_UNREACHABLE();
}
}
static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) {
static const char* _upb_Decoder_ReverseSkipVarint(const char* ptr,
uint32_t val) {
uint32_t seen = 0;
do {
ptr--;
@ -1037,10 +1053,12 @@ static const char* decode_reverse_skip_varint(const char* ptr, uint32_t val) {
return ptr;
}
static const char* decode_unknown(upb_Decoder* d, const char* ptr,
upb_Message* msg, int field_number,
static const char* _upb_Decoder_DecodeUnknownField(upb_Decoder* d,
const char* ptr,
upb_Message* msg,
int field_number,
int wire_type, wireval val) {
if (field_number == 0) return decode_err(d, kUpb_DecodeStatus_Malformed);
if (field_number == 0) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed);
// Since unknown fields are the uncommon case, we do a little extra work here
// to walk backwards through the buffer to find the field start. This frees
@ -1068,37 +1086,38 @@ static const char* decode_unknown(upb_Decoder* d, const char* ptr,
assert(start == d->debug_valstart);
uint32_t tag = ((uint32_t)field_number << 3) | wire_type;
start = decode_reverse_skip_varint(start, tag);
start = _upb_Decoder_ReverseSkipVarint(start, tag);
assert(start == d->debug_tagstart);
if (wire_type == kUpb_WireType_StartGroup) {
d->unknown = start;
d->unknown_msg = msg;
ptr = decode_group(d, ptr, NULL, NULL, field_number);
ptr = _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
start = d->unknown;
d->unknown = NULL;
}
if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
return decode_err(d, kUpb_DecodeStatus_OutOfMemory);
_upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
}
} else if (wire_type == kUpb_WireType_StartGroup) {
ptr = decode_group(d, ptr, NULL, NULL, field_number);
ptr = _upb_Decoder_DecodeUnknownGroup(d, ptr, field_number);
}
return ptr;
}
UPB_NOINLINE
static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
upb_Message* msg,
const upb_MiniTable* layout) {
int last_field_index = 0;
#if UPB_FASTTABLE
// The first time we want to skip fast dispatch, because we may have just been
// invoked by the fast parser to handle a case that it bailed on.
if (!decode_isdone(d, &ptr)) goto nofast;
if (!_upb_Decoder_IsDone(d, &ptr)) goto nofast;
#endif
while (!decode_isdone(d, &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
uint32_t tag;
const upb_MiniTable_Field* field;
int field_number;
@ -1106,7 +1125,7 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
wireval val;
int op;
if (decode_tryfastdispatch(d, &ptr, msg, layout)) break;
if (_upb_Decoder_TryFastDispatch(d, &ptr, msg, layout)) break;
#if UPB_FASTTABLE
nofast:
@ -1117,7 +1136,7 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
#endif
UPB_ASSERT(ptr < d->limit_ptr);
ptr = decode_tag(d, ptr, &tag);
ptr = _upb_Decoder_DecodeTag(d, ptr, &tag);
field_number = tag >> 3;
wire_type = tag & 7;
@ -1130,15 +1149,16 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
return ptr;
}
field = decode_findfield(d, layout, field_number, &last_field_index);
ptr = decode_wireval(d, ptr, field, wire_type, &val, &op);
field = _upb_Decoder_FindField(d, layout, field_number, &last_field_index);
ptr = _upb_Decoder_DecodeWireValue(d, ptr, field, wire_type, &val, &op);
if (op >= 0) {
ptr = decode_known(d, ptr, msg, layout, field, op, &val);
ptr = _upb_Decoder_DecodeKnownField(d, ptr, msg, layout, field, op, &val);
} else {
switch (op) {
case OP_UNKNOWN:
ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val);
ptr = _upb_Decoder_DecodeUnknownField(d, ptr, msg, field_number,
wire_type, val);
break;
case OP_MSGSET_ITEM:
ptr = upb_Decoder_DecodeMessageSetItem(d, ptr, msg, layout);
@ -1148,22 +1168,24 @@ static const char* decode_msg(upb_Decoder* d, const char* ptr, upb_Message* msg,
}
return UPB_UNLIKELY(layout && layout->required_count)
? decode_checkrequired(d, ptr, msg, layout)
? _upb_Decoder_CheckRequired(d, ptr, msg, layout)
: ptr;
}
const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data) {
const char* _upb_FastDecoder_DecodeGeneric(struct upb_Decoder* d,
const char* ptr, upb_Message* msg,
intptr_t table, uint64_t hasbits,
uint64_t data) {
(void)data;
*(uint32_t*)msg |= hasbits;
return decode_msg(d, ptr, msg, decode_totablep(table));
return _upb_Decoder_DecodeMessage(d, ptr, msg, decode_totablep(table));
}
static upb_DecodeStatus decode_top(struct upb_Decoder* d, const char* buf,
void* msg, const upb_MiniTable* l) {
if (!decode_tryfastdispatch(d, &buf, msg, l)) {
decode_msg(d, buf, msg, l);
static upb_DecodeStatus _upb_Decoder_DecodeTop(struct upb_Decoder* d,
const char* buf, void* msg,
const upb_MiniTable* l) {
if (!_upb_Decoder_TryFastDispatch(d, &buf, msg, l)) {
_upb_Decoder_DecodeMessage(d, buf, msg, l);
}
if (d->end_group != DECODE_NOGROUP) return kUpb_DecodeStatus_Malformed;
if (d->missing_required) return kUpb_DecodeStatus_MissingRequired;
@ -1203,7 +1225,7 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg,
upb_DecodeStatus status = UPB_SETJMP(state.err);
if (UPB_LIKELY(status == kUpb_DecodeStatus_Ok)) {
status = decode_top(&state, buf, msg, l);
status = _upb_Decoder_DecodeTop(&state, buf, msg, l);
}
arena->head.ptr = state.arena.head.ptr;

@ -57,7 +57,7 @@
/* Uncomment either of these for debugging purposes. */ \
/* fprintf(stderr, m); */ \
/*__builtin_trap(); */ \
return fastdecode_generic(d, ptr, msg, table, hasbits, 0);
return _upb_FastDecoder_DecodeGeneric(d, ptr, msg, table, hasbits, 0);
typedef enum {
CARD_s = 0, /* Singular (optional, non-repeated) */
@ -70,12 +70,10 @@ UPB_NOINLINE
static const char* fastdecode_isdonefallback(UPB_PARSE_PARAMS) {
int overrun = data;
int status;
ptr = decode_isdonefallback_inl(d, ptr, overrun, &status);
if (ptr == NULL) {
return fastdecode_err(d, status);
}
data = fastdecode_loadtag(ptr);
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
ptr = _upb_Decoder_IsDoneFallbackInline(d, ptr, overrun, &status);
if (ptr == NULL) _upb_FastDecoder_ErrorJmp(d, status);
data = _upb_FastDecoder_LoadTag(ptr);
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS);
}
UPB_FORCEINLINE
@ -87,7 +85,7 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
*(uint32_t*)msg |= hasbits; // Sync hasbits.
const upb_MiniTable* l = decode_totablep(table);
return UPB_UNLIKELY(l->required_count)
? decode_checkrequired(d, ptr, msg, l)
? _upb_Decoder_CheckRequired(d, ptr, msg, l)
: ptr;
} else {
data = overrun;
@ -96,8 +94,8 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
}
// Read two bytes of tag data (for a one-byte tag, the high byte is junk).
data = fastdecode_loadtag(ptr);
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS);
data = _upb_FastDecoder_LoadTag(ptr);
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS);
}
UPB_FORCEINLINE
@ -176,9 +174,9 @@ static const char* fastdecode_delimited(upb_Decoder* d, const char* ptr,
// Corrupt wire format: invalid limit.
return NULL;
}
int delta = decode_pushlimit(d, ptr, len);
int delta = _upb_Decoder_PushLimit(d, ptr, len);
ptr = func(d, ptr, ctx);
decode_poplimit(d, ptr, delta);
_upb_Decoder_PopLimit(d, ptr, delta);
} else {
// Fast case: Sub-message is <128 bytes and fits in the current buffer.
// This means we can preserve limit/limit_ptr verbatim.
@ -258,8 +256,8 @@ static fastdecode_nextret fastdecode_nextrepeated(upb_Decoder* d, void* dst,
fastdecode_nextret ret;
dst = (char*)dst + valbytes;
if (UPB_LIKELY(!decode_isdone(d, ptr))) {
ret.tag = fastdecode_loadtag(*ptr);
if (UPB_LIKELY(!_upb_Decoder_IsDone(d, ptr))) {
ret.tag = _upb_FastDecoder_LoadTag(*ptr);
if (fastdecode_tagmatch(ret.tag, data, tagbytes)) {
ret.next = FD_NEXT_SAMEFIELD;
} else {
@ -315,7 +313,7 @@ static void* fastdecode_getfield(upb_Decoder* d, const char* ptr,
}
begin = _upb_array_ptr(farr->arr);
farr->end = begin + (farr->arr->capacity * valbytes);
*data = fastdecode_loadtag(ptr);
*data = _upb_FastDecoder_LoadTag(ptr);
return begin + (farr->arr->size * valbytes);
}
default:
@ -402,7 +400,7 @@ done:
\
ptr += tagbytes; \
ptr = fastdecode_varint64(ptr, &val); \
if (ptr == NULL) return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
if (ptr == NULL) _upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
val = fastdecode_munge(val, valbytes, zigzag); \
memcpy(dst, &val, valbytes); \
\
@ -415,7 +413,7 @@ done:
goto again; \
case FD_NEXT_OTHERFIELD: \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
case FD_NEXT_ATLIMIT: \
return ptr; \
} \
@ -437,7 +435,7 @@ static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr,
void* dst = data->dst;
uint64_t val;
while (!decode_isdone(d, &ptr)) {
while (!_upb_Decoder_IsDone(d, &ptr)) {
dst = fastdecode_resizearr(d, dst, &data->farr, data->valbytes);
ptr = fastdecode_varint64(ptr, &val);
if (ptr == NULL) return NULL;
@ -466,7 +464,7 @@ static const char* fastdecode_topackedvarint(upb_Decoder* d, const char* ptr,
ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \
\
if (UPB_UNLIKELY(ptr == NULL)) { \
return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
} \
\
UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0);
@ -561,7 +559,7 @@ TAGBYTES(p)
goto again; \
case FD_NEXT_OTHERFIELD: \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
case FD_NEXT_ATLIMIT: \
return ptr; \
} \
@ -582,7 +580,7 @@ TAGBYTES(p)
\
if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \
(size % valbytes) != 0)) { \
return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
} \
\
upb_Array** arr_p = fastdecode_fieldmem(msg, data); \
@ -593,7 +591,7 @@ TAGBYTES(p)
if (UPB_LIKELY(!arr)) { \
*arr_p = arr = _upb_Array_New(&d->arena, elems, elem_size_lg2); \
if (!arr) { \
return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
} \
} else { \
_upb_Array_Resize(arr, elems, &d->arena); \
@ -659,8 +657,8 @@ static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data) {
upb_StringView* dst = (upb_StringView*)data;
if (!decode_verifyutf8_inl(dst->data, dst->size)) {
return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8);
if (!_upb_Decoder_VerifyUtf8Inline(dst->data, dst->size)) {
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_BadUtf8);
}
UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS);
}
@ -674,7 +672,7 @@ static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr,
\
if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \
dst->size = 0; \
return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
} \
\
if (d->options & kUpb_DecodeOption_AliasString) { \
@ -683,7 +681,7 @@ static const char* fastdecode_verifyutf8(upb_Decoder* d, const char* ptr,
} else { \
char* data = upb_Arena_Malloc(&d->arena, size); \
if (!data) { \
return fastdecode_err(d, kUpb_DecodeStatus_OutOfMemory); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); \
} \
memcpy(data, ptr, size); \
dst->data = data; \
@ -774,8 +772,9 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
ptr += size; \
\
if (card == CARD_r) { \
if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
if (validate_utf8 && \
!_upb_Decoder_VerifyUtf8Inline(dst->data, dst->size)) { \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_BadUtf8); \
} \
fastdecode_nextret ret = fastdecode_nextrepeated( \
d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
@ -785,7 +784,7 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
goto again; \
case FD_NEXT_OTHERFIELD: \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
case FD_NEXT_ATLIMIT: \
return ptr; \
} \
@ -852,8 +851,9 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
ptr += size; \
\
if (card == CARD_r) { \
if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \
return fastdecode_err(d, kUpb_DecodeStatus_BadUtf8); \
if (validate_utf8 && \
!_upb_Decoder_VerifyUtf8Inline(dst->data, dst->size)) { \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_BadUtf8); \
} \
fastdecode_nextret ret = fastdecode_nextrepeated( \
d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_StringView)); \
@ -866,12 +866,12 @@ static void fastdecode_docopy(upb_Decoder* d, const char* ptr, uint32_t size,
/* data also. */ \
fastdecode_commitarr(dst, &farr, sizeof(upb_StringView)); \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
} \
goto again; \
case FD_NEXT_OTHERFIELD: \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
case FD_NEXT_ATLIMIT: \
return ptr; \
} \
@ -966,7 +966,7 @@ static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr,
} \
\
if (--d->depth == 0) { \
return fastdecode_err(d, kUpb_DecodeStatus_MaxDepthExceeded); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_MaxDepthExceeded); \
} \
\
upb_Message** dst; \
@ -1003,7 +1003,7 @@ static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr,
ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \
\
if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \
return fastdecode_err(d, kUpb_DecodeStatus_Malformed); \
_upb_FastDecoder_ErrorJmp(d, kUpb_DecodeStatus_Malformed); \
} \
\
if (card == CARD_r) { \
@ -1016,7 +1016,7 @@ static const char* fastdecode_tosubmsg(upb_Decoder* d, const char* ptr,
case FD_NEXT_OTHERFIELD: \
d->depth++; \
data = ret.tag; \
UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \
UPB_MUSTTAIL return _upb_FastDecoder_TagDispatch(UPB_PARSE_ARGS); \
case FD_NEXT_ATLIMIT: \
d->depth++; \
return ptr; \

@ -75,9 +75,10 @@ struct upb_Decoder;
// The fallback, generic parsing function that can handle any field type.
// This just uses the regular (non-fast) parser to parse a single field.
const char* fastdecode_generic(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data);
const char* _upb_FastDecoder_DecodeGeneric(struct upb_Decoder* d,
const char* ptr, upb_Message* msg,
intptr_t table, uint64_t hasbits,
uint64_t data);
#define UPB_PARSE_PARAMS \
struct upb_Decoder *d, const char *ptr, upb_Message *msg, intptr_t table, \

@ -1541,7 +1541,7 @@ static void make_layout(upb_DefBuilder* ctx, const upb_MessageDef* m) {
/* TODO(haberman): initialize fast tables so that reflection-based parsing
* can get the same speeds as linked-in types. */
l->fasttable[0].field_parser = &fastdecode_generic;
l->fasttable[0].field_parser = &_upb_FastDecoder_DecodeGeneric;
l->fasttable[0].field_data = 0;
if (upb_MessageDef_IsMapEntry(m)) {

@ -72,12 +72,12 @@ typedef struct upb_Decoder {
* of our optimizations. That is also why we must declare it in a separate file,
* otherwise the compiler will see that it calls longjmp() and deduce that it is
* noreturn. */
const char* fastdecode_err(upb_Decoder* d, int status);
const char* _upb_FastDecoder_ErrorJmp(upb_Decoder* d, int status);
extern const uint8_t upb_utf8_offsets[];
UPB_INLINE
bool decode_verifyutf8_inl(const char* ptr, int len) {
bool _upb_Decoder_VerifyUtf8Inline(const char* ptr, int len) {
const char* end = ptr + len;
// Check 8 bytes at a time for any non-ASCII char.
@ -100,7 +100,7 @@ non_ascii:
return utf8_range2((const unsigned char*)ptr, end - ptr) == 0;
}
const char* decode_checkrequired(upb_Decoder* d, const char* ptr,
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l);
@ -115,7 +115,7 @@ UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) {
}
UPB_INLINE
const char* decode_isdonefallback_inl(upb_Decoder* d, const char* ptr,
const char* _upb_Decoder_IsDoneFallbackInline(upb_Decoder* d, const char* ptr,
int overrun, int* status) {
if (overrun < d->limit) {
/* Need to copy remaining data into patch buffer. */
@ -143,24 +143,25 @@ const char* decode_isdonefallback_inl(upb_Decoder* d, const char* ptr,
}
}
const char* decode_isdonefallback(upb_Decoder* d, const char* ptr, int overrun);
const char* _upb_Decoder_IsDoneFallback(upb_Decoder* d, const char* ptr,
int overrun);
UPB_INLINE
bool decode_isdone(upb_Decoder* d, const char** ptr) {
bool _upb_Decoder_IsDone(upb_Decoder* d, const char** ptr) {
int overrun = *ptr - d->end;
if (UPB_LIKELY(*ptr < d->limit_ptr)) {
return false;
} else if (UPB_LIKELY(overrun == d->limit)) {
return true;
} else {
*ptr = decode_isdonefallback(d, *ptr, overrun);
*ptr = _upb_Decoder_IsDoneFallback(d, *ptr, overrun);
return false;
}
}
#if UPB_FASTTABLE
UPB_INLINE
const char* fastdecode_tagdispatch(upb_Decoder* d, const char* ptr,
const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t tag) {
const upb_MiniTable* table_p = decode_totablep(table);
@ -175,33 +176,34 @@ const char* fastdecode_tagdispatch(upb_Decoder* d, const char* ptr,
}
#endif
UPB_INLINE uint32_t fastdecode_loadtag(const char* ptr) {
UPB_INLINE uint32_t _upb_FastDecoder_LoadTag(const char* ptr) {
uint16_t tag;
memcpy(&tag, ptr, 2);
return tag;
}
UPB_INLINE void decode_checklimit(upb_Decoder* d) {
UPB_INLINE void _upb_Decoder_CheckLimit(upb_Decoder* d) {
UPB_ASSERT(d->limit_ptr == d->end + UPB_MIN(0, d->limit));
}
UPB_INLINE int decode_pushlimit(upb_Decoder* d, const char* ptr, int size) {
UPB_INLINE int _upb_Decoder_PushLimit(upb_Decoder* d, const char* ptr,
int size) {
int limit = size + (int)(ptr - d->end);
int delta = d->limit - limit;
decode_checklimit(d);
_upb_Decoder_CheckLimit(d);
d->limit = limit;
d->limit_ptr = d->end + UPB_MIN(0, limit);
decode_checklimit(d);
_upb_Decoder_CheckLimit(d);
return delta;
}
UPB_INLINE void decode_poplimit(upb_Decoder* d, const char* ptr,
UPB_INLINE void _upb_Decoder_PopLimit(upb_Decoder* d, const char* ptr,
int saved_delta) {
UPB_ASSERT(ptr - d->end == d->limit);
decode_checklimit(d);
_upb_Decoder_CheckLimit(d);
d->limit += saved_delta;
d->limit_ptr = d->end + UPB_MIN(0, d->limit);
decode_checklimit(d);
_upb_Decoder_CheckLimit(d);
}
#include "upb/port_undef.inc"

@ -1208,9 +1208,9 @@ std::vector<TableEntry> FastDecodeTable(const protobuf::Descriptor* message,
}
while ((size_t)slot >= table.size()) {
size_t size = std::max(static_cast<size_t>(1), table.size() * 2);
table.resize(size, TableEntry{"fastdecode_generic", 0});
table.resize(size, TableEntry{"_upb_FastDecoder_DecodeGeneric", 0});
}
if (table[slot].first != "fastdecode_generic") {
if (table[slot].first != "_upb_FastDecoder_DecodeGeneric") {
// A hotter field already filled this slot.
continue;
}

Loading…
Cancel
Save