From d0c85637e752839249d82ff7cad452a3a0b8a9f0 Mon Sep 17 00:00:00 2001 From: Eric Salo Date: Tue, 28 Nov 2023 20:50:48 -0800 Subject: [PATCH] upb: lock down upb_MiniTableSub PiperOrigin-RevId: 586187469 --- upb/message/accessors.c | 6 ++-- upb/message/accessors.h | 11 +++--- upb/message/copy.c | 14 ++++---- upb/message/promote.c | 6 ++-- upb/message/tagged_ptr.h | 15 ++++---- upb/mini_descriptor/decode.c | 4 +-- upb/mini_descriptor/decode.h | 9 ++--- upb/mini_descriptor/internal/encode_test.cc | 5 +-- upb/mini_descriptor/link.c | 15 ++++++-- upb/mini_table/internal/extension.h | 4 +-- upb/mini_table/internal/sub.h | 36 +++++++++++++++++-- upb/mini_table/message.h | 12 +++---- upb/mini_table/sub.h | 39 +++++++++++++++++++- upb/reflection/field_def.c | 7 ++-- upb/test/fuzz_util.cc | 4 +-- upb/wire/decode.c | 40 +++++++++++++++------ upb/wire/decode_fast.c | 4 ++- upb/wire/encode.c | 15 +++++--- upb_generator/protoc-gen-upb_minitable.cc | 8 +++-- 19 files changed, 186 insertions(+), 68 deletions(-) diff --git a/upb/message/accessors.c b/upb/message/accessors.c index 70a60a0536..15531b95e8 100644 --- a/upb/message/accessors.c +++ b/upb/message/accessors.c @@ -15,6 +15,7 @@ #include "upb/message/message.h" #include "upb/mini_table/field.h" #include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" #include "upb/wire/encode.h" // Must be last. @@ -22,11 +23,12 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, const upb_MiniTable* mini_table, - const upb_MiniTableField* field, + const upb_MiniTableField* f, upb_Message* map_entry_message, upb_Arena* arena) { + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. const upb_MiniTable* map_entry_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); UPB_ASSERT(map_entry_mini_table->field_count == 2); const upb_MiniTableField* map_entry_key_field = diff --git a/upb/message/accessors.h b/upb/message/accessors.h index 703d506bf1..d0b164be54 100644 --- a/upb/message/accessors.h +++ b/upb/message/accessors.h @@ -28,10 +28,10 @@ #include "upb/mini_table/extension.h" #include "upb/mini_table/field.h" #include "upb/mini_table/internal/field.h" +#include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" // Must be last. -#include "upb/mini_table/internal/field.h" -#include "upb/mini_table/message.h" #include "upb/port/def.inc" #ifdef __cplusplus @@ -346,7 +346,8 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( UPB_ASSUME(UPB_PRIVATE(_upb_MiniTableField_GetRep)(field) == UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); UPB_ASSUME(upb_MiniTableField_IsScalar(field)); - UPB_ASSERT(mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg); + UPB_ASSERT(upb_MiniTableSub_Message( + mini_table->subs[field->UPB_PRIVATE(submsg_index)])); _upb_Message_SetNonExtensionField(msg, field, &sub_message); } @@ -365,8 +366,8 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*); if (!sub_message) { - const upb_MiniTable* sub_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( + mini_table->subs[field->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(sub_mini_table); sub_message = _upb_Message_New(sub_mini_table, arena); *UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message; diff --git a/upb/message/copy.c b/upb/message/copy.c index 4be6573396..8c0819b268 100644 --- a/upb/message/copy.c +++ b/upb/message/copy.c @@ -29,6 +29,7 @@ #include "upb/mini_table/internal/message.h" #include "upb/mini_table/internal/size_log2.h" #include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" // Must be last. #include "upb/port/def.inc" @@ -115,11 +116,12 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, const upb_MiniTable* mini_table, - const upb_MiniTableField* field, + const upb_MiniTableField* f, upb_Message* clone, upb_Arena* arena) { + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. const upb_MiniTable* map_entry_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_table); const upb_MiniTableField* key_field = &map_entry_table->fields[0]; @@ -131,7 +133,7 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, if (!cloned_map) { return NULL; } - _upb_Message_SetNonExtensionField(clone, field, &cloned_map); + _upb_Message_SetNonExtensionField(clone, f, &cloned_map); return cloned_map; } @@ -267,9 +269,9 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, } else { upb_Array* msg_array = (upb_Array*)msg_ext->data.ptr; UPB_ASSERT(msg_array); - upb_Array* cloned_array = - upb_Array_DeepClone(msg_array, upb_MiniTableField_CType(field), - msg_ext->ext->UPB_PRIVATE(sub).submsg, arena); + upb_Array* cloned_array = upb_Array_DeepClone( + msg_array, upb_MiniTableField_CType(field), + upb_MiniTableExtension_GetSubMessage(msg_ext->ext), arena); if (!cloned_array) { return NULL; } diff --git a/upb/message/promote.c b/upb/message/promote.c index acd3192ad3..bffc9a0055 100644 --- a/upb/message/promote.c +++ b/upb/message/promote.c @@ -26,6 +26,7 @@ #include "upb/mini_table/field.h" #include "upb/mini_table/internal/field.h" #include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" #include "upb/wire/decode.h" #include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/internal/constants.h" @@ -324,8 +325,9 @@ upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMessageArray( upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap( upb_Message* msg, const upb_MiniTable* mini_table, const upb_MiniTableField* field, int decode_options, upb_Arena* arena) { - const upb_MiniTable* map_entry_mini_table = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. + const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( + mini_table->subs[field->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); UPB_ASSERT(map_entry_mini_table); UPB_ASSERT(map_entry_mini_table->field_count == 2); diff --git a/upb/message/tagged_ptr.h b/upb/message/tagged_ptr.h index 2596cd74d5..9004c773dd 100644 --- a/upb/message/tagged_ptr.h +++ b/upb/message/tagged_ptr.h @@ -5,8 +5,8 @@ // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd -#ifndef UPB_MINI_TABLE_TYPES_H_ -#define UPB_MINI_TABLE_TYPES_H_ +#ifndef UPB_MINI_TABLE_TAGGED_PTR_H_ +#define UPB_MINI_TABLE_TAGGED_PTR_H_ #include @@ -15,10 +15,6 @@ // Must be last. #include "upb/port/def.inc" -#ifdef __cplusplus -extern "C" { -#endif - // When a upb_Message* is stored in a message, array, or map, it is stored in a // tagged form. If the tag bit is set, the referenced upb_Message is of type // _kUpb_MiniTable_Empty (a sentinel message type with no fields) instead of @@ -27,8 +23,13 @@ extern "C" { // // See the documentation for kUpb_DecodeOption_ExperimentalAllowUnlinked for // more information. + typedef uintptr_t upb_TaggedMessagePtr; +#ifdef __cplusplus +extern "C" { +#endif + // Internal-only because empty messages cannot be created by the user. UPB_INLINE upb_TaggedMessagePtr _upb_TaggedMessagePtr_Pack(upb_Message* ptr, bool empty) { @@ -66,4 +67,4 @@ UPB_INLINE upb_Message* _upb_TaggedMessagePtr_GetEmptyMessage( #include "upb/port/undef.inc" -#endif /* UPB_MINI_TABLE_TYPES_H_ */ +#endif /* UPB_MINI_TABLE_TAGGED_PTR_H_ */ diff --git a/upb/mini_descriptor/decode.c b/upb/mini_descriptor/decode.c index 15db665ca1..b104bc1b18 100644 --- a/upb/mini_descriptor/decode.c +++ b/upb/mini_descriptor/decode.c @@ -394,7 +394,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, upb_MdDecoder_CheckOutOfMemory(&d->base, subs); uint32_t i = 0; for (; i < sub_counts.submsg_count; i++) { - subs[i].submsg = &_kUpb_MiniTable_Empty; + subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty; } if (sub_counts.subenum_count) { upb_MiniTableField* f = d->fields; @@ -405,7 +405,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, } } for (; i < sub_counts.submsg_count + sub_counts.subenum_count; i++) { - subs[i].subenum = NULL; + subs[i].UPB_PRIVATE(subenum) = NULL; } } d->table->subs = subs; diff --git a/upb/mini_descriptor/decode.h b/upb/mini_descriptor/decode.h index ec7c12e9f0..dedf24f287 100644 --- a/upb/mini_descriptor/decode.h +++ b/upb/mini_descriptor/decode.h @@ -76,8 +76,7 @@ UPB_API upb_MiniTableExtension* _upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( const char* data, size_t len, const upb_MiniTable* extendee, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = NULL; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(NULL); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -85,8 +84,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_Build( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTable* submsg, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.submsg = submsg; + upb_MiniTableSub sub = upb_MiniTableSub_FromMessage(submsg); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } @@ -94,8 +92,7 @@ UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildMessage( UPB_API_INLINE upb_MiniTableExtension* upb_MiniTableExtension_BuildEnum( const char* data, size_t len, const upb_MiniTable* extendee, upb_MiniTableEnum* subenum, upb_Arena* arena, upb_Status* status) { - upb_MiniTableSub sub; - sub.subenum = subenum; + upb_MiniTableSub sub = upb_MiniTableSub_FromEnum(subenum); return _upb_MiniTableExtension_Build( data, len, extendee, sub, kUpb_MiniTablePlatform_Native, arena, status); } diff --git a/upb/mini_descriptor/internal/encode_test.cc b/upb/mini_descriptor/internal/encode_test.cc index 5da2443eb1..7d1663dd0f 100644 --- a/upb/mini_descriptor/internal/encode_test.cc +++ b/upb/mini_descriptor/internal/encode_test.cc @@ -28,6 +28,7 @@ #include "upb/mini_table/internal/field.h" #include "upb/mini_table/internal/message.h" #include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" // begin:google_only // #include "testing/fuzzing/fuzztest.h" @@ -240,8 +241,8 @@ TEST_P(MiniTableTest, SubsInitializedToEmpty) { e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr()); ASSERT_NE(nullptr, table); EXPECT_EQ(table->field_count, 2); - EXPECT_EQ(table->subs[0].submsg, &_kUpb_MiniTable_Empty); - EXPECT_EQ(table->subs[1].submsg, &_kUpb_MiniTable_Empty); + EXPECT_EQ(upb_MiniTableSub_Message(table->subs[0]), &_kUpb_MiniTable_Empty); + EXPECT_EQ(upb_MiniTableSub_Message(table->subs[1]), &_kUpb_MiniTable_Empty); } TEST(MiniTableEnumTest, PositiveAndNegative) { diff --git a/upb/mini_descriptor/link.c b/upb/mini_descriptor/link.c index 39da601ce7..4fc63445e5 100644 --- a/upb/mini_descriptor/link.c +++ b/upb/mini_descriptor/link.c @@ -7,6 +7,17 @@ #include "upb/mini_descriptor/link.h" +#include +#include + +#include "upb/base/descriptor_constants.h" +#include "upb/mini_table/enum.h" +#include "upb/mini_table/field.h" +#include "upb/mini_table/internal/field.h" +#include "upb/mini_table/internal/message.h" +#include "upb/mini_table/message.h" +#include "upb/mini_table/sub.h" + // Must be last. #include "upb/port/def.inc" @@ -43,7 +54,7 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, // TODO: Add this assert back once YouTube is updated to not call // this function repeatedly. // UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty); - table_sub->submsg = sub; + *table_sub = upb_MiniTableSub_FromMessage(sub); return true; } @@ -56,7 +67,7 @@ bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, upb_MiniTableSub* table_sub = (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; - table_sub->subenum = sub; + *table_sub = upb_MiniTableSub_FromEnum(sub); return true; } diff --git a/upb/mini_table/internal/extension.h b/upb/mini_table/internal/extension.h index b05932458c..7625944c9c 100644 --- a/upb/mini_table/internal/extension.h +++ b/upb/mini_table/internal/extension.h @@ -41,12 +41,12 @@ UPB_INLINE uint32_t UPB_PRIVATE(_upb_MiniTableExtension_Number)( UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( _upb_MiniTableExtension_GetSubMessage)( const struct upb_MiniTableExtension* e) { - return e->UPB_PRIVATE(sub).submsg; + return e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg); } UPB_INLINE void UPB_PRIVATE(_upb_MiniTableExtension_SetSubMessage)( struct upb_MiniTableExtension* e, const struct upb_MiniTable* m) { - e->UPB_PRIVATE(sub).submsg = m; + e->UPB_PRIVATE(sub).UPB_PRIVATE(submsg) = m; } #ifdef __cplusplus diff --git a/upb/mini_table/internal/sub.h b/upb/mini_table/internal/sub.h index fe236db96d..99e35bd33c 100644 --- a/upb/mini_table/internal/sub.h +++ b/upb/mini_table/internal/sub.h @@ -12,10 +12,42 @@ #include "upb/port/def.inc" union upb_MiniTableSub { - const struct upb_MiniTable* submsg; - const struct upb_MiniTableEnum* subenum; + const struct upb_MiniTable* UPB_PRIVATE(submsg); + const struct upb_MiniTableEnum* UPB_PRIVATE(subenum); }; +#ifdef __cplusplus +extern "C" { +#endif + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromEnum)( + const struct upb_MiniTableEnum* subenum) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(subenum) = subenum; + return out; +} + +UPB_INLINE union upb_MiniTableSub UPB_PRIVATE(_upb_MiniTableSub_FromMessage)( + const struct upb_MiniTable* submsg) { + union upb_MiniTableSub out; + out.UPB_PRIVATE(submsg) = submsg; + return out; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(_upb_MiniTableSub_Enum)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(subenum); +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)( + const union upb_MiniTableSub sub) { + return sub.UPB_PRIVATE(submsg); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + #include "upb/port/undef.inc" #endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ diff --git a/upb/mini_table/message.h b/upb/mini_table/message.h index 332338ccc8..337557027f 100644 --- a/upb/mini_table/message.h +++ b/upb/mini_table/message.h @@ -11,7 +11,7 @@ #include "upb/mini_table/enum.h" #include "upb/mini_table/field.h" #include "upb/mini_table/internal/message.h" -#include "upb/mini_table/internal/sub.h" +#include "upb/mini_table/sub.h" // Must be last. #include "upb/port/def.inc" @@ -35,8 +35,8 @@ UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( const upb_MiniTable* mini_table, const upb_MiniTableField* field) { UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message); - const upb_MiniTable* ret = - mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* ret = upb_MiniTableSub_Message( + mini_table->subs[field->UPB_PRIVATE(submsg_index)]); UPB_ASSUME(ret); return ret == &_kUpb_MiniTable_Empty ? NULL : ret; } @@ -44,9 +44,9 @@ UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable( // Returns the MiniTableEnum for this enum field. If the field is unlinked, // returns NULL. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Enum); - return mini_table->subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTable* mini_table, const upb_MiniTableField* f) { + UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum); + return upb_MiniTableSub_Enum(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); } // Returns true if this MiniTable field is linked to a MiniTable for the diff --git a/upb/mini_table/sub.h b/upb/mini_table/sub.h index 1c5d67e1eb..cd2253a357 100644 --- a/upb/mini_table/sub.h +++ b/upb/mini_table/sub.h @@ -10,6 +10,43 @@ #include "upb/mini_table/internal/sub.h" +// Must be last. +#include "upb/port/def.inc" + typedef union upb_MiniTableSub upb_MiniTableSub; -#endif /* UPB_MINI_TABLE_INTERNAL_SUB_H_ */ +#ifdef __cplusplus +extern "C" { +#endif + +// Constructors + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) { + return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum); +} + +UPB_API_INLINE upb_MiniTableSub +upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) { + return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg); +} + +// Getters + +UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub); +} + +UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( + upb_MiniTableSub sub) { + return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port/undef.inc" + +#endif /* UPB_MINI_TABLE_SUB_H_ */ diff --git a/upb/reflection/field_def.c b/upb/reflection/field_def.c index a6d287cc7e..bf29ff0f5d 100644 --- a/upb/reflection/field_def.c +++ b/upb/reflection/field_def.c @@ -22,6 +22,7 @@ #include "upb/mini_descriptor/decode.h" #include "upb/mini_descriptor/internal/encode.h" #include "upb/mini_descriptor/internal/modifiers.h" +#include "upb/mini_table/enum.h" #include "upb/mini_table/extension.h" #include "upb/mini_table/field.h" #include "upb/mini_table/message.h" @@ -934,9 +935,11 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx, upb_MiniTableExtension* mut_ext = (upb_MiniTableExtension*)ext; upb_MiniTableSub sub = {NULL}; if (upb_FieldDef_IsSubMessage(f)) { - sub.submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + const upb_MiniTable* submsg = upb_MessageDef_MiniTable(f->sub.msgdef); + sub = upb_MiniTableSub_FromMessage(submsg); } else if (_upb_FieldDef_IsClosedEnum(f)) { - sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + const upb_MiniTableEnum* subenum = _upb_EnumDef_MiniTable(f->sub.enumdef); + sub = upb_MiniTableSub_FromEnum(subenum); } bool ok2 = upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext, upb_MessageDef_MiniTable(f->msgdef), diff --git a/upb/test/fuzz_util.cc b/upb/test/fuzz_util.cc index 299ab24c58..613e63cfaa 100644 --- a/upb/test/fuzz_util.cc +++ b/upb/test/fuzz_util.cc @@ -101,12 +101,12 @@ bool Builder::LinkExtension(upb_MiniTableExtension* ext) { if (upb_MiniTableField_CType(field) == kUpb_CType_Message) { auto mt = NextMiniTable(); if (!mt) field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32; - ext->UPB_PRIVATE(sub).submsg = mt; + ext->UPB_PRIVATE(sub) = upb_MiniTableSub_FromMessage(mt); } if (upb_MiniTableField_IsClosedEnum(field)) { auto et = NextEnumTable(); if (!et) field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32; - ext->UPB_PRIVATE(sub).subenum = et; + ext->UPB_PRIVATE(sub) = upb_MiniTableSub_FromEnum(et); } return true; } diff --git a/upb/wire/decode.c b/upb/wire/decode.c index 113bf5531a..0e1a6fcf39 100644 --- a/upb/wire/decode.c +++ b/upb/wire/decode.c @@ -87,6 +87,25 @@ typedef union { uint32_t size; } wireval; +// Ideally these two functions should take the owning MiniTable pointer as a +// first argument, then we could just put them in mini_table/message.h as nice +// clean getters. But we don't have that so instead we gotta write these +// Frankenfunctions that take an array of subtables. + +// Returns the MiniTable corresponding to a given MiniTableField +// from an array of MiniTableSubs. +static const upb_MiniTable* _upb_MiniTableSubs_MessageByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Message(subs[field->UPB_PRIVATE(submsg_index)]); +} + +// Returns the MiniTableEnum corresponding to a given MiniTableField +// from an array of MiniTableSub. +static const upb_MiniTableEnum* _upb_MiniTableSubs_EnumByField( + const upb_MiniTableSub* subs, const upb_MiniTableField* field) { + return upb_MiniTableSub_Enum(subs[field->UPB_PRIVATE(submsg_index)]); +} + static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout); @@ -223,7 +242,7 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); upb_Message* msg = _upb_Message_New(subl, &d->arena); if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); @@ -247,7 +266,7 @@ static upb_Message* _upb_Decoder_ReuseSubMessage( upb_Decoder* d, const upb_MiniTableSub* subs, const upb_MiniTableField* field, upb_TaggedMessagePtr* target) { upb_TaggedMessagePtr tagged = *target; - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) { return _upb_TaggedMessagePtr_GetMessage(tagged); @@ -298,7 +317,7 @@ static const char* _upb_Decoder_DecodeSubMessage( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field, int size) { int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size); - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP); upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta); @@ -329,7 +348,7 @@ UPB_FORCEINLINE static const char* _upb_Decoder_DecodeKnownGroup( upb_Decoder* d, const char* ptr, upb_Message* submsg, const upb_MiniTableSub* subs, const upb_MiniTableField* field) { - const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, field->number); } @@ -382,7 +401,7 @@ static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); 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++; @@ -453,7 +472,7 @@ static const char* _upb_Decoder_DecodeEnumPacked( upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr, const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val) { - const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum; + const upb_MiniTableEnum* e = _upb_MiniTableSubs_EnumByField(subs, field); int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void); while (!_upb_Decoder_IsDone(d, &ptr)) { @@ -593,7 +612,7 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, upb_Map* map = *map_p; upb_MapEntry ent; UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message); - const upb_MiniTable* entry = subs[field->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(entry); UPB_ASSERT(entry->field_count == 2); @@ -653,7 +672,7 @@ static const char* _upb_Decoder_DecodeToSubMessage( if (UPB_UNLIKELY(op == kUpb_DecodeOp_Enum) && !_upb_Decoder_CheckEnum(d, ptr, msg, - subs[field->UPB_PRIVATE(submsg_index)].subenum, + _upb_MiniTableSubs_EnumByField(subs, field), field, val)) { return ptr; } @@ -971,9 +990,10 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, int* op) { // If sub-message is not linked, treat as unknown. if (field->mode & kUpb_LabelFlags_IsExtension) return; - const upb_MiniTableSub* sub = &mt->subs[field->UPB_PRIVATE(submsg_index)]; + const upb_MiniTable* mt_sub = + _upb_MiniTableSubs_MessageByField(mt->subs, field); if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) || - sub->submsg != &_kUpb_MiniTable_Empty) { + mt_sub != &_kUpb_MiniTable_Empty) { return; } #ifndef NDEBUG diff --git a/upb/wire/decode_fast.c b/upb/wire/decode_fast.c index 5a412ef308..a77aea3dad 100644 --- a/upb/wire/decode_fast.c +++ b/upb/wire/decode_fast.c @@ -20,6 +20,7 @@ #include "upb/message/array.h" #include "upb/message/internal/array.h" #include "upb/message/internal/types.h" +#include "upb/mini_table/sub.h" #include "upb/wire/internal/decode.h" // Must be last. @@ -914,7 +915,8 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e, upb_Message** dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ const upb_MiniTable* tablep = decode_totablep(table); \ - const upb_MiniTable* subtablep = tablep->subs[submsg_idx].submsg; \ + const upb_MiniTable* subtablep = \ + upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ diff --git a/upb/wire/encode.c b/upb/wire/encode.c index ca2b46561b..30cef79b08 100644 --- a/upb/wire/encode.c +++ b/upb/wire/encode.c @@ -271,7 +271,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Group: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } @@ -285,7 +286,8 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem, case kUpb_FieldType_Message: { size_t size; upb_TaggedMessagePtr submsg = *(upb_TaggedMessagePtr*)field_mem; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (submsg == 0) { return; } @@ -374,7 +376,8 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, case kUpb_FieldType_Group: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; @@ -389,7 +392,8 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, case kUpb_FieldType_Message: { const upb_TaggedMessagePtr* start = _upb_array_constptr(arr); const upb_TaggedMessagePtr* ptr = start + arr->size; - const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* subm = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded); do { size_t size; @@ -428,7 +432,8 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, const upb_MiniTableSub* subs, const upb_MiniTableField* f) { const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); - const upb_MiniTable* layout = subs[f->UPB_PRIVATE(submsg_index)].submsg; + const upb_MiniTable* layout = + upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(layout->field_count == 2); if (map == NULL) return; diff --git a/upb_generator/protoc-gen-upb_minitable.cc b/upb_generator/protoc-gen-upb_minitable.cc index 79b59ebe01..2f58330821 100644 --- a/upb_generator/protoc-gen-upb_minitable.cc +++ b/upb_generator/protoc-gen-upb_minitable.cc @@ -385,16 +385,18 @@ void WriteMessageField(upb::FieldDefPtr field, std::string GetSub(upb::FieldDefPtr field) { if (auto message_def = field.message_type()) { - return absl::Substitute("{.submsg = &$0}", MessageInitName(message_def)); + return absl::Substitute("{.UPB_PRIVATE(submsg) = &$0}", + MessageInitName(message_def)); } if (auto enum_def = field.enum_subdef()) { if (enum_def.is_closed()) { - return absl::Substitute("{.subenum = &$0}", EnumInit(enum_def)); + return absl::Substitute("{.UPB_PRIVATE(subenum) = &$0}", + EnumInit(enum_def)); } } - return std::string("{.submsg = NULL}"); + return std::string("{.UPB_PRIVATE(submsg) = NULL}"); } // Writes a single message into a .upb.c source file.