runtime: type align (#405)

This commit is contained in:
七叶
2024-06-24 17:15:45 +08:00
committed by GitHub
parent ec1b1ffe16
commit 0b2d6407dd
2 changed files with 70 additions and 45 deletions

View File

@@ -187,10 +187,12 @@ func doInitNamed(ret *Type, pkgPath, fullName string, underlying *Type, methods
func Func(in, out []*Type, variadic bool) *FuncType { func Func(in, out []*Type, variadic bool) *FuncType {
ret := &FuncType{ ret := &FuncType{
Type: Type{ Type: Type{
Size_: unsafe.Sizeof(uintptr(0)), Size_: unsafe.Sizeof(uintptr(0)),
Hash: uint32(abi.Func), // TODO(xsw): hash Hash: uint32(abi.Func), // TODO(xsw): hash
Kind_: uint8(abi.Func), Align_: uint8(pointerAlign),
Str_: "func(...)", FieldAlign_: uint8(pointerAlign),
Kind_: uint8(abi.Func),
Str_: "func(...)",
}, },
In: in, In: in,
Out: out, Out: out,
@@ -206,10 +208,12 @@ func Func(in, out []*Type, variadic bool) *FuncType {
func Interface(pkgPath, name string, methods []Imethod) *InterfaceType { func Interface(pkgPath, name string, methods []Imethod) *InterfaceType {
ret := &abi.InterfaceType{ ret := &abi.InterfaceType{
Type: Type{ Type: Type{
Size_: unsafe.Sizeof(eface{}), Size_: unsafe.Sizeof(eface{}),
Hash: uint32(abi.Interface), // TODO(xsw): hash Hash: uint32(abi.Interface), // TODO(xsw): hash
Kind_: uint8(abi.Interface), Align_: uint8(pointerAlign),
Str_: name, FieldAlign_: uint8(pointerAlign),
Kind_: uint8(abi.Interface),
Str_: name,
}, },
PkgPath_: pkgPath, PkgPath_: pkgPath,
Methods: methods, 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.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64, abi.Uintptr,
abi.Float32, abi.Float64: abi.Float32, abi.Float64:
return *(*uintptr)(v.data) == *(*uintptr)(u.data) return *(*uintptr)(v.data) == *(*uintptr)(u.data)
case abi.Complex64, abi.Complex128: case abi.Complex64:
panic("TODO complex") return *(*complex64)(v.data) == *(*complex64)(u.data)
case abi.Complex128:
return *(*complex128)(v.data) == *(*complex128)(u.data)
case abi.String: case abi.String:
return *(*string)(v.data) == *(*string)(u.data) return *(*string)(v.data) == *(*string)(u.data)
case abi.Pointer, abi.UnsafePointer: case abi.Pointer, abi.UnsafePointer:

View File

@@ -28,53 +28,55 @@ type Type = abi.Type
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
func Basic(kind Kind) *Type { func Basic(kind Kind) *Type {
name, size := basicTypeInfo(kind) name, size, align := basicTypeInfo(kind)
return &Type{ return &Type{
Size_: size, Size_: size,
Hash: uint32(kind), // TODO(xsw): hash Hash: uint32(kind), // TODO(xsw): hash
Kind_: uint8(kind), Align_: uint8(align),
Str_: name, 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 { switch kind {
case abi.Bool: case abi.Bool:
return "bool", unsafe.Sizeof(false) return "bool", unsafe.Sizeof(false), unsafe.Alignof(false)
case abi.Int: case abi.Int:
return "int", unsafe.Sizeof(0) return "int", unsafe.Sizeof(0), unsafe.Alignof(0)
case abi.Int8: case abi.Int8:
return "int8", 1 return "int8", 1, 1
case abi.Int16: case abi.Int16:
return "int16", 2 return "int16", 2, 2
case abi.Int32: case abi.Int32:
return "int32", 4 return "int32", 4, 4
case abi.Int64: case abi.Int64:
return "int64", 8 return "int64", 8, 8
case abi.Uint: case abi.Uint:
return "uint", unsafe.Sizeof(uint(0)) return "uint", unsafe.Sizeof(uint(0)), unsafe.Alignof(uint(0))
case abi.Uint8: case abi.Uint8:
return "uint8", 1 return "uint8", 1, 1
case abi.Uint16: case abi.Uint16:
return "uint16", 2 return "uint16", 2, 2
case abi.Uint32: case abi.Uint32:
return "uint32", 4 return "uint32", 4, 4
case abi.Uint64: case abi.Uint64:
return "uint64", 8 return "uint64", 8, 8
case abi.Uintptr: case abi.Uintptr:
return "uintptr", unsafe.Sizeof(uintptr(0)) return "uintptr", unsafe.Sizeof(uintptr(0)), unsafe.Alignof(uintptr(0))
case abi.Float32: case abi.Float32:
return "float32", 4 return "float32", 4, 4
case abi.Float64: case abi.Float64:
return "float64", 8 return "float64", 8, 8
case abi.Complex64: case abi.Complex64:
return "complex64", 8 return "complex64", 8, 4
case abi.Complex128: case abi.Complex128:
return "complex128", 16 return "complex128", 16, 8
case abi.String: case abi.String:
return "string", unsafe.Sizeof(String{}) return "string", unsafe.Sizeof(String{}), unsafe.Alignof("")
case abi.UnsafePointer: 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") panic("unreachable")
} }
@@ -104,6 +106,15 @@ func Struct(pkgPath string, size uintptr, fields ...abi.StructField) *Type {
PkgPath_: pkgPath, PkgPath_: pkgPath,
Fields: fields, 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 return &ret.Type
} }
@@ -119,12 +130,16 @@ func PointerTo(elem *Type) *Type {
return ret return ret
} }
const pointerAlign = uint8(unsafe.Alignof(uintptr(0)))
func newPointer(elem *Type) *Type { func newPointer(elem *Type) *Type {
ptr := &abi.PtrType{ ptr := &abi.PtrType{
Type: Type{ Type: Type{
Size_: unsafe.Sizeof(uintptr(0)), Size_: unsafe.Sizeof(uintptr(0)),
Hash: uint32(abi.Pointer), // TODO(xsw): hash Hash: uint32(abi.Pointer), // TODO(xsw): hash
Kind_: uint8(abi.Pointer), Align_: pointerAlign,
FieldAlign_: pointerAlign,
Kind_: uint8(abi.Pointer),
}, },
Elem: elem, Elem: elem,
} }
@@ -141,10 +156,12 @@ func newPointer(elem *Type) *Type {
func SliceOf(elem *Type) *Type { func SliceOf(elem *Type) *Type {
ret := &abi.SliceType{ ret := &abi.SliceType{
Type: Type{ Type: Type{
Size_: unsafe.Sizeof([]int{}), Size_: unsafe.Sizeof([]int{}),
Hash: uint32(abi.Slice), Hash: uint32(abi.Slice),
Kind_: uint8(abi.Slice), Align_: pointerAlign,
Str_: "[]" + elem.String(), FieldAlign_: pointerAlign,
Kind_: uint8(abi.Slice),
Str_: "[]" + elem.String(),
}, },
Elem: elem, Elem: elem,
} }
@@ -155,10 +172,12 @@ func SliceOf(elem *Type) *Type {
func ArrayOf(length uintptr, elem *Type) *Type { func ArrayOf(length uintptr, elem *Type) *Type {
ret := &abi.ArrayType{ ret := &abi.ArrayType{
Type: Type{ Type: Type{
Size_: length * elem.Size_, Size_: length * elem.Size_,
Hash: uint32(abi.Array), Hash: uint32(abi.Array),
Kind_: uint8(abi.Array), Align_: elem.Align_,
Str_: "[...]" + elem.String(), // TODO(xsw): itoa FieldAlign_: elem.FieldAlign_,
Kind_: uint8(abi.Array),
Str_: "[...]" + elem.String(), // TODO(xsw): itoa
}, },
Elem: elem, Elem: elem,
Slice: SliceOf(elem), Slice: SliceOf(elem),