From ac1015e3c417ecb18d8f449a4e6aaaff3c4f53b9 Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 21 Aug 2017 13:44:23 -0700 Subject: [PATCH] Trimmed vtables of trailing zeroes. This is something the format supports, but none of the builders were doing. Can save 10-20% on FlatBuffer binary size! Also fixed the Go tests. Change-Id: I616c56ce9bbcfcaee23aa24f0532fcb60b6a8c75 Tested: on Linux. --- go/builder.go | 5 +++ include/flatbuffers/flatbuffers.h | 36 +++++++++++++++----- include/flatbuffers/reflection_generated.h | 37 +++++++++++++++++---- java/com/google/flatbuffers/FlatBufferBuilder.java | 12 ++++--- js/flatbuffers.js | 17 ++++++---- net/FlatBuffers/FlatBufferBuilder.cs | 10 ++++-- php/FlatbufferBuilder.php | 10 ++++-- python/flatbuffers/builder.py | 4 +++ samples/monster_generated.h | 4 +-- src/idl_gen_cpp.cpp | 3 +- src/idl_parser.cpp | 3 +- src/reflection.cpp | 2 +- tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs | 8 ++--- tests/GoTest.sh | 3 ++ tests/go_test.go | 7 ++-- tests/javatest.bin | Bin 512 -> 512 bytes tests/monster_test.bfbs | Bin 5280 -> 5272 bytes tests/monster_test_generated.h | 10 +++--- tests/monsterdata_python_wire.mon | Bin 416 -> 352 bytes tests/monsterdata_test.mon | Bin 512 -> 448 bytes tests/namespace_test/namespace_test1_generated.h | 2 +- tests/namespace_test/namespace_test2_generated.h | 6 ++-- tests/py_test.py | 6 ++-- tests/test.cpp | 2 +- tests/union_vector/union_vector_generated.h | 4 +-- 25 files changed, 129 insertions(+), 62 deletions(-) diff --git a/go/builder.go b/go/builder.go index cf21dd5..a7bf4a1 100644 --- a/go/builder.go +++ b/go/builder.go @@ -110,6 +110,11 @@ func (b *Builder) WriteVtable() (n UOffsetT) { objectOffset := b.Offset() existingVtable := UOffsetT(0) + // Trim vtable of trailing zeroes. + i := len(b.vtable) - 1; + for ; i >= 0 && b.vtable[i] == 0; i-- {} + b.vtable = b.vtable[:i + 1]; + // Search backwards through existing vtables, because similar vtables // are likely to have been recently appended. See // BenchmarkVtableDeduplication for a case in which this heuristic diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index f1ecc56..ab17b6e 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -704,8 +704,8 @@ class FlatBufferBuilder explicit FlatBufferBuilder(size_t initial_size = 1024, Allocator *allocator = nullptr, bool own_allocator = false) - : buf_(initial_size, allocator, own_allocator), nested(false), - finished(false), minalign_(1), force_defaults_(false), + : buf_(initial_size, allocator, own_allocator), max_voffset_(0), + nested(false), finished(false), minalign_(1), force_defaults_(false), dedup_vtables_(true), string_pool(nullptr) { offsetbuf_.reserve(16); // Avoid first few reallocs. vtables_.reserve(16); @@ -725,7 +725,7 @@ class FlatBufferBuilder /// to construct another buffer. void Clear() { buf_.clear(); - offsetbuf_.clear(); + ClearOffsets(); nested = false; finished = false; vtables_.clear(); @@ -839,6 +839,7 @@ class FlatBufferBuilder void TrackField(voffset_t field, uoffset_t off) { FieldLoc fl = { off, field }; offsetbuf_.push_back(fl); + max_voffset_ = (std::max)(max_voffset_, field); } // Like PushElement, but additionally tracks the field this represents. @@ -899,7 +900,7 @@ class FlatBufferBuilder // This finishes one serialized object by generating the vtable if it's a // table, comparing it against existing vtables, and writing the // resulting vtable offset. - uoffset_t EndTable(uoffset_t start, voffset_t numfields) { + uoffset_t EndTable(uoffset_t start) { // If you get this assert, a corresponding StartTable wasn't called. assert(nested); // Write the vtable offset, which is the start of any Table. @@ -908,11 +909,17 @@ class FlatBufferBuilder // 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: - buf_.fill_big(numfields * sizeof(voffset_t)); + // Include space for the last offset and ensure empty tables have a + // minimum size. + max_voffset_ = (std::max)(static_cast(max_voffset_ + + sizeof(voffset_t)), + FieldIndexToOffset(0)); + buf_.fill_big(max_voffset_); auto table_object_size = vtableoffsetloc - start; assert(table_object_size < 0x10000); // Vtable use 16bit offsets. - PushElement(static_cast(table_object_size)); - PushElement(FieldIndexToOffset(numfields)); + WriteScalar(buf_.data() + sizeof(voffset_t), + static_cast(table_object_size)); + WriteScalar(buf_.data(), max_voffset_); // Write the offsets into the table for (auto field_location = offsetbuf_.begin(); field_location != offsetbuf_.end(); @@ -922,7 +929,7 @@ class FlatBufferBuilder assert(!ReadScalar(buf_.data() + field_location->id)); WriteScalar(buf_.data() + field_location->id, pos); } - offsetbuf_.clear(); + ClearOffsets(); auto vt1 = reinterpret_cast(buf_.data()); auto vt1_size = ReadScalar(vt1); auto vt_use = GetSize(); @@ -955,6 +962,11 @@ class FlatBufferBuilder return vtableoffsetloc; } + // DEPRECATED: call the version above instead. + uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) { + return EndTable(start); + } + // 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) { @@ -973,7 +985,10 @@ class FlatBufferBuilder uoffset_t EndStruct() { return GetSize(); } - void ClearOffsets() { offsetbuf_.clear(); } + void ClearOffsets() { + offsetbuf_.clear(); + max_voffset_ = 0; + } // Aligns such that when "len" bytes are written, an object can be written // after it with "alignment" without padding. @@ -1510,6 +1525,9 @@ class FlatBufferBuilder // Accumulating offsets of table members while it is being built. std::vector offsetbuf_; + // Track how much of the vtable is in use, so we can output the most compact + // possible vtable. + voffset_t max_voffset_; // Ensure objects are not nested. bool nested; diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h index 097084b..3bbab11 100644 --- a/include/flatbuffers/reflection_generated.h +++ b/include/flatbuffers/reflection_generated.h @@ -42,6 +42,29 @@ enum BaseType { Union = 16 }; +inline BaseType (&EnumValuesBaseType())[17] { + static BaseType values[] = { + None, + UType, + Bool, + Byte, + UByte, + Short, + UShort, + Int, + UInt, + Long, + ULong, + Float, + Double, + String, + Vector, + Obj, + Union + }; + return values; +} + inline const char **EnumNamesBaseType() { static const char *names[] = { "None", @@ -113,7 +136,7 @@ struct TypeBuilder { } TypeBuilder &operator=(const TypeBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 3); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -173,7 +196,7 @@ struct KeyValueBuilder { } KeyValueBuilder &operator=(const KeyValueBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 2); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, KeyValue::VT_KEY); return o; @@ -266,7 +289,7 @@ struct EnumValBuilder { } EnumValBuilder &operator=(const EnumValBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 4); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, EnumVal::VT_NAME); return o; @@ -381,7 +404,7 @@ struct EnumBuilder { } EnumBuilder &operator=(const EnumBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 6); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, Enum::VT_NAME); fbb_.Required(o, Enum::VT_VALUES); @@ -544,7 +567,7 @@ struct FieldBuilder { } FieldBuilder &operator=(const FieldBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 11); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, Field::VT_NAME); fbb_.Required(o, Field::VT_TYPE); @@ -695,7 +718,7 @@ struct ObjectBuilder { } ObjectBuilder &operator=(const ObjectBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 7); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, Object::VT_NAME); fbb_.Required(o, Object::VT_FIELDS); @@ -808,7 +831,7 @@ struct SchemaBuilder { } SchemaBuilder &operator=(const SchemaBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 5); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, Schema::VT_OBJECTS); fbb_.Required(o, Schema::VT_ENUMS); diff --git a/java/com/google/flatbuffers/FlatBufferBuilder.java b/java/com/google/flatbuffers/FlatBufferBuilder.java index 3ef4282..0214fd2 100644 --- a/java/com/google/flatbuffers/FlatBufferBuilder.java +++ b/java/com/google/flatbuffers/FlatBufferBuilder.java @@ -478,7 +478,7 @@ public class FlatBufferBuilder { obj.sortTables(offsets, bb); return createVectorOfTables(offsets); } - + /** * Encode the string `s` in the buffer using UTF-8. If {@code s} is * already a {@link CharBuffer}, this method is allocation free. @@ -744,7 +744,11 @@ public class FlatBufferBuilder { addInt(0); int vtableloc = offset(); // Write out the current vtable. - for (int i = vtable_in_use - 1; i >= 0 ; i--) { + int i = vtable_in_use - 1; + // Trim trailing zeroes. + for (; i >= 0 && vtable[i] == 0; i--) {} + int trimmed_size = i + 1; + for (; i >= 0 ; i--) { // Offset relative to the start of the table. short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0); addShort(off); @@ -752,12 +756,12 @@ public class FlatBufferBuilder { final int standard_fields = 2; // The fields below: addShort((short)(vtableloc - object_start)); - addShort((short)((vtable_in_use + standard_fields) * SIZEOF_SHORT)); + addShort((short)((trimmed_size + standard_fields) * SIZEOF_SHORT)); // Search for an existing vtable that matches the current one. int existing_vtable = 0; outer_loop: - for (int i = 0; i < num_vtables; i++) { + for (i = 0; i < num_vtables; i++) { int vt1 = bb.capacity() - vtables[i]; int vt2 = space; short len = bb.getShort(vt1); diff --git a/js/flatbuffers.js b/js/flatbuffers.js index ccbd362..4c2bf52 100644 --- a/js/flatbuffers.js +++ b/js/flatbuffers.js @@ -604,23 +604,28 @@ flatbuffers.Builder.prototype.endObject = function() { this.addInt32(0); var vtableloc = this.offset(); + // Trim trailing zeroes. + var i = this.vtable_in_use - 1; + for (; i >= 0 && this.vtable[i] == 0; i--) {} + var trimmed_size = i + 1; + // Write out the current vtable. - for (var i = this.vtable_in_use - 1; i >= 0; i--) { + for (; i >= 0; i--) { // Offset relative to the start of the table. this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); } var standard_fields = 2; // The fields below: this.addInt16(vtableloc - this.object_start); - this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT); + var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT; + this.addInt16(len); // Search for an existing vtable that matches the current one. var existing_vtable = 0; + var vt1 = this.space; outer_loop: - for (var i = 0; i < this.vtables.length; i++) { - var vt1 = this.bb.capacity() - this.vtables[i]; - var vt2 = this.space; - var len = this.bb.readInt16(vt1); + for (i = 0; i < this.vtables.length; i++) { + var vt2 = this.bb.capacity() - this.vtables[i]; if (len == this.bb.readInt16(vt2)) { for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) { if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { diff --git a/net/FlatBuffers/FlatBufferBuilder.cs b/net/FlatBuffers/FlatBufferBuilder.cs index b6701df..90627fd 100644 --- a/net/FlatBuffers/FlatBufferBuilder.cs +++ b/net/FlatBuffers/FlatBufferBuilder.cs @@ -500,7 +500,11 @@ namespace FlatBuffers AddInt((int)0); var vtableloc = Offset; // Write out the current vtable. - for (int i = _vtableSize - 1; i >= 0 ; i--) { + int i = _vtableSize - 1; + // Trim trailing zeroes. + for (; i >= 0 && _vtable[i] == 0; i--) {} + int trimmedSize = i + 1; + for (; i >= 0 ; i--) { // Offset relative to the start of the table. short off = (short)(_vtable[i] != 0 ? vtableloc - _vtable[i] @@ -513,12 +517,12 @@ namespace FlatBuffers const int standardFields = 2; // The fields below: AddShort((short)(vtableloc - _objectStart)); - AddShort((short)((_vtableSize + standardFields) * + AddShort((short)((trimmedSize + standardFields) * sizeof(short))); // Search for an existing vtable that matches the current one. int existingVtable = 0; - for (int i = 0; i < _numVtables; i++) { + for (i = 0; i < _numVtables; i++) { int vt1 = _bb.Length - _vtables[i]; int vt2 = _space; short len = _bb.GetShort(vt1); diff --git a/php/FlatbufferBuilder.php b/php/FlatbufferBuilder.php index 5c18bf4..925b438 100644 --- a/php/FlatbufferBuilder.php +++ b/php/FlatbufferBuilder.php @@ -596,7 +596,7 @@ class FlatbufferBuilder if (function_exists('mb_detect_encoding')) { return (bool) mb_detect_encoding($bytes, 'UTF-8', true); } - + $len = strlen($bytes); if ($len < 1) { /* NOTE: always return 1 when passed string is null */ @@ -812,14 +812,18 @@ class FlatbufferBuilder $this->addInt(0); $vtableloc = $this->offset(); - for ($i = $this->vtable_in_use -1; $i >= 0; $i--) { + $i = $this->vtable_in_use -1; + // Trim trailing zeroes. + for (; $i >= 0 && $this->vtable[$i] == 0; $i--) {} + $trimmed_size = $i + 1; + for (; $i >= 0; $i--) { $off = ($this->vtable[$i] != 0) ? $vtableloc - $this->vtable[$i] : 0; $this->addShort($off); } $standard_fields = 2; // the fields below $this->addShort($vtableloc - $this->object_start); - $this->addShort(($this->vtable_in_use + $standard_fields) * Constants::SIZEOF_SHORT); + $this->addShort(($trimmed_size + $standard_fields) * Constants::SIZEOF_SHORT); // search for an existing vtable that matches the current one. $existing_vtable = 0; diff --git a/python/flatbuffers/builder.py b/python/flatbuffers/builder.py index 552d0e2..e6d6882 100644 --- a/python/flatbuffers/builder.py +++ b/python/flatbuffers/builder.py @@ -193,6 +193,10 @@ class Builder(object): objectOffset = self.Offset() existingVtable = None + # Trim trailing 0 offsets. + while self.current_vtable and self.current_vtable[-1] == 0: + self.current_vtable.pop() + # Search backwards through existing vtables, because similar vtables # are likely to have been recently appended. See # BenchmarkVtableDeduplication for a case in which this heuristic diff --git a/samples/monster_generated.h b/samples/monster_generated.h index cfa30af..2f3141b 100644 --- a/samples/monster_generated.h +++ b/samples/monster_generated.h @@ -316,7 +316,7 @@ struct MonsterBuilder { } MonsterBuilder &operator=(const MonsterBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 10); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -426,7 +426,7 @@ struct WeaponBuilder { } WeaponBuilder &operator=(const WeaponBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 2); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp index fb57dc9..0953b1a 100644 --- a/src/idl_gen_cpp.cpp +++ b/src/idl_gen_cpp.cpp @@ -1531,9 +1531,8 @@ class CppGenerator : public BaseGenerator { "(const {{STRUCT_NAME}}Builder &);"; // Finish() function. - auto num_fields = NumToString(struct_def.fields.vec.size()); code_ += " flatbuffers::Offset<{{STRUCT_NAME}}> Finish() {"; - code_ += " const auto end = fbb_.EndTable(start_, " + num_fields + ");"; + code_ += " const auto end = fbb_.EndTable(start_);"; code_ += " auto o = flatbuffers::Offset<{{STRUCT_NAME}}>(end);"; for (auto it = struct_def.fields.vec.begin(); diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp index 4d9e230..d9811bd 100644 --- a/src/idl_parser.cpp +++ b/src/idl_parser.cpp @@ -1071,8 +1071,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, builder_.PopBytes(struct_def.bytesize); assert(!ovalue); } else { - auto val = builder_.EndTable(start, - static_cast(struct_def.fields.vec.size())); + auto val = builder_.EndTable(start); if (ovalue) *ovalue = val; if (value) *value = NumToString(val); } diff --git a/src/reflection.cpp b/src/reflection.cpp index 2eee461..2f05a34 100644 --- a/src/reflection.cpp +++ b/src/reflection.cpp @@ -481,7 +481,7 @@ Offset CopyTable(FlatBufferBuilder &fbb, fbb.ClearOffsets(); return fbb.EndStruct(); } else { - return fbb.EndTable(start, static_cast(fielddefs->size())); + return fbb.EndTable(start); } } diff --git a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs index e8182d7..d933246 100644 --- a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs +++ b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs @@ -205,11 +205,11 @@ namespace FlatBuffers.Test builder.EndObject(); Assert.ArrayEqual(new byte[] { - 0, 0, 0, 0, 0, 0, // padding to 16 bytes - 6, 0, // vtable bytes + // No padding. + 4, 0, // vtable bytes 4, 0, // end of object from here - 0, 0, // entry 0 is empty (default value) - 6, 0, 0, 0, // int32 offset for start of vtable + // entry 0 is not stored (trimmed end of vtable) + 4, 0, 0, 0, // int32 offset for start of vtable }, builder.DataBuffer.Data); } diff --git a/tests/GoTest.sh b/tests/GoTest.sh index 248a13f..88e7a3f 100755 --- a/tests/GoTest.sh +++ b/tests/GoTest.sh @@ -30,6 +30,9 @@ mkdir -p ${go_src}/github.com/google/flatbuffers/go mkdir -p ${go_src}/flatbuffers_test cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/ +# do not compile the gRPC generated files, which are not tested by go_test.go +# below, but have their own test. +rm ./go_gen/src/MyGame/Example/*_grpc.go cp -a ../go/* ./go_gen/src/github.com/google/flatbuffers/go cp -a ./go_test.go ./go_gen/src/flatbuffers_test/ diff --git a/tests/go_test.go b/tests/go_test.go index 2fc6512..1eb92a0 100644 --- a/tests/go_test.go +++ b/tests/go_test.go @@ -715,10 +715,10 @@ func CheckByteLayout(fail func(string, ...interface{})) { b.PrependBoolSlot(0, false, false) b.EndObject() check([]byte{ - 6, 0, // vtable bytes + 4, 0, // vtable bytes 4, 0, // end of object from here - 0, 0, // entry 1 is zero - 6, 0, 0, 0, // offset for start of vtable (int32) + // entry 1 is zero and not stored. + 4, 0, 0, 0, // offset for start of vtable (int32) }) // test 10: vtable with one int16 @@ -1085,7 +1085,6 @@ func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UO b.PrependByteSlot(7, 1, 0) b.PrependUOffsetTSlot(8, mon2, 0) b.PrependUOffsetTSlot(9, test4, 0) - b.PrependUOffsetTSlot(9, test5, 0) mon := b.EndObject() b.Finish(mon) diff --git a/tests/javatest.bin b/tests/javatest.bin index 25b80cf5aa3c2802806409fcbf4e31f637fe7651..77835c736b37d60fcf336052a491c9526fd5112e 100644 GIT binary patch delta 159 zcmZo*X<(6LU|?u)0TL-doCCx_z*qq!8YbSx_Li<=7Pj{7&su>fwu8XzRIW#0K_UD3;+NC literal 512 zcmbtQy9&ZU5M1MfC>9p!6tNOp{Q<>7(nJLXEi4RpprA(1G=fD6KPaDOX%}ZM25i#k zaDl%3D)_^ygE7wRVK9pt`6e7szLKLl$4-sx{X;%w-h!m3S zyqJYZ5E0Zv2~kl!1O-JGgz(KbiINgr%F5KgGc$+_{y%5_v)?&q=9}-#>`+;M*|k-b z2W}3DE7hpEPzuA6T0LB@A5(LS6>M@ES)%Bt%{=>NMY+Io6xFA?uGqBfAEIeQdY5+f{1XH;f} zT;wC|H8!A^ZWs|Uq;VnfEi__;F-22GH8-W$v0ZfhQe>5o)70gNh%5ipJdzVs&{Iaf z=o}?tD@`$yry2)}!yuJ8BVw0Elw6|}XQWpnN-k!?$QzBQd6)?!^J(*3Ag3!LV!st1 zHP2(JXQWLdYMx0t<0=w^8c_`M=$@+@`8c_v;_KX^0=<;uj^aydbl*kh?2d>(^D3%z zV9uU3d|2b2sMOh$zz#xDz$!TSwSxf;Di_UoiMqr^v=Dl$F-A4sX6&JE?3yZ>8 z#Z@($d*BQ4C2I7Qh@{5VN=?-1+lsaH+E;`V^v%~GDiljzh95hv^EdPSSN&0}q8B{2 z&<}rDcokQ5Mu2w`2#J_RRG(OvK&bdY8Zy9s`hk+y_cR;x5A4Hy8ViJr<+aXdD`ivC l@mD_bR31tkO(gl7qTJx8EP3@7{siKzhJ*F658E!zYxEV^kaWT^B*q!EH)KafRIAud{OXiyjx)Ptl4 zB8;SjjDmuYUZSFU2NsOHO8@q+A*ACvjNEEe|#s~b;-6fXHRs%1$vB89H38Fi$7?!C5~R&!E+UL z^4v!EEeCLv(v~RZQpB1m01V*m)MHSEHHpRa&>Aj#GAB#&dgMamv}qcgQ96DeTsH7g zAhi|Xi{@F`<=km&sH}k5?5N0Lwq4BsKT=X#5~WbDc~UGGr8--vETs`cB6DmzINS2b zQ{|gsQ1db*Z#~`N$aflXNo41YY1%k$MI`5((mW{`w9!wFT*GX391^+7wgp@(BTLGm zO7pm*0Iz79J%laPWG}?tksiAf(V%ONm>8H}60L^bI10t6MpUUOnsvl+nDU)rQM{m- zO8L*U-?<%w)aQ(eA&qle0QS&(XBg*b+?n8}ie-0J&y&Of39S zt4as1*|P`7ub&3htlgInbQnaZGi(STQ}OI$<;&5Hz9(k5>M_EL}coMd~$ zMFoqhde!J*wvl6(eoR;Z_HU!h28w#r{moxWXsfnNHeI7Q!lwW3tj&goU|5`P0{ zz2c8!IX&aKg}(d4BB)NFQUISX5E7LdQQc#;7&-PIGDyvVwek#sLzqotfpA1#vuqw4 qcqsY!Ex*6x$<|~Czo#fG_%TcV2qa7X44U~eyObiV$w)eQ8~*~38zuk% diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h index 1ef66cd..3375cf6 100644 --- a/tests/monster_test_generated.h +++ b/tests/monster_test_generated.h @@ -345,7 +345,7 @@ struct MonsterBuilder { } MonsterBuilder &operator=(const MonsterBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 0); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -404,7 +404,7 @@ struct TestSimpleTableWithEnumBuilder { } TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 1); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -487,7 +487,7 @@ struct StatBuilder { } StatBuilder &operator=(const StatBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 3); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -1015,7 +1015,7 @@ struct MonsterBuilder { } MonsterBuilder &operator=(const MonsterBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 34); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); fbb_.Required(o, Monster::VT_NAME); return o; @@ -1352,7 +1352,7 @@ struct TypeAliasesBuilder { } TypeAliasesBuilder &operator=(const TypeAliasesBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 12); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } diff --git a/tests/monsterdata_python_wire.mon b/tests/monsterdata_python_wire.mon index 8d77225abb0ba4fbbc96a0f59f7f7ee7ef8a9755..55e37bf03961f9afdc7bd84220dcde2c8a5e8264 100644 GIT binary patch delta 110 zcmZ3${D4U~f&mqHF!)Rq_LTDgilzYZ1R$OP#A|>U2pB>14TgzTS`*j!Xo5tTfY=9! dZJ=y91`P%-1`!4x1`ePI2(U2lOpau92LKoC48#Bc delta 117 zcmaFBw18PSf&mqHFoaAL_LK_%isk_E6d;}h#BYEY2pB=M1mnaiEk=fkbAy$cfZPrs ot^i^XTaH14fr~+e!GnPV$O8eEiH6D(9YiKNurYc}mSl7X0G^W%>Hq)$ diff --git a/tests/monsterdata_test.mon b/tests/monsterdata_test.mon index d700f4bff3037b1a95be34fdbf6bc647b64388e2..8cb9cafd80b02c9f4f0e8325a0c8113a330f88c9 100644 GIT binary patch delta 178 zcmZo*Ilvqq!N9=a>+cr~q`<&~p@o41$YNvA0FpXD%*tTEV8UPlWZ3{Q2skjfFeET! zFnBQdFcdIUFa$t^p=1a{1VhZka7|MKMg|52Al?C#m;=NaKnzmqc(U>?2p2AC>;qvF kpjZJA9|7V86Za~!0BMGa4+cr~q`<&~p@V?~$YNtK0Fov^%*tTFV8h@5WVrw_2zW5~Fk~B146YoTLdVn1R6kuQh5o808$&QTm0L5h=8UO$Q diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h index 796d9c2..6fc6df7 100644 --- a/tests/namespace_test/namespace_test1_generated.h +++ b/tests/namespace_test/namespace_test1_generated.h @@ -105,7 +105,7 @@ struct TableInNestedNSBuilder { } TableInNestedNSBuilder &operator=(const TableInNestedNSBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 1); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h index 6c13047..7e650f4 100644 --- a/tests/namespace_test/namespace_test2_generated.h +++ b/tests/namespace_test/namespace_test2_generated.h @@ -76,7 +76,7 @@ struct TableInFirstNSBuilder { } TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 3); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -140,7 +140,7 @@ struct TableInCBuilder { } TableInCBuilder &operator=(const TableInCBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 2); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -190,7 +190,7 @@ struct SecondTableInABuilder { } SecondTableInABuilder &operator=(const SecondTableInABuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 1); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } diff --git a/tests/py_test.py b/tests/py_test.py index b543d2d..d15a316 100644 --- a/tests/py_test.py +++ b/tests/py_test.py @@ -490,10 +490,10 @@ class TestByteLayout(unittest.TestCase): b.PrependBoolSlot(0, False, False) b.EndObject() self.assertBuilderEquals(b, [ - 6, 0, # vtable bytes + 4, 0, # vtable bytes 4, 0, # end of object from here - 0, 0, # entry 1 is zero - 6, 0, 0, 0, # offset for start of vtable (int32) + # entry 1 is zero and not stored + 4, 0, 0, 0, # offset for start of vtable (int32) ]) def test_vtable_with_one_int16(self): diff --git a/tests/test.cpp b/tests/test.cpp index 6dbb9e4..1062c09 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -863,7 +863,7 @@ void FuzzTest1() { case 10: builder.AddElement(off, double_val, 0); break; } } - objects[i] = builder.EndTable(start, fields_per_object); + objects[i] = builder.EndTable(start); } builder.PreAlign(0); // Align whole buffer. diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h index 8758ad4..213053e 100644 --- a/tests/union_vector/union_vector_generated.h +++ b/tests/union_vector/union_vector_generated.h @@ -196,7 +196,7 @@ struct AttackerBuilder { } AttackerBuilder &operator=(const AttackerBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 1); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } @@ -309,7 +309,7 @@ struct MovieBuilder { } MovieBuilder &operator=(const MovieBuilder &); flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_, 4); + const auto end = fbb_.EndTable(start_); auto o = flatbuffers::Offset(end); return o; } -- 2.7.4