1 // Copyright 2014 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.
11 // For gccgo, use go:linkname to rename compiler-called functions to
12 // themselves, so that the compiler will export them.
14 //go:linkname requireitab runtime.requireitab
15 //go:linkname assertitab runtime.assertitab
16 //go:linkname assertI2T runtime.assertI2T
17 //go:linkname ifacetypeeq runtime.ifacetypeeq
18 //go:linkname efacetype runtime.efacetype
19 //go:linkname ifacetype runtime.ifacetype
20 //go:linkname ifaceE2E2 runtime.ifaceE2E2
21 //go:linkname ifaceI2E2 runtime.ifaceI2E2
22 //go:linkname ifaceE2I2 runtime.ifaceE2I2
23 //go:linkname ifaceI2I2 runtime.ifaceI2I2
24 //go:linkname ifaceE2T2P runtime.ifaceE2T2P
25 //go:linkname ifaceI2T2P runtime.ifaceI2T2P
26 //go:linkname ifaceE2T2 runtime.ifaceE2T2
27 //go:linkname ifaceI2T2 runtime.ifaceI2T2
28 //go:linkname ifaceT2Ip runtime.ifaceT2Ip
29 // Temporary for C code to call:
30 //go:linkname getitab runtime.getitab
32 // The gccgo itab structure is different than the gc one.
34 // Both gccgo and gc represent empty interfaces the same way:
35 // a two field struct, where the first field points to a type descriptor
36 // (a *_type) and the second field is the data pointer.
38 // Non-empty interfaces are also two-field structs, and the second
39 // field is the data pointer. However, for gccgo, the first field, the
40 // itab field, is different. The itab field points to the interface
41 // method table, which is the implemention of a specific interface
42 // type for a specific dynamic non-interface type. An interface
43 // method table is a list of pointer values. The first pointer is the
44 // type descriptor (a *_type) for the dynamic type. The subsequent
45 // pointers are pointers to function code, which implement the methods
46 // required by the interface. The pointers are sorted by name.
48 // The method pointers in the itab are C function pointers, not Go
49 // function pointers; they may be called directly, and they have no
50 // closures. The receiver is always passed as a pointer, and it is
51 // always the same pointer stored in the interface value. A value
52 // method starts by copying the receiver value out of the pointer into
55 // A method call on an interface value is by definition calling a
56 // method at a known index m in the list of methods. Given a non-empty
57 // interface value i, the call i.m(args) looks like
58 // i.itab[m+1](i.iface, args)
60 // Both an empty interface and a non-empty interface have a data
61 // pointer field. The meaning of this field is determined by the
62 // kindDirectIface bit in the `kind` field of the type descriptor of
63 // the value stored in the interface. If kindDirectIface is set, then
64 // the data pointer field in the interface value is exactly the value
65 // stored in the interface. Otherwise, the data pointer field is a
66 // pointer to memory that holds the value. It follows from this that
67 // kindDirectIface can only be set for a type whose representation is
68 // simply a pointer. In the current gccgo implementation, this is set
69 // only for pointer types (including unsafe.Pointer). In the future it
70 // could also be set for other types: channels, maps, functions,
71 // single-field structs and single-element arrays whose single field
72 // is simply a pointer.
74 // For a nil interface value both fields in the interface struct are nil.
76 // Return the interface method table for a value of type rhs converted
77 // to an interface of type lhs.
78 func getitab(lhs
, rhs
*_type
, canfail
bool) unsafe
.Pointer
{
83 if lhs
.kind
&kindMask
!= kindInterface
{
84 throw("getitab called for non-interface type")
87 lhsi
:= (*interfacetype
)(unsafe
.Pointer(lhs
))
89 if len(lhsi
.methods
) == 0 {
90 throw("getitab called for empty interface type")
93 if rhs
.uncommontype
== nil ||
len(rhs
.methods
) == 0 {
97 panic(&TypeAssertionError
{nil, rhs
, lhs
, *lhsi
.methods
[0].name
})
100 methods
:= make([]unsafe
.Pointer
, len(lhsi
.methods
)+1)
101 methods
[0] = unsafe
.Pointer(rhs
)
104 for li
:= range lhsi
.methods
{
105 lhsMethod
:= &lhsi
.methods
[li
]
106 var rhsMethod
*method
109 if ri
>= len(rhs
.methods
) {
113 panic(&TypeAssertionError
{nil, rhs
, lhs
, *lhsMethod
.name
})
116 rhsMethod
= &rhs
.methods
[ri
]
117 if (lhsMethod
.name
== rhsMethod
.name ||
*lhsMethod
.name
== *rhsMethod
.name
) &&
118 (lhsMethod
.pkgPath
== rhsMethod
.pkgPath ||
*lhsMethod
.pkgPath
== *rhsMethod
.pkgPath
) {
125 if !eqtype(lhsMethod
.typ
, rhsMethod
.mtyp
) {
129 panic(&TypeAssertionError
{nil, rhs
, lhs
, *lhsMethod
.name
})
132 methods
[li
+1] = unsafe
.Pointer(rhsMethod
.tfn
)
136 return unsafe
.Pointer(&methods
[0])
139 // Return the interface method table for a value of type rhs converted
140 // to an interface of type lhs. Panics if the conversion is impossible.
141 func requireitab(lhs
, rhs
*_type
) unsafe
.Pointer
{
142 return getitab(lhs
, rhs
, false)
145 // Return the interface method table for a value of type rhs converted
146 // to an interface of type lhs. Panics if the conversion is
147 // impossible or if the rhs type is nil.
148 func assertitab(lhs
, rhs
*_type
) unsafe
.Pointer
{
150 panic(&TypeAssertionError
{nil, nil, lhs
, ""})
153 if lhs
.kind
&kindMask
!= kindInterface
{
154 throw("assertitab called for non-interface type")
157 lhsi
:= (*interfacetype
)(unsafe
.Pointer(lhs
))
159 if len(lhsi
.methods
) == 0 {
160 return unsafe
.Pointer(rhs
)
163 return getitab(lhs
, rhs
, false)
166 // Check whether an interface type may be converted to a non-interface
167 // type, panicing if not.
168 func assertI2T(lhs
, rhs
, inter
*_type
) {
170 panic(&TypeAssertionError
{nil, nil, lhs
, ""})
172 if !eqtype(lhs
, rhs
) {
173 panic(&TypeAssertionError
{inter
, rhs
, lhs
, ""})
177 // Compare two type descriptors for equality.
178 func ifacetypeeq(a
, b
*_type
) bool {
182 // Return the type descriptor of an empty interface.
183 // FIXME: This should be inlined by the compiler.
184 func efacetype(e eface
) *_type
{
188 // Return the type descriptor of a non-empty interface.
189 // FIXME: This should be inlined by the compiler.
190 func ifacetype(i iface
) *_type
{
194 return *(**_type
)(i
.tab
)
197 // Convert an empty interface to an empty interface, for a comma-ok
199 func ifaceE2E2(e eface
) (eface
, bool) {
200 return e
, e
._type
!= nil
203 // Convert a non-empty interface to an empty interface, for a comma-ok
205 func ifaceI2E2(i iface
) (eface
, bool) {
207 return eface
{nil, nil}, false
209 return eface
{*(**_type
)(i
.tab
), i
.data
}, true
213 // Convert an empty interface to a non-empty interface, for a comma-ok
215 func ifaceE2I2(inter
*_type
, e eface
) (iface
, bool) {
217 return iface
{nil, nil}, false
219 itab
:= getitab(inter
, e
._type
, true)
221 return iface
{nil, nil}, false
223 return iface
{itab
, e
.data
}, true
228 // Convert a non-empty interface to a non-empty interface, for a
229 // comma-ok type assertion.
230 func ifaceI2I2(inter
*_type
, i iface
) (iface
, bool) {
232 return iface
{nil, nil}, false
234 itab
:= getitab(inter
, *(**_type
)(i
.tab
), true)
236 return iface
{nil, nil}, false
238 return iface
{itab
, i
.data
}, true
243 // Convert an empty interface to a pointer non-interface type.
244 func ifaceE2T2P(t
*_type
, e eface
) (unsafe
.Pointer
, bool) {
245 if !eqtype(t
, e
._type
) {
252 // Convert a non-empty interface to a pointer non-interface type.
253 func ifaceI2T2P(t
*_type
, i iface
) (unsafe
.Pointer
, bool) {
254 if i
.tab
== nil ||
!eqtype(t
, *(**_type
)(i
.tab
)) {
261 // Convert an empty interface to a non-pointer non-interface type.
262 func ifaceE2T2(t
*_type
, e eface
, ret unsafe
.Pointer
) bool {
263 if !eqtype(t
, e
._type
) {
267 typedmemmove(t
, ret
, e
.data
)
272 // Convert a non-empty interface to a non-pointer non-interface type.
273 func ifaceI2T2(t
*_type
, i iface
, ret unsafe
.Pointer
) bool {
274 if i
.tab
== nil ||
!eqtype(t
, *(**_type
)(i
.tab
)) {
278 typedmemmove(t
, ret
, i
.data
)
283 // Return whether we can convert a type to an interface type.
284 func ifaceT2Ip(to
, from
*_type
) bool {
289 if to
.kind
&kindMask
!= kindInterface
{
290 throw("ifaceT2Ip called with non-interface type")
292 toi
:= (*interfacetype
)(unsafe
.Pointer(to
))
294 if from
.uncommontype
== nil ||
len(from
.methods
) == 0 {
295 return len(toi
.methods
) == 0
299 for li
:= range toi
.methods
{
300 toMethod
:= &toi
.methods
[li
]
301 var fromMethod
*method
303 if ri
>= len(from
.methods
) {
307 fromMethod
= &from
.methods
[ri
]
308 if (toMethod
.name
== fromMethod
.name ||
*toMethod
.name
== *fromMethod
.name
) &&
309 (toMethod
.pkgPath
== fromMethod
.pkgPath ||
*toMethod
.pkgPath
== *fromMethod
.pkgPath
) {
316 if !eqtype(fromMethod
.mtyp
, toMethod
.typ
) {
326 //go:linkname reflect_ifaceE2I reflect.ifaceE2I
327 func reflect_ifaceE2I(inter
*interfacetype
, e eface
, dst
*iface
) {
330 panic(TypeAssertionError
{nil, nil, &inter
.typ
, ""})
332 dst
.tab
= requireitab((*_type
)(unsafe
.Pointer(inter
)), t
)
336 // staticbytes is used to avoid convT2E for byte-sized values.
337 var staticbytes
= [...]byte{
338 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
339 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
340 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
341 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
342 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
343 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
344 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
345 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
346 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
347 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
348 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
349 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
350 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
351 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
352 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
353 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
354 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
355 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
356 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
357 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
358 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
359 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
360 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
361 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
362 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
363 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
364 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
365 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
366 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
367 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
368 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
369 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,