summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/reflect.goc
blob: 51222f1c429bed60ad16395619b2e8c7c5bb921d (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
// Copyright 2009 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 reflect
#include "runtime.h"
#include "type.h"

static Type*
gettype(void *typ)
{
	// typ is a *runtime.Type (or *runtime.MapType, etc), but the Type
	// defined in type.h includes an interface value header
	// in front of the raw structure.  the -2 below backs up
	// to the interface value header.
	return (Type*)((void**)typ - 2);
}

/*
 * Go wrappers around the C functions near the bottom of hashmap.c
 * There's no recursion here even though it looks like there is:
 * the names after func are in the reflect package name space
 * but the names in the C bodies are in the standard C name space.
 */

func mapaccess(map *byte, key *byte, val *byte) (pres bool) {
	mapaccess((Hmap*)map, key, val, &pres);
}

func mapassign(map *byte, key *byte, val *byte) {
	mapassign((Hmap*)map, key, val);
}

func maplen(map *byte) (len int32) {
	// length is first word of map
	len = *(uint32*)map;
}

func mapiterinit(map *byte) (it *byte) {
	it = (byte*)mapiterinit((Hmap*)map);
}

func mapiternext(it *byte) {
	mapiternext((struct hash_iter*)it);
}

func mapiterkey(it *byte, key *byte) (ok bool) {
	ok = mapiterkey((struct hash_iter*)it, key);
}

func makemap(typ *byte) (map *byte) {
	MapType *t;

	t = (MapType*)gettype(typ);
	map = (byte*)makemap(t->key, t->elem, 0);
}

/*
 * Go wrappers around the C functions in chan.c
 */

func makechan(typ *byte, size uint32) (ch *byte) {
	ChanType *t;

	// typ is a *runtime.ChanType, but the ChanType
	// defined in type.h includes an interface value header
	// in front of the raw ChanType.  the -2 below backs up
	// to the interface value header.
	t = (ChanType*)gettype(typ);
	ch = (byte*)makechan(t->elem, size);
}

func chansend(ch *byte, val *byte, pres *bool) {
	chansend((Hchan*)ch, val, pres);
}

func chanrecv(ch *byte, val *byte, pres *bool) {
	chanrecv((Hchan*)ch, val, pres);
}

func chanclose(ch *byte) {
	chanclose((Hchan*)ch);
}

func chanclosed(ch *byte) (r bool) {
	r = chanclosed((Hchan*)ch);
}

func chanlen(ch *byte) (r int32) {
	r = chanlen((Hchan*)ch);
}

func chancap(ch *byte) (r int32) {
	r = chancap((Hchan*)ch);
}


/*
 * Go wrappers around the functions in iface.c
 */

func setiface(typ *byte, x *byte, ret *byte) {
	InterfaceType *t;

	t = (InterfaceType*)gettype(typ);
	if(t->mhdr.len == 0) {
		// already an empty interface
		*(Eface*)ret = *(Eface*)x;
		return;
	}
	if(((Eface*)x)->type == nil) {
		// can assign nil to any interface
		((Iface*)ret)->tab = nil;
		((Iface*)ret)->data = nil;
		return;
	}
	ifaceE2I((InterfaceType*)gettype(typ), *(Eface*)x, (Iface*)ret);
}