diff --git a/internal/runtime/z_face.go b/internal/runtime/z_face.go index 71ad7889..74719a9f 100644 --- a/internal/runtime/z_face.go +++ b/internal/runtime/z_face.go @@ -187,10 +187,12 @@ func doInitNamed(ret *Type, pkgPath, fullName string, underlying *Type, methods func Func(in, out []*Type, variadic bool) *FuncType { ret := &FuncType{ Type: Type{ - Size_: unsafe.Sizeof(uintptr(0)), - Hash: uint32(abi.Func), // TODO(xsw): hash - Kind_: uint8(abi.Func), - Str_: "func(...)", + Size_: unsafe.Sizeof(uintptr(0)), + Hash: uint32(abi.Func), // TODO(xsw): hash + Align_: uint8(pointerAlign), + FieldAlign_: uint8(pointerAlign), + Kind_: uint8(abi.Func), + Str_: "func(...)", }, In: in, Out: out, @@ -206,10 +208,12 @@ func Func(in, out []*Type, variadic bool) *FuncType { func Interface(pkgPath, name string, methods []Imethod) *InterfaceType { ret := &abi.InterfaceType{ Type: Type{ - Size_: unsafe.Sizeof(eface{}), - Hash: uint32(abi.Interface), // TODO(xsw): hash - Kind_: uint8(abi.Interface), - Str_: name, + Size_: unsafe.Sizeof(eface{}), + Hash: uint32(abi.Interface), // TODO(xsw): hash + Align_: uint8(pointerAlign), + FieldAlign_: uint8(pointerAlign), + Kind_: uint8(abi.Interface), + Str_: name, }, PkgPath_: pkgPath, Methods: methods, @@ -368,8 +372,10 @@ func EfaceEqual(v, u eface) bool { abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64, abi.Uintptr, abi.Float32, abi.Float64: return *(*uintptr)(v.data) == *(*uintptr)(u.data) - case abi.Complex64, abi.Complex128: - panic("TODO complex") + case abi.Complex64: + return *(*complex64)(v.data) == *(*complex64)(u.data) + case abi.Complex128: + return *(*complex128)(v.data) == *(*complex128)(u.data) case abi.String: return *(*string)(v.data) == *(*string)(u.data) case abi.Pointer, abi.UnsafePointer: diff --git a/internal/runtime/z_type.go b/internal/runtime/z_type.go index b6f1893a..9b590c25 100644 --- a/internal/runtime/z_type.go +++ b/internal/runtime/z_type.go @@ -28,53 +28,55 @@ type Type = abi.Type // ----------------------------------------------------------------------------- func Basic(kind Kind) *Type { - name, size := basicTypeInfo(kind) + name, size, align := basicTypeInfo(kind) return &Type{ - Size_: size, - Hash: uint32(kind), // TODO(xsw): hash - Kind_: uint8(kind), - Str_: name, + Size_: size, + Hash: uint32(kind), // TODO(xsw): hash + Align_: uint8(align), + FieldAlign_: uint8(align), + Kind_: uint8(kind), + Str_: name, } } -func basicTypeInfo(kind abi.Kind) (string, uintptr) { +func basicTypeInfo(kind abi.Kind) (string, uintptr, uintptr) { switch kind { case abi.Bool: - return "bool", unsafe.Sizeof(false) + return "bool", unsafe.Sizeof(false), unsafe.Alignof(false) case abi.Int: - return "int", unsafe.Sizeof(0) + return "int", unsafe.Sizeof(0), unsafe.Alignof(0) case abi.Int8: - return "int8", 1 + return "int8", 1, 1 case abi.Int16: - return "int16", 2 + return "int16", 2, 2 case abi.Int32: - return "int32", 4 + return "int32", 4, 4 case abi.Int64: - return "int64", 8 + return "int64", 8, 8 case abi.Uint: - return "uint", unsafe.Sizeof(uint(0)) + return "uint", unsafe.Sizeof(uint(0)), unsafe.Alignof(uint(0)) case abi.Uint8: - return "uint8", 1 + return "uint8", 1, 1 case abi.Uint16: - return "uint16", 2 + return "uint16", 2, 2 case abi.Uint32: - return "uint32", 4 + return "uint32", 4, 4 case abi.Uint64: - return "uint64", 8 + return "uint64", 8, 8 case abi.Uintptr: - return "uintptr", unsafe.Sizeof(uintptr(0)) + return "uintptr", unsafe.Sizeof(uintptr(0)), unsafe.Alignof(uintptr(0)) case abi.Float32: - return "float32", 4 + return "float32", 4, 4 case abi.Float64: - return "float64", 8 + return "float64", 8, 8 case abi.Complex64: - return "complex64", 8 + return "complex64", 8, 4 case abi.Complex128: - return "complex128", 16 + return "complex128", 16, 8 case abi.String: - return "string", unsafe.Sizeof(String{}) + return "string", unsafe.Sizeof(String{}), unsafe.Alignof("") case abi.UnsafePointer: - return "unsafe.Pointer", unsafe.Sizeof(unsafe.Pointer(nil)) + return "unsafe.Pointer", unsafe.Sizeof(unsafe.Pointer(nil)), unsafe.Alignof(unsafe.Pointer(nil)) } panic("unreachable") } @@ -104,6 +106,15 @@ func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type { PkgPath_: pkgPath, Fields: fields, } + var typalign uint8 + for _, f := range fields { + ft := f.Typ + if ft.Align_ > typalign { + typalign = ft.Align_ + } + } + ret.Align_ = typalign + ret.FieldAlign_ = typalign return &ret.Type } @@ -119,12 +130,16 @@ func PointerTo(elem *Type) *Type { return ret } +const pointerAlign = uint8(unsafe.Alignof(uintptr(0))) + func newPointer(elem *Type) *Type { ptr := &abi.PtrType{ Type: Type{ - Size_: unsafe.Sizeof(uintptr(0)), - Hash: uint32(abi.Pointer), // TODO(xsw): hash - Kind_: uint8(abi.Pointer), + Size_: unsafe.Sizeof(uintptr(0)), + Hash: uint32(abi.Pointer), // TODO(xsw): hash + Align_: pointerAlign, + FieldAlign_: pointerAlign, + Kind_: uint8(abi.Pointer), }, Elem: elem, } @@ -141,10 +156,12 @@ func newPointer(elem *Type) *Type { func SliceOf(elem *Type) *Type { ret := &abi.SliceType{ Type: Type{ - Size_: unsafe.Sizeof([]int{}), - Hash: uint32(abi.Slice), - Kind_: uint8(abi.Slice), - Str_: "[]" + elem.String(), + Size_: unsafe.Sizeof([]int{}), + Hash: uint32(abi.Slice), + Align_: pointerAlign, + FieldAlign_: pointerAlign, + Kind_: uint8(abi.Slice), + Str_: "[]" + elem.String(), }, Elem: elem, } @@ -155,10 +172,12 @@ func SliceOf(elem *Type) *Type { func ArrayOf(length uintptr, elem *Type) *Type { ret := &abi.ArrayType{ Type: Type{ - Size_: length * elem.Size_, - Hash: uint32(abi.Array), - Kind_: uint8(abi.Array), - Str_: "[...]" + elem.String(), // TODO(xsw): itoa + Size_: length * elem.Size_, + Hash: uint32(abi.Array), + Align_: elem.Align_, + FieldAlign_: elem.FieldAlign_, + Kind_: uint8(abi.Array), + Str_: "[...]" + elem.String(), // TODO(xsw): itoa }, Elem: elem, Slice: SliceOf(elem),