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.
4
5package runtime
6
7import (
8	"unsafe"
9)
10
11// For gccgo, use go:linkname to rename compiler-called functions to
12// themselves, so that the compiler will export them.
13//
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
31
32// The gccgo itab structure is different than the gc one.
33//
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.
37//
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.
47//
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
53// a local variable.
54//
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)
59
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.
73
74// For a nil interface value both fields in the interface struct are nil.
75
76// Return the interface method table for a value of type rhs converted
77// to an interface of type lhs.
78func getitab(lhs, rhs *_type, canfail bool) unsafe.Pointer {
79	if rhs == nil {
80		return nil
81	}
82
83	if lhs.kind&kindMask != kindInterface {
84		throw("getitab called for non-interface type")
85	}
86
87	lhsi := (*interfacetype)(unsafe.Pointer(lhs))
88
89	if len(lhsi.methods) == 0 {
90		throw("getitab called for empty interface type")
91	}
92
93	if rhs.uncommontype == nil || len(rhs.methods) == 0 {
94		if canfail {
95			return nil
96		}
97		panic(&TypeAssertionError{nil, rhs, lhs, *lhsi.methods[0].name})
98	}
99
100	methods := make([]unsafe.Pointer, len(lhsi.methods)+1)
101	methods[0] = unsafe.Pointer(rhs)
102
103	ri := 0
104	for li := range lhsi.methods {
105		lhsMethod := &lhsi.methods[li]
106		var rhsMethod *method
107
108		for {
109			if ri >= len(rhs.methods) {
110				if canfail {
111					return nil
112				}
113				panic(&TypeAssertionError{nil, rhs, lhs, *lhsMethod.name})
114			}
115
116			rhsMethod = &rhs.methods[ri]
117			if (lhsMethod.name == rhsMethod.name || *lhsMethod.name == *rhsMethod.name) &&
118				(lhsMethod.pkgPath == rhsMethod.pkgPath || *lhsMethod.pkgPath == *rhsMethod.pkgPath) {
119				break
120			}
121
122			ri++
123		}
124
125		if !eqtype(lhsMethod.typ, rhsMethod.mtyp) {
126			if canfail {
127				return nil
128			}
129			panic(&TypeAssertionError{nil, rhs, lhs, *lhsMethod.name})
130		}
131
132		methods[li+1] = unsafe.Pointer(rhsMethod.tfn)
133		ri++
134	}
135
136	return unsafe.Pointer(&methods[0])
137}
138
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.
141func requireitab(lhs, rhs *_type) unsafe.Pointer {
142	return getitab(lhs, rhs, false)
143}
144
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.
148func assertitab(lhs, rhs *_type) unsafe.Pointer {
149	if rhs == nil {
150		panic(&TypeAssertionError{nil, nil, lhs, ""})
151	}
152
153	if lhs.kind&kindMask != kindInterface {
154		throw("assertitab called for non-interface type")
155	}
156
157	lhsi := (*interfacetype)(unsafe.Pointer(lhs))
158
159	if len(lhsi.methods) == 0 {
160		return unsafe.Pointer(rhs)
161	}
162
163	return getitab(lhs, rhs, false)
164}
165
166// Check whether an interface type may be converted to a non-interface
167// type, panicing if not.
168func assertI2T(lhs, rhs, inter *_type) {
169	if rhs == nil {
170		panic(&TypeAssertionError{nil, nil, lhs, ""})
171	}
172	if !eqtype(lhs, rhs) {
173		panic(&TypeAssertionError{inter, rhs, lhs, ""})
174	}
175}
176
177// Compare two type descriptors for equality.
178func ifacetypeeq(a, b *_type) bool {
179	return eqtype(a, b)
180}
181
182// Return the type descriptor of an empty interface.
183// FIXME: This should be inlined by the compiler.
184func efacetype(e eface) *_type {
185	return e._type
186}
187
188// Return the type descriptor of a non-empty interface.
189// FIXME: This should be inlined by the compiler.
190func ifacetype(i iface) *_type {
191	if i.tab == nil {
192		return nil
193	}
194	return *(**_type)(i.tab)
195}
196
197// Convert an empty interface to an empty interface, for a comma-ok
198// type assertion.
199func ifaceE2E2(e eface) (eface, bool) {
200	return e, e._type != nil
201}
202
203// Convert a non-empty interface to an empty interface, for a comma-ok
204// type assertion.
205func ifaceI2E2(i iface) (eface, bool) {
206	if i.tab == nil {
207		return eface{nil, nil}, false
208	} else {
209		return eface{*(**_type)(i.tab), i.data}, true
210	}
211}
212
213// Convert an empty interface to a non-empty interface, for a comma-ok
214// type assertion.
215func ifaceE2I2(inter *_type, e eface) (iface, bool) {
216	if e._type == nil {
217		return iface{nil, nil}, false
218	} else {
219		itab := getitab(inter, e._type, true)
220		if itab == nil {
221			return iface{nil, nil}, false
222		} else {
223			return iface{itab, e.data}, true
224		}
225	}
226}
227
228// Convert a non-empty interface to a non-empty interface, for a
229// comma-ok type assertion.
230func ifaceI2I2(inter *_type, i iface) (iface, bool) {
231	if i.tab == nil {
232		return iface{nil, nil}, false
233	} else {
234		itab := getitab(inter, *(**_type)(i.tab), true)
235		if itab == nil {
236			return iface{nil, nil}, false
237		} else {
238			return iface{itab, i.data}, true
239		}
240	}
241}
242
243// Convert an empty interface to a pointer non-interface type.
244func ifaceE2T2P(t *_type, e eface) (unsafe.Pointer, bool) {
245	if !eqtype(t, e._type) {
246		return nil, false
247	} else {
248		return e.data, true
249	}
250}
251
252// Convert a non-empty interface to a pointer non-interface type.
253func ifaceI2T2P(t *_type, i iface) (unsafe.Pointer, bool) {
254	if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
255		return nil, false
256	} else {
257		return i.data, true
258	}
259}
260
261// Convert an empty interface to a non-pointer non-interface type.
262func ifaceE2T2(t *_type, e eface, ret unsafe.Pointer) bool {
263	if !eqtype(t, e._type) {
264		typedmemclr(t, ret)
265		return false
266	} else {
267		typedmemmove(t, ret, e.data)
268		return true
269	}
270}
271
272// Convert a non-empty interface to a non-pointer non-interface type.
273func ifaceI2T2(t *_type, i iface, ret unsafe.Pointer) bool {
274	if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
275		typedmemclr(t, ret)
276		return false
277	} else {
278		typedmemmove(t, ret, i.data)
279		return true
280	}
281}
282
283// Return whether we can convert a type to an interface type.
284func ifaceT2Ip(to, from *_type) bool {
285	if from == nil {
286		return false
287	}
288
289	if to.kind&kindMask != kindInterface {
290		throw("ifaceT2Ip called with non-interface type")
291	}
292	toi := (*interfacetype)(unsafe.Pointer(to))
293
294	if from.uncommontype == nil || len(from.methods) == 0 {
295		return len(toi.methods) == 0
296	}
297
298	ri := 0
299	for li := range toi.methods {
300		toMethod := &toi.methods[li]
301		var fromMethod *method
302		for {
303			if ri >= len(from.methods) {
304				return false
305			}
306
307			fromMethod = &from.methods[ri]
308			if (toMethod.name == fromMethod.name || *toMethod.name == *fromMethod.name) &&
309				(toMethod.pkgPath == fromMethod.pkgPath || *toMethod.pkgPath == *fromMethod.pkgPath) {
310				break
311			}
312
313			ri++
314		}
315
316		if !eqtype(fromMethod.mtyp, toMethod.typ) {
317			return false
318		}
319
320		ri++
321	}
322
323	return true
324}
325
326//go:linkname reflect_ifaceE2I reflect.ifaceE2I
327func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
328	t := e._type
329	if t == nil {
330		panic(TypeAssertionError{nil, nil, &inter.typ, ""})
331	}
332	dst.tab = requireitab((*_type)(unsafe.Pointer(inter)), t)
333	dst.data = e.data
334}
335
336// staticbytes is used to avoid convT2E for byte-sized values.
337var 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,
370}
371