diff --git a/examples/components/components.s b/examples/components/components.s index 80e4d6c..ec1c3dc 100644 --- a/examples/components/components.s +++ b/examples/components/components.s @@ -27,25 +27,25 @@ TEXT ·ArrayThree(SB),0,$0-64 RET // func FieldByte(s Struct) byte -TEXT ·FieldByte(SB),0,$0-184 +TEXT ·FieldByte(SB),0,$0-177 MOVB s_Byte(FP), AL MOVB AL, ret+176(FP) RET // func FieldInt8(s Struct) int8 -TEXT ·FieldInt8(SB),0,$0-184 +TEXT ·FieldInt8(SB),0,$0-177 MOVB s_Int8+1(FP), AL MOVB AL, ret+176(FP) RET // func FieldUint16(s Struct) uint16 -TEXT ·FieldUint16(SB),0,$0-184 +TEXT ·FieldUint16(SB),0,$0-178 MOVW s_Uint16+2(FP), AX MOVW AX, ret+176(FP) RET // func FieldInt32(s Struct) int32 -TEXT ·FieldInt32(SB),0,$0-184 +TEXT ·FieldInt32(SB),0,$0-180 MOVL s_Int32+4(FP), AX MOVL AX, ret+176(FP) RET @@ -57,7 +57,7 @@ TEXT ·FieldUint64(SB),0,$0-184 RET // func FieldFloat32(s Struct) float32 -TEXT ·FieldFloat32(SB),0,$0-184 +TEXT ·FieldFloat32(SB),0,$0-180 MOVSS s_Float32+16(FP), X0 MOVSS X0, ret+176(FP) RET @@ -81,19 +81,19 @@ TEXT ·FieldSliceCap(SB),0,$0-184 RET // func FieldArrayTwoBTwo(s Struct) byte -TEXT ·FieldArrayTwoBTwo(SB),0,$0-184 +TEXT ·FieldArrayTwoBTwo(SB),0,$0-177 MOVB s_Array_2_B_2+114(FP), AL MOVB AL, ret+176(FP) RET // func FieldArrayOneC(s Struct) uint16 -TEXT ·FieldArrayOneC(SB),0,$0-184 +TEXT ·FieldArrayOneC(SB),0,$0-178 MOVW s_Array_1_C+100(FP), AX MOVW AX, ret+176(FP) RET // func FieldComplex64Imag(s Struct) float32 -TEXT ·FieldComplex64Imag(SB),0,$0-184 +TEXT ·FieldComplex64Imag(SB),0,$0-180 MOVSS s_Complex64_imag+156(FP), X0 MOVSS X0, ret+176(FP) RET diff --git a/gotypes/signature.go b/gotypes/signature.go index 692b205..555c4ff 100644 --- a/gotypes/signature.go +++ b/gotypes/signature.go @@ -64,15 +64,21 @@ func (s *Signature) init() { p := s.sig.Params() r := s.sig.Results() - // Compute offsets of parameters and return values. + // Compute parameter offsets. vs := tuplevars(p) - vs = append(vs, tuplevars(r)...) vs = append(vs, types.NewParam(token.NoPos, nil, "sentinel", types.Typ[types.Uint64])) - offsets := Sizes.Offsetsof(vs) + paramsoffsets := Sizes.Offsetsof(vs) + paramssize := paramsoffsets[p.Len()] + s.params = newTuple(p, paramsoffsets, paramssize, "arg") - // Build components for them. - s.params = newTuple(p, offsets, "arg") - s.results = newTuple(r, offsets[p.Len():], "ret") + // Result offsets. + vs = tuplevars(r) + resultsoffsets := Sizes.Offsetsof(vs) + for i := range resultsoffsets { + resultsoffsets[i] += paramssize + } + resultssize := Sizes.Sizeof(types.NewStruct(vs, nil)) + s.results = newTuple(r, resultsoffsets, resultssize, "ret") } type Tuple struct { @@ -81,10 +87,10 @@ type Tuple struct { size int } -func newTuple(t *types.Tuple, offsets []int64, defaultprefix string) *Tuple { +func newTuple(t *types.Tuple, offsets []int64, size int64, defaultprefix string) *Tuple { tuple := &Tuple{ byname: map[string]Component{}, - size: int(offsets[t.Len()] - offsets[0]), + size: int(size), } for i := 0; i < t.Len(); i++ { v := t.At(i) diff --git a/gotypes/signature_test.go b/gotypes/signature_test.go index 42f560b..eeec311 100644 --- a/gotypes/signature_test.go +++ b/gotypes/signature_test.go @@ -93,3 +93,23 @@ func TypesTuplesEqual(a, b *types.Tuple) bool { func TypesVarsEqual(a, b *types.Var) bool { return a.Name() == b.Name() && types.Identical(a.Type(), b.Type()) } + +func TestSignatureSizes(t *testing.T) { + cases := []struct { + Expr string + ArgSize int + }{ + {"func()", 0}, + {"func(uint64) uint64", 16}, + {"func([7]byte) byte", 9}, + } + for _, c := range cases { + s, err := ParseSignature(c.Expr) + if err != nil { + t.Fatal(err) + } + if s.Bytes() != c.ArgSize { + t.Errorf("%s: size %d expected %d", s, s.Bytes(), c.ArgSize) + } + } +}