github.com/go-darwin/sys@v0.0.0-20220510002607-68fd01f054ca/string.go (about) 1 // Copyright 2021 The Go Darwin Authors 2 // SPDX-License-Identifier: BSD-3-Clause 3 4 //go:build darwin 5 // +build darwin 6 7 package sys 8 9 import "unsafe" 10 11 // TmpStringBufSize constant is known to the compiler. 12 // There is no fundamental theory behind this number. 13 const TmpStringBufSize = 32 14 15 // TmpBuf is a temporary byte array. 16 type TmpBuf [TmpStringBufSize]byte 17 18 //go:linkname concatstrings runtime.concatstrings 19 func concatstrings(buf *TmpBuf, a []string) string 20 21 // Concatstrings implements a Go string concatenation x+y+z+... 22 // 23 // The operands are passed in the slice a. 24 // If buf != nil, the compiler has determined that the result does not 25 // escape the calling function, so the string data can be stored in buf 26 // if small enough. 27 func Concatstrings(buf *TmpBuf, a []string) string { 28 return concatstrings(buf, a) 29 } 30 31 //go:linkname concatstring2 runtime.concatstring2 32 func concatstring2(buf *TmpBuf, a0, a1 string) string 33 34 // Concatstring2 concats two strings. 35 func Concatstring2(buf *TmpBuf, a0, a1 string) string { 36 return concatstring2(buf, a0, a1) 37 } 38 39 //go:linkname concatstring3 runtime.concatstring3 40 func concatstring3(buf *TmpBuf, a0, a1, a2 string) string 41 42 // Concatstring3 concats three strings. 43 func Concatstring3(buf *TmpBuf, a0, a1, a2 string) string { 44 return concatstring3(buf, a0, a1, a2) 45 } 46 47 //go:linkname concatstring4 runtime.concatstring4 48 func concatstring4(buf *TmpBuf, a0, a1, a2, a3 string) string 49 50 // Concatstring4 concats four strings. 51 func Concatstring4(buf *TmpBuf, a0, a1, a2, a3 string) string { 52 return concatstring4(buf, a0, a1, a2, a3) 53 } 54 55 //go:linkname concatstring5 runtime.concatstring5 56 func concatstring5(buf *TmpBuf, a0, a1, a2, a3, a4 string) string 57 58 // Concatstring5 concats five strings. 59 func Concatstring5(buf *TmpBuf, a0, a1, a2, a3, a4 string) string { 60 return concatstring5(buf, a0, a1, a2, a3, a4) 61 } 62 63 //go:linkname slicebytetostring runtime.slicebytetostring 64 func slicebytetostring(buf *TmpBuf, ptr *byte, n int) (str string) 65 66 // SliceByteToString converts a byte slice to a string. 67 // 68 // It is inserted by the compiler into generated code. 69 // ptr is a pointer to the first element of the slice; 70 // n is the length of the slice. 71 // 72 // Buf is a fixed-size buffer for the result, 73 // it is not nil if the result does not escape. 74 func SliceByteToString(buf *TmpBuf, ptr *byte, n int) (str string) { 75 return slicebytetostring(buf, ptr, n) 76 } 77 78 //go:linkname stringDataOnStack runtime.stringDataOnStack 79 func stringDataOnStack(s string) bool 80 81 // StringDataOnStack reports whether the string's data is 82 // stored on the current goroutine's stack. 83 func StringDataOnStack(s string) bool { 84 return stringDataOnStack(s) 85 } 86 87 //go:linkname rawstringtmp runtime.rawstringtmp 88 func rawstringtmp(buf *TmpBuf, l int) (s string, b []byte) 89 90 // RawStringTmp returns a "string" referring to the actual []byte bytes. 91 func RawStringTmp(buf *TmpBuf, l int) (s string, b []byte) { 92 return rawstringtmp(buf, l) 93 } 94 95 //go:linkname slicebytetostringtmp runtime.slicebytetostringtmp 96 func slicebytetostringtmp(ptr *byte, n int) (str string) 97 98 // SliceByteToStringTmp returns a "string" referring to the actual []byte bytes. 99 // 100 // Callers need to ensure that the returned string will not be used after 101 // the calling goroutine modifies the original slice or synchronizes with 102 // another goroutine. 103 // 104 // The function is only called when instrumenting 105 // and otherwise intrinsified by the compiler. 106 // 107 // Some internal compiler optimizations use this function. 108 // - Used for m[T1{... Tn{..., string(k), ...} ...}] and m[string(k)] 109 // where k is []byte, T1 to Tn is a nesting of struct and array literals. 110 // - Used for "<"+string(b)+">" concatenation where b is []byte. 111 // - Used for string(b)=="foo" comparison where b is []byte. 112 func SliceByteToStringTmp(ptr *byte, n int) (str string) { 113 return slicebytetostringtmp(ptr, n) 114 } 115 116 //go:linkname stringtoslicebyte runtime.stringtoslicebyte 117 func stringtoslicebyte(buf *TmpBuf, s string) []byte 118 119 // StringToSliceByte converts a string to a byte slice. 120 func StringToSliceByte(buf *TmpBuf, s string) []byte { 121 return stringtoslicebyte(buf, s) 122 } 123 124 //go:linkname stringtoslicerune runtime.stringtoslicerune 125 func stringtoslicerune(buf *[TmpStringBufSize]rune, s string) []rune 126 127 // StringToSliceRune converts a string to a rune slice. 128 func StringToSliceRune(buf *[TmpStringBufSize]rune, s string) []rune { 129 return stringtoslicerune(buf, s) 130 } 131 132 //go:linkname slicerunetostring runtime.slicerunetostring 133 func slicerunetostring(buf *TmpBuf, a []rune) string 134 135 // SliceRuneToString converts a rune slice to a string. 136 func SliceRuneToString(buf *TmpBuf, a []rune) string { 137 return slicerunetostring(buf, a) 138 } 139 140 // StringStruct actual string type struct. 141 type StringStruct struct { 142 Str unsafe.Pointer 143 Length int 144 } 145 146 // StringStructDWARF variant with *byte pointer type for DWARF debugging. 147 type StringStructDWARF struct { 148 Str *byte 149 Length int 150 } 151 152 //go:linkname stringStructOf runtime.stringStructOf 153 func stringStructOf(sp *string) *StringStruct 154 155 // StringStructOf converts a sp to StringStruct. 156 func StringStructOf(sp *string) *StringStruct { 157 return stringStructOf(sp) 158 } 159 160 //go:linkname intstring runtime.intstring 161 func intstring(buf *[4]byte, v int64) (s string) 162 163 // IntString converts a int64 v to string. 164 func IntString(buf *[4]byte, v int64) (s string) { 165 return intstring(buf, v) 166 } 167 168 //go:linkname rawstring runtime.rawstring 169 func rawstring(size int) (s string, b []byte) 170 171 // RawString allocates storage for a new string. The returned 172 // string and byte slice both refer to the same storage. 173 // The storage is not zeroed. Callers should use 174 // b to set the string contents and then drop b. 175 func RawString(size int) (s string, b []byte) { 176 return rawstring(size) 177 } 178 179 //go:linkname rawbyteslice runtime.rawbyteslice 180 func rawbyteslice(size int) (b []byte) 181 182 // RawByteSlice allocates a new byte slice. The byte slice is not zeroed. 183 func RawByteSlice(size int) (b []byte) { 184 return rawbyteslice(size) 185 } 186 187 //go:linkname rawruneslice runtime.rawruneslice 188 func rawruneslice(size int) (b []rune) 189 190 // RawRuneSlice allocates a new rune slice. The rune slice is not zeroed. 191 func RawRuneSlice(size int) (b []rune) { 192 return rawruneslice(size) 193 } 194 195 //go:linkname gobytes runtime.gobytes 196 func gobytes(p *byte, n int) (b []byte) 197 198 // GoBytes converts a n length C pointer to Go byte slice. 199 // This function used by C.GoBytes. 200 func GoBytes(p *byte, n int) (b []byte) { 201 return gobytes(p, n) 202 } 203 204 //go:linkname gostringn runtime.gostringn 205 func gostringn(p *byte, l int) string 206 207 // GostringN converts a l length C string to Go string. 208 // This function used by C.GostringN. 209 func GoStringN(p *byte, l int) string { 210 return gostringn(p, l) 211 } 212 213 //go:nosplit 214 //go:linkname findnull runtime.findnull 215 func findnull(s *byte) int 216 217 // FindNull finds NULL in *byte type s. 218 // 219 //go:nosplit 220 func FindNull(s *byte) int { 221 return findnull(s) 222 } 223 224 //go:linkname findnullw runtime.findnullw 225 func findnullw(s *uint16) int 226 227 // FindNullW finds NULL in *uint16 type s. 228 func FindNullW(s *uint16) int { 229 return findnullw(s) 230 } 231 232 //go:nosplit 233 //go:linkname gostringnocopy runtime.gostringnocopy 234 func gostringnocopy(str *byte) string 235 236 // GoString converts a C string to a Go string. 237 // This function used by C.GoString. 238 // 239 //go:nosplit 240 func GoString(str *byte) string { 241 return gostringnocopy(str) 242 } 243 244 func gostring(s *int8) string { 245 n, arr := 0, (*[1 << 20]byte)(unsafe.Pointer(s)) 246 for arr[n] != 0 { 247 n++ 248 } 249 return string(arr[:n]) 250 } 251 252 //go:linkname gostringw runtime.gostringw 253 func gostringw(strw *uint16) string 254 255 // GoStringW converts a uint16 pointer to a string. 256 func GoStringW(strw *uint16) string { 257 return gostringw(strw) 258 }