print1.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  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. package runtime
  5. import "unsafe"
  6. // The compiler knows that a print of a value of this type
  7. // should use printhex instead of printuint (decimal).
  8. type hex uint64
  9. func bytes(s string) (ret []byte) {
  10. rp := (*slice)(unsafe.Pointer(&ret))
  11. sp := (*_string)(noescape(unsafe.Pointer(&s)))
  12. rp.array = sp.str
  13. rp.len = uint(sp.len)
  14. rp.cap = uint(sp.len)
  15. return
  16. }
  17. // printf is only called from C code. It has no type information for the args,
  18. // but C stacks are ignored by the garbage collector anyway, so having
  19. // type information would not add anything.
  20. //go:nosplit
  21. func printf(s *byte) {
  22. vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
  23. }
  24. // sprintf is only called from C code. It has no type information for the args,
  25. // but C stacks are ignored by the garbage collector anyway, so having
  26. // type information would not add anything.
  27. //go:nosplit
  28. func snprintf(dst *byte, n int32, s *byte) {
  29. buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:n:n]
  30. gp := getg()
  31. gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
  32. vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
  33. buf[len(gp.writebuf)] = '\x00'
  34. gp.writebuf = nil
  35. }
  36. //var debuglock mutex
  37. // write to goroutine-local buffer if diverting output,
  38. // or else standard error.
  39. func gwrite(b []byte) {
  40. if len(b) == 0 {
  41. return
  42. }
  43. gp := getg()
  44. if gp == nil || gp.writebuf == nil {
  45. write(2, unsafe.Pointer(&b[0]), int32(len(b)))
  46. return
  47. }
  48. n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
  49. gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
  50. }
  51. func prints(s *byte) {
  52. b := (*[1 << 30]byte)(unsafe.Pointer(s))
  53. for i := 0; ; i++ {
  54. if b[i] == 0 {
  55. gwrite(b[:i])
  56. return
  57. }
  58. }
  59. }
  60. func printsp() {
  61. print(" ")
  62. }
  63. func printnl() {
  64. print("\n")
  65. }
  66. // Very simple printf. Only for debugging prints.
  67. // Do not add to this without checking with Rob.
  68. func vprintf(str string, arg unsafe.Pointer) {
  69. //lock(&debuglock);
  70. s := bytes(str)
  71. start := 0
  72. i := 0
  73. for ; i < len(s); i++ {
  74. if s[i] != '%' {
  75. continue
  76. }
  77. if i > start {
  78. gwrite(s[start:i])
  79. }
  80. if i++; i >= len(s) {
  81. break
  82. }
  83. var siz uintptr
  84. switch s[i] {
  85. case 't', 'c':
  86. siz = 1
  87. case 'd', 'x': // 32-bit
  88. arg = roundup(arg, 4)
  89. siz = 4
  90. case 'D', 'U', 'X', 'f': // 64-bit
  91. arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
  92. siz = 8
  93. case 'C':
  94. arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
  95. siz = 16
  96. case 'p', 's': // pointer-sized
  97. arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
  98. siz = unsafe.Sizeof(uintptr(0))
  99. case 'S': // pointer-aligned but bigger
  100. arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
  101. siz = unsafe.Sizeof(string(""))
  102. case 'a': // pointer-aligned but bigger
  103. arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
  104. siz = unsafe.Sizeof([]byte{})
  105. case 'i', 'e': // pointer-aligned but bigger
  106. arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
  107. siz = unsafe.Sizeof(interface{}(nil))
  108. }
  109. switch s[i] {
  110. case 'a':
  111. printslice(*(*[]byte)(arg))
  112. case 'c':
  113. printbyte(*(*byte)(arg))
  114. case 'd':
  115. printint(int64(*(*int32)(arg)))
  116. case 'D':
  117. printint(int64(*(*int64)(arg)))
  118. case 'e':
  119. printeface(*(*interface{})(arg))
  120. case 'f':
  121. printfloat(*(*float64)(arg))
  122. case 'C':
  123. printcomplex(*(*complex128)(arg))
  124. case 'i':
  125. printiface(*(*fInterface)(arg))
  126. case 'p':
  127. printpointer(*(*unsafe.Pointer)(arg))
  128. case 's':
  129. prints(*(**byte)(arg))
  130. case 'S':
  131. printstring(*(*string)(arg))
  132. case 't':
  133. printbool(*(*bool)(arg))
  134. case 'U':
  135. printuint(*(*uint64)(arg))
  136. case 'x':
  137. printhex(uint64(*(*uint32)(arg)))
  138. case 'X':
  139. printhex(*(*uint64)(arg))
  140. }
  141. arg = add(arg, siz)
  142. start = i + 1
  143. }
  144. if start < i {
  145. gwrite(s[start:i])
  146. }
  147. //unlock(&debuglock);
  148. }
  149. func printpc(p unsafe.Pointer) {
  150. print("PC=", hex(uintptr(p)))
  151. }
  152. func printbool(v bool) {
  153. if v {
  154. print("true")
  155. } else {
  156. print("false")
  157. }
  158. }
  159. func printbyte(c byte) {
  160. gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
  161. }
  162. func printfloat(v float64) {
  163. switch {
  164. case v != v:
  165. print("NaN")
  166. return
  167. case v+v == v && v > 0:
  168. print("+Inf")
  169. return
  170. case v+v == v && v < 0:
  171. print("-Inf")
  172. return
  173. }
  174. const n = 7 // digits printed
  175. var buf [n + 7]byte
  176. buf[0] = '+'
  177. e := 0 // exp
  178. if v == 0 {
  179. if 1/v < 0 {
  180. buf[0] = '-'
  181. }
  182. } else {
  183. if v < 0 {
  184. v = -v
  185. buf[0] = '-'
  186. }
  187. // normalize
  188. for v >= 10 {
  189. e++
  190. v /= 10
  191. }
  192. for v < 1 {
  193. e--
  194. v *= 10
  195. }
  196. // round
  197. h := 5.0
  198. for i := 0; i < n; i++ {
  199. h /= 10
  200. }
  201. v += h
  202. if v >= 10 {
  203. e++
  204. v /= 10
  205. }
  206. }
  207. // format +d.dddd+edd
  208. for i := 0; i < n; i++ {
  209. s := int(v)
  210. buf[i+2] = byte(s + '0')
  211. v -= float64(s)
  212. v *= 10
  213. }
  214. buf[1] = buf[2]
  215. buf[2] = '.'
  216. buf[n+2] = 'e'
  217. buf[n+3] = '+'
  218. if e < 0 {
  219. e = -e
  220. buf[n+3] = '-'
  221. }
  222. buf[n+4] = byte(e/100) + '0'
  223. buf[n+5] = byte(e/10)%10 + '0'
  224. buf[n+6] = byte(e%10) + '0'
  225. gwrite(buf[:])
  226. }
  227. func printcomplex(c complex128) {
  228. print("(", real(c), imag(c), "i)")
  229. }
  230. func printuint(v uint64) {
  231. var buf [100]byte
  232. i := len(buf)
  233. for i--; i > 0; i-- {
  234. buf[i] = byte(v%10 + '0')
  235. if v < 10 {
  236. break
  237. }
  238. v /= 10
  239. }
  240. gwrite(buf[i:])
  241. }
  242. func printint(v int64) {
  243. if v < 0 {
  244. print("-")
  245. v = -v
  246. }
  247. printuint(uint64(v))
  248. }
  249. func printhex(v uint64) {
  250. const dig = "0123456789abcdef"
  251. var buf [100]byte
  252. i := len(buf)
  253. for i--; i > 0; i-- {
  254. buf[i] = dig[v%16]
  255. if v < 16 {
  256. break
  257. }
  258. v /= 16
  259. }
  260. i--
  261. buf[i] = 'x'
  262. i--
  263. buf[i] = '0'
  264. gwrite(buf[i:])
  265. }
  266. func printpointer(p unsafe.Pointer) {
  267. printhex(uint64(uintptr(p)))
  268. }
  269. func printstring(s string) {
  270. if uintptr(len(s)) > maxstring {
  271. gwrite(bytes("[string too long]"))
  272. return
  273. }
  274. gwrite(bytes(s))
  275. }
  276. func printslice(s []byte) {
  277. sp := (*slice)(unsafe.Pointer(&s))
  278. print("[", len(s), "/", cap(s), "]")
  279. printpointer(unsafe.Pointer(sp.array))
  280. }
  281. func printeface(e interface{}) {
  282. ep := (*eface)(unsafe.Pointer(&e))
  283. print("(", ep._type, ",", ep.data, ")")
  284. }
  285. func printiface(i fInterface) {
  286. ip := (*iface)(unsafe.Pointer(&i))
  287. print("(", ip.tab, ",", ip.data, ")")
  288. }