summaryrefslogtreecommitdiff
path: root/libgo/runtime/iface.goc
blob: 05e37736b8879c2e6627f2001e72d7ef1c076a9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runtime
#include "go-panic.h"
#include "go-type.h"
#include "interface.h"
#define nil NULL

typedef _Bool bool;
typedef struct __go_type_descriptor descriptor;
typedef const struct __go_type_descriptor const_descriptor;
typedef struct __go_interface interface;
typedef struct __go_empty_interface empty_interface;

// Compare two type descriptors.
func ifacetypeeq(a *descriptor, b *descriptor) (eq bool) {
	eq = __go_type_descriptors_equal(a, b);
}

// Return the descriptor for an empty interface type.n
func efacetype(e empty_interface) (d *const_descriptor) {
	return e.__type_descriptor;
}

// Return the descriptor for a non-empty interface type.
func ifacetype(i interface) (d *const_descriptor) {
	if (i.__methods == nil) {
		return nil;
	}
	d = i.__methods[0];
}

// Convert an empty interface to an empty interface.
func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		__go_panic_msg("invalid interface value");
	ret = e;
	ok = ret.__type_descriptor != nil;
}

// Convert a non-empty interface to an empty interface.
func ifaceI2E2(i interface) (ret empty_interface, ok bool) {
	if (i.__methods == nil) {
		ret.__type_descriptor = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__type_descriptor = i.__methods[0];
		ret.__object = i.__object;
		ok = 1;
	}
}

// Convert an empty interface to a non-empty interface.
func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		__go_panic_msg("invalid interface value");
	if (e.__type_descriptor == nil) {
		ret.__methods = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__methods = __go_convert_interface_2(inter,
							 e.__type_descriptor,
							 1);
		ret.__object = e.__object;
		ok = ret.__methods != nil;
	}
}

// Convert a non-empty interface to a non-empty interface.
func ifaceI2I2(inter *descriptor, i interface) (ret interface, ok bool) {
	if (i.__methods == nil) {
		ret.__methods = nil;
		ret.__object = nil;
		ok = 0;
	} else {
		ret.__methods = __go_convert_interface_2(inter,
							 i.__methods[0], 1);
		ret.__object = i.__object;
		ok = ret.__methods != nil;
	}
}

// Convert an empty interface to a pointer type.
func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		__go_panic_msg("invalid interface value");
	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
		ret = nil;
		ok = 0;
	} else {
		ret = e.__object;
		ok = 1;
	}
}

// Convert a non-empty interface to a pointer type.
func ifaceI2T2P(inter *descriptor, i interface) (ret *void, ok bool) {
	if (i.__methods == nil
	    || !__go_type_descriptors_equal(inter, i.__methods[0])) {
		ret = nil;
		ok = 0;
	} else {
		ret = i.__object;
		ok = 1;
	}
}

// Convert an empty interface to a non-pointer type.
func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
	if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
		__go_panic_msg("invalid interface value");
	if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
		__builtin_memset(ret, 0, inter->__size);
		ok = 0;
	} else {
		__builtin_memcpy(ret, e.__object, inter->__size);
		ok = 1;
	}
}

// Convert a non-empty interface to a non-pointer type.
func ifaceI2T2(inter *descriptor, i interface, ret *void) (ok bool) {
	if (i.__methods == nil
	    || !__go_type_descriptors_equal(inter, i.__methods[0])) {
		__builtin_memset(ret, 0, inter->__size);
		ok = 0;
	} else {
		__builtin_memcpy(ret, i.__object, inter->__size);
		ok = 1;
	}
}

// Return whether we can convert an interface to a type.
func ifaceI2Tp(to *descriptor, from *descriptor) (ok bool) {
	ok = __go_can_convert_to_interface(to, from);
}