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
138 )
139
140
141
142
143 var boundsErrorFmts = [...]string{
144 boundsIndex: "index out of range [%x] with length %y",
145 boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
146 boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
147 boundsSliceB: "slice bounds out of range [%x:%y]",
148 boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
149 boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
150 boundsSlice3B: "slice bounds out of range [:%x:%y]",
151 boundsSlice3C: "slice bounds out of range [%x:%y:]",
152 }
153
154
155 var boundsNegErrorFmts = [...]string{
156 boundsIndex: "index out of range [%x]",
157 boundsSliceAlen: "slice bounds out of range [:%x]",
158 boundsSliceAcap: "slice bounds out of range [:%x]",
159 boundsSliceB: "slice bounds out of range [%x:]",
160 boundsSlice3Alen: "slice bounds out of range [::%x]",
161 boundsSlice3Acap: "slice bounds out of range [::%x]",
162 boundsSlice3B: "slice bounds out of range [:%x:]",
163 boundsSlice3C: "slice bounds out of range [%x::]",
164 }
165
166 func (e boundsError) RuntimeError() {}
167
168 func appendIntStr(b []byte, v int64, signed bool) []byte {
169 if signed && v < 0 {
170 b = append(b, '-')
171 v = -v
172 }
173 var buf [20]byte
174 b = append(b, itoa(buf[:], uint64(v))...)
175 return b
176 }
177
178 func (e boundsError) Error() string {
179 fmt := boundsErrorFmts[e.code]
180 if e.signed && e.x < 0 {
181 fmt = boundsNegErrorFmts[e.code]
182 }
183
184
185 b := make([]byte, 0, 100)
186 b = append(b, "runtime error: "...)
187 for i := 0; i < len(fmt); i++ {
188 c := fmt[i]
189 if c != '%' {
190 b = append(b, c)
191 continue
192 }
193 i++
194 switch fmt[i] {
195 case 'x':
196 b = appendIntStr(b, e.x, e.signed)
197 case 'y':
198 b = appendIntStr(b, int64(e.y), true)
199 }
200 }
201 return string(b)
202 }
203
204 type stringer interface {
205 String() string
206 }
207
208
209
210
211 func printany(i interface{}) {
212 switch v := i.(type) {
213 case nil:
214 print("nil")
215 case bool:
216 print(v)
217 case int:
218 print(v)
219 case int8:
220 print(v)
221 case int16:
222 print(v)
223 case int32:
224 print(v)
225 case int64:
226 print(v)
227 case uint:
228 print(v)
229 case uint8:
230 print(v)
231 case uint16:
232 print(v)
233 case uint32:
234 print(v)
235 case uint64:
236 print(v)
237 case uintptr:
238 print(v)
239 case float32:
240 print(v)
241 case float64:
242 print(v)
243 case complex64:
244 print(v)
245 case complex128:
246 print(v)
247 case string:
248 print(v)
249 default:
250 printanycustomtype(i)
251 }
252 }
253
254 func printanycustomtype(i interface{}) {
255 eface := efaceOf(&i)
256 typestring := eface._type.string()
257
258 switch eface._type.kind {
259 case kindString:
260 print(typestring, `("`, *(*string)(eface.data), `")`)
261 case kindBool:
262 print(typestring, "(", *(*bool)(eface.data), ")")
263 case kindInt:
264 print(typestring, "(", *(*int)(eface.data), ")")
265 case kindInt8:
266 print(typestring, "(", *(*int8)(eface.data), ")")
267 case kindInt16:
268 print(typestring, "(", *(*int16)(eface.data), ")")
269 case kindInt32:
270 print(typestring, "(", *(*int32)(eface.data), ")")
271 case kindInt64:
272 print(typestring, "(", *(*int64)(eface.data), ")")
273 case kindUint:
274 print(typestring, "(", *(*uint)(eface.data), ")")
275 case kindUint8:
276 print(typestring, "(", *(*uint8)(eface.data), ")")
277 case kindUint16:
278 print(typestring, "(", *(*uint16)(eface.data), ")")
279 case kindUint32:
280 print(typestring, "(", *(*uint32)(eface.data), ")")
281 case kindUint64:
282 print(typestring, "(", *(*uint64)(eface.data), ")")
283 case kindUintptr:
284 print(typestring, "(", *(*uintptr)(eface.data), ")")
285 case kindFloat32:
286 print(typestring, "(", *(*float32)(eface.data), ")")
287 case kindFloat64:
288 print(typestring, "(", *(*float64)(eface.data), ")")
289 case kindComplex64:
290 print(typestring, *(*complex64)(eface.data))
291 case kindComplex128:
292 print(typestring, *(*complex128)(eface.data))
293 default:
294 print("(", typestring, ") ", eface.data)
295 }
296 }
297
298
299
300
301
302 func panicwrap() {
303 pc := getcallerpc()
304 name := funcname(findfunc(pc))
305
306
307
308 i := bytealg.IndexByteString(name, '(')
309 if i < 0 {
310 throw("panicwrap: no ( in " + name)
311 }
312 pkg := name[:i-1]
313 if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
314 throw("panicwrap: unexpected string after package name: " + name)
315 }
316 name = name[i+2:]
317 i = bytealg.IndexByteString(name, ')')
318 if i < 0 {
319 throw("panicwrap: no ) in " + name)
320 }
321 if i+2 >= len(name) || name[i:i+2] != ")." {
322 throw("panicwrap: unexpected string after type name: " + name)
323 }
324 typ := name[:i]
325 meth := name[i+2:]
326 panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
327 }
328
View as plain text