gotypes: support struct fields

This commit is contained in:
Michael McLoughlin
2018-12-17 23:28:31 -08:00
parent 7f3efa1eb5
commit bc9a2aa46b
6 changed files with 210 additions and 28 deletions

View File

@@ -9,12 +9,69 @@ import (
func main() {
Package("github.com/mmcloughlin/avo/examples/components")
// Add confirms that we correctly deduce the packing of Struct.
TEXT("Add", "func(x uint64, s Struct, y uint64) uint64")
x := Load(Param("x"), GP64v())
y := Load(Param("y"), GP64v())
ADDQ(x, y)
Store(y, ReturnIndex(0))
TEXT("FieldByte", "func(s Struct) byte")
b := Load(Param("s").Field("Byte"), GP8v())
Store(b, ReturnIndex(0))
RET()
TEXT("FieldInt8", "func(s Struct) int8")
i8 := Load(Param("s").Field("Int8"), GP8v())
Store(i8, ReturnIndex(0))
RET()
TEXT("FieldUint16", "func(s Struct) uint16")
u16 := Load(Param("s").Field("Uint16"), GP16v())
Store(u16, ReturnIndex(0))
RET()
TEXT("FieldInt32", "func(s Struct) int32")
i32 := Load(Param("s").Field("Int32"), GP32v())
Store(i32, ReturnIndex(0))
RET()
TEXT("FieldUint64", "func(s Struct) uint64")
u64 := Load(Param("s").Field("Uint64"), GP64v())
Store(u64, ReturnIndex(0))
RET()
TEXT("FieldFloat32", "func(s Struct) float32")
f32 := Load(Param("s").Field("Float32"), Xv())
Store(f32, ReturnIndex(0))
RET()
TEXT("FieldFloat64", "func(s Struct) float64")
f64 := Load(Param("s").Field("Float64"), Xv())
Store(f64, ReturnIndex(0))
RET()
TEXT("FieldStringLen", "func(s Struct) int")
l := Load(Param("s").Field("String").Len(), GP64v())
Store(l, ReturnIndex(0))
RET()
TEXT("FieldSliceCap", "func(s Struct) int")
c := Load(Param("s").Field("Slice").Cap(), GP64v())
Store(c, ReturnIndex(0))
RET()
TEXT("FieldArrayTwoBTwo", "func(s Struct) byte")
b2 := Load(Param("s").Field("Array").Index(2).Field("B").Index(2), GP8v())
Store(b2, ReturnIndex(0))
RET()
TEXT("FieldArrayOneC", "func(s Struct) uint16")
c1 := Load(Param("s").Field("Array").Index(1).Field("C"), GP16v())
Store(c1, ReturnIndex(0))
RET()
TEXT("FieldComplex64Imag", "func(s Struct) float32")
c64i := Load(Param("s").Field("Complex64").Imag(), Xv())
Store(c64i, ReturnIndex(0))
RET()
TEXT("FieldComplex128Real", "func(s Struct) float64")
c128r := Load(Param("s").Field("Complex128").Real(), Xv())
Store(c128r, ReturnIndex(0))
RET()
Generate()

View File

@@ -2,7 +2,9 @@ package components
type Struct struct {
Byte byte
Uint32 uint32
Int8 int8
Uint16 uint16
Int32 int32
Uint64 uint64
Float32 float32
Float64 float64

View File

@@ -1,10 +1,68 @@
#include "textflag.h"
// func Add(x uint64, s Struct, y uint64) uint64
TEXT ·Add(SB),0,$0-200
MOVQ x(FP), AX
MOVQ y+184(FP), CX
ADDQ AX, CX
MOVQ CX, ret+192(FP)
// func FieldByte(s Struct) byte
TEXT ·FieldByte(SB),0,$0-184
MOVB s_Byte(FP), AL
MOVB AL, ret+176(FP)
RET
// func FieldInt8(s Struct) int8
TEXT ·FieldInt8(SB),0,$0-184
MOVB s_Int8+1(FP), AL
MOVB AL, ret+176(FP)
RET
// func FieldUint16(s Struct) uint16
TEXT ·FieldUint16(SB),0,$0-184
MOVW s_Uint16+2(FP), AX
MOVW AX, ret+176(FP)
RET
// func FieldInt32(s Struct) int32
TEXT ·FieldInt32(SB),0,$0-184
MOVL s_Int32+4(FP), AX
MOVL AX, ret+176(FP)
RET
// func FieldUint64(s Struct) uint64
TEXT ·FieldUint64(SB),0,$0-184
MOVQ s_Uint64+8(FP), AX
MOVQ AX, ret+176(FP)
RET
// func FieldFloat32(s Struct) float32
TEXT ·FieldFloat32(SB),0,$0-184
MOVSS s_Float32+16(FP), X0
MOVSS X0, ret+176(FP)
RET
// func FieldFloat64(s Struct) float64
TEXT ·FieldFloat64(SB),0,$0-184
MOVSD s_Float64+24(FP), X0
MOVSD X0, ret+176(FP)
RET
// func FieldStringLen(s Struct) int
TEXT ·FieldStringLen(SB),0,$0-184
MOVQ s_String_len+40(FP), AX
MOVQ AX, ret+176(FP)
RET
// func FieldSliceCap(s Struct) int
TEXT ·FieldSliceCap(SB),0,$0-184
MOVQ s_Slice_cap+64(FP), AX
MOVQ AX, ret+176(FP)
RET
// func FieldArrayTwoBTwo(s Struct) byte
TEXT ·FieldArrayTwoBTwo(SB),0,$0-184
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
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
MOVSS s_Complex64_imag+156(FP), X0
MOVSS X0, ret+176(FP)
RET
// func FieldComplex128Real(s Struct) float64
TEXT ·FieldComplex128Real(SB),0,$0-184
MOVSD s_Complex128_real+160(FP), X0
MOVSD X0, ret+176(FP)
RET

View File

@@ -7,9 +7,27 @@ import (
//go:generate go run asm.go -out components.s -stubs stub.go
func TestAdd(t *testing.T) {
expect := func(x uint64, s Struct, y uint64) uint64 { return x + y }
if err := quick.CheckEqual(Add, expect, nil); err != nil {
t.Fatal(err)
func TestFunctionsEqual(t *testing.T) {
cases := []struct {
f, g interface{}
}{
{FieldByte, func(s Struct) byte { return s.Byte }},
{FieldInt8, func(s Struct) int8 { return s.Int8 }},
{FieldUint16, func(s Struct) uint16 { return s.Uint16 }},
{FieldInt32, func(s Struct) int32 { return s.Int32 }},
{FieldUint64, func(s Struct) uint64 { return s.Uint64 }},
{FieldFloat32, func(s Struct) float32 { return s.Float32 }},
{FieldFloat64, func(s Struct) float64 { return s.Float64 }},
{FieldStringLen, func(s Struct) int { return len(s.String) }},
{FieldSliceCap, func(s Struct) int { return cap(s.Slice) }},
{FieldArrayTwoBTwo, func(s Struct) byte { return s.Array[2].B[2] }},
{FieldArrayOneC, func(s Struct) uint16 { return s.Array[1].C }},
{FieldComplex64Imag, func(s Struct) float32 { return imag(s.Complex64) }},
{FieldComplex128Real, func(s Struct) float64 { return real(s.Complex128) }},
}
for _, c := range cases {
if err := quick.CheckEqual(c.f, c.g, nil); err != nil {
t.Fatal(err)
}
}
}

View File

@@ -1,3 +1,15 @@
package components
func Add(x uint64, s Struct, y uint64) uint64
func FieldByte(s Struct) byte
func FieldInt8(s Struct) int8
func FieldUint16(s Struct) uint16
func FieldInt32(s Struct) int32
func FieldUint64(s Struct) uint64
func FieldFloat32(s Struct) float32
func FieldFloat64(s Struct) float64
func FieldStringLen(s Struct) int
func FieldSliceCap(s Struct) int
func FieldArrayTwoBTwo(s Struct) byte
func FieldArrayOneC(s Struct) uint16
func FieldComplex64Imag(s Struct) float32
func FieldComplex128Real(s Struct) float64