1 // Copyright 2009 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 "unsafe" 8 9 //go:nosplit 10 func findnull(s *byte) int { 11 if s == nil { 12 return 0 13 } 14 p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s)) 15 l := 0 16 for p[l] != 0 { 17 l++ 18 } 19 return l 20 } 21 22 func findnullw(s *uint16) int { 23 if s == nil { 24 return 0 25 } 26 p := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(s)) 27 l := 0 28 for p[l] != 0 { 29 l++ 30 } 31 return l 32 } 33 34 var maxstring uintptr = 256 // a hint for print 35 36 //go:nosplit 37 func gostringnocopy(str *byte) string { 38 ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)} 39 s := *(*string)(unsafe.Pointer(&ss)) 40 for { 41 ms := maxstring 42 if uintptr(len(s)) <= ms || casuintptr(&maxstring, ms, uintptr(len(s))) { 43 break 44 } 45 } 46 return s 47 } 48 49 func gostringw(strw *uint16) string { 50 var buf [8]byte 51 str := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(strw)) 52 n1 := 0 53 for i := 0; str[i] != 0; i++ { 54 n1 += runetochar(buf[:], rune(str[i])) 55 } 56 s, b := rawstring(n1 + 4) 57 n2 := 0 58 for i := 0; str[i] != 0; i++ { 59 // check for race 60 if n2 >= n1 { 61 break 62 } 63 n2 += runetochar(b[n2:], rune(str[i])) 64 } 65 b[n2] = 0 // for luck 66 return s[:n2] 67 } 68