}
type funcLayoutTest struct {
- rcvr, t Type
- argsize, retOffset uintptr
- stack []byte
+ rcvr, t Type
+ size, argsize, retOffset uintptr
+ stack []byte
+ gc []byte
}
var funcLayoutTests []funcLayoutTest
funcLayoutTest{
nil,
ValueOf(func(a, b string) string { return "" }).Type(),
+ 6 * PtrSize,
4 * PtrSize,
4 * PtrSize,
[]byte{BitsPointer, BitsScalar, BitsPointer},
+ []byte{BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar},
})
- var r []byte
+ var r, s []byte
if PtrSize == 4 {
r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer}
+ s = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer, BitsScalar}
} else {
r = []byte{BitsScalar, BitsScalar, BitsPointer}
+ s = []byte{BitsScalar, BitsScalar, BitsPointer, BitsScalar}
}
funcLayoutTests = append(funcLayoutTests,
funcLayoutTest{
nil,
ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
+ roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
roundup(3*4, PtrSize) + PtrSize + 2,
roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
r,
+ s,
})
funcLayoutTests = append(funcLayoutTests,
ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
4 * PtrSize,
4 * PtrSize,
+ 4 * PtrSize,
+ []byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
[]byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
})
ValueOf(func(a S) {}).Type(),
4 * PtrSize,
4 * PtrSize,
+ 4 * PtrSize,
+ []byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
[]byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
})
funcLayoutTest{
ValueOf((*byte)(nil)).Type(),
ValueOf(func(a uintptr, b *int) {}).Type(),
+ roundup(3*PtrSize, argAlign),
3 * PtrSize,
roundup(3*PtrSize, argAlign),
[]byte{BitsPointer, BitsScalar, BitsPointer},
+ []byte{BitsPointer, BitsScalar, BitsPointer},
+ })
+
+ funcLayoutTests = append(funcLayoutTests,
+ funcLayoutTest{
+ nil,
+ ValueOf(func(a uintptr){}).Type(),
+ PtrSize,
+ PtrSize,
+ PtrSize,
+ []byte{},
+ []byte{BitsScalar},
+ })
+
+ funcLayoutTests = append(funcLayoutTests,
+ funcLayoutTest{
+ nil,
+ ValueOf(func() uintptr{return 0}).Type(),
+ PtrSize,
+ 0,
+ 0,
+ []byte{},
+ []byte{BitsScalar},
+ })
+
+ funcLayoutTests = append(funcLayoutTests,
+ funcLayoutTest{
+ ValueOf(uintptr(0)).Type(),
+ ValueOf(func(a uintptr){}).Type(),
+ 2*PtrSize,
+ 2*PtrSize,
+ 2*PtrSize,
+ []byte{BitsPointer},
+ []byte{BitsPointer, BitsScalar},
+ // Note: this one is tricky, as the receiver is not a pointer. But we
+ // pass the receiver by reference to the autogenerated pointer-receiver
+ // version of the function.
})
}
func TestFuncLayout(t *testing.T) {
for _, lt := range funcLayoutTests {
- _, argsize, retOffset, stack := FuncLayout(lt.t, lt.rcvr)
+ typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr)
+ if typ.Size() != lt.size {
+ t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size)
+ }
if argsize != lt.argsize {
t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
}
if !bytes.Equal(stack, lt.stack) {
t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
}
+ if !bytes.Equal(gc, lt.gc) {
+ t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc)
+ }
+ if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
+ t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs)
+ }
}
}