// 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.Rnd(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.Rnd(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,
}
