github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/runtime/unsafe.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"runtime/internal/math"
     9  	"unsafe"
    10  )
    11  
    12  func unsafestring(ptr unsafe.Pointer, len int) {
    13  	if len < 0 {
    14  		panicunsafestringlen()
    15  	}
    16  
    17  	if uintptr(len) > -uintptr(ptr) {
    18  		if ptr == nil {
    19  			panicunsafestringnilptr()
    20  		}
    21  		panicunsafestringlen()
    22  	}
    23  }
    24  
    25  // Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeString
    26  func unsafestring64(ptr unsafe.Pointer, len64 int64) {
    27  	len := int(len64)
    28  	if int64(len) != len64 {
    29  		panicunsafestringlen()
    30  	}
    31  	unsafestring(ptr, len)
    32  }
    33  
    34  func unsafestringcheckptr(ptr unsafe.Pointer, len64 int64) {
    35  	unsafestring64(ptr, len64)
    36  
    37  	// Check that underlying array doesn't straddle multiple heap objects.
    38  	// unsafestring64 has already checked for overflow.
    39  	if checkptrStraddles(ptr, uintptr(len64)) {
    40  		throw("checkptr: unsafe.String result straddles multiple allocations")
    41  	}
    42  }
    43  
    44  func panicunsafestringlen() {
    45  	panic(errorString("unsafe.String: len out of range"))
    46  }
    47  
    48  func panicunsafestringnilptr() {
    49  	panic(errorString("unsafe.String: ptr is nil and len is not zero"))
    50  }
    51  
    52  // Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
    53  func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
    54  	if len < 0 {
    55  		panicunsafeslicelen()
    56  	}
    57  
    58  	if et.size == 0 {
    59  		if ptr == nil && len > 0 {
    60  			panicunsafeslicenilptr()
    61  		}
    62  	}
    63  
    64  	mem, overflow := math.MulUintptr(et.size, uintptr(len))
    65  	if overflow || mem > -uintptr(ptr) {
    66  		if ptr == nil {
    67  			panicunsafeslicenilptr()
    68  		}
    69  		panicunsafeslicelen()
    70  	}
    71  }
    72  
    73  // Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
    74  func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
    75  	len := int(len64)
    76  	if int64(len) != len64 {
    77  		panicunsafeslicelen()
    78  	}
    79  	unsafeslice(et, ptr, len)
    80  }
    81  
    82  func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
    83  	unsafeslice64(et, ptr, len64)
    84  
    85  	// Check that underlying array doesn't straddle multiple heap objects.
    86  	// unsafeslice64 has already checked for overflow.
    87  	if checkptrStraddles(ptr, uintptr(len64)*et.size) {
    88  		throw("checkptr: unsafe.Slice result straddles multiple allocations")
    89  	}
    90  }
    91  
    92  func panicunsafeslicelen() {
    93  	panic(errorString("unsafe.Slice: len out of range"))
    94  }
    95  
    96  func panicunsafeslicenilptr() {
    97  	panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
    98  }