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