// Copyright 2022 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 runtime

import (
	"runtime/internal/math"
	"unsafe"
)

func unsafestring(ptr unsafe.Pointer, len int) {
	if len < 0 {
		panicunsafestringlen()
	}

	if uintptr(len) > -uintptr(ptr) {
		if ptr == nil {
			panicunsafestringnilptr()
		}
		panicunsafestringlen()
	}
}

// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeString
func unsafestring64(ptr unsafe.Pointer, len64 int64) {
	len := int(len64)
	if int64(len) != len64 {
		panicunsafestringlen()
	}
	unsafestring(ptr, len)
}

func unsafestringcheckptr(ptr unsafe.Pointer, len64 int64) {
	unsafestring64(ptr, len64)

	// Check that underlying array doesn't straddle multiple heap objects.
	// unsafestring64 has already checked for overflow.
	if checkptrStraddles(ptr, uintptr(len64)) {
		throw("checkptr: unsafe.String result straddles multiple allocations")
	}
}

func panicunsafestringlen() {
	panic(errorString("unsafe.String: len out of range"))
}

func panicunsafestringnilptr() {
	panic(errorString("unsafe.String: ptr is nil and len is not zero"))
}

// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
	if len < 0 {
		panicunsafeslicelen1(getcallerpc())
	}

	if et.Size_ == 0 {
		if ptr == nil && len > 0 {
			panicunsafeslicenilptr1(getcallerpc())
		}
	}

	mem, overflow := math.MulUintptr(et.Size_, uintptr(len))
	if overflow || mem > -uintptr(ptr) {
		if ptr == nil {
			panicunsafeslicenilptr1(getcallerpc())
		}
		panicunsafeslicelen1(getcallerpc())
	}
}

// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
	len := int(len64)
	if int64(len) != len64 {
		panicunsafeslicelen1(getcallerpc())
	}
	unsafeslice(et, ptr, len)
}

func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
	unsafeslice64(et, ptr, len64)

	// Check that underlying array doesn't straddle multiple heap objects.
	// unsafeslice64 has already checked for overflow.
	if checkptrStraddles(ptr, uintptr(len64)*et.Size_) {
		throw("checkptr: unsafe.Slice result straddles multiple allocations")
	}
}

func panicunsafeslicelen() {
	// This is called only from compiler-generated code, so we can get the
	// source of the panic.
	panicunsafeslicelen1(getcallerpc())
}

//go:yeswritebarrierrec
func panicunsafeslicelen1(pc uintptr) {
	panicCheck1(pc, "unsafe.Slice: len out of range")
	panic(errorString("unsafe.Slice: len out of range"))
}

func panicunsafeslicenilptr() {
	// This is called only from compiler-generated code, so we can get the
	// source of the panic.
	panicunsafeslicenilptr1(getcallerpc())
}

//go:yeswritebarrierrec
func panicunsafeslicenilptr1(pc uintptr) {
	panicCheck1(pc, "unsafe.Slice: ptr is nil and len is not zero")
	panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
}

//go:linkname reflect_unsafeslice reflect.unsafeslice
func reflect_unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
	unsafeslice(et, ptr, len)
}
