diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 8801b28c8b..53b82640a3 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -5885,14 +5891,14 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, upb_Message* map_entry_message, upb_Arena* arena) { // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_mini_table = - upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); - UPB_ASSERT(map_entry_mini_table->field_count == 2); + UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; // Map key/value cannot have explicit defaults, // hence assuming a zero default is valid. upb_MessageValue default_val; @@ -5975,7 +5981,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type, case kUpb_CType_Message: { const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value; bool is_empty = upb_TaggedMessagePtr_IsEmpty(source); - if (is_empty) sub = &_kUpb_MiniTable_Empty; + if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)(); UPB_ASSERT(source); upb_Message* clone = upb_Message_DeepClone( _upb_TaggedMessagePtr_GetMessage(source), sub, arena); @@ -5998,7 +6004,8 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, upb_MessageValue key, val; size_t iter = kUpb_Map_Begin; while (upb_Map_Next(map, &key, &val, &iter)) { - const upb_MiniTableField* value_field = &map_entry_table->fields[1]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; const upb_MiniTable* value_sub = (value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub) ? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field) @@ -6021,12 +6028,14 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, upb_Message* clone, upb_Arena* arena) { // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_table = - upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_table); - const upb_MiniTableField* key_field = &map_entry_table->fields[0]; - const upb_MiniTableField* value_field = &map_entry_table->fields[1]; + const upb_MiniTableField* key_field = + &map_entry_table->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; upb_Map* cloned_map = upb_Map_DeepClone( map, upb_MiniTableField_CType(key_field), @@ -6094,8 +6103,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); // Only copy message area skipping upb_Message_Internal. memcpy(dst, src, mini_table->size); - for (size_t i = 0; i < mini_table->field_count; ++i) { - const upb_MiniTableField* field = &mini_table->fields[i]; + for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) { + const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsScalar(field)) { switch (upb_MiniTableField_CType(field)) { case kUpb_CType_Message: { @@ -6109,7 +6118,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, // decode status, or possible parse failure here. bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged); const upb_MiniTable* sub_message_table = - is_empty ? &_kUpb_MiniTable_Empty + is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)() : upb_MiniTable_GetSubMessageTable(mini_table, field); upb_Message* dst_sub_message = upb_Message_DeepClone(sub_message, sub_message_table, arena); @@ -7203,16 +7212,16 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, upb_SubCounts sub_counts) { uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count; - size_t subs_bytes = sizeof(*d->table->subs) * total_count; + size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count; upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, subs); uint32_t i = 0; for (; i < sub_counts.submsg_count; i++) { - subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty; + subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)(); } if (sub_counts.subenum_count) { upb_MiniTableField* f = d->fields; - upb_MiniTableField* end_f = f + d->table->field_count; + upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count); for (; f < end_f; f++) { if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) { f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count; @@ -7222,7 +7231,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, subs[i].UPB_PRIVATE(subenum) = NULL; } } - d->table->subs = subs; + d->table->UPB_PRIVATE(subs) = subs; } static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, @@ -7253,7 +7262,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, ch <= kUpb_EncodedValue_MaxModifier) { ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { - d->table->ext |= kUpb_ExtMode_Extendable; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; } } else if (ch == kUpb_EncodedValue_End) { if (!d->table) { @@ -7263,7 +7272,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } else if (kUpb_EncodedValue_MinSkip <= ch && ch <= kUpb_EncodedValue_MaxSkip) { if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); need_dense_below = false; } uint32_t skip; @@ -7278,7 +7287,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); } return ptr; @@ -7292,14 +7301,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); upb_SubCounts sub_counts = {0, 0}; - d->table->field_count = 0; - d->table->fields = d->fields; + d->table->UPB_PRIVATE(field_count) = 0; + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), - &d->table->field_count, &sub_counts); + &d->table->UPB_PRIVATE(field_count), &sub_counts); upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len, - sizeof(*d->fields) * d->table->field_count); - d->table->fields = d->fields; + sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count)); + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_AllocateSubs(d, sub_counts); } @@ -7326,7 +7335,7 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) { static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) { // Add items for all non-oneof fields (oneofs were already added). - int n = d->table->field_count; + int n = d->table->UPB_PRIVATE(field_count); for (int i = 0; i < n; i++) { upb_MiniTableField* f = &d->fields[i]; if (f->offset >= kOneofBase) continue; @@ -7350,27 +7359,29 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTable* ret = d->table; - int n = ret->field_count; + int n = ret->UPB_PRIVATE(field_count); int last_hasbit = 0; // 0 cannot be used. // First assign required fields, which must have the lowest hasbits. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kRequiredPresence) { field->presence = ++last_hasbit; } else if (field->offset == kNoPresence) { field->presence = 0; } } - ret->required_count = last_hasbit; - - if (ret->required_count > 63) { + if (last_hasbit > 63) { upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); } + ret->UPB_PRIVATE(required_count) = last_hasbit; + // Next assign non-required hasbit fields. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kHasbitPresence) { field->presence = ++last_hasbit; } @@ -7409,7 +7420,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { while (true) { f->presence = ~item->offset; if (f->offset == kUpb_LayoutItem_IndexSentinel) break; - UPB_ASSERT(f->offset - kOneofBase < d->table->field_count); + UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count)); f = &d->fields[f->offset - kOneofBase]; } } @@ -7477,9 +7488,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, upb_MtDecoder_ParseMessage(d, data, len); upb_MtDecoder_AssignHasbits(d); - if (UPB_UNLIKELY(d->table->field_count != 2)) { + if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) { upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", - d->table->field_count); + d->table->UPB_PRIVATE(field_count)); UPB_UNREACHABLE(); } @@ -7490,8 +7501,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, } } - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1); - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2); // Map entries have a pre-determined layout, regardless of types. // NOTE: sync with mini_table/message_internal.h. @@ -7503,7 +7514,7 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, // Map entries have a special bit set to signal it's a map entry, used in // upb_MiniTable_SetSubMessage() below. - d->table->ext |= kUpb_ExtMode_IsMapEntry; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; } static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, @@ -7515,11 +7526,11 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, upb_MiniTable* ret = d->table; ret->size = 0; - ret->field_count = 0; - ret->ext = kUpb_ExtMode_IsMessageSet; - ret->dense_below = 0; - ret->table_mask = -1; - ret->required_count = 0; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; } static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( @@ -7528,11 +7539,11 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table); decoder->table->size = 0; - decoder->table->field_count = 0; - decoder->table->ext = kUpb_ExtMode_NonExtendable; - decoder->table->dense_below = 0; - decoder->table->table_mask = -1; - decoder->table->required_count = 0; + decoder->table->UPB_PRIVATE(field_count) = 0; + decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table->UPB_PRIVATE(dense_below) = 0; + decoder->table->UPB_PRIVATE(table_mask) = -1; + decoder->table->UPB_PRIVATE(required_count) = 0; // Strip off and verify the version tag. if (!len--) goto done; @@ -7625,7 +7636,7 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension( f->offset = 0; f->presence = 0; - if (extendee->ext & kUpb_ExtMode_IsMessageSet) { + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { // Extensions of MessageSet must be messages. if (!upb_MiniTableField_IsSubMessage(f)) return NULL; @@ -7701,17 +7712,18 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTable* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); - const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry; + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; switch (field->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Message: if (sub_is_map) { - const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry; + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; if (UPB_UNLIKELY(table_is_map)) return false; field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; @@ -7727,23 +7739,23 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, } upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; // TODO: Add this assert back once YouTube is updated to not call // this function repeatedly. - // UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty); + // UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg)); *table_sub = upb_MiniTableSub_FromMessage(sub); return true; } bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTableEnum* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; *table_sub = upb_MiniTableSub_FromEnum(sub); return true; } @@ -7753,8 +7765,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { *subs = f; ++subs; @@ -7762,8 +7774,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, } } - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { *subs = f; ++subs; @@ -7784,8 +7796,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { const upb_MiniTable* sub = sub_tables[msg_count++]; if (msg_count > sub_table_count) return false; @@ -7795,8 +7807,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, } } - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsClosedEnum(f)) { const upb_MiniTableEnum* sub = sub_enums[enum_count++]; if (enum_count > sub_enum_count) return false; @@ -8219,21 +8231,21 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( // Must be last. const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* t, uint32_t number) { + const upb_MiniTable* m, uint32_t number) { const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX // Ideal case: index into dense fields - if (i < t->dense_below) { - UPB_ASSERT(t->fields[i].number == number); - return &t->fields[i]; + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_PRIVATE(fields)[i].number == number); + return &m->UPB_PRIVATE(fields)[i]; } // Slow case: binary search - int lo = t->dense_below; - int hi = t->field_count - 1; + int lo = m->UPB_PRIVATE(dense_below); + int hi = m->UPB_PRIVATE(field_count) - 1; while (lo <= hi) { int mid = (lo + hi) / 2; - uint32_t num = t->fields[mid].number; + uint32_t num = m->UPB_PRIVATE(fields)[mid].number; if (num < number) { lo = mid + 1; continue; @@ -8242,7 +8254,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( hi = mid - 1; continue; } - return &t->fields[mid]; + return &m->UPB_PRIVATE(fields)[mid]; } return NULL; } @@ -8252,8 +8264,9 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { return NULL; } - const upb_MiniTableField* ptr = &m->fields[0]; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; for (; ptr < end; ptr++) { if (ptr->presence == (*f).presence) { return ptr; @@ -8265,7 +8278,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, const upb_MiniTableField** f) { const upb_MiniTableField* ptr = *f; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; while (++ptr < end) { if (ptr->presence == (*f)->presence) { *f = ptr; @@ -8276,15 +8290,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, } -const struct upb_MiniTable _kUpb_MiniTable_Empty = { - .subs = NULL, - .fields = NULL, +#include + +// Must be last. + +// A MiniTable for an empty message, used for unlinked sub-messages. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = { + .UPB_PRIVATE(subs) = NULL, + .UPB_PRIVATE(fields) = NULL, .size = 0, - .field_count = 0, - .ext = kUpb_ExtMode_NonExtendable, - .dense_below = 0, - .table_mask = -1, - .required_count = 0, + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, }; @@ -9587,7 +9606,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { file, f->layout_index); } else { const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); - return &layout->fields[f->layout_index]; + return &layout->UPB_PRIVATE(fields)[f->layout_index]; } } @@ -11794,7 +11813,7 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); } else { m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); - UPB_ASSERT(m->field_count == m->layout->field_count); + UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count)); // We don't need the result of this call, but it will assign layout_index // for all the fields in O(n lg n) time. @@ -11830,9 +11849,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, UPB_ASSERT(layout_index < m->field_count); upb_MiniTableField* mt_f = - (upb_MiniTableField*)&m->layout->fields[layout_index]; + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; if (sub_m) { - if (!mt->subs) { + if (!mt->UPB_PRIVATE(subs)) { _upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name); } UPB_ASSERT(mt_f); @@ -11852,8 +11871,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, for (int i = 0; i < m->field_count; i++) { const upb_FieldDef* f = upb_MessageDef_Field(m, i); const int layout_index = _upb_FieldDef_LayoutIndex(f); - UPB_ASSERT(layout_index < m->layout->field_count); - const upb_MiniTableField* mt_f = &m->layout->fields[layout_index]; + UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); UPB_ASSERT(upb_FieldDef_HasPresence(f) == @@ -12630,6 +12650,8 @@ typedef union { // 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. +// TODO: Move these to mini_table/ anyway since there are other places +// that could use them. // Returns the MiniTable corresponding to a given MiniTableField // from an array of MiniTableSubs. @@ -12786,9 +12808,9 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, upb_Message* msg = _upb_Message_New(subl, &d->arena); if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - // Extensions should not be unlinked. A message extension should not be + // Extensions should not be unlinked. A message extension should not be // registered until its sub-message type is available to be linked. - bool is_empty = subl == &_kUpb_MiniTable_Empty; + bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl); bool is_extension = field->mode & kUpb_LabelFlags_IsExtension; UPB_ASSERT(!(is_empty && is_extension)); @@ -12807,7 +12829,8 @@ static upb_Message* _upb_Decoder_ReuseSubMessage( upb_TaggedMessagePtr tagged = *target; const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) { + if (!upb_TaggedMessagePtr_IsEmpty(tagged) || + UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) { return _upb_TaggedMessagePtr_GetMessage(tagged); } @@ -13131,8 +13154,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) { [kUpb_FieldType_SInt64] = 8, }; - const upb_MiniTableField* key_field = &entry->fields[0]; - const upb_MiniTableField* val_field = &entry->fields[1]; + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k)); @@ -13154,9 +13177,9 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(entry); - UPB_ASSERT(entry->field_count == 2); - UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[0])); - UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[1])); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); if (!map) { map = _upb_Decoder_CreateMap(d, entry); @@ -13166,11 +13189,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, // Parse map entry. memset(&ent, 0, sizeof(ent)); - if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group) { // Create proactively to handle the case where it doesn't appear. upb_TaggedMessagePtr msg; - _upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg); + _upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs), + &entry->UPB_PRIVATE(fields)[1], &msg); ent.data.v.val = upb_value_uintptr(msg); } @@ -13271,15 +13297,15 @@ static const char* _upb_Decoder_DecodeToSubMessage( UPB_NOINLINE const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l) { - UPB_ASSERT(l->required_count); + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { return ptr; } uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(l) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { d->missing_required = true; } return ptr; @@ -13288,11 +13314,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, UPB_FORCEINLINE static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr, upb_Message* msg, - const upb_MiniTable* layout) { + const upb_MiniTable* m) { #if UPB_FASTTABLE - if (layout && layout->table_mask != (unsigned char)-1) { + if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) { uint16_t tag = _upb_FastDecoder_LoadTag(*ptr); - intptr_t table = decode_totable(layout); + intptr_t table = decode_totable(m); *ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag); return true; } @@ -13448,30 +13474,30 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, if (t == NULL) return &none; size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX - if (idx < t->dense_below) { + if (idx < t->UPB_PRIVATE(dense_below)) { /* Fastest case: index into dense fields. */ goto found; } - if (t->dense_below < t->field_count) { + if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) { /* Linear search non-dense fields. Resume scanning from last_field_index * since fields are usually in order. */ size_t last = *last_field_index; - for (idx = last; idx < t->field_count; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) { + if (t->UPB_PRIVATE(fields)[idx].number == field_number) { goto found; } } - for (idx = t->dense_below; idx < last; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) { + if (t->UPB_PRIVATE(fields)[idx].number == field_number) { goto found; } } } if (d->extreg) { - switch (t->ext) { + switch (t->UPB_PRIVATE(ext)) { case kUpb_ExtMode_Extendable: { const upb_MiniTableExtension* ext = upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); @@ -13491,9 +13517,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, return &none; /* Unknown field. */ found: - UPB_ASSERT(t->fields[idx].number == field_number); + UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].number == field_number); *last_field_index = idx; - return &t->fields[idx]; + return &t->UPB_PRIVATE(fields)[idx]; } int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { @@ -13530,9 +13556,9 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, // If sub-message is not linked, treat as unknown. if (field->mode & kUpb_LabelFlags_IsExtension) return; const upb_MiniTable* mt_sub = - _upb_MiniTableSubs_MessageByField(mt->subs, field); + _upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field); if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) || - mt_sub != &_kUpb_MiniTable_Empty) { + !UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) { return; } #ifndef NDEBUG @@ -13543,7 +13569,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, do { UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); const upb_MiniTableSub* oneof_sub = - &mt->subs[oneof->UPB_PRIVATE(submsg_index)]; + &mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)]; UPB_ASSERT(!oneof_sub); } while (upb_MiniTable_NextOneofField(mt, &oneof)); } @@ -13671,7 +13697,7 @@ static const char* _upb_Decoder_DecodeKnownField( upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout, const upb_MiniTableField* field, int op, wireval* val) { - const upb_MiniTableSub* subs = layout->subs; + const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs); uint8_t mode = field->mode; if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { @@ -13825,7 +13851,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, } } - return UPB_UNLIKELY(layout && layout->required_count) + return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count)) ? _upb_Decoder_CheckRequired(d, ptr, msg, layout) : ptr; } @@ -13961,9 +13987,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) { case kUpb_IsDoneStatus_Done: *(uint32_t*)msg |= hasbits; // Sync hasbits. - const upb_MiniTable* l = decode_totablep(table); - return UPB_UNLIKELY(l->required_count) - ? _upb_Decoder_CheckRequired(d, ptr, msg, l) + const upb_MiniTable* m = decode_totablep(table); + return UPB_UNLIKELY(m->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, m) : ptr; case kUpb_IsDoneStatus_NotDone: break; @@ -14812,12 +14838,12 @@ 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 = \ - upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \ + const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \ + *UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ - if (subtablep->table_mask == (uint8_t)-1) { \ + if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \ d->depth++; \ RETURN_GENERIC("submessage doesn't have fast tables."); \ } \ @@ -15082,7 +15108,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e, upb_TaggedMessagePtr tagged, const upb_MiniTable* m, size_t* size) { if (upb_TaggedMessagePtr_IsEmpty(tagged)) { - m = &_kUpb_MiniTable_Empty; + m = UPB_PRIVATE(_upb_MiniTable_Empty)(); } encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size); } @@ -15283,12 +15309,12 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, static void encode_mapentry(upb_encstate* e, uint32_t number, const upb_MiniTable* layout, const upb_MapEntry* ent) { - const upb_MiniTableField* key_field = &layout->fields[0]; - const upb_MiniTableField* val_field = &layout->fields[1]; + const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1]; size_t pre_len = e->limit - e->ptr; size_t size; - encode_scalar(e, &ent->data.v, layout->subs, val_field); - encode_scalar(e, &ent->data.k, layout->subs, key_field); + encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field); + encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); encode_tag(e, number, kUpb_WireType_Delimited); @@ -15300,15 +15326,15 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); const upb_MiniTable* layout = upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); - UPB_ASSERT(layout->field_count == 2); + UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2); if (map == NULL) return; if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap(&e->sorter, - layout->fields[0].UPB_PRIVATE(descriptortype), map, - &sorted); + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { encode_mapentry(e, f->number, layout, &ent); @@ -15410,11 +15436,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) { + if ((e->options & kUpb_EncodeOption_CheckRequired) && + m->UPB_PRIVATE(required_count)) { uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(m) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { encode_err(e, kUpb_EncodeStatus_MissingRequired); } } @@ -15428,7 +15455,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, } } - if (m->ext != kUpb_ExtMode_NonExtendable) { + if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) { /* Encode all extensions together. Unlike C++, we do not attempt to keep * these in field number order relative to normal fields or even to each * other. */ @@ -15439,25 +15466,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, _upb_sortedmap sorted; _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted); while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { const upb_Message_Extension* end = ext + ext_count; for (; ext != end; ext++) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } } } } - if (m->field_count) { - const upb_MiniTableField* f = &m->fields[m->field_count]; - const upb_MiniTableField* first = &m->fields[0]; + if (m->UPB_PRIVATE(field_count)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; while (f != first) { f--; - if (encode_shouldencode(e, msg, m->subs, f)) { - encode_field(e, msg, m->subs, f); + if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) { + encode_field(e, msg, m->UPB_PRIVATE(subs), f); } } } @@ -15598,3 +15626,4 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/php/ext/google/protobuf/php-upb.h b/php/ext/google/protobuf/php-upb.h index 703a4420ee..332c1420d2 100644 --- a/php/ext/google/protobuf/php-upb.h +++ b/php/ext/google/protobuf/php-upb.h @@ -180,6 +180,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -1309,82 +1315,6 @@ upb_MiniTableField_Type(const upb_MiniTableField* f) { #define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ -// Must be last. - -struct upb_Decoder; -typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, - upb_Message* msg, intptr_t table, - uint64_t hasbits, uint64_t data); -typedef struct { - uint64_t field_data; - _upb_FieldParser* field_parser; -} _upb_FastTable_Entry; - -typedef enum { - kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. - kUpb_ExtMode_Extendable = 1, // Normal extendable message. - kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. - kUpb_ExtMode_IsMessageSet_ITEM = - 3, // MessageSet item (temporary only, see decode.c) - - // During table building we steal a bit to indicate that the message is a map - // entry. *Only* used during table building! - kUpb_ExtMode_IsMapEntry = 4, -} upb_ExtMode; - -// upb_MiniTable represents the memory layout of a given upb_MessageDef. -// The members are public so generated code can initialize them, -// but users MUST NOT directly read or write any of its members. -struct upb_MiniTable { - const union upb_MiniTableSub* subs; - const struct upb_MiniTableField* fields; - - // Must be aligned to sizeof(void*). Doesn't include internal members like - // unknown fields, extension dict, pointer to msglayout, etc. - uint16_t size; - - uint16_t field_count; - uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 - uint8_t dense_below; - uint8_t table_mask; - uint8_t required_count; // Required fields have the lowest hasbits. - - // To statically initialize the tables of variable length, we need a flexible - // array member, and we need to compile in gnu99 mode (constant initialization - // of flexible array members is a GNU extension, not in C99 unfortunately. - _upb_FastTable_Entry fasttable[]; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -// A MiniTable for an empty message, used for unlinked sub-messages. -extern const struct upb_MiniTable _kUpb_MiniTable_Empty; - -// Computes a bitmask in which the |l->required_count| lowest bits are set, -// except that we skip the lowest bit (because upb never uses hasbit 0). -// -// Sample output: -// requiredmask(1) => 0b10 (0x2) -// requiredmask(5) => 0b111110 (0x3e) -UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { - int n = l->required_count; - assert(0 < n && n <= 63); - return ((1ULL << n) - 1) << 1; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ - -#ifndef UPB_MINI_TABLE_SUB_H_ -#define UPB_MINI_TABLE_SUB_H_ - - #ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ #define UPB_MINI_TABLE_INTERNAL_SUB_H_ @@ -1432,34 +1362,117 @@ UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)( // Must be last. -typedef union upb_MiniTableSub upb_MiniTableSub; +struct upb_Decoder; +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. +struct upb_MiniTable { + const union upb_MiniTableSub* UPB_PRIVATE(subs); + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to sizeof(void*). Doesn't include internal members like + // unknown fields, extension dict, pointer to msglayout, etc. + uint16_t size; + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + + // To statically initialize the tables of variable length, we need a flexible + // array member, and we need to compile in gnu99 mode (constant initialization + // of flexible array members is a GNU extension, not in C99 unfortunately. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +}; #ifdef __cplusplus extern "C" { #endif -// Constructors +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); -UPB_API_INLINE upb_MiniTableSub -upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) { - return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum); + return &UPB_PRIVATE(_kUpb_MiniTable_Empty); } -UPB_API_INLINE upb_MiniTableSub -upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) { - return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg); +UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)( + const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); } -// Getters +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)( + const struct upb_MiniTable* m) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); -UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( - upb_MiniTableSub sub) { - return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub); + return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty); } -UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( - upb_MiniTableSub sub) { - return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub); +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE( + _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_PRIVATE(subs)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message); + const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSUME(ret); + return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE( + _upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum); + return UPB_PRIVATE(_upb_MiniTableSub_Enum)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// RequiredMask(1) => 0b10 (0x2) +// RequiredMask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; } #ifdef __cplusplus @@ -1467,50 +1480,54 @@ UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( #endif -#endif /* UPB_MINI_TABLE_SUB_H_ */ +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ // Must be last. +typedef struct upb_MiniTable upb_MiniTable; + #ifdef __cplusplus extern "C" { #endif -typedef struct upb_MiniTable upb_MiniTable; - UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* table, uint32_t number); + const upb_MiniTable* m, uint32_t number); UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( - const upb_MiniTable* t, uint32_t index) { - return &t->fields[index]; + const upb_MiniTable* m, uint32_t index) { + return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index); +} + +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m); } -// Returns the MiniTable for this message field. If the field is unlinked, -// returns NULL. +// Returns the MiniTable for a message field, NULL if the field is unlinked. 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 = upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)]); - UPB_ASSUME(ret); - return ret == &_kUpb_MiniTable_Empty ? NULL : ret; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f); } -// Returns the MiniTableEnum for this enum field. If the field is unlinked, -// returns NULL. +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - 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)]); + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f); } // Returns true if this MiniTable field is linked to a MiniTable for the // sub-message. UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f); } +// TODO: Implement convenience getters for map entries: +// +// upb_MiniTable_GetMapKey() +// upb_MiniTable_GetMapValue() +// These could also assert that this is indeed a map entry (well, as best we +// can. We can assert that there are two fields with field numbers 1 and 2). + // If this field is in a oneof, returns the first field in the oneof. // // Otherwise returns NULL. @@ -2400,8 +2417,8 @@ struct upb_Message_InternalData { /* Maps upb_CType -> memory size. */ extern char _upb_CTypeo_size[12]; -UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) { - return t->size + sizeof(upb_Message_Internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) { + return m->size + sizeof(upb_Message_Internal); } // Inline version upb_Message_New(), for internal use. @@ -2897,6 +2914,49 @@ UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i, #endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#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 + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + // Must be last. #ifdef __cplusplus @@ -3212,7 +3272,7 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); UPB_ASSUME(upb_MiniTableField_IsScalar(field)); UPB_ASSERT(upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)])); + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)])); _upb_Message_SetNonExtensionField(msg, field, &sub_message); } @@ -3232,7 +3292,7 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*); if (!sub_message) { const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)]); + mini_table->UPB_PRIVATE(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; @@ -3302,9 +3362,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; return _upb_Message_GetOrCreateMutableMap( msg, field, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), @@ -13420,12 +13480,12 @@ non_ascii: const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l); + const upb_MiniTable* m); /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { - return ((intptr_t)tablep << 8) | tablep->table_mask; + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); } UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { @@ -13466,9 +13526,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr, size_t idx = tag & mask; UPB_ASSUME((idx & 7) == 0); idx >>= 3; - data = table_p->fasttable[idx].field_data ^ tag; - UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table, - hasbits, data); + data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag; + UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser( + d, ptr, msg, table, hasbits, data); } #endif @@ -13778,3 +13838,4 @@ UPB_INLINE const char* upb_WireReader_SkipValue( #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/ruby/ext/google/protobuf_c/ruby-upb.c b/ruby/ext/google/protobuf_c/ruby-upb.c index eb7ec42376..63fca83f9d 100644 --- a/ruby/ext/google/protobuf_c/ruby-upb.c +++ b/ruby/ext/google/protobuf_c/ruby-upb.c @@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -5400,14 +5406,14 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map, upb_Message* map_entry_message, upb_Arena* arena) { // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_mini_table = - upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_mini_table); - UPB_ASSERT(map_entry_mini_table->field_count == 2); + UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; // Map key/value cannot have explicit defaults, // hence assuming a zero default is valid. upb_MessageValue default_val; @@ -5490,7 +5496,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type, case kUpb_CType_Message: { const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value; bool is_empty = upb_TaggedMessagePtr_IsEmpty(source); - if (is_empty) sub = &_kUpb_MiniTable_Empty; + if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)(); UPB_ASSERT(source); upb_Message* clone = upb_Message_DeepClone( _upb_TaggedMessagePtr_GetMessage(source), sub, arena); @@ -5513,7 +5519,8 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type, upb_MessageValue key, val; size_t iter = kUpb_Map_Begin; while (upb_Map_Next(map, &key, &val, &iter)) { - const upb_MiniTableField* value_field = &map_entry_table->fields[1]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; const upb_MiniTable* value_sub = (value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub) ? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field) @@ -5536,12 +5543,14 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map, upb_Message* clone, upb_Arena* arena) { // TODO: use a variant of upb_MiniTable_GetSubMessageTable() here. - const upb_MiniTable* map_entry_table = - upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]); + const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message( + mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); UPB_ASSERT(map_entry_table); - const upb_MiniTableField* key_field = &map_entry_table->fields[0]; - const upb_MiniTableField* value_field = &map_entry_table->fields[1]; + const upb_MiniTableField* key_field = + &map_entry_table->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* value_field = + &map_entry_table->UPB_PRIVATE(fields)[1]; upb_Map* cloned_map = upb_Map_DeepClone( map, upb_MiniTableField_CType(key_field), @@ -5609,8 +5618,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0); // Only copy message area skipping upb_Message_Internal. memcpy(dst, src, mini_table->size); - for (size_t i = 0; i < mini_table->field_count; ++i) { - const upb_MiniTableField* field = &mini_table->fields[i]; + for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) { + const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsScalar(field)) { switch (upb_MiniTableField_CType(field)) { case kUpb_CType_Message: { @@ -5624,7 +5633,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src, // decode status, or possible parse failure here. bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged); const upb_MiniTable* sub_message_table = - is_empty ? &_kUpb_MiniTable_Empty + is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)() : upb_MiniTable_GetSubMessageTable(mini_table, field); upb_Message* dst_sub_message = upb_Message_DeepClone(sub_message, sub_message_table, arena); @@ -6718,16 +6727,16 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d, static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, upb_SubCounts sub_counts) { uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count; - size_t subs_bytes = sizeof(*d->table->subs) * total_count; + size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count; upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes); upb_MdDecoder_CheckOutOfMemory(&d->base, subs); uint32_t i = 0; for (; i < sub_counts.submsg_count; i++) { - subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty; + subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)(); } if (sub_counts.subenum_count) { upb_MiniTableField* f = d->fields; - upb_MiniTableField* end_f = f + d->table->field_count; + upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count); for (; f < end_f; f++) { if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) { f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count; @@ -6737,7 +6746,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d, subs[i].UPB_PRIVATE(subenum) = NULL; } } - d->table->subs = subs; + d->table->UPB_PRIVATE(subs) = subs; } static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, @@ -6768,7 +6777,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, ch <= kUpb_EncodedValue_MaxModifier) { ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers); if (msg_modifiers & kUpb_MessageModifier_IsExtendable) { - d->table->ext |= kUpb_ExtMode_Extendable; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable; } } else if (ch == kUpb_EncodedValue_End) { if (!d->table) { @@ -6778,7 +6787,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } else if (kUpb_EncodedValue_MinSkip <= ch && ch <= kUpb_EncodedValue_MaxSkip) { if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); need_dense_below = false; } uint32_t skip; @@ -6793,7 +6802,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr, } if (need_dense_below) { - d->table->dense_below = d->table->field_count; + d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count); } return ptr; @@ -6807,14 +6816,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data, upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields); upb_SubCounts sub_counts = {0, 0}; - d->table->field_count = 0; - d->table->fields = d->fields; + d->table->UPB_PRIVATE(field_count) = 0; + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields), - &d->table->field_count, &sub_counts); + &d->table->UPB_PRIVATE(field_count), &sub_counts); upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len, - sizeof(*d->fields) * d->table->field_count); - d->table->fields = d->fields; + sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count)); + d->table->UPB_PRIVATE(fields) = d->fields; upb_MtDecoder_AllocateSubs(d, sub_counts); } @@ -6841,7 +6850,7 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) { static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) { // Add items for all non-oneof fields (oneofs were already added). - int n = d->table->field_count; + int n = d->table->UPB_PRIVATE(field_count); for (int i = 0; i < n; i++) { upb_MiniTableField* f = &d->fields[i]; if (f->offset >= kOneofBase) continue; @@ -6865,27 +6874,29 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) { static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) { upb_MiniTable* ret = d->table; - int n = ret->field_count; + int n = ret->UPB_PRIVATE(field_count); int last_hasbit = 0; // 0 cannot be used. // First assign required fields, which must have the lowest hasbits. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kRequiredPresence) { field->presence = ++last_hasbit; } else if (field->offset == kNoPresence) { field->presence = 0; } } - ret->required_count = last_hasbit; - - if (ret->required_count > 63) { + if (last_hasbit > 63) { upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields"); } + ret->UPB_PRIVATE(required_count) = last_hasbit; + // Next assign non-required hasbit fields. for (int i = 0; i < n; i++) { - upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i]; + upb_MiniTableField* field = + (upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i]; if (field->offset == kHasbitPresence) { field->presence = ++last_hasbit; } @@ -6924,7 +6935,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) { while (true) { f->presence = ~item->offset; if (f->offset == kUpb_LayoutItem_IndexSentinel) break; - UPB_ASSERT(f->offset - kOneofBase < d->table->field_count); + UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count)); f = &d->fields[f->offset - kOneofBase]; } } @@ -6992,9 +7003,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, upb_MtDecoder_ParseMessage(d, data, len); upb_MtDecoder_AssignHasbits(d); - if (UPB_UNLIKELY(d->table->field_count != 2)) { + if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) { upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map", - d->table->field_count); + d->table->UPB_PRIVATE(field_count)); UPB_UNREACHABLE(); } @@ -7005,8 +7016,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, } } - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1); - upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1); + upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2); // Map entries have a pre-determined layout, regardless of types. // NOTE: sync with mini_table/message_internal.h. @@ -7018,7 +7029,7 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data, // Map entries have a special bit set to signal it's a map entry, used in // upb_MiniTable_SetSubMessage() below. - d->table->ext |= kUpb_ExtMode_IsMapEntry; + d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry; } static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, @@ -7030,11 +7041,11 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data, upb_MiniTable* ret = d->table; ret->size = 0; - ret->field_count = 0; - ret->ext = kUpb_ExtMode_IsMessageSet; - ret->dense_below = 0; - ret->table_mask = -1; - ret->required_count = 0; + ret->UPB_PRIVATE(field_count) = 0; + ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet; + ret->UPB_PRIVATE(dense_below) = 0; + ret->UPB_PRIVATE(table_mask) = -1; + ret->UPB_PRIVATE(required_count) = 0; } static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( @@ -7043,11 +7054,11 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf( upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table); decoder->table->size = 0; - decoder->table->field_count = 0; - decoder->table->ext = kUpb_ExtMode_NonExtendable; - decoder->table->dense_below = 0; - decoder->table->table_mask = -1; - decoder->table->required_count = 0; + decoder->table->UPB_PRIVATE(field_count) = 0; + decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable; + decoder->table->UPB_PRIVATE(dense_below) = 0; + decoder->table->UPB_PRIVATE(table_mask) = -1; + decoder->table->UPB_PRIVATE(required_count) = 0; // Strip off and verify the version tag. if (!len--) goto done; @@ -7140,7 +7151,7 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension( f->offset = 0; f->presence = 0; - if (extendee->ext & kUpb_ExtMode_IsMessageSet) { + if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) { // Extensions of MessageSet must be messages. if (!upb_MiniTableField_IsSubMessage(f)) return NULL; @@ -7216,17 +7227,18 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len, bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTable* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); - const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry; + const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; switch (field->UPB_PRIVATE(descriptortype)) { case kUpb_FieldType_Message: if (sub_is_map) { - const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry; + const bool table_is_map = + table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry; if (UPB_UNLIKELY(table_is_map)) return false; field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map; @@ -7242,23 +7254,23 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table, } upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; // TODO: Add this assert back once YouTube is updated to not call // this function repeatedly. - // UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty); + // UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg)); *table_sub = upb_MiniTableSub_FromMessage(sub); return true; } bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field, const upb_MiniTableEnum* sub) { - UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field && - (uintptr_t)field < - (uintptr_t)(table->fields + table->field_count)); + UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field && + (uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) + + table->UPB_PRIVATE(field_count))); UPB_ASSERT(sub); upb_MiniTableSub* table_sub = - (void*)&table->subs[field->UPB_PRIVATE(submsg_index)]; + (void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]; *table_sub = upb_MiniTableSub_FromEnum(sub); return true; } @@ -7268,8 +7280,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { *subs = f; ++subs; @@ -7277,8 +7289,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt, } } - for (int i = 0; i < mt->field_count; i++) { - const upb_MiniTableField* f = &mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) { *subs = f; ++subs; @@ -7299,8 +7311,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, uint32_t msg_count = 0; uint32_t enum_count = 0; - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_CType(f) == kUpb_CType_Message) { const upb_MiniTable* sub = sub_tables[msg_count++]; if (msg_count > sub_table_count) return false; @@ -7310,8 +7322,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables, } } - for (int i = 0; i < mt->field_count; i++) { - upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i]; + for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) { + upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i]; if (upb_MiniTableField_IsClosedEnum(f)) { const upb_MiniTableEnum* sub = sub_enums[enum_count++]; if (enum_count > sub_enum_count) return false; @@ -7734,21 +7746,21 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup( // Must be last. const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* t, uint32_t number) { + const upb_MiniTable* m, uint32_t number) { const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX // Ideal case: index into dense fields - if (i < t->dense_below) { - UPB_ASSERT(t->fields[i].number == number); - return &t->fields[i]; + if (i < m->UPB_PRIVATE(dense_below)) { + UPB_ASSERT(m->UPB_PRIVATE(fields)[i].number == number); + return &m->UPB_PRIVATE(fields)[i]; } // Slow case: binary search - int lo = t->dense_below; - int hi = t->field_count - 1; + int lo = m->UPB_PRIVATE(dense_below); + int hi = m->UPB_PRIVATE(field_count) - 1; while (lo <= hi) { int mid = (lo + hi) / 2; - uint32_t num = t->fields[mid].number; + uint32_t num = m->UPB_PRIVATE(fields)[mid].number; if (num < number) { lo = mid + 1; continue; @@ -7757,7 +7769,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( hi = mid - 1; continue; } - return &t->fields[mid]; + return &m->UPB_PRIVATE(fields)[mid]; } return NULL; } @@ -7767,8 +7779,9 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) { return NULL; } - const upb_MiniTableField* ptr = &m->fields[0]; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; for (; ptr < end; ptr++) { if (ptr->presence == (*f).presence) { return ptr; @@ -7780,7 +7793,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m, bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, const upb_MiniTableField** f) { const upb_MiniTableField* ptr = *f; - const upb_MiniTableField* end = &m->fields[m->field_count]; + const upb_MiniTableField* end = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; while (++ptr < end) { if (ptr->presence == (*f)->presence) { *f = ptr; @@ -7791,15 +7805,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m, } -const struct upb_MiniTable _kUpb_MiniTable_Empty = { - .subs = NULL, - .fields = NULL, +#include + +// Must be last. + +// A MiniTable for an empty message, used for unlinked sub-messages. +const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = { + .UPB_PRIVATE(subs) = NULL, + .UPB_PRIVATE(fields) = NULL, .size = 0, - .field_count = 0, - .ext = kUpb_ExtMode_NonExtendable, - .dense_below = 0, - .table_mask = -1, - .required_count = 0, + .UPB_PRIVATE(field_count) = 0, + .UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable, + .UPB_PRIVATE(dense_below) = 0, + .UPB_PRIVATE(table_mask) = -1, + .UPB_PRIVATE(required_count) = 0, }; @@ -9102,7 +9121,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) { file, f->layout_index); } else { const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef); - return &layout->fields[f->layout_index]; + return &layout->UPB_PRIVATE(fields)[f->layout_index]; } } @@ -11309,7 +11328,7 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) { m->layout = _upb_MessageDef_MakeMiniTable(ctx, m); } else { m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++); - UPB_ASSERT(m->field_count == m->layout->field_count); + UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count)); // We don't need the result of this call, but it will assign layout_index // for all the fields in O(n lg n) time. @@ -11345,9 +11364,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, UPB_ASSERT(layout_index < m->field_count); upb_MiniTableField* mt_f = - (upb_MiniTableField*)&m->layout->fields[layout_index]; + (upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index]; if (sub_m) { - if (!mt->subs) { + if (!mt->UPB_PRIVATE(subs)) { _upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name); } UPB_ASSERT(mt_f); @@ -11367,8 +11386,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx, for (int i = 0; i < m->field_count; i++) { const upb_FieldDef* f = upb_MessageDef_Field(m, i); const int layout_index = _upb_FieldDef_LayoutIndex(f); - UPB_ASSERT(layout_index < m->layout->field_count); - const upb_MiniTableField* mt_f = &m->layout->fields[layout_index]; + UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count)); + const upb_MiniTableField* mt_f = + &m->layout->UPB_PRIVATE(fields)[layout_index]; UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f)); UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f)); UPB_ASSERT(upb_FieldDef_HasPresence(f) == @@ -12145,6 +12165,8 @@ typedef union { // 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. +// TODO: Move these to mini_table/ anyway since there are other places +// that could use them. // Returns the MiniTable corresponding to a given MiniTableField // from an array of MiniTableSubs. @@ -12301,9 +12323,9 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d, upb_Message* msg = _upb_Message_New(subl, &d->arena); if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory); - // Extensions should not be unlinked. A message extension should not be + // Extensions should not be unlinked. A message extension should not be // registered until its sub-message type is available to be linked. - bool is_empty = subl == &_kUpb_MiniTable_Empty; + bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl); bool is_extension = field->mode & kUpb_LabelFlags_IsExtension; UPB_ASSERT(!(is_empty && is_extension)); @@ -12322,7 +12344,8 @@ static upb_Message* _upb_Decoder_ReuseSubMessage( upb_TaggedMessagePtr tagged = *target; const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(subl); - if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) { + if (!upb_TaggedMessagePtr_IsEmpty(tagged) || + UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) { return _upb_TaggedMessagePtr_GetMessage(tagged); } @@ -12646,8 +12669,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) { [kUpb_FieldType_SInt64] = 8, }; - const upb_MiniTableField* key_field = &entry->fields[0]; - const upb_MiniTableField* val_field = &entry->fields[1]; + const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1]; char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)]; char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)]; UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k)); @@ -12669,9 +12692,9 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field); UPB_ASSERT(entry); - UPB_ASSERT(entry->field_count == 2); - UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[0])); - UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[1])); + UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0])); + UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1])); if (!map) { map = _upb_Decoder_CreateMap(d, entry); @@ -12681,11 +12704,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr, // Parse map entry. memset(&ent, 0, sizeof(ent)); - if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message || - entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) { + if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Message || + entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) == + kUpb_FieldType_Group) { // Create proactively to handle the case where it doesn't appear. upb_TaggedMessagePtr msg; - _upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg); + _upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs), + &entry->UPB_PRIVATE(fields)[1], &msg); ent.data.v.val = upb_value_uintptr(msg); } @@ -12786,15 +12812,15 @@ static const char* _upb_Decoder_DecodeToSubMessage( UPB_NOINLINE const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l) { - UPB_ASSERT(l->required_count); + const upb_MiniTable* m) { + UPB_ASSERT(m->UPB_PRIVATE(required_count)); if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) { return ptr; } uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(l) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { d->missing_required = true; } return ptr; @@ -12803,11 +12829,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, UPB_FORCEINLINE static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr, upb_Message* msg, - const upb_MiniTable* layout) { + const upb_MiniTable* m) { #if UPB_FASTTABLE - if (layout && layout->table_mask != (unsigned char)-1) { + if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) { uint16_t tag = _upb_FastDecoder_LoadTag(*ptr); - intptr_t table = decode_totable(layout); + intptr_t table = decode_totable(m); *ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag); return true; } @@ -12963,30 +12989,30 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, if (t == NULL) return &none; size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX - if (idx < t->dense_below) { + if (idx < t->UPB_PRIVATE(dense_below)) { /* Fastest case: index into dense fields. */ goto found; } - if (t->dense_below < t->field_count) { + if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) { /* Linear search non-dense fields. Resume scanning from last_field_index * since fields are usually in order. */ size_t last = *last_field_index; - for (idx = last; idx < t->field_count; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) { + if (t->UPB_PRIVATE(fields)[idx].number == field_number) { goto found; } } - for (idx = t->dense_below; idx < last; idx++) { - if (t->fields[idx].number == field_number) { + for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) { + if (t->UPB_PRIVATE(fields)[idx].number == field_number) { goto found; } } } if (d->extreg) { - switch (t->ext) { + switch (t->UPB_PRIVATE(ext)) { case kUpb_ExtMode_Extendable: { const upb_MiniTableExtension* ext = upb_ExtensionRegistry_Lookup(d->extreg, t, field_number); @@ -13006,9 +13032,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d, return &none; /* Unknown field. */ found: - UPB_ASSERT(t->fields[idx].number == field_number); + UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].number == field_number); *last_field_index = idx; - return &t->fields[idx]; + return &t->UPB_PRIVATE(fields)[idx]; } int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) { @@ -13045,9 +13071,9 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, // If sub-message is not linked, treat as unknown. if (field->mode & kUpb_LabelFlags_IsExtension) return; const upb_MiniTable* mt_sub = - _upb_MiniTableSubs_MessageByField(mt->subs, field); + _upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field); if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) || - mt_sub != &_kUpb_MiniTable_Empty) { + !UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) { return; } #ifndef NDEBUG @@ -13058,7 +13084,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt, do { UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message); const upb_MiniTableSub* oneof_sub = - &mt->subs[oneof->UPB_PRIVATE(submsg_index)]; + &mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)]; UPB_ASSERT(!oneof_sub); } while (upb_MiniTable_NextOneofField(mt, &oneof)); } @@ -13186,7 +13212,7 @@ static const char* _upb_Decoder_DecodeKnownField( upb_Decoder* d, const char* ptr, upb_Message* msg, const upb_MiniTable* layout, const upb_MiniTableField* field, int op, wireval* val) { - const upb_MiniTableSub* subs = layout->subs; + const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs); uint8_t mode = field->mode; if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) { @@ -13340,7 +13366,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr, } } - return UPB_UNLIKELY(layout && layout->required_count) + return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count)) ? _upb_Decoder_CheckRequired(d, ptr, msg, layout) : ptr; } @@ -13476,9 +13502,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) { switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) { case kUpb_IsDoneStatus_Done: *(uint32_t*)msg |= hasbits; // Sync hasbits. - const upb_MiniTable* l = decode_totablep(table); - return UPB_UNLIKELY(l->required_count) - ? _upb_Decoder_CheckRequired(d, ptr, msg, l) + const upb_MiniTable* m = decode_totablep(table); + return UPB_UNLIKELY(m->UPB_PRIVATE(required_count)) + ? _upb_Decoder_CheckRequired(d, ptr, msg, m) : ptr; case kUpb_IsDoneStatus_NotDone: break; @@ -14327,12 +14353,12 @@ 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 = \ - upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \ + const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \ + *UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \ fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \ fastdecode_arr farr; \ \ - if (subtablep->table_mask == (uint8_t)-1) { \ + if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \ d->depth++; \ RETURN_GENERIC("submessage doesn't have fast tables."); \ } \ @@ -14597,7 +14623,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e, upb_TaggedMessagePtr tagged, const upb_MiniTable* m, size_t* size) { if (upb_TaggedMessagePtr_IsEmpty(tagged)) { - m = &_kUpb_MiniTable_Empty; + m = UPB_PRIVATE(_upb_MiniTable_Empty)(); } encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size); } @@ -14798,12 +14824,12 @@ static void encode_array(upb_encstate* e, const upb_Message* msg, static void encode_mapentry(upb_encstate* e, uint32_t number, const upb_MiniTable* layout, const upb_MapEntry* ent) { - const upb_MiniTableField* key_field = &layout->fields[0]; - const upb_MiniTableField* val_field = &layout->fields[1]; + const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0]; + const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1]; size_t pre_len = e->limit - e->ptr; size_t size; - encode_scalar(e, &ent->data.v, layout->subs, val_field); - encode_scalar(e, &ent->data.k, layout->subs, key_field); + encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field); + encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field); size = (e->limit - e->ptr) - pre_len; encode_varint(e, size); encode_tag(e, number, kUpb_WireType_Delimited); @@ -14815,15 +14841,15 @@ static void encode_map(upb_encstate* e, const upb_Message* msg, const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*); const upb_MiniTable* layout = upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]); - UPB_ASSERT(layout->field_count == 2); + UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2); if (map == NULL) return; if (e->options & kUpb_EncodeOption_Deterministic) { _upb_sortedmap sorted; - _upb_mapsorter_pushmap(&e->sorter, - layout->fields[0].UPB_PRIVATE(descriptortype), map, - &sorted); + _upb_mapsorter_pushmap( + &e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype), + map, &sorted); upb_MapEntry ent; while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) { encode_mapentry(e, f->number, layout, &ent); @@ -14925,11 +14951,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, const upb_MiniTable* m, size_t* size) { size_t pre_len = e->limit - e->ptr; - if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) { + if ((e->options & kUpb_EncodeOption_CheckRequired) && + m->UPB_PRIVATE(required_count)) { uint64_t msg_head; memcpy(&msg_head, msg, 8); msg_head = _upb_BigEndian_Swap64(msg_head); - if (upb_MiniTable_requiredmask(m) & ~msg_head) { + if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { encode_err(e, kUpb_EncodeStatus_MissingRequired); } } @@ -14943,7 +14970,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, } } - if (m->ext != kUpb_ExtMode_NonExtendable) { + if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) { /* Encode all extensions together. Unlike C++, we do not attempt to keep * these in field number order relative to normal fields or even to each * other. */ @@ -14954,25 +14981,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg, _upb_sortedmap sorted; _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted); while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } _upb_mapsorter_popmap(&e->sorter, &sorted); } else { const upb_Message_Extension* end = ext + ext_count; for (; ext != end; ext++) { - encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet); + encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet); } } } } - if (m->field_count) { - const upb_MiniTableField* f = &m->fields[m->field_count]; - const upb_MiniTableField* first = &m->fields[0]; + if (m->UPB_PRIVATE(field_count)) { + const upb_MiniTableField* f = + &m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)]; + const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0]; while (f != first) { f--; - if (encode_shouldencode(e, msg, m->subs, f)) { - encode_field(e, msg, m->subs, f); + if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) { + encode_field(e, msg, m->UPB_PRIVATE(subs), f); } } } @@ -15113,3 +15141,4 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS diff --git a/ruby/ext/google/protobuf_c/ruby-upb.h b/ruby/ext/google/protobuf_c/ruby-upb.h index 61342b0927..a93465d0a8 100755 --- a/ruby/ext/google/protobuf_c/ruby-upb.h +++ b/ruby/ext/google/protobuf_c/ruby-upb.h @@ -182,6 +182,12 @@ Error, UINTPTR_MAX is undefined #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only +#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY +#define UPB_ONLYBITS(x) x +#else +#define UPB_ONLYBITS(x) UPB_PRIVATE(x) +#endif + /* Configure whether fasttable is switched on or not. *************************/ #ifdef __has_attribute @@ -1311,82 +1317,6 @@ upb_MiniTableField_Type(const upb_MiniTableField* f) { #define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ -// Must be last. - -struct upb_Decoder; -typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, - upb_Message* msg, intptr_t table, - uint64_t hasbits, uint64_t data); -typedef struct { - uint64_t field_data; - _upb_FieldParser* field_parser; -} _upb_FastTable_Entry; - -typedef enum { - kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. - kUpb_ExtMode_Extendable = 1, // Normal extendable message. - kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. - kUpb_ExtMode_IsMessageSet_ITEM = - 3, // MessageSet item (temporary only, see decode.c) - - // During table building we steal a bit to indicate that the message is a map - // entry. *Only* used during table building! - kUpb_ExtMode_IsMapEntry = 4, -} upb_ExtMode; - -// upb_MiniTable represents the memory layout of a given upb_MessageDef. -// The members are public so generated code can initialize them, -// but users MUST NOT directly read or write any of its members. -struct upb_MiniTable { - const union upb_MiniTableSub* subs; - const struct upb_MiniTableField* fields; - - // Must be aligned to sizeof(void*). Doesn't include internal members like - // unknown fields, extension dict, pointer to msglayout, etc. - uint16_t size; - - uint16_t field_count; - uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1 - uint8_t dense_below; - uint8_t table_mask; - uint8_t required_count; // Required fields have the lowest hasbits. - - // To statically initialize the tables of variable length, we need a flexible - // array member, and we need to compile in gnu99 mode (constant initialization - // of flexible array members is a GNU extension, not in C99 unfortunately. - _upb_FastTable_Entry fasttable[]; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -// A MiniTable for an empty message, used for unlinked sub-messages. -extern const struct upb_MiniTable _kUpb_MiniTable_Empty; - -// Computes a bitmask in which the |l->required_count| lowest bits are set, -// except that we skip the lowest bit (because upb never uses hasbit 0). -// -// Sample output: -// requiredmask(1) => 0b10 (0x2) -// requiredmask(5) => 0b111110 (0x3e) -UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) { - int n = l->required_count; - assert(0 < n && n <= 63); - return ((1ULL << n) - 1) << 1; -} - -#ifdef __cplusplus -} /* extern "C" */ -#endif - - -#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ - -#ifndef UPB_MINI_TABLE_SUB_H_ -#define UPB_MINI_TABLE_SUB_H_ - - #ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_ #define UPB_MINI_TABLE_INTERNAL_SUB_H_ @@ -1434,34 +1364,117 @@ UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)( // Must be last. -typedef union upb_MiniTableSub upb_MiniTableSub; +struct upb_Decoder; +typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, + upb_Message* msg, intptr_t table, + uint64_t hasbits, uint64_t data); +typedef struct { + uint64_t field_data; + _upb_FieldParser* field_parser; +} _upb_FastTable_Entry; + +typedef enum { + kUpb_ExtMode_NonExtendable = 0, // Non-extendable message. + kUpb_ExtMode_Extendable = 1, // Normal extendable message. + kUpb_ExtMode_IsMessageSet = 2, // MessageSet message. + kUpb_ExtMode_IsMessageSet_ITEM = + 3, // MessageSet item (temporary only, see decode.c) + + // During table building we steal a bit to indicate that the message is a map + // entry. *Only* used during table building! + kUpb_ExtMode_IsMapEntry = 4, +} upb_ExtMode; + +// upb_MiniTable represents the memory layout of a given upb_MessageDef. +// The members are public so generated code can initialize them, +// but users MUST NOT directly read or write any of its members. +struct upb_MiniTable { + const union upb_MiniTableSub* UPB_PRIVATE(subs); + const struct upb_MiniTableField* UPB_ONLYBITS(fields); + + // Must be aligned to sizeof(void*). Doesn't include internal members like + // unknown fields, extension dict, pointer to msglayout, etc. + uint16_t size; + + uint16_t UPB_ONLYBITS(field_count); + + uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1 + uint8_t UPB_PRIVATE(dense_below); + uint8_t UPB_PRIVATE(table_mask); + uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits. + + // To statically initialize the tables of variable length, we need a flexible + // array member, and we need to compile in gnu99 mode (constant initialization + // of flexible array members is a GNU extension, not in C99 unfortunately. + _upb_FastTable_Entry UPB_PRIVATE(fasttable)[]; +}; #ifdef __cplusplus extern "C" { #endif -// Constructors +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); -UPB_API_INLINE upb_MiniTableSub -upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) { - return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum); + return &UPB_PRIVATE(_kUpb_MiniTable_Empty); } -UPB_API_INLINE upb_MiniTableSub -upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) { - return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg); +UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)( + const struct upb_MiniTable* m) { + return m->UPB_ONLYBITS(field_count); } -// Getters +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)( + const struct upb_MiniTable* m) { + extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty); -UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum( - upb_MiniTableSub sub) { - return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub); + return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty); } -UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( - upb_MiniTableSub sub) { - return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub); +UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE( + _upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_ONLYBITS(fields)[i]; +} + +UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE( + _upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) { + return &m->UPB_PRIVATE(subs)[i]; +} + +UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE( + _upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message); + const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); + UPB_ASSUME(ret); + return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret; +} + +UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE( + _upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m, + const struct upb_MiniTableField* f) { + UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum); + return UPB_PRIVATE(_upb_MiniTableSub_Enum)( + m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]); +} + +UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)( + const struct upb_MiniTable* m, const struct upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL; +} + +// Computes a bitmask in which the |m->required_count| lowest bits are set, +// except that we skip the lowest bit (because upb never uses hasbit 0). +// +// Sample output: +// RequiredMask(1) => 0b10 (0x2) +// RequiredMask(5) => 0b111110 (0x3e) +UPB_INLINE uint64_t +UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) { + int n = m->UPB_PRIVATE(required_count); + UPB_ASSERT(0 < n && n <= 63); + return ((1ULL << n) - 1) << 1; } #ifdef __cplusplus @@ -1469,50 +1482,54 @@ UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message( #endif -#endif /* UPB_MINI_TABLE_SUB_H_ */ +#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */ // Must be last. +typedef struct upb_MiniTable upb_MiniTable; + #ifdef __cplusplus extern "C" { #endif -typedef struct upb_MiniTable upb_MiniTable; - UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber( - const upb_MiniTable* table, uint32_t number); + const upb_MiniTable* m, uint32_t number); UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex( - const upb_MiniTable* t, uint32_t index) { - return &t->fields[index]; + const upb_MiniTable* m, uint32_t index) { + return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index); +} + +UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) { + return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m); } -// Returns the MiniTable for this message field. If the field is unlinked, -// returns NULL. +// Returns the MiniTable for a message field, NULL if the field is unlinked. 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 = upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)]); - UPB_ASSUME(ret); - return ret == &_kUpb_MiniTable_Empty ? NULL : ret; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f); } -// Returns the MiniTableEnum for this enum field. If the field is unlinked, -// returns NULL. +// Returns the MiniTableEnum for a message field, NULL if the field is unlinked. UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable( - 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)]); + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f); } // Returns true if this MiniTable field is linked to a MiniTable for the // sub-message. UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked( - const upb_MiniTable* mini_table, const upb_MiniTableField* field) { - return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL; + const upb_MiniTable* m, const upb_MiniTableField* f) { + return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f); } +// TODO: Implement convenience getters for map entries: +// +// upb_MiniTable_GetMapKey() +// upb_MiniTable_GetMapValue() +// These could also assert that this is indeed a map entry (well, as best we +// can. We can assert that there are two fields with field numbers 1 and 2). + // If this field is in a oneof, returns the first field in the oneof. // // Otherwise returns NULL. @@ -2402,8 +2419,8 @@ struct upb_Message_InternalData { /* Maps upb_CType -> memory size. */ extern char _upb_CTypeo_size[12]; -UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) { - return t->size + sizeof(upb_Message_Internal); +UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) { + return m->size + sizeof(upb_Message_Internal); } // Inline version upb_Message_New(), for internal use. @@ -2899,6 +2916,49 @@ UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i, #endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */ +#ifndef UPB_MINI_TABLE_SUB_H_ +#define UPB_MINI_TABLE_SUB_H_ + + +// Must be last. + +typedef union upb_MiniTableSub upb_MiniTableSub; + +#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 + + +#endif /* UPB_MINI_TABLE_SUB_H_ */ + // Must be last. #ifdef __cplusplus @@ -3214,7 +3274,7 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr( UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte)); UPB_ASSUME(upb_MiniTableField_IsScalar(field)); UPB_ASSERT(upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)])); + mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)])); _upb_Message_SetNonExtensionField(msg, field, &sub_message); } @@ -3234,7 +3294,7 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage( upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*); if (!sub_message) { const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message( - mini_table->subs[field->UPB_PRIVATE(submsg_index)]); + mini_table->UPB_PRIVATE(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; @@ -3304,9 +3364,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap( const upb_MiniTableField* field, upb_Arena* arena) { UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message); const upb_MiniTableField* map_entry_key_field = - &map_entry_mini_table->fields[0]; + &map_entry_mini_table->UPB_PRIVATE(fields)[0]; const upb_MiniTableField* map_entry_value_field = - &map_entry_mini_table->fields[1]; + &map_entry_mini_table->UPB_PRIVATE(fields)[1]; return _upb_Message_GetOrCreateMutableMap( msg, field, _upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)), @@ -13239,12 +13299,12 @@ non_ascii: const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr, const upb_Message* msg, - const upb_MiniTable* l); + const upb_MiniTable* m); /* x86-64 pointers always have the high 16 bits matching. So we can shift * left 8 and right 8 without loss of information. */ UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) { - return ((intptr_t)tablep << 8) | tablep->table_mask; + return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask); } UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) { @@ -13285,9 +13345,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr, size_t idx = tag & mask; UPB_ASSUME((idx & 7) == 0); idx >>= 3; - data = table_p->fasttable[idx].field_data ^ tag; - UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table, - hasbits, data); + data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag; + UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser( + d, ptr, msg, table, hasbits, data); } #endif @@ -13597,3 +13657,4 @@ UPB_INLINE const char* upb_WireReader_SkipValue( #undef UPB_ATOMIC #undef UPB_USE_C11_ATOMICS #undef UPB_PRIVATE +#undef UPB_ONLYBITS