fix signature size/alignment computation

This commit is contained in:
Michael McLoughlin
2018-12-19 13:08:56 -08:00
parent 33f5561d91
commit 48a84b6b13
3 changed files with 42 additions and 16 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)
}
}
}