diff --git a/upb/decode.h b/upb/decode.h index 650418c1ce..9de8638de5 100644 --- a/upb/decode.h +++ b/upb/decode.h @@ -14,7 +14,6 @@ extern "C" { bool upb_decode(const char *buf, size_t size, upb_msg *msg, const upb_msglayout *l, upb_arena *arena); - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/upb/decode.int.h b/upb/decode.int.h index 4a7c70385a..c49521fa21 100644 --- a/upb/decode.int.h +++ b/upb/decode.int.h @@ -26,6 +26,14 @@ typedef struct upb_decstate { const char *fastdecode_dispatch(upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *table, uint64_t hasbits); + +/* Error function that will abort decoding with longjmp(). We can't declare this + * UPB_NORETURN, even though it is appropriate, because if we do then compilers + * will "helpfully" refuse to tailcall to it + * (see: https://stackoverflow.com/a/55657013), which will defeat a major goal + * 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_decstate *d); #include "upb/port_undef.inc" diff --git a/upb/decode_fast.h b/upb/decode_fast.h index bb0f14d721..67315206eb 100644 --- a/upb/decode_fast.h +++ b/upb/decode_fast.h @@ -11,6 +11,8 @@ struct upb_decstate; +// 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_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *table, uint64_t hasbits, uint64_t data);