// Copyright 2023 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 rttype allows the compiler to share type information with
// the runtime. The shared type information is stored in
// internal/abi. This package translates those types from the host
// machine on which the compiler runs to the target machine on which
// the compiled program will run. In particular, this package handles
// layout differences between e.g. a 64 bit compiler and 32 bit
// target.
package rttype

import (
	"cmd/compile/internal/base"
	"cmd/compile/internal/objw"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"internal/abi"
	"reflect"
)

// The type structures shared with the runtime.
var Type *types.Type

var ArrayType *types.Type
var ChanType *types.Type
var FuncType *types.Type
var InterfaceType *types.Type
var MapType *types.Type
var PtrType *types.Type
var SliceType *types.Type
var StructType *types.Type

// Types that are parts of the types above.
var IMethod *types.Type
var Method *types.Type
var StructField *types.Type
var UncommonType *types.Type

// Type switches and asserts
var InterfaceSwitch *types.Type
var TypeAssert *types.Type

func Init() {
	// Note: this has to be called explicitly instead of being
	// an init function so it runs after the types package has
	// been properly initialized.
	Type = fromReflect(reflect.TypeOf(abi.Type{}))
	ArrayType = fromReflect(reflect.TypeOf(abi.ArrayType{}))
	ChanType = fromReflect(reflect.TypeOf(abi.ChanType{}))
	FuncType = fromReflect(reflect.TypeOf(abi.FuncType{}))
	InterfaceType = fromReflect(reflect.TypeOf(abi.InterfaceType{}))
	MapType = fromReflect(reflect.TypeOf(abi.MapType{}))
	PtrType = fromReflect(reflect.TypeOf(abi.PtrType{}))
	SliceType = fromReflect(reflect.TypeOf(abi.SliceType{}))
	StructType = fromReflect(reflect.TypeOf(abi.StructType{}))

	IMethod = fromReflect(reflect.TypeOf(abi.Imethod{}))
	Method = fromReflect(reflect.TypeOf(abi.Method{}))
	StructField = fromReflect(reflect.TypeOf(abi.StructField{}))
	UncommonType = fromReflect(reflect.TypeOf(abi.UncommonType{}))

	InterfaceSwitch = fromReflect(reflect.TypeOf(abi.InterfaceSwitch{}))
	TypeAssert = fromReflect(reflect.TypeOf(abi.TypeAssert{}))

	// Make sure abi functions are correct. These functions are used
	// by the linker which doesn't have the ability to do type layout,
	// so we check the functions it uses here.
	ptrSize := types.PtrSize
	if got, want := int64(abi.CommonSize(ptrSize)), Type.Size(); got != want {
		base.Fatalf("abi.CommonSize() == %d, want %d", got, want)
	}
	if got, want := int64(abi.StructFieldSize(ptrSize)), StructField.Size(); got != want {
		base.Fatalf("abi.StructFieldSize() == %d, want %d", got, want)
	}
	if got, want := int64(abi.UncommonSize()), UncommonType.Size(); got != want {
		base.Fatalf("abi.UncommonSize() == %d, want %d", got, want)
	}
	if got, want := int64(abi.TFlagOff(ptrSize)), Type.OffsetOf("TFlag"); got != want {
		base.Fatalf("abi.TFlagOff() == %d, want %d", got, want)
	}
}

// fromReflect translates from a host type to the equivalent target type.
func fromReflect(rt reflect.Type) *types.Type {
	t := reflectToType(rt)
	types.CalcSize(t)
	return t
}

// reflectToType converts from a reflect.Type (which is a compiler
// host type) to a *types.Type, which is a target type.  The result
// must be CalcSize'd before using.
func reflectToType(rt reflect.Type) *types.Type {
	switch rt.Kind() {
	case reflect.Bool:
		return types.Types[types.TBOOL]
	case reflect.Int:
		return types.Types[types.TINT]
	case reflect.Int32:
		return types.Types[types.TINT32]
	case reflect.Uint8:
		return types.Types[types.TUINT8]
	case reflect.Uint16:
		return types.Types[types.TUINT16]
	case reflect.Uint32:
		return types.Types[types.TUINT32]
	case reflect.Uintptr:
		return types.Types[types.TUINTPTR]
	case reflect.Ptr, reflect.Func, reflect.UnsafePointer:
		// TODO: there's no mechanism to distinguish different pointer types,
		// so we treat them all as unsafe.Pointer.
		return types.Types[types.TUNSAFEPTR]
	case reflect.Slice:
		return types.NewSlice(reflectToType(rt.Elem()))
	case reflect.Array:
		return types.NewArray(reflectToType(rt.Elem()), int64(rt.Len()))
	case reflect.Struct:
		fields := make([]*types.Field, rt.NumField())
		for i := 0; i < rt.NumField(); i++ {
			f := rt.Field(i)
			ft := reflectToType(f.Type)
			fields[i] = &types.Field{Sym: &types.Sym{Name: f.Name}, Type: ft}
		}
		return types.NewStruct(fields)
	default:
		base.Fatalf("unhandled kind %s", rt.Kind())
		return nil
	}
}

// A Cursor represents a typed location inside a static variable where we
// are going to write.
type Cursor struct {
	lsym   *obj.LSym
	offset int64
	typ    *types.Type
}

// NewCursor returns a cursor starting at lsym+off and having type t.
func NewCursor(lsym *obj.LSym, off int64, t *types.Type) Cursor {
	return Cursor{lsym: lsym, offset: off, typ: t}
}

// WritePtr writes a pointer "target" to the component at the location specified by c.
func (c Cursor) WritePtr(target *obj.LSym) {
	if c.typ.Kind() != types.TUNSAFEPTR {
		base.Fatalf("can't write ptr, it has kind %s", c.typ.Kind())
	}
	if target == nil {
		objw.Uintptr(c.lsym, int(c.offset), 0)
	} else {
		objw.SymPtr(c.lsym, int(c.offset), target, 0)
	}
}
func (c Cursor) WriteUintptr(val uint64) {
	if c.typ.Kind() != types.TUINTPTR {
		base.Fatalf("can't write uintptr, it has kind %s", c.typ.Kind())
	}
	objw.Uintptr(c.lsym, int(c.offset), val)
}
func (c Cursor) WriteUint32(val uint32) {
	if c.typ.Kind() != types.TUINT32 {
		base.Fatalf("can't write uint32, it has kind %s", c.typ.Kind())
	}
	objw.Uint32(c.lsym, int(c.offset), val)
}
func (c Cursor) WriteUint16(val uint16) {
	if c.typ.Kind() != types.TUINT16 {
		base.Fatalf("can't write uint16, it has kind %s", c.typ.Kind())
	}
	objw.Uint16(c.lsym, int(c.offset), val)
}
func (c Cursor) WriteUint8(val uint8) {
	if c.typ.Kind() != types.TUINT8 {
		base.Fatalf("can't write uint8, it has kind %s", c.typ.Kind())
	}
	objw.Uint8(c.lsym, int(c.offset), val)
}
func (c Cursor) WriteInt(val int64) {
	if c.typ.Kind() != types.TINT {
		base.Fatalf("can't write int, it has kind %s", c.typ.Kind())
	}
	objw.Uintptr(c.lsym, int(c.offset), uint64(val))
}
func (c Cursor) WriteInt32(val int32) {
	if c.typ.Kind() != types.TINT32 {
		base.Fatalf("can't write int32, it has kind %s", c.typ.Kind())
	}
	objw.Uint32(c.lsym, int(c.offset), uint32(val))
}
func (c Cursor) WriteBool(val bool) {
	if c.typ.Kind() != types.TBOOL {
		base.Fatalf("can't write bool, it has kind %s", c.typ.Kind())
	}
	objw.Bool(c.lsym, int(c.offset), val)
}

// WriteSymPtrOff writes a "pointer" to the given symbol. The symbol
// is encoded as a uint32 offset from the start of the section.
func (c Cursor) WriteSymPtrOff(target *obj.LSym, weak bool) {
	if c.typ.Kind() != types.TINT32 && c.typ.Kind() != types.TUINT32 {
		base.Fatalf("can't write SymPtr, it has kind %s", c.typ.Kind())
	}
	if target == nil {
		objw.Uint32(c.lsym, int(c.offset), 0)
	} else if weak {
		objw.SymPtrWeakOff(c.lsym, int(c.offset), target)
	} else {
		objw.SymPtrOff(c.lsym, int(c.offset), target)
	}
}

// WriteSlice writes a slice header to c. The pointer is target+off, the len and cap fields are given.
func (c Cursor) WriteSlice(target *obj.LSym, off, len, cap int64) {
	if c.typ.Kind() != types.TSLICE {
		base.Fatalf("can't write slice, it has kind %s", c.typ.Kind())
	}
	objw.SymPtr(c.lsym, int(c.offset), target, int(off))
	objw.Uintptr(c.lsym, int(c.offset)+types.PtrSize, uint64(len))
	objw.Uintptr(c.lsym, int(c.offset)+2*types.PtrSize, uint64(cap))
	// TODO: ability to switch len&cap. Maybe not needed here, as every caller
	// passes the same thing for both?
	if len != cap {
		base.Fatalf("len != cap (%d != %d)", len, cap)
	}
}

// Reloc adds a relocation from the current cursor position.
// Reloc fills in Off and Siz fields. Caller should fill in the rest (Type, others).
func (c Cursor) Reloc() *obj.Reloc {
	r := obj.Addrel(c.lsym)
	r.Off = int32(c.offset)
	r.Siz = uint8(c.typ.Size())
	return r
}

// Field selects the field with the given name from the struct pointed to by c.
func (c Cursor) Field(name string) Cursor {
	if c.typ.Kind() != types.TSTRUCT {
		base.Fatalf("can't call Field on non-struct %v", c.typ)
	}
	for _, f := range c.typ.Fields() {
		if f.Sym.Name == name {
			return Cursor{lsym: c.lsym, offset: c.offset + f.Offset, typ: f.Type}
		}
	}
	base.Fatalf("couldn't find field %s in %v", name, c.typ)
	return Cursor{}
}

type ArrayCursor struct {
	c Cursor // cursor pointing at first element
	n int    // number of elements
}

// NewArrayCursor returns a cursor starting at lsym+off and having n copies of type t.
func NewArrayCursor(lsym *obj.LSym, off int64, t *types.Type, n int) ArrayCursor {
	return ArrayCursor{
		c: NewCursor(lsym, off, t),
		n: n,
	}
}

// Elem selects element i of the array pointed to by c.
func (a ArrayCursor) Elem(i int) Cursor {
	if i < 0 || i >= a.n {
		base.Fatalf("element index %d out of range [0:%d]", i, a.n)
	}
	return Cursor{lsym: a.c.lsym, offset: a.c.offset + int64(i)*a.c.typ.Size(), typ: a.c.typ}
}

// ModifyArray converts a cursor pointing at a type [k]T to a cursor pointing
// at a type [n]T.
// Also returns the size delta, aka (n-k)*sizeof(T).
func (c Cursor) ModifyArray(n int) (ArrayCursor, int64) {
	if c.typ.Kind() != types.TARRAY {
		base.Fatalf("can't call ModifyArray on non-array %v", c.typ)
	}
	k := c.typ.NumElem()
	return ArrayCursor{c: Cursor{lsym: c.lsym, offset: c.offset, typ: c.typ.Elem()}, n: n}, (int64(n) - k) * c.typ.Elem().Size()
}
