diff --git a/generated_for_cmake/upb/json/parser.c b/generated_for_cmake/upb/json/parser.c index 9955a024aa..0efc7301d1 100644 --- a/generated_for_cmake/upb/json/parser.c +++ b/generated_for_cmake/upb/json/parser.c @@ -391,7 +391,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p, upb_handlertype_t type) { upb_selector_t sel; bool ok = upb_handlers_getselector(p->top->f, type, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return sel; } @@ -416,7 +416,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) { const upb_json_parsermethod *method; ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); method = upb_value_getconstptr(v); frame->name_table = &method->name_table; @@ -2021,7 +2021,7 @@ static void end_member(upb_json_parser *p) { /* send ENDSUBMSG in repeated-field-of-mapentries frame. */ p->top--; ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel); } diff --git a/upb/decode.c b/upb/decode.c index f1be7502c3..9f1e986e73 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -53,7 +53,6 @@ static const uint8_t desctype_to_mapsize[] = { /* Data pertaining to the parse. */ typedef struct { - const char *ptr; /* Current parsing position. */ const char *field_start; /* Start of this field. */ const char *limit; /* End of delimited region or end of buffer. */ upb_arena *arena; @@ -61,60 +60,52 @@ typedef struct { uint32_t end_group; /* Set to field number of END_GROUP tag, if any. */ } upb_decstate; -/* Data passed by value to each parsing function. */ -typedef struct { - char *msg; - const upb_msglayout *layout; - upb_decstate *state; -} upb_decframe; - #define CHK(x) if (!(x)) { return 0; } +#define PTR_AT(msg, ofs, type) (type*)((const char*)msg + ofs) -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number); -static bool upb_decode_message(upb_decstate *d, char *msg, - const upb_msglayout *l); +static const char *upb_skip_unknowngroup(const char *ptr, upb_decstate *d, + int field_number); +static const char *upb_decode_message(const char *ptr, const upb_msglayout *l, + upb_msg *msg, upb_decstate *d); -static bool upb_decode_varint(const char **ptr, const char *limit, - uint64_t *val) { +static const char *upb_decode_varint(const char *ptr, const char *limit, + uint64_t *val) { uint8_t byte; int bitpos = 0; - const char *p = *ptr; *val = 0; do { - CHK(bitpos < 70 && p < limit); - byte = *p; + CHK(bitpos < 70 && ptr < limit); + byte = *ptr; *val |= (uint64_t)(byte & 0x7F) << bitpos; - p++; + ptr++; bitpos += 7; } while (byte & 0x80); - *ptr = p; - return true; + return ptr; } -static bool upb_decode_varint32(const char **ptr, const char *limit, - uint32_t *val) { +static const char *upb_decode_varint32(const char *ptr, const char *limit, + uint32_t *val) { uint64_t u64; - CHK(upb_decode_varint(ptr, limit, &u64) && u64 <= UINT32_MAX); + CHK(ptr = upb_decode_varint(ptr, limit, &u64)) + CHK(u64 <= UINT32_MAX); *val = (uint32_t)u64; - return true; + return ptr; } -static bool upb_decode_64bit(const char **ptr, const char *limit, - uint64_t *val) { - CHK(limit - *ptr >= 8); - memcpy(val, *ptr, 8); - *ptr += 8; - return true; +static const char *upb_decode_64bit(const char *ptr, const char *limit, + uint64_t *val) { + CHK(limit - ptr >= 8); + memcpy(val, ptr, 8); + return ptr + 8; } -static bool upb_decode_32bit(const char **ptr, const char *limit, - uint32_t *val) { - CHK(limit - *ptr >= 4); - memcpy(val, *ptr, 4); - *ptr += 4; - return true; +static const char *upb_decode_32bit(const char *ptr, const char *limit, + uint32_t *val) { + CHK(limit - ptr >= 4); + memcpy(val, ptr, 4); + return ptr + 4; } static int32_t upb_zzdecode_32(uint32_t n) { @@ -125,68 +116,68 @@ static int64_t upb_zzdecode_64(uint64_t n) { return (n >> 1) ^ -(int64_t)(n & 1); } -static bool upb_decode_string(const char **ptr, const char *limit, - int *outlen) { +static const char *upb_decode_string(const char *ptr, const char *limit, + int *outlen) { uint32_t len; - CHK(upb_decode_varint32(ptr, limit, &len) && - len < INT32_MAX && - limit - *ptr >= (int32_t)len); + CHK(ptr = upb_decode_varint32(ptr, limit, &len)); + CHK(len < INT32_MAX); + CHK(limit - ptr >= (int32_t)len); *outlen = len; - return true; + return ptr; } static void upb_set32(void *msg, size_t ofs, uint32_t val) { memcpy((char*)msg + ofs, &val, sizeof(val)); } -static bool upb_append_unknown(upb_decstate *d, upb_decframe *frame) { - upb_msg_addunknown(frame->msg, d->field_start, d->ptr - d->field_start, - d->arena); - return true; +static const char *upb_append_unknown(const char *ptr, upb_msg *msg, upb_decstate *d) { + upb_msg_addunknown(msg, d->field_start, ptr - d->field_start, d->arena); + return ptr; } - -static bool upb_skip_unknownfielddata(upb_decstate *d, uint32_t tag, - uint32_t group_fieldnum) { +static const char *upb_skip_unknownfielddata(const char *ptr, upb_decstate *d, + uint32_t tag, + uint32_t group_fieldnum) { switch (tag & 7) { case UPB_WIRE_TYPE_VARINT: { uint64_t val; - return upb_decode_varint(&d->ptr, d->limit, &val); + return upb_decode_varint(ptr, d->limit, &val); } case UPB_WIRE_TYPE_32BIT: { uint32_t val; - return upb_decode_32bit(&d->ptr, d->limit, &val); + return upb_decode_32bit(ptr, d->limit, &val); } case UPB_WIRE_TYPE_64BIT: { uint64_t val; - return upb_decode_64bit(&d->ptr, d->limit, &val); + return upb_decode_64bit(ptr, d->limit, &val); } case UPB_WIRE_TYPE_DELIMITED: { int len; - CHK(upb_decode_string(&d->ptr, d->limit, &len)); - d->ptr += len; - return true; + CHK(ptr = upb_decode_string(ptr, d->limit, &len)); + return ptr + len; } case UPB_WIRE_TYPE_START_GROUP: - return upb_skip_unknowngroup(d, tag >> 3); + return upb_skip_unknowngroup(ptr, d, tag >> 3); case UPB_WIRE_TYPE_END_GROUP: - return (tag >> 3) == group_fieldnum; + CHK((tag >> 3) == group_fieldnum); + return ptr; } return false; } -static bool upb_skip_unknowngroup(upb_decstate *d, int field_number) { - while (d->ptr < d->limit && d->end_group == 0) { +static const char *upb_skip_unknowngroup(const char *ptr, upb_decstate *d, + int field_number) { + while (ptr < d->limit && d->end_group == 0) { uint32_t tag = 0; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); - CHK(upb_skip_unknownfielddata(d, tag, field_number)); + CHK(ptr = upb_decode_varint32(ptr, d->limit, &tag)); + CHK(ptr = upb_skip_unknownfielddata(ptr, d, tag, field_number)); } CHK(d->end_group == field_number); d->end_group = 0; - return true; + return ptr; } static void *upb_array_reserve(upb_array *arr, size_t elements, @@ -208,83 +199,80 @@ bool upb_array_add(upb_array *arr, size_t elements, size_t elem_size, return true; } -static upb_array *upb_getarr(upb_decframe *frame, - const upb_msglayout_field *field) { +static upb_array *upb_getarr(upb_msg *msg, const upb_msglayout_field *field) { UPB_ASSERT(field->label == UPB_LABEL_REPEATED); - return *(upb_array**)&frame->msg[field->offset]; + return *PTR_AT(msg, field->offset, upb_array*); } -static upb_array *upb_getorcreatearr(upb_decframe *frame, - const upb_msglayout_field *field) { - upb_array *arr = upb_getarr(frame, field); +static upb_array *upb_getorcreatearr(upb_msg *msg, + const upb_msglayout_field *field, + upb_decstate *d) { + upb_array *arr = upb_getarr(msg, field); if (!arr) { upb_fieldtype_t type = desctype_to_fieldtype[field->descriptortype]; - arr = _upb_array_new(frame->state->arena, type); + arr = _upb_array_new(d->arena, type); CHK(arr); - *(upb_array**)&frame->msg[field->offset] = arr; + *PTR_AT(msg, field->offset, upb_array*) = arr; } return arr; } -static upb_msg *upb_getorcreatemsg(upb_decframe *frame, +static upb_msg *upb_getorcreatemsg(upb_msg *msg, const upb_msglayout_field *field, - const upb_msglayout **subm) { - upb_msg **submsg = (void*)(frame->msg + field->offset); - *subm = frame->layout->submsgs[field->submsg_index]; + const upb_msglayout *layout, + upb_decstate *d) { + upb_msg **submsg = PTR_AT(msg, field->offset, upb_msg*); UPB_ASSERT(field->label != UPB_LABEL_REPEATED); if (!*submsg) { - *submsg = _upb_msg_new(*subm, frame->state->arena); + *submsg = _upb_msg_new(layout, d->arena); CHK(*submsg); } return *submsg; } -static upb_msg *upb_addmsg(upb_decframe *frame, +static upb_msg *upb_addmsg(upb_msg *msg, const upb_msglayout_field *field, - const upb_msglayout **subm) { + const upb_msglayout *layout, + upb_decstate *d) { upb_msg *submsg; - upb_array *arr = upb_getorcreatearr(frame, field); + upb_array *arr = upb_getorcreatearr(msg, field, d); UPB_ASSERT(field->label == UPB_LABEL_REPEATED); UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE || field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP); - *subm = frame->layout->submsgs[field->submsg_index]; - submsg = _upb_msg_new(*subm, frame->state->arena); + submsg = _upb_msg_new(layout, d->arena); CHK(submsg); - upb_array_add(arr, 1, sizeof(submsg), &submsg, frame->state->arena); + upb_array_add(arr, 1, sizeof(submsg), &submsg, d->arena); return submsg; } -static void upb_sethasbit(upb_decframe *frame, - const upb_msglayout_field *field) { +static void upb_sethasbit(upb_msg *msg, const upb_msglayout_field *field) { int32_t hasbit = field->presence; UPB_ASSERT(field->presence > 0); - frame->msg[hasbit / 8] |= (1 << (hasbit % 8)); + *PTR_AT(msg, hasbit / 8, char) |= (1 << (hasbit % 8)); } -static void upb_setoneofcase(upb_decframe *frame, - const upb_msglayout_field *field) { +static void upb_setoneofcase(upb_msg *msg, const upb_msglayout_field *field) { UPB_ASSERT(field->presence < 0); - upb_set32(frame->msg, ~field->presence, field->number); + upb_set32(msg, ~field->presence, field->number); } -static bool upb_decode_addval(upb_decframe *frame, - const upb_msglayout_field *field, void *val, - size_t size) { - char *field_mem = frame->msg + field->offset; +static bool upb_decode_addval(upb_msg *msg, const upb_msglayout_field *field, + void *val, size_t size, upb_decstate *d) { + char *field_mem = PTR_AT(msg, field->offset, char); upb_array *arr; if (field->label == UPB_LABEL_REPEATED) { - arr = upb_getorcreatearr(frame, field); + arr = upb_getorcreatearr(msg, field, d); CHK(arr); - field_mem = upb_array_reserve(arr, 1, size, frame->state->arena); + field_mem = upb_array_reserve(arr, 1, size, d->arena); CHK(field_mem); } @@ -292,142 +280,147 @@ static bool upb_decode_addval(upb_decframe *frame, return true; } -static void upb_decode_setpresent(upb_decframe *frame, +static void upb_decode_setpresent(upb_msg *msg, const upb_msglayout_field *field) { if (field->label == UPB_LABEL_REPEATED) { - upb_array *arr = upb_getarr(frame, field); + upb_array *arr = upb_getarr(msg, field); UPB_ASSERT(arr->len < arr->size); arr->len++; } else if (field->presence < 0) { - upb_setoneofcase(frame, field); + upb_setoneofcase(msg, field); } else if (field->presence > 0) { - upb_sethasbit(frame, field); + upb_sethasbit(msg, field); } } -static bool upb_decode_msgfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, int limit) { +static const char *upb_decode_msgfield(const char *ptr, + const upb_msglayout *layout, int limit, + upb_msg *msg, upb_decstate *d) { const char* saved_limit = d->limit; - d->limit = d->ptr + limit; + d->limit = ptr + limit; CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); + ptr = upb_decode_message(ptr, layout, msg, d); d->depth++; d->limit = saved_limit; CHK(d->end_group == 0); - return true; + return ptr; } -static bool upb_decode_groupfield(upb_decstate *d, upb_msg *msg, - const upb_msglayout *layout, - int field_number) { +static const char *upb_decode_groupfield(const char *ptr, + const upb_msglayout *layout, + int field_number, upb_msg *msg, + upb_decstate *d) { CHK(--d->depth >= 0); - upb_decode_message(d, msg, layout); + ptr = upb_decode_message(ptr, layout, msg, d); d->depth++; CHK(d->end_group == field_number); d->end_group = 0; - return true; + return ptr; } -static bool upb_decode_varintfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { +static const char *upb_decode_varintfield(const char *ptr, upb_msg *msg, + const upb_msglayout_field *field, + upb_decstate *d) { uint64_t val; - CHK(upb_decode_varint(&d->ptr, d->limit, &val)); + CHK(ptr = upb_decode_varint(ptr, d->limit, &val)); switch (field->descriptortype) { case UPB_DESCRIPTOR_TYPE_INT64: case UPB_DESCRIPTOR_TYPE_UINT64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + CHK(upb_decode_addval(msg, field, &val, sizeof(val), d)); break; case UPB_DESCRIPTOR_TYPE_INT32: case UPB_DESCRIPTOR_TYPE_UINT32: case UPB_DESCRIPTOR_TYPE_ENUM: { uint32_t val32 = (uint32_t)val; - CHK(upb_decode_addval(frame, field, &val32, sizeof(val32))); + CHK(upb_decode_addval(msg, field, &val32, sizeof(val32), d)); break; } case UPB_DESCRIPTOR_TYPE_BOOL: { bool valbool = val != 0; - CHK(upb_decode_addval(frame, field, &valbool, sizeof(valbool))); + CHK(upb_decode_addval(msg, field, &valbool, sizeof(valbool), d)); break; } case UPB_DESCRIPTOR_TYPE_SINT32: { int32_t decoded = upb_zzdecode_32((uint32_t)val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + CHK(upb_decode_addval(msg, field, &decoded, sizeof(decoded), d)); break; } case UPB_DESCRIPTOR_TYPE_SINT64: { int64_t decoded = upb_zzdecode_64(val); - CHK(upb_decode_addval(frame, field, &decoded, sizeof(decoded))); + CHK(upb_decode_addval(msg, field, &decoded, sizeof(decoded), d)); break; } default: - return upb_append_unknown(d, frame); + return upb_append_unknown(ptr, msg, d); } - upb_decode_setpresent(frame, field); - return true; + upb_decode_setpresent(msg, field); + return ptr; } -static bool upb_decode_64bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { +static const char *upb_decode_64bitfield(const char *ptr, + const upb_msglayout_field *field, + upb_msg *msg, upb_decstate *d) { uint64_t val; - CHK(upb_decode_64bit(&d->ptr, d->limit, &val)); + CHK(ptr = upb_decode_64bit(ptr, d->limit, &val)); switch (field->descriptortype) { case UPB_DESCRIPTOR_TYPE_DOUBLE: case UPB_DESCRIPTOR_TYPE_FIXED64: case UPB_DESCRIPTOR_TYPE_SFIXED64: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + CHK(upb_decode_addval(msg, field, &val, sizeof(val), d)); break; default: - return upb_append_unknown(d, frame); + return upb_append_unknown(ptr, msg, d); } - upb_decode_setpresent(frame, field); - return true; + upb_decode_setpresent(msg, field); + return ptr; } -static bool upb_decode_32bitfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { +static const char *upb_decode_32bitfield(const char *ptr, + const upb_msglayout_field *field, + upb_msg *msg, upb_decstate *d) { uint32_t val; - CHK(upb_decode_32bit(&d->ptr, d->limit, &val)); + CHK(ptr = upb_decode_32bit(ptr, d->limit, &val)); switch (field->descriptortype) { case UPB_DESCRIPTOR_TYPE_FLOAT: case UPB_DESCRIPTOR_TYPE_FIXED32: case UPB_DESCRIPTOR_TYPE_SFIXED32: - CHK(upb_decode_addval(frame, field, &val, sizeof(val))); + CHK(upb_decode_addval(msg, field, &val, sizeof(val), d)); break; default: - return upb_append_unknown(d, frame); + return upb_append_unknown(ptr, msg, d); } - upb_decode_setpresent(frame, field); - return true; + upb_decode_setpresent(msg, field); + return ptr; } -static bool upb_decode_fixedpacked(upb_decstate *d, upb_array *arr, - uint32_t len, int elem_size) { +static const char *upb_decode_fixedpacked(const char *ptr, upb_decstate *d, + upb_array *arr, uint32_t len, + int elem_size) { size_t elements = len / elem_size; CHK((size_t)(elements * elem_size) == len); - CHK(upb_array_add(arr, elements, elem_size, d->ptr, d->arena)); - d->ptr += len; - - return true; + CHK(upb_array_add(arr, elements, elem_size, ptr, d->arena)); + return ptr + len; } -static upb_strview upb_decode_strfield(upb_decstate *d, uint32_t len) { - upb_strview ret; - ret.data = d->ptr; - ret.size = len; - d->ptr += len; - return ret; +static const char *upb_decode_strfield(const char *ptr, upb_decstate *d, + uint32_t len, upb_strview *str) { + str->data = ptr; + str->size = len; + return ptr + len; } -static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field, int len) { - upb_array *arr = upb_getorcreatearr(frame, field); +static const char *upb_decode_toarray(const char *ptr, + const upb_msglayout *layout, + const upb_msglayout_field *field, int len, + upb_msg *msg, upb_decstate *d) { + upb_array *arr = upb_getorcreatearr(msg, field, d); CHK(arr); #define VARINT_CASE(ctype, decode) \ @@ -435,33 +428,33 @@ static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, #define VARINT_CASE_EX(ctype, decode, dtype) \ { \ - const char *ptr = d->ptr; \ const char *limit = ptr + len; \ while (ptr < limit) { \ uint64_t val; \ ctype decoded; \ - CHK(upb_decode_varint(&ptr, limit, &val)); \ + CHK(ptr = upb_decode_varint(ptr, limit, &val)); \ decoded = (decode)((dtype)val); \ CHK(upb_array_add(arr, 1, sizeof(decoded), &decoded, d->arena)); \ } \ - d->ptr = ptr; \ - return true; \ + return ptr; \ } switch (field->descriptortype) { case UPB_DESCRIPTOR_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - return upb_array_add(arr, 1, sizeof(str), &str, d->arena); + upb_strview str; + ptr = upb_decode_strfield(ptr, d, len, &str); + CHK(upb_array_add(arr, 1, sizeof(str), &str, d->arena)); + return ptr; } case UPB_DESCRIPTOR_TYPE_FLOAT: case UPB_DESCRIPTOR_TYPE_FIXED32: case UPB_DESCRIPTOR_TYPE_SFIXED32: - return upb_decode_fixedpacked(d, arr, len, sizeof(int32_t)); + return upb_decode_fixedpacked(ptr, d, arr, len, sizeof(int32_t)); case UPB_DESCRIPTOR_TYPE_DOUBLE: case UPB_DESCRIPTOR_TYPE_FIXED64: case UPB_DESCRIPTOR_TYPE_SFIXED64: - return upb_decode_fixedpacked(d, arr, len, sizeof(int64_t)); + return upb_decode_fixedpacked(ptr, d, arr, len, sizeof(int64_t)); case UPB_DESCRIPTOR_TYPE_INT32: case UPB_DESCRIPTOR_TYPE_UINT32: case UPB_DESCRIPTOR_TYPE_ENUM: @@ -476,22 +469,24 @@ static bool upb_decode_toarray(upb_decstate *d, upb_decframe *frame, case UPB_DESCRIPTOR_TYPE_SINT64: VARINT_CASE_EX(int64_t, upb_zzdecode_64, uint64_t); case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_addmsg(frame, field, &subm); + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + upb_msg *submsg = upb_addmsg(msg, field, subl, d); CHK(submsg); - return upb_decode_msgfield(d, submsg, subm, len); + return upb_decode_msgfield(ptr, subl, len, submsg, d); } case UPB_DESCRIPTOR_TYPE_GROUP: - return upb_append_unknown(d, frame); + return upb_append_unknown(ptr, msg, d); } #undef VARINT_CASE UPB_UNREACHABLE(); } -static bool upb_decode_mapfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field, int len) { - upb_map *map = *(upb_map**)&frame->msg[field->offset]; - const upb_msglayout *entry = frame->layout->submsgs[field->submsg_index]; +static const char *upb_decode_mapfield(const char *ptr, + const upb_msglayout *layout, + const upb_msglayout_field *field, + int len, upb_msg *msg, upb_decstate *d) { + upb_map *map = *PTR_AT(msg, field->offset, upb_map*); + const upb_msglayout *entry = layout->submsgs[field->submsg_index]; upb_map_entry ent; if (!map) { @@ -504,51 +499,53 @@ static bool upb_decode_mapfield(upb_decstate *d, upb_decframe *frame, UPB_ASSERT(val_field->number == 2); UPB_ASSERT(key_field->offset == 0); UPB_ASSERT(val_field->offset == sizeof(upb_strview)); - map = _upb_map_new(frame->state->arena, key_size, val_size); - *(upb_map**)&frame->msg[field->offset] = map; + map = _upb_map_new(d->arena, key_size, val_size); + *PTR_AT(msg, field->offset, upb_map*) = map; } /* Parse map entry. */ memset(&ent, 0, sizeof(ent)); - CHK(upb_decode_msgfield(d, &ent.k, entry, len)); + CHK(ptr = upb_decode_msgfield(ptr, entry, len, &ent.k, d)); /* Insert into map. */ _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, d->arena); - return true; + return ptr; } -static bool upb_decode_delimitedfield(upb_decstate *d, upb_decframe *frame, - const upb_msglayout_field *field) { +static const char *upb_decode_delimitedfield(const char *ptr, + const upb_msglayout *layout, + const upb_msglayout_field *field, + upb_msg *msg, upb_decstate *d) { int len; - CHK(upb_decode_string(&d->ptr, d->limit, &len)); + CHK(ptr = upb_decode_string(ptr, d->limit, &len)); if (field->label == UPB_LABEL_REPEATED) { - return upb_decode_toarray(d, frame, field, len); + return upb_decode_toarray(ptr, layout, field, len, msg, d); } else if (field->label == UPB_LABEL_MAP) { - return upb_decode_mapfield(d, frame, field, len); + return upb_decode_mapfield(ptr, layout, field, len, msg, d); } else { switch (field->descriptortype) { case UPB_DESCRIPTOR_TYPE_STRING: case UPB_DESCRIPTOR_TYPE_BYTES: { - upb_strview str = upb_decode_strfield(d, len); - CHK(upb_decode_addval(frame, field, &str, sizeof(str))); + upb_strview str; + ptr = upb_decode_strfield(ptr, d, len, &str); + CHK(upb_decode_addval(msg, field, &str, sizeof(str), d)); break; } case UPB_DESCRIPTOR_TYPE_MESSAGE: { - const upb_msglayout *subm; - upb_msg *submsg = upb_getorcreatemsg(frame, field, &subm); + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; + upb_msg *submsg = upb_getorcreatemsg(msg, field, subl, d); CHK(submsg); - CHK(upb_decode_msgfield(d, submsg, subm, len)); + CHK(ptr = upb_decode_msgfield(ptr, subl, len, submsg, d)); break; } default: /* TODO(haberman): should we accept the last element of a packed? */ - d->ptr += len; - return upb_append_unknown(d, frame); + return upb_append_unknown(ptr + len, msg, d); } - upb_decode_setpresent(frame, field); - return true; + upb_decode_setpresent(msg, field); + return ptr; } } @@ -565,77 +562,75 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l, return NULL; /* Unknown field. */ } -static bool upb_decode_field(upb_decstate *d, upb_decframe *frame) { +static const char *upb_decode_field(const char *ptr, + const upb_msglayout *layout, upb_msg *msg, + upb_decstate *d) { uint32_t tag; const upb_msglayout_field *field; int field_number; - d->field_start = d->ptr; - CHK(upb_decode_varint32(&d->ptr, d->limit, &tag)); + d->field_start = ptr; + CHK(ptr = upb_decode_varint32(ptr, d->limit, &tag)); field_number = tag >> 3; - field = upb_find_field(frame->layout, field_number); + field = upb_find_field(layout, field_number); if (field) { switch (tag & 7) { case UPB_WIRE_TYPE_VARINT: - return upb_decode_varintfield(d, frame, field); + return upb_decode_varintfield(ptr, msg, field, d); case UPB_WIRE_TYPE_32BIT: - return upb_decode_32bitfield(d, frame, field); + return upb_decode_32bitfield(ptr, field, msg, d); case UPB_WIRE_TYPE_64BIT: - return upb_decode_64bitfield(d, frame, field); + return upb_decode_64bitfield(ptr, field, msg, d); case UPB_WIRE_TYPE_DELIMITED: - return upb_decode_delimitedfield(d, frame, field); + return upb_decode_delimitedfield(ptr, layout, field, msg, d); case UPB_WIRE_TYPE_START_GROUP: { - const upb_msglayout *layout; + const upb_msglayout *subl = layout->submsgs[field->submsg_index]; upb_msg *group; if (field->label == UPB_LABEL_REPEATED) { - group = upb_addmsg(frame, field, &layout); + group = upb_addmsg(msg, field, subl, d); } else { - group = upb_getorcreatemsg(frame, field, &layout); + group = upb_getorcreatemsg(msg, field, subl, d); } - return upb_decode_groupfield(d, group, layout, field_number); + return upb_decode_groupfield(ptr, subl, field_number, group, d); } case UPB_WIRE_TYPE_END_GROUP: d->end_group = field_number; - return true; + return ptr; default: CHK(false); } } else { CHK(field_number != 0); - CHK(upb_skip_unknownfielddata(d, tag, -1)); - CHK(upb_append_unknown(d, frame)); - return true; + CHK(ptr = upb_skip_unknownfielddata(ptr, d, tag, -1)); + CHK(ptr = upb_append_unknown(ptr, msg, d)); + return ptr; } UPB_UNREACHABLE(); } -static bool upb_decode_message(upb_decstate *d, char *msg, const upb_msglayout *l) { - upb_decframe frame; - frame.msg = msg; - frame.layout = l; - frame.state = d; - - while (d->ptr < d->limit) { - CHK(upb_decode_field(d, &frame)); +static const char *upb_decode_message(const char *ptr, const upb_msglayout *l, + upb_msg *msg, upb_decstate *d) { + while (ptr < d->limit) { + CHK(ptr = upb_decode_field(ptr, l, msg, d)); } - return true; + return ptr; } bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, upb_arena *arena) { upb_decstate state; - state.ptr = buf; state.limit = buf + size; state.arena = arena; state.depth = 64; state.end_group = 0; - CHK(upb_decode_message(&state, msg, l)); + CHK(upb_decode_message(buf, l, msg, &state)); return state.end_group == 0; } #undef CHK +#undef PTR_AT diff --git a/upb/def.c b/upb/def.c index 1a83687788..c3c9d104fc 100644 --- a/upb/def.c +++ b/upb/def.c @@ -1331,7 +1331,7 @@ static bool create_fielddef( break; } } - assert(found); + UPB_ASSERT(found); } } else { /* extension field. */ diff --git a/upb/json/parser.rl b/upb/json/parser.rl index 1180ce137f..eefdadf577 100644 --- a/upb/json/parser.rl +++ b/upb/json/parser.rl @@ -389,7 +389,7 @@ static upb_selector_t getsel_for_handlertype(upb_json_parser *p, upb_handlertype_t type) { upb_selector_t sel; bool ok = upb_handlers_getselector(p->top->f, type, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return sel; } @@ -414,7 +414,7 @@ static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) { const upb_json_parsermethod *method; ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); method = upb_value_getconstptr(v); frame->name_table = &method->name_table; @@ -2019,7 +2019,7 @@ static void end_member(upb_json_parser *p) { /* send ENDSUBMSG in repeated-field-of-mapentries frame. */ p->top--; ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel); - UPB_ASSERT(ok); + UPB_ASSUME(ok); upb_sink_endsubmsg(p->top->sink, (p->top + 1)->sink, sel); } diff --git a/upb/pb/compile_decoder.c b/upb/pb/compile_decoder.c index f5c7d65646..44b310fe3f 100644 --- a/upb/pb/compile_decoder.c +++ b/upb/pb/compile_decoder.c @@ -910,10 +910,10 @@ const upb_pbdecodermethod *upb_pbcodecache_get(upb_pbcodecache *c, } else { g = mgroup_new(h, c->lazy); ok = upb_inttable_insertptr(&c->groups, md, upb_value_constptr(g)); - UPB_ASSERT(ok); + UPB_ASSUME(ok); } ok = upb_inttable_lookupptr(&g->methods, h, &v); - UPB_ASSERT(ok); + UPB_ASSUME(ok); return upb_value_getptr(v); } diff --git a/upb/port_def.inc b/upb/port_def.inc index 992148e736..51f8eac96f 100644 --- a/upb/port_def.inc +++ b/upb/port_def.inc @@ -128,6 +128,18 @@ int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg); #define UPB_UNUSED(var) (void)var +/* UPB_ASSUME(): in release mode, we tell the compiler to assume this is true. + */ +#ifdef NDEBUG +#ifdef __GNUC__ +#define UPB_ASSUME(expr) if (!(expr)) __builtin_unreachable() +#else +#define UPB_ASSUME(expr) do {} if (false && (expr)) +#endif +#else +#define UPB_ASSUME(expr) assert(expr) +#endif + /* UPB_ASSERT(): in release mode, we use the expression without letting it be * evaluated. This prevents "unused variable" warnings. */ #ifdef NDEBUG diff --git a/upb/port_undef.inc b/upb/port_undef.inc index 6a4daa5076..e91e9644bb 100644 --- a/upb/port_undef.inc +++ b/upb/port_undef.inc @@ -12,6 +12,7 @@ #undef UPB_MAX #undef UPB_MIN #undef UPB_UNUSED +#undef UPB_ASSUME #undef UPB_ASSERT #undef UPB_ASSERT_DEBUGVAR #undef UPB_UNREACHABLE