Fixed possible alignment issue in Go
authorrw <me@rwinslow.com>
Thu, 4 Sep 2014 06:26:06 +0000 (23:26 -0700)
committerWouter van Oortmerssen <wvo@google.com>
Fri, 5 Sep 2014 00:35:08 +0000 (17:35 -0700)
Java patch with same purpose:
cdb0dca39d683d577caa7fde21a1b6db9aa64734

Change-Id: I57d268cc0064843779eb7812a9e69326d9ab2498
Tested: on Darwin

go/builder.go
src/idl_gen_go.cpp
tests/MyGame/Example/Monster.go
tests/go_test.go

index 423620b..46543c8 100644 (file)
@@ -231,9 +231,10 @@ func (b *Builder) PrependUOffsetT(off UOffsetT) {
 // A vector has the following format:
 //   <UOffsetT: number of elements in this vector>
 //   <T: data>+, where T is the type of elements of this vector.
-func (b *Builder) StartVector(elemSize, numElems int) UOffsetT {
+func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {
        b.notNested()
        b.Prep(SizeUint32, elemSize*numElems)
+       b.Prep(alignment, elemSize*numElems) // Just in case alignment > int.
        return b.Offset()
 }
 
index 95ebf37..ce12d17 100755 (executable)
@@ -426,8 +426,12 @@ static void BuildVectorOfTable(const StructDef &struct_def,
   code += MakeCamel(field.name);
   code += "Vector(builder *flatbuffers.Builder, numElems int) ";
   code += "flatbuffers.UOffsetT { return builder.StartVector(";
-  code += NumToString(InlineSize(field.value.type.VectorType()));
-  code += ", numElems) }\n";
+  auto vector_type = field.value.type.VectorType();
+  auto alignment = InlineAlignment(vector_type);
+  auto elem_size = InlineSize(vector_type);
+  code += NumToString(elem_size);
+  code += ", numElems, " + NumToString(alignment);
+  code += ")\n}\n";
 }
 
 // Get the offset of the end of a table.
index 2e35ab6..16b1053 100644 (file)
@@ -193,23 +193,42 @@ func (rcv *Monster) TestnestedflatbufferLength() int {
        return 0
 }
 
-func MonsterStart(builder *flatbuffers.Builder) { builder.StartObject(14) }
+func (rcv *Monster) Testempty(obj *Monster) *Monster {
+       o := flatbuffers.UOffsetT(rcv._tab.Offset(32))
+       if o != 0 {
+               x := rcv._tab.Indirect(o + rcv._tab.Pos)
+               if obj == nil {
+                       obj = new(Monster)
+               }
+               obj.Init(rcv._tab.Bytes, x)
+               return obj
+       }
+       return nil
+}
+
+func MonsterStart(builder *flatbuffers.Builder) { builder.StartObject(15) }
 func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) { builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0) }
 func MonsterAddMana(builder *flatbuffers.Builder, mana int16) { builder.PrependInt16Slot(1, mana, 150) }
 func MonsterAddHp(builder *flatbuffers.Builder, hp int16) { builder.PrependInt16Slot(2, hp, 100) }
 func MonsterAddName(builder *flatbuffers.Builder, name flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(name), 0) }
 func MonsterAddInventory(builder *flatbuffers.Builder, inventory flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(5, flatbuffers.UOffsetT(inventory), 0) }
-func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems) }
+func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems, 1)
+}
 func MonsterAddColor(builder *flatbuffers.Builder, color int8) { builder.PrependInt8Slot(6, color, 8) }
 func MonsterAddTestType(builder *flatbuffers.Builder, testType byte) { builder.PrependByteSlot(7, testType, 0) }
 func MonsterAddTest(builder *flatbuffers.Builder, test flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(test), 0) }
 func MonsterAddTest4(builder *flatbuffers.Builder, test4 flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(9, flatbuffers.UOffsetT(test4), 0) }
-func MonsterStartTest4Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
+func MonsterStartTest4Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 2)
+}
 func MonsterAddTestarrayofstring(builder *flatbuffers.Builder, testarrayofstring flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(10, flatbuffers.UOffsetT(testarrayofstring), 0) }
-func MonsterStartTestarrayofstringVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
+func MonsterStartTestarrayofstringVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4)
+}
 func MonsterAddTestarrayoftables(builder *flatbuffers.Builder, testarrayoftables flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(11, flatbuffers.UOffsetT(testarrayoftables), 0) }
-func MonsterStartTestarrayoftablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems) }
+func MonsterStartTestarrayoftablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(4, numElems, 4)
+}
 func MonsterAddEnemy(builder *flatbuffers.Builder, enemy flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(12, flatbuffers.UOffsetT(enemy), 0) }
 func MonsterAddTestnestedflatbuffer(builder *flatbuffers.Builder, testnestedflatbuffer flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(13, flatbuffers.UOffsetT(testnestedflatbuffer), 0) }
-func MonsterStartTestnestedflatbufferVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems) }
+func MonsterStartTestnestedflatbufferVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT { return builder.StartVector(1, numElems, 1)
+}
+func MonsterAddTestempty(builder *flatbuffers.Builder, testempty flatbuffers.UOffsetT) { builder.PrependUOffsetTSlot(14, flatbuffers.UOffsetT(testempty), 0) }
 func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT { return builder.EndObject() }
index 5ca2ef7..313ee64 100644 (file)
@@ -429,7 +429,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
 
        b = flatbuffers.NewBuilder(0)
        check([]byte{})
-       b.StartVector(flatbuffers.SizeByte, 1)
+       b.StartVector(flatbuffers.SizeByte, 1, 1)
        check([]byte{0, 0, 0}) // align to 4bytes
        b.PrependByte(1)
        check([]byte{1, 0, 0, 0})
@@ -439,7 +439,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
        // test 3: 2xbyte vector
 
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeByte, 2)
+       b.StartVector(flatbuffers.SizeByte, 2, 1)
        check([]byte{0, 0}) // align to 4bytes
        b.PrependByte(1)
        check([]byte{1, 0, 0})
@@ -451,7 +451,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
        // test 4: 1xuint16 vector
 
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeUint16, 1)
+       b.StartVector(flatbuffers.SizeUint16, 1, 1)
        check([]byte{0, 0}) // align to 4bytes
        b.PrependUint16(1)
        check([]byte{1, 0, 0, 0})
@@ -461,7 +461,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
        // test 5: 2xuint16 vector
 
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeUint16, 2)
+       b.StartVector(flatbuffers.SizeUint16, 2, 1)
        check([]byte{}) // align to 4bytes
        b.PrependUint16(0xABCD)
        check([]byte{0xCD, 0xAB})
@@ -565,7 +565,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
 
        // test 12: vtable with empty vector
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeByte, 0)
+       b.StartVector(flatbuffers.SizeByte, 0, 1)
        vecend := b.EndVector(0)
        b.StartObject(1)
        b.PrependUOffsetTSlot(0, vecend, 0)
@@ -581,7 +581,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
 
        // test 12b: vtable with empty vector of byte and some scalars
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeByte, 0)
+       b.StartVector(flatbuffers.SizeByte, 0, 1)
        vecend = b.EndVector(0)
        b.StartObject(2)
        b.PrependInt16Slot(0, 55, 0)
@@ -601,7 +601,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
 
        // test 13: vtable with 1 int16 and 2-vector of int16
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeInt16, 2)
+       b.StartVector(flatbuffers.SizeInt16, 2, 1)
        b.PrependInt16(0x1234)
        b.PrependInt16(0x5678)
        vecend = b.EndVector(2)
@@ -649,7 +649,7 @@ func CheckByteLayout(fail func(string, ...interface{})) {
 
        // test 15: vtable with 1 vector of 2 struct of 2 int8
        b = flatbuffers.NewBuilder(0)
-       b.StartVector(flatbuffers.SizeInt8*2, 2)
+       b.StartVector(flatbuffers.SizeInt8*2, 2, 1)
        b.PrependInt8(33)
        b.PrependInt8(44)
        b.PrependInt8(55)
@@ -824,7 +824,7 @@ func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UO
        b := flatbuffers.NewBuilder(0)
        str := b.CreateString("MyMonster")
 
-       b.StartVector(1, 5)
+       b.StartVector(1, 5, 1)
        b.PrependByte(4)
        b.PrependByte(3)
        b.PrependByte(2)
@@ -837,7 +837,7 @@ func CheckManualBuild(fail func(string, ...interface{})) ([]byte, flatbuffers.UO
        mon2 := b.EndObject()
 
        // Test4Vector
-       b.StartVector(4, 2)
+       b.StartVector(4, 2, 1)
 
        // Test 0
        b.Prep(2, 4)