Source file
src/runtime/error.go
1
2
3
4
5 package runtime
6
7 import (
8 "internal/abi"
9 "internal/bytealg"
10 "internal/runtime/sys"
11 )
12
13
14
15
16
17
18
19
20
21
22
23
24 type Error interface {
25 error
26
27
28
29
30
31 RuntimeError()
32 }
33
34
35 type TypeAssertionError struct {
36 _interface *_type
37 concrete *_type
38 asserted *_type
39 missingMethod string
40 }
41
42 func (*TypeAssertionError) RuntimeError() {}
43
44 func (e *TypeAssertionError) Error() string {
45 inter := "interface"
46 if e._interface != nil {
47 inter = toRType(e._interface).string()
48 }
49 as := toRType(e.asserted).string()
50 if e.concrete == nil {
51 return "interface conversion: " + inter + " is nil, not " + as
52 }
53 cs := toRType(e.concrete).string()
54 if e.missingMethod == "" {
55 msg := "interface conversion: " + inter + " is " + cs + ", not " + as
56 if cs == as {
57
58 if toRType(e.concrete).pkgpath() != toRType(e.asserted).pkgpath() {
59 msg += " (types from different packages)"
60 } else {
61 msg += " (types from different scopes)"
62 }
63 }
64 return msg
65 }
66 return "interface conversion: " + cs + " is not " + as +
67 ": missing method " + e.missingMethod
68 }
69
70
71
72
73
74
75 func itoa(buf []byte, val uint64) []byte {
76 i := len(buf) - 1
77 for val >= 10 {
78 buf[i] = byte(val%10 + '0')
79 i--
80 val /= 10
81 }
82 buf[i] = byte(val + '0')
83 return buf[i:]
84 }
85
86
87 type errorString string
88
89 func (e errorString) RuntimeError() {}
90
91 func (e errorString) Error() string {
92 return "runtime error: " + string(e)
93 }
94
95 type errorAddressString struct {
96 msg string
97 addr uintptr
98 }
99
100 func (e errorAddressString) RuntimeError() {}
101
102 func (e errorAddressString) Error() string {
103 return "runtime error: " + e.msg
104 }
105
106
107
108
109
110
111 func (e errorAddressString) Addr() uintptr {
112 return e.addr
113 }
114
115
116
117
118 type plainError string
119
120 func (e plainError) RuntimeError() {}
121
122 func (e plainError) Error() string {
123 return string(e)
124 }
125
126
127 type boundsError struct {
128 x int64
129 y int
130
131
132
133
134 signed bool
135 code boundsErrorCode
136 }
137
138 type boundsErrorCode uint8
139
140 const (
141 boundsIndex boundsErrorCode = iota
142
143 boundsSliceAlen
144 boundsSliceAcap
145 boundsSliceB
146
147 boundsSlice3Alen
148 boundsSlice3Acap
149 boundsSlice3B
150 boundsSlice3C
151
152 boundsConvert
153
154 )
155
156
157
158
159 var boundsErrorFmts = [...]string{
160 boundsIndex: "index out of range [%x] with length %y",
161 boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
162 boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
163 boundsSliceB: "slice bounds out of range [%x:%y]",
164 boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
165 boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
166 boundsSlice3B: "slice bounds out of range [:%x:%y]",
167 boundsSlice3C: "slice bounds out of range [%x:%y:]",
168 boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
169 }
170
171
172 var boundsNegErrorFmts = [...]string{
173 boundsIndex: "index out of range [%x]",
174 boundsSliceAlen: "slice bounds out of range [:%x]",
175 boundsSliceAcap: "slice bounds out of range [:%x]",
176 boundsSliceB: "slice bounds out of range [%x:]",
177 boundsSlice3Alen: "slice bounds out of range [::%x]",
178 boundsSlice3Acap: "slice bounds out of range [::%x]",
179 boundsSlice3B: "slice bounds out of range [:%x:]",
180 boundsSlice3C: "slice bounds out of range [%x::]",
181 }
182
183 func (e boundsError) RuntimeError() {}
184
185 func appendIntStr(b []byte, v int64, signed bool) []byte {
186 if signed && v < 0 {
187 b = append(b, '-')
188 v = -v
189 }
190 var buf [20]byte
191 b = append(b, itoa(buf[:], uint64(v))...)
192 return b
193 }
194
195 func (e boundsError) Error() string {
196 fmt := boundsErrorFmts[e.code]
197 if e.signed && e.x < 0 {
198 fmt = boundsNegErrorFmts[e.code]
199 }
200
201
202 b := make([]byte, 0, 100)
203 b = append(b, "runtime error: "...)
204 for i := 0; i < len(fmt); i++ {
205 c := fmt[i]
206 if c != '%' {
207 b = append(b, c)
208 continue
209 }
210 i++
211 switch fmt[i] {
212 case 'x':
213 b = appendIntStr(b, e.x, e.signed)
214 case 'y':
215 b = appendIntStr(b, int64(e.y), true)
216 }
217 }
218 return string(b)
219 }
220
221 type stringer interface {
222 String() string
223 }
224
225
226
227
228
229
230
231
232
233 func printpanicval(v any) {
234 switch v := v.(type) {
235 case nil:
236 print("nil")
237 case bool:
238 print(v)
239 case int:
240 print(v)
241 case int8:
242 print(v)
243 case int16:
244 print(v)
245 case int32:
246 print(v)
247 case int64:
248 print(v)
249 case uint:
250 print(v)
251 case uint8:
252 print(v)
253 case uint16:
254 print(v)
255 case uint32:
256 print(v)
257 case uint64:
258 print(v)
259 case uintptr:
260 print(v)
261 case float32:
262 print(v)
263 case float64:
264 print(v)
265 case complex64:
266 print(v)
267 case complex128:
268 print(v)
269 case string:
270 printindented(v)
271 default:
272 printanycustomtype(v)
273 }
274 }
275
276
277 func printanycustomtype(i any) {
278 eface := efaceOf(&i)
279 typestring := toRType(eface._type).string()
280
281 switch eface._type.Kind_ {
282 case abi.String:
283 print(typestring, `("`)
284 printindented(*(*string)(eface.data))
285 print(`")`)
286 case abi.Bool:
287 print(typestring, "(", *(*bool)(eface.data), ")")
288 case abi.Int:
289 print(typestring, "(", *(*int)(eface.data), ")")
290 case abi.Int8:
291 print(typestring, "(", *(*int8)(eface.data), ")")
292 case abi.Int16:
293 print(typestring, "(", *(*int16)(eface.data), ")")
294 case abi.Int32:
295 print(typestring, "(", *(*int32)(eface.data), ")")
296 case abi.Int64:
297 print(typestring, "(", *(*int64)(eface.data), ")")
298 case abi.Uint:
299 print(typestring, "(", *(*uint)(eface.data), ")")
300 case abi.Uint8:
301 print(typestring, "(", *(*uint8)(eface.data), ")")
302 case abi.Uint16:
303 print(typestring, "(", *(*uint16)(eface.data), ")")
304 case abi.Uint32:
305 print(typestring, "(", *(*uint32)(eface.data), ")")
306 case abi.Uint64:
307 print(typestring, "(", *(*uint64)(eface.data), ")")
308 case abi.Uintptr:
309 print(typestring, "(", *(*uintptr)(eface.data), ")")
310 case abi.Float32:
311 print(typestring, "(", *(*float32)(eface.data), ")")
312 case abi.Float64:
313 print(typestring, "(", *(*float64)(eface.data), ")")
314 case abi.Complex64:
315 print(typestring, *(*complex64)(eface.data))
316 case abi.Complex128:
317 print(typestring, *(*complex128)(eface.data))
318 default:
319 print("(", typestring, ") ", eface.data)
320 }
321 }
322
323
324 func printindented(s string) {
325 for {
326 i := bytealg.IndexByteString(s, '\n')
327 if i < 0 {
328 break
329 }
330 i += len("\n")
331 print(s[:i])
332 print("\t")
333 s = s[i:]
334 }
335 print(s)
336 }
337
338
339
340
341
342 func panicwrap() {
343 pc := sys.GetCallerPC()
344 name := funcNameForPrint(funcname(findfunc(pc)))
345
346
347
348 i := bytealg.IndexByteString(name, '(')
349 if i < 0 {
350 throw("panicwrap: no ( in " + name)
351 }
352 pkg := name[:i-1]
353 if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
354 throw("panicwrap: unexpected string after package name: " + name)
355 }
356 name = name[i+2:]
357 i = bytealg.IndexByteString(name, ')')
358 if i < 0 {
359 throw("panicwrap: no ) in " + name)
360 }
361 if i+2 >= len(name) || name[i:i+2] != ")." {
362 throw("panicwrap: unexpected string after type name: " + name)
363 }
364 typ := name[:i]
365 meth := name[i+2:]
366 panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
367 }
368
View as plain text