From 1cfbf16e320ca9bdadd9c24eb1d2d68b25369ba6 Mon Sep 17 00:00:00 2001 From: Pimyn Girgis Date: Tue, 2 Dec 2025 12:28:10 +0000 Subject: executor: update flatbuffers Update flatbuffers to v23.5.26, which matches the compiler version in the new env container. --- executor/_include/flatbuffers/flatbuffer_builder.h | 571 +++++++++++++++------ 1 file changed, 411 insertions(+), 160 deletions(-) (limited to 'executor/_include/flatbuffers/flatbuffer_builder.h') diff --git a/executor/_include/flatbuffers/flatbuffer_builder.h b/executor/_include/flatbuffers/flatbuffer_builder.h index f9432338f..0a38b4ac3 100644 --- a/executor/_include/flatbuffers/flatbuffer_builder.h +++ b/executor/_include/flatbuffers/flatbuffer_builder.h @@ -17,12 +17,16 @@ #ifndef FLATBUFFERS_FLATBUFFER_BUILDER_H_ #define FLATBUFFERS_FLATBUFFER_BUILDER_H_ +#include +#include #include #include +#include #include "flatbuffers/allocator.h" #include "flatbuffers/array.h" #include "flatbuffers/base.h" +#include "flatbuffers/buffer.h" #include "flatbuffers/buffer_ref.h" #include "flatbuffers/default_allocator.h" #include "flatbuffers/detached_buffer.h" @@ -39,8 +43,9 @@ namespace flatbuffers { // Converts a Field ID to a virtual table offset. inline voffset_t FieldIndexToOffset(voffset_t field_id) { // Should correspond to what EndTable() below builds up. - const int fixed_fields = 2; // Vtable size and Object Size. - return static_cast((field_id + fixed_fields) * sizeof(voffset_t)); + const voffset_t fixed_fields = + 2 * sizeof(voffset_t); // Vtable size and Object Size. + return fixed_fields + field_id * sizeof(voffset_t); } template> @@ -67,8 +72,13 @@ T *data(std::vector &v) { /// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/ /// `CreateVector` functions. Do this is depth-first order to build up a tree to /// the root. `Finish()` wraps up the buffer ready for transport. -class FlatBufferBuilder { +template class FlatBufferBuilderImpl { public: + // This switches the size type of the builder, based on if its 64-bit aware + // (uoffset64_t) or not (uoffset_t). + typedef + typename std::conditional::type SizeT; + /// @brief Default constructor for FlatBufferBuilder. /// @param[in] initial_size The initial size of the buffer, in bytes. Defaults /// to `1024`. @@ -80,13 +90,16 @@ class FlatBufferBuilder { /// minimum alignment upon reallocation. Only needed if you intend to store /// types with custom alignment AND you wish to read the buffer in-place /// directly after creation. - explicit FlatBufferBuilder( + explicit FlatBufferBuilderImpl( size_t initial_size = 1024, Allocator *allocator = nullptr, bool own_allocator = false, size_t buffer_minalign = AlignOf()) - : buf_(initial_size, allocator, own_allocator, buffer_minalign), + : buf_(initial_size, allocator, own_allocator, buffer_minalign, + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -97,10 +110,13 @@ class FlatBufferBuilder { } /// @brief Move constructor for FlatBufferBuilder. - FlatBufferBuilder(FlatBufferBuilder &&other) - : buf_(1024, nullptr, false, AlignOf()), + FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept + : buf_(1024, nullptr, false, AlignOf(), + static_cast(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE + : FLATBUFFERS_MAX_BUFFER_SIZE)), num_field_loc(0), max_voffset_(0), + length_of_64_bit_region_(0), nested(false), finished(false), minalign_(1), @@ -115,18 +131,19 @@ class FlatBufferBuilder { } /// @brief Move assignment operator for FlatBufferBuilder. - FlatBufferBuilder &operator=(FlatBufferBuilder &&other) { + FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept { // Move construct a temporary and swap idiom - FlatBufferBuilder temp(std::move(other)); + FlatBufferBuilderImpl temp(std::move(other)); Swap(temp); return *this; } - void Swap(FlatBufferBuilder &other) { + void Swap(FlatBufferBuilderImpl &other) { using std::swap; buf_.swap(other.buf_); swap(num_field_loc, other.num_field_loc); swap(max_voffset_, other.max_voffset_); + swap(length_of_64_bit_region_, other.length_of_64_bit_region_); swap(nested, other.nested); swap(finished, other.finished); swap(minalign_, other.minalign_); @@ -135,7 +152,7 @@ class FlatBufferBuilder { swap(string_pool, other.string_pool); } - ~FlatBufferBuilder() { + ~FlatBufferBuilderImpl() { if (string_pool) delete string_pool; } @@ -152,12 +169,36 @@ class FlatBufferBuilder { nested = false; finished = false; minalign_ = 1; + length_of_64_bit_region_ = 0; if (string_pool) string_pool->clear(); } /// @brief The current size of the serialized buffer, counting from the end. + /// @return Returns an `SizeT` with the current size of the buffer. + SizeT GetSize() const { return buf_.size(); } + + /// @brief The current size of the serialized buffer relative to the end of + /// the 32-bit region. /// @return Returns an `uoffset_t` with the current size of the buffer. - uoffset_t GetSize() const { return buf_.size(); } + template + // Only enable this method for the 64-bit builder, as only that builder is + // concerned with the 32/64-bit boundary, and should be the one to bare any + // run time costs. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + //[32-bit region][64-bit region] + // [XXXXXXXXXXXXXXXXXXX] GetSize() + // [YYYYYYYYYYYYY] length_of_64_bit_region_ + // [ZZZZ] return size + return static_cast(GetSize() - length_of_64_bit_region_); + } + + template + // Only enable this method for the 32-bit builder. + typename std::enable_if::type GetSizeRelative32BitRegion() + const { + return static_cast(GetSize()); + } /// @brief Get the serialized buffer (after you call `Finish()`). /// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the @@ -269,14 +310,16 @@ class FlatBufferBuilder { } // Write a single aligned scalar to the buffer - template uoffset_t PushElement(T element) { + template + ReturnT PushElement(T element) { AssertScalarT(); Align(sizeof(T)); buf_.push_small(EndianScalar(element)); - return GetSize(); + return CalculateOffset(); } - template uoffset_t PushElement(Offset off) { + template class OffsetT = Offset> + uoffset_t PushElement(OffsetT off) { // Special case for offsets: see ReferTo below. return PushElement(ReferTo(off.o)); } @@ -306,11 +349,16 @@ class FlatBufferBuilder { AddElement(field, ReferTo(off.o), static_cast(0)); } + template void AddOffset(voffset_t field, Offset64 off) { + if (off.IsNull()) return; // Don't store. + AddElement(field, ReferTo(off.o), static_cast(0)); + } + template void AddStruct(voffset_t field, const T *structptr) { if (!structptr) return; // Default, don't store. Align(AlignOf()); buf_.push_small(*structptr); - TrackField(field, GetSize()); + TrackField(field, CalculateOffset()); } void AddStructOffset(voffset_t field, uoffset_t off) { @@ -321,12 +369,29 @@ class FlatBufferBuilder { // This function converts them to be relative to the current location // in the buffer (when stored here), pointing upwards. uoffset_t ReferTo(uoffset_t off) { - // Align to ensure GetSize() below is correct. + // Align to ensure GetSizeRelative32BitRegion() below is correct. Align(sizeof(uoffset_t)); - // Offset must refer to something already in buffer. - const uoffset_t size = GetSize(); + // 32-bit offsets are relative to the tail of the 32-bit region of the + // buffer. For most cases (without 64-bit entities) this is equivalent to + // size of the whole buffer (e.g. GetSize()) + return ReferTo(off, GetSizeRelative32BitRegion()); + } + + uoffset64_t ReferTo(uoffset64_t off) { + // Align to ensure GetSize() below is correct. + Align(sizeof(uoffset64_t)); + // 64-bit offsets are relative to tail of the whole buffer + return ReferTo(off, GetSize()); + } + + template T ReferTo(const T off, const T2 size) { + FLATBUFFERS_ASSERT(off && off <= size); + return size - off + static_cast(sizeof(T)); + } + + template T ReferTo(const T off, const T size) { FLATBUFFERS_ASSERT(off && off <= size); - return size - off + static_cast(sizeof(uoffset_t)); + return size - off + static_cast(sizeof(T)); } void NotNested() { @@ -348,7 +413,7 @@ class FlatBufferBuilder { uoffset_t StartTable() { NotNested(); nested = true; - return GetSize(); + return GetSizeRelative32BitRegion(); } // This finishes one serialized object by generating the vtable if it's a @@ -359,7 +424,9 @@ class FlatBufferBuilder { FLATBUFFERS_ASSERT(nested); // Write the vtable offset, which is the start of any Table. // We fill its value later. - auto vtableoffsetloc = PushElement(0); + // This is relative to the end of the 32-bit region. + const uoffset_t vtable_offset_loc = + static_cast(PushElement(0)); // Write a vtable, which consists entirely of voffset_t elements. // It starts with the number of offsets, followed by a type id, followed // by the offsets themselves. In reverse: @@ -369,7 +436,7 @@ class FlatBufferBuilder { (std::max)(static_cast(max_voffset_ + sizeof(voffset_t)), FieldIndexToOffset(0)); buf_.fill_big(max_voffset_); - auto table_object_size = vtableoffsetloc - start; + const uoffset_t table_object_size = vtable_offset_loc - start; // Vtable use 16bit offsets. FLATBUFFERS_ASSERT(table_object_size < 0x10000); WriteScalar(buf_.data() + sizeof(voffset_t), @@ -379,7 +446,8 @@ class FlatBufferBuilder { for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc); it < buf_.scratch_end(); it += sizeof(FieldLoc)) { auto field_location = reinterpret_cast(it); - auto pos = static_cast(vtableoffsetloc - field_location->off); + const voffset_t pos = + static_cast(vtable_offset_loc - field_location->off); // If this asserts, it means you've set a field twice. FLATBUFFERS_ASSERT( !ReadScalar(buf_.data() + field_location->id)); @@ -388,7 +456,7 @@ class FlatBufferBuilder { ClearOffsets(); auto vt1 = reinterpret_cast(buf_.data()); auto vt1_size = ReadScalar(vt1); - auto vt_use = GetSize(); + auto vt_use = GetSizeRelative32BitRegion(); // See if we already have generated a vtable with this exact same // layout before. If so, make it point to the old one, remove this one. if (dedup_vtables_) { @@ -399,23 +467,24 @@ class FlatBufferBuilder { auto vt2_size = ReadScalar(vt2); if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; vt_use = *vt_offset_ptr; - buf_.pop(GetSize() - vtableoffsetloc); + buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc); break; } } // If this is a new vtable, remember it. - if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); } + if (vt_use == GetSizeRelative32BitRegion()) { + buf_.scratch_push_small(vt_use); + } // Fill the vtable offset we created above. - // The offset points from the beginning of the object to where the - // vtable is stored. + // The offset points from the beginning of the object to where the vtable is + // stored. // Offsets default direction is downward in memory for future format // flexibility (storing all vtables at the start of the file). - WriteScalar(buf_.data_at(vtableoffsetloc), + WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_), static_cast(vt_use) - - static_cast(vtableoffsetloc)); - + static_cast(vtable_offset_loc)); nested = false; - return vtableoffsetloc; + return vtable_offset_loc; } FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]]) @@ -425,14 +494,20 @@ class FlatBufferBuilder { // This checks a required field has been set in a given table that has // just been constructed. - template void Required(Offset table, voffset_t field); + template void Required(Offset table, voffset_t field) { + auto table_ptr = reinterpret_cast(buf_.data_at(table.o)); + bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; + // If this fails, the caller will show what field needs to be set. + FLATBUFFERS_ASSERT(ok); + (void)ok; + } uoffset_t StartStruct(size_t alignment) { Align(alignment); - return GetSize(); + return GetSizeRelative32BitRegion(); } - uoffset_t EndStruct() { return GetSize(); } + uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); } void ClearOffsets() { buf_.scratch_pop(num_field_loc * sizeof(FieldLoc)); @@ -441,15 +516,18 @@ class FlatBufferBuilder { } // Aligns such that when "len" bytes are written, an object can be written - // after it with "alignment" without padding. + // after it (forward in the buffer) with "alignment" without padding. void PreAlign(size_t len, size_t alignment) { if (len == 0) return; TrackMinAlign(alignment); buf_.fill(PaddingBytes(GetSize() + len, alignment)); } - template void PreAlign(size_t len) { - AssertScalarT(); - PreAlign(len, sizeof(T)); + + // Aligns such than when "len" bytes are written, an object of type `AlignT` + // can be written after it (forward in the buffer) without padding. + template void PreAlign(size_t len) { + AssertScalarT(); + PreAlign(len, AlignOf()); } /// @endcond @@ -457,34 +535,35 @@ class FlatBufferBuilder { /// @param[in] str A const char pointer to the data to be stored as a string. /// @param[in] len The number of bytes that should be stored from `str`. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str, size_t len) { - NotNested(); - PreAlign(len + 1); // Always 0-terminated. - buf_.fill(1); - PushBytes(reinterpret_cast(str), len); - PushElement(static_cast(len)); - return Offset(GetSize()); + template class OffsetT = Offset> + OffsetT CreateString(const char *str, size_t len) { + CreateStringImpl(str, len); + return OffsetT( + CalculateOffset::offset_type>()); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A const char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(const char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which is null-terminated. /// @param[in] str A char pointer to a C-string to add to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(char *str) { - return CreateString(str, strlen(str)); + template class OffsetT = Offset> + OffsetT CreateString(char *str) { + return CreateString(str, strlen(str)); } /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const reference to a std::string to store in the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(const std::string &str) { - return CreateString(str.c_str(), str.length()); + template class OffsetT = Offset> + OffsetT CreateString(const std::string &str) { + return CreateString(str.c_str(), str.length()); } // clang-format off @@ -492,8 +571,9 @@ class FlatBufferBuilder { /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const string_view to copy in to the buffer. /// @return Returns the offset in the buffer where the string starts. - Offset CreateString(flatbuffers::string_view str) { - return CreateString(str.data(), str.size()); + template