// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package noder

import (
	"fmt"

	"cmd/compile/internal/types"
	"cmd/compile/internal/types2"
)

// Code below based on go/types.StdSizes.
// Intentional differences are marked with "gc:".

type gcSizes struct{}

func (s *gcSizes) Alignof(T types2.Type) int64 {
	// For arrays and structs, alignment is defined in terms
	// of alignment of the elements and fields, respectively.
	switch t := T.Underlying().(type) {
	case *types2.Array:
		// spec: "For a variable x of array type: unsafe.Alignof(x)
		// is the same as unsafe.Alignof(x[0]), but at least 1."
		return s.Alignof(t.Elem())
	case *types2.Struct:
		if t.NumFields() == 0 && types2.IsSyncAtomicAlign64(T) {
			// Special case: sync/atomic.align64 is an
			// empty struct we recognize as a signal that
			// the struct it contains must be
			// 64-bit-aligned.
			//
			// This logic is equivalent to the logic in
			// cmd/compile/internal/types/size.go:calcStructOffset
			return 8
		}

		// spec: "For a variable x of struct type: unsafe.Alignof(x)
		// is the largest of the values unsafe.Alignof(x.f) for each
		// field f of x, but at least 1."
		max := int64(1)
		for i, nf := 0, t.NumFields(); i < nf; i++ {
			if a := s.Alignof(t.Field(i).Type()); a > max {
				max = a
			}
		}
		return max
	case *types2.Slice, *types2.Interface:
		// Multiword data structures are effectively structs
		// in which each element has size PtrSize.
		return int64(types.PtrSize)
	case *types2.Basic:
		// Strings are like slices and interfaces.
		if t.Info()&types2.IsString != 0 {
			return int64(types.PtrSize)
		}
	}
	a := s.Sizeof(T) // may be 0
	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
	if a < 1 {
		return 1
	}
	// complex{64,128} are aligned like [2]float{32,64}.
	if isComplex(T) {
		a /= 2
	}
	if a > int64(types.RegSize) {
		return int64(types.RegSize)
	}
	return a
}

func isComplex(T types2.Type) bool {
	basic, ok := T.Underlying().(*types2.Basic)
	return ok && basic.Info()&types2.IsComplex != 0
}

func (s *gcSizes) Offsetsof(fields []*types2.Var) []int64 {
	offsets := make([]int64, len(fields))
	var o int64
	for i, f := range fields {
		typ := f.Type()
		a := s.Alignof(typ)
		o = types.RoundUp(o, a)
		offsets[i] = o
		o += s.Sizeof(typ)
	}
	return offsets
}

func (s *gcSizes) Sizeof(T types2.Type) int64 {
	switch t := T.Underlying().(type) {
	case *types2.Basic:
		k := t.Kind()
		if int(k) < len(basicSizes) {
			if s := basicSizes[k]; s > 0 {
				return int64(s)
			}
		}
		switch k {
		case types2.String:
			return int64(types.PtrSize) * 2
		case types2.Int, types2.Uint, types2.Uintptr, types2.UnsafePointer:
			return int64(types.PtrSize)
		}
		panic(fmt.Sprintf("unimplemented basic: %v (kind %v)", T, k))
	case *types2.Array:
		n := t.Len()
		if n <= 0 {
			return 0
		}
		// n > 0
		// gc: Size includes alignment padding.
		return s.Sizeof(t.Elem()) * n
	case *types2.Slice:
		return int64(types.PtrSize) * 3
	case *types2.Struct:
		n := t.NumFields()
		if n == 0 {
			return 0
		}
		fields := make([]*types2.Var, n)
		for i := range fields {
			fields[i] = t.Field(i)
		}
		offsets := s.Offsetsof(fields)

		// gc: The last field of a non-zero-sized struct is not allowed to
		// have size 0.
		last := s.Sizeof(fields[n-1].Type())
		if last == 0 && offsets[n-1] > 0 {
			last = 1
		}

		// gc: Size includes alignment padding.
		return types.RoundUp(offsets[n-1]+last, s.Alignof(t))
	case *types2.Interface:
		return int64(types.PtrSize) * 2
	case *types2.Chan, *types2.Map, *types2.Pointer, *types2.Signature:
		return int64(types.PtrSize)
	default:
		panic(fmt.Sprintf("unimplemented type: %T", t))
	}
}

var basicSizes = [...]byte{
	types2.Invalid:    1,
	types2.Bool:       1,
	types2.Int8:       1,
	types2.Int16:      2,
	types2.Int32:      4,
	types2.Int64:      8,
	types2.Uint8:      1,
	types2.Uint16:     2,
	types2.Uint32:     4,
	types2.Uint64:     8,
	types2.Float32:    4,
	types2.Float64:    8,
	types2.Complex64:  8,
	types2.Complex128: 16,
}
