// n is the length of the slice.
// Buf is a fixed-size buffer for the result,
// it is not nil if the result does not escape.
-func slicebytetostring(buf *tmpBuf, ptr *byte, n int) (str string) {
+func slicebytetostring(buf *tmpBuf, ptr *byte, n int) string {
if n == 0 {
// Turns out to be a relatively common case.
// Consider that you want to parse out data between parens in "foo()bar",
if goarch.BigEndian {
p = add(p, 7)
}
- stringStructOf(&str).str = p
- stringStructOf(&str).len = 1
- return
+ return unsafe.String((*byte)(p), 1)
}
var p unsafe.Pointer
} else {
p = mallocgc(uintptr(n), nil, false)
}
- stringStructOf(&str).str = p
- stringStructOf(&str).len = n
memmove(p, unsafe.Pointer(ptr), uintptr(n))
- return
+ return unsafe.String((*byte)(p), n)
}
// stringDataOnStack reports whether the string's data is
// stored on the current goroutine's stack.
func stringDataOnStack(s string) bool {
- ptr := uintptr(stringStructOf(&s).str)
+ ptr := uintptr(unsafe.Pointer(unsafe.StringData(s)))
stk := getg().stack
return stk.lo <= ptr && ptr < stk.hi
}
// where k is []byte, T1 to Tn is a nesting of struct and array literals.
// - Used for "<"+string(b)+">" concatenation where b is []byte.
// - Used for string(b)=="foo" comparison where b is []byte.
-func slicebytetostringtmp(ptr *byte, n int) (str string) {
+func slicebytetostringtmp(ptr *byte, n int) string {
if raceenabled && n > 0 {
racereadrangepc(unsafe.Pointer(ptr),
uintptr(n),
if asanenabled && n > 0 {
asanread(unsafe.Pointer(ptr), uintptr(n))
}
- stringStructOf(&str).str = unsafe.Pointer(ptr)
- stringStructOf(&str).len = n
- return
+ return unsafe.String(ptr, n)
}
func stringtoslicebyte(buf *tmpBuf, s string) []byte {
// b to set the string contents and then drop b.
func rawstring(size int) (s string, b []byte) {
p := mallocgc(uintptr(size), nil, false)
-
- stringStructOf(&s).str = p
- stringStructOf(&s).len = size
-
- *(*slice)(unsafe.Pointer(&b)) = slice{p, size, size}
-
- return
+ return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
}
// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
func rawbyteslice(size int) (b []byte) {
- cap := roundupsize(uintptr(size))
+ cap := roundupsize(uintptr(size), true)
p := mallocgc(cap, nil, false)
if cap != uintptr(size) {
memclrNoHeapPointers(add(p, uintptr(size)), cap-uintptr(size))
if uintptr(size) > maxAlloc/4 {
throw("out of memory")
}
- mem := roundupsize(uintptr(size) * 4)
+ mem := roundupsize(uintptr(size)*4, true)
p := mallocgc(mem, nil, false)
if mem != uintptr(size)*4 {
memclrNoHeapPointers(add(p, uintptr(size)*4), mem-uintptr(size)*4)
return s
}
+// internal_syscall_gostring is a version of gostring for internal/syscall/unix.
+//
+//go:linkname internal_syscall_gostring internal/syscall/unix.gostring
+func internal_syscall_gostring(p *byte) string {
+ return gostring(p)
+}
+
func gostringn(p *byte, l int) string {
if l == 0 {
return ""
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
+func hasSuffix(s, suffix string) bool {
+ return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
const (
maxUint64 = ^uint64(0)
maxInt64 = int64(maxUint64 >> 1)