(T types.Type)
| 17 | } |
| 18 | |
| 19 | func (s *stdSizes) Alignof(T types.Type) int64 { |
| 20 | // For arrays and structs, alignment is defined in terms |
| 21 | // of alignment of the elements and fields, respectively. |
| 22 | switch t := T.Underlying().(type) { |
| 23 | case *types.Array: |
| 24 | // spec: "For a variable x of array type: unsafe.Alignof(x) |
| 25 | // is the same as unsafe.Alignof(x[0]), but at least 1." |
| 26 | return s.Alignof(t.Elem()) |
| 27 | case *types.Struct: |
| 28 | // spec: "For a variable x of struct type: unsafe.Alignof(x) |
| 29 | // is the largest of the values unsafe.Alignof(x.f) for each |
| 30 | // field f of x, but at least 1." |
| 31 | max := int64(1) |
| 32 | for i := 0; i < t.NumFields(); i++ { |
| 33 | f := t.Field(i) |
| 34 | if a := s.Alignof(f.Type()); a > max { |
| 35 | max = a |
| 36 | } |
| 37 | } |
| 38 | return max |
| 39 | case *types.Slice, *types.Interface: |
| 40 | // Multiword data structures are effectively structs |
| 41 | // in which each element has size WordSize. |
| 42 | return s.PtrSize |
| 43 | case *types.Basic: |
| 44 | // Strings are like slices and interfaces. |
| 45 | if t.Info()&types.IsString != 0 { |
| 46 | return s.PtrSize |
| 47 | } |
| 48 | case *types.Signature: |
| 49 | // Even though functions in tinygo are 2 pointers, they are not 2 pointer aligned |
| 50 | return s.PtrSize |
| 51 | } |
| 52 | |
| 53 | a := s.Sizeof(T) // may be 0 |
| 54 | // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1." |
| 55 | if a < 1 { |
| 56 | return 1 |
| 57 | } |
| 58 | // complex{64,128} are aligned like [2]float{32,64}. |
| 59 | if t, ok := T.Underlying().(*types.Basic); ok && t.Info()&types.IsComplex != 0 { |
| 60 | a /= 2 |
| 61 | } |
| 62 | if a > s.MaxAlign { |
| 63 | return s.MaxAlign |
| 64 | } |
| 65 | return a |
| 66 | } |
| 67 | |
| 68 | func (s *stdSizes) Offsetsof(fields []*types.Var) []int64 { |
| 69 | offsets := make([]int64, len(fields)) |
no test coverage detected