mirror of
https://github.com/golang/go
synced 2024-11-22 17:24:53 -07:00
reflection for maps
R=r DELTA=304 (248 added, 34 deleted, 22 changed) OCL=31345 CL=31347
This commit is contained in:
parent
0ae7882b5c
commit
764b6ec1aa
@ -2,6 +2,7 @@
|
|||||||
# Use of this source code is governed by a BSD-style
|
# Use of this source code is governed by a BSD-style
|
||||||
# license that can be found in the LICENSE file.
|
# license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
# DO NOT EDIT. Automatically generated by gobuild.
|
# DO NOT EDIT. Automatically generated by gobuild.
|
||||||
# gobuild -m >Makefile
|
# gobuild -m >Makefile
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ test: packages
|
|||||||
|
|
||||||
coverage: packages
|
coverage: packages
|
||||||
gotest
|
gotest
|
||||||
6cov -g `pwd` | grep -v '_test\.go:'
|
6cov -g $$(pwd) | grep -v '_test\.go:'
|
||||||
|
|
||||||
%.$O: %.go
|
%.$O: %.go
|
||||||
$(GC) -I_obj $*.go
|
$(GC) -I_obj $*.go
|
||||||
|
@ -597,3 +597,57 @@ func TestNilPtrValueSub(t *testing.T) {
|
|||||||
t.Error("NewValue((*int)(nil)).(*PtrValue).Elem() != nil");
|
t.Error("NewValue((*int)(nil)).(*PtrValue).Elem() != nil");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMapAccess(t *testing.T) {
|
||||||
|
m := map[string]int{ "a": 1, "b": 2 };
|
||||||
|
mv := NewValue(m).(*MapValue);
|
||||||
|
if n := mv.Len(); n != len(m) {
|
||||||
|
t.Errorf("Len = %d, want %d", n, len(m));
|
||||||
|
}
|
||||||
|
keys := mv.Keys();
|
||||||
|
i := 0;
|
||||||
|
newmap := MakeMap(mv.Type().(*MapType));
|
||||||
|
for k, v := range m {
|
||||||
|
// Check that returned Keys match keys in range.
|
||||||
|
// These aren't required to be in the same order,
|
||||||
|
// but they are in this implementation, which makes
|
||||||
|
// the test easier.
|
||||||
|
if i >= len(keys) {
|
||||||
|
t.Errorf("Missing key #%d %q", i, k);
|
||||||
|
} else if kv := keys[i].(*StringValue); kv.Get() != k {
|
||||||
|
t.Errorf("Keys[%d] = %q, want %q", i, kv.Get(), k);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Check that value lookup is correct.
|
||||||
|
vv := mv.Get(NewValue(k));
|
||||||
|
if vi := vv.(*IntValue).Get(); vi != v {
|
||||||
|
t.Errorf("Key %q: have value %d, want %d", vi, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy into new map.
|
||||||
|
newmap.Put(NewValue(k), NewValue(v));
|
||||||
|
}
|
||||||
|
vv := mv.Get(NewValue("not-present"));
|
||||||
|
if vv != nil {
|
||||||
|
t.Errorf("Invalid key: got non-nil value %s", valueToString(vv));
|
||||||
|
}
|
||||||
|
|
||||||
|
newm := newmap.Interface().(map[string]int);
|
||||||
|
if len(newm) != len(m) {
|
||||||
|
t.Errorf("length after copy: newm=%d, m=%d", newm, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range newm {
|
||||||
|
mv, ok := m[k];
|
||||||
|
if mv != v {
|
||||||
|
t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newmap.Put(NewValue("a"), nil);
|
||||||
|
v, ok := newm["a"];
|
||||||
|
if ok {
|
||||||
|
t.Errorf("newm[\"a\"] = %d after delete", v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ package reflect
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect";
|
"reflect";
|
||||||
|
"runtime";
|
||||||
"unsafe";
|
"unsafe";
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,8 +59,12 @@ type Value interface {
|
|||||||
// It is for advanced clients that also
|
// It is for advanced clients that also
|
||||||
// import the "unsafe" package.
|
// import the "unsafe" package.
|
||||||
Addr() uintptr;
|
Addr() uintptr;
|
||||||
|
|
||||||
|
getAddr() addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MakeZero(typ Type) Value
|
||||||
|
|
||||||
type value struct {
|
type value struct {
|
||||||
typ Type;
|
typ Type;
|
||||||
addr addr;
|
addr addr;
|
||||||
@ -74,6 +79,10 @@ func (v *value) Addr() uintptr {
|
|||||||
return uintptr(v.addr);
|
return uintptr(v.addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *value) getAddr() addr {
|
||||||
|
return v.addr;
|
||||||
|
}
|
||||||
|
|
||||||
type InterfaceValue struct
|
type InterfaceValue struct
|
||||||
type StructValue struct
|
type StructValue struct
|
||||||
|
|
||||||
@ -742,21 +751,77 @@ func (v *MapValue) Set(x *MapValue) {
|
|||||||
*(*uintptr)(v.addr) = *(*uintptr)(x.addr);
|
*(*uintptr)(v.addr) = *(*uintptr)(x.addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elem returns the value associated with key in the map v.
|
// implemented in ../pkg/runtime/reflect.cgo
|
||||||
|
func mapaccess(m, key, val *byte) bool
|
||||||
|
func mapassign(m, key, val *byte)
|
||||||
|
func maplen(m *byte) int32
|
||||||
|
func mapiterinit(m *byte) *byte
|
||||||
|
func mapiternext(it *byte)
|
||||||
|
func mapiterkey(it *byte, key *byte) bool
|
||||||
|
func makemap(t *runtime.MapType) *byte
|
||||||
|
|
||||||
|
// Get returns the value associated with key in the map v.
|
||||||
// It returns nil if key is not found in the map.
|
// It returns nil if key is not found in the map.
|
||||||
func (v *MapValue) Elem(key Value) Value {
|
func (v *MapValue) Get(key Value) Value {
|
||||||
panic("unimplemented: map Elem");
|
t := v.Type().(*MapType);
|
||||||
|
typesMustMatch(t.Key(), key.Type());
|
||||||
|
m := *(**byte)(v.addr);
|
||||||
|
if m == nil {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
newval := MakeZero(t.Elem());
|
||||||
|
if !mapaccess(m, (*byte)(key.getAddr()), (*byte)(newval.getAddr())) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return newval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put sets the value associated with key in the map v to val.
|
||||||
|
// If val is nil, Put deletes the key from map.
|
||||||
|
func (v *MapValue) Put(key, val Value) {
|
||||||
|
t := v.Type().(*MapType);
|
||||||
|
typesMustMatch(t.Key(), key.Type());
|
||||||
|
var vaddr *byte;
|
||||||
|
if val != nil {
|
||||||
|
typesMustMatch(t.Elem(), val.Type());
|
||||||
|
vaddr = (*byte)(val.getAddr());
|
||||||
|
}
|
||||||
|
m := *(**byte)(v.addr);
|
||||||
|
mapassign(m, (*byte)(key.getAddr()), vaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of keys in the map v.
|
// Len returns the number of keys in the map v.
|
||||||
func (v *MapValue) Len() int {
|
func (v *MapValue) Len() int {
|
||||||
panic("unimplemented: map Len");
|
m := *(**byte)(v.addr);
|
||||||
|
if m == nil {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return int(maplen(m));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys returns a slice containing all the keys present in the map,
|
// Keys returns a slice containing all the keys present in the map,
|
||||||
// in unspecified order.
|
// in unspecified order.
|
||||||
func (v *MapValue) Keys() []Value {
|
func (v *MapValue) Keys() []Value {
|
||||||
panic("unimplemented: map Keys");
|
tk := v.Type().(*MapType).Key();
|
||||||
|
m := *(**byte)(v.addr);
|
||||||
|
it := mapiterinit(m);
|
||||||
|
a := make([]Value, maplen(m));
|
||||||
|
var i int;
|
||||||
|
for i = 0; i < len(a); i++ {
|
||||||
|
k := MakeZero(tk);
|
||||||
|
if !mapiterkey(it, (*byte)(k.getAddr())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a[i] = k;
|
||||||
|
mapiternext(it);
|
||||||
|
}
|
||||||
|
return a[0:i];
|
||||||
|
}
|
||||||
|
|
||||||
|
func MakeMap(typ *MapType) *MapValue {
|
||||||
|
v := MakeZero(typ).(*MapValue);
|
||||||
|
*(**byte)(v.addr) = makemap((*runtime.MapType)(unsafe.Pointer(typ)));
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -946,7 +1011,7 @@ func newFuncValue(typ Type, addr addr) *FuncValue {
|
|||||||
return newValue(typ, addr, true).(*FuncValue);
|
return newValue(typ, addr, true).(*FuncValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakeZeroValue returns a zero Value for the specified Type.
|
// MakeZero returns a zero Value for the specified Type.
|
||||||
func MakeZero(typ Type) Value {
|
func MakeZero(typ Type) Value {
|
||||||
// TODO: this will have to move into
|
// TODO: this will have to move into
|
||||||
// the runtime proper in order to play nicely
|
// the runtime proper in order to play nicely
|
||||||
|
@ -60,6 +60,7 @@ OFILES=\
|
|||||||
msize.$O\
|
msize.$O\
|
||||||
print.$O\
|
print.$O\
|
||||||
proc.$O\
|
proc.$O\
|
||||||
|
reflect.$O\
|
||||||
rune.$O\
|
rune.$O\
|
||||||
runtime.$O\
|
runtime.$O\
|
||||||
rt0.$O\
|
rt0.$O\
|
||||||
|
@ -662,16 +662,14 @@ donothing(uint32 s, void *a, void *b)
|
|||||||
USED(b);
|
USED(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct hash Hmap;
|
|
||||||
static int32 debug = 0;
|
static int32 debug = 0;
|
||||||
|
|
||||||
// newmap(keysize uint32, valsize uint32,
|
// newmap(keysize uint32, valsize uint32,
|
||||||
// keyalg uint32, valalg uint32,
|
// keyalg uint32, valalg uint32,
|
||||||
// hint uint32) (hmap *map[any]any);
|
// hint uint32) (hmap *map[any]any);
|
||||||
void
|
Hmap*
|
||||||
sys·newmap(uint32 keysize, uint32 valsize,
|
makemap(uint32 keysize, uint32 valsize,
|
||||||
uint32 keyalg, uint32 valalg, uint32 hint,
|
uint32 keyalg, uint32 valalg, uint32 hint)
|
||||||
Hmap* ret)
|
|
||||||
{
|
{
|
||||||
Hmap *h;
|
Hmap *h;
|
||||||
|
|
||||||
@ -721,13 +719,39 @@ sys·newmap(uint32 keysize, uint32 valsize,
|
|||||||
h->vo2 = rnd(h->ko2+keysize, valsize);
|
h->vo2 = rnd(h->ko2+keysize, valsize);
|
||||||
h->po2 = rnd(h->vo2+valsize, 1);
|
h->po2 = rnd(h->vo2+valsize, 1);
|
||||||
|
|
||||||
ret = h;
|
|
||||||
FLUSH(&ret);
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
printf("newmap: map=%p; keysize=%d; valsize=%d; keyalg=%d; valalg=%d; offsets=%d,%d; %d,%d,%d; %d,%d,%d\n",
|
printf("newmap: map=%p; keysize=%d; valsize=%d; keyalg=%d; valalg=%d; offsets=%d,%d; %d,%d,%d; %d,%d,%d\n",
|
||||||
h, keysize, valsize, keyalg, valalg, h->ko0, h->vo0, h->ko1, h->vo1, h->po1, h->ko2, h->vo2, h->po2);
|
h, keysize, valsize, keyalg, valalg, h->ko0, h->vo0, h->ko1, h->vo1, h->po1, h->ko2, h->vo2, h->po2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// newmap(keysize uint32, valsize uint32,
|
||||||
|
// keyalg uint32, valalg uint32,
|
||||||
|
// hint uint32) (hmap *map[any]any);
|
||||||
|
void
|
||||||
|
sys·newmap(uint32 keysize, uint32 valsize,
|
||||||
|
uint32 keyalg, uint32 valalg, uint32 hint,
|
||||||
|
Hmap *ret)
|
||||||
|
{
|
||||||
|
ret = makemap(keysize, valsize, keyalg, valalg, hint);
|
||||||
|
FLUSH(&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mapaccess(Hmap *h, byte *ak, byte *av, bool *pres)
|
||||||
|
{
|
||||||
|
byte *res;
|
||||||
|
|
||||||
|
res = nil;
|
||||||
|
if(hash_lookup(h, ak, (void**)&res)) {
|
||||||
|
*pres = true;
|
||||||
|
h->valalg->copy(h->valsize, av, res+h->datavo);
|
||||||
|
} else {
|
||||||
|
*pres = false;
|
||||||
|
h->valalg->copy(h->valsize, av, nil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapaccess1(hmap *map[any]any, key any) (val any);
|
// mapaccess1(hmap *map[any]any, key any) (val any);
|
||||||
@ -735,17 +759,14 @@ void
|
|||||||
sys·mapaccess1(Hmap *h, ...)
|
sys·mapaccess1(Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av;
|
byte *ak, *av;
|
||||||
byte *res;
|
bool pres;
|
||||||
int32 hit;
|
|
||||||
|
|
||||||
ak = (byte*)&h + h->ko1;
|
ak = (byte*)&h + h->ko1;
|
||||||
av = (byte*)&h + h->vo1;
|
av = (byte*)&h + h->vo1;
|
||||||
|
|
||||||
res = nil;
|
mapaccess(h, ak, av, &pres);
|
||||||
hit = hash_lookup(h, ak, (void**)&res);
|
if(!pres)
|
||||||
if(!hit)
|
|
||||||
throw("sys·mapaccess1: key not in map");
|
throw("sys·mapaccess1: key not in map");
|
||||||
h->valalg->copy(h->valsize, av, res+h->datavo);
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("sys·mapaccess1: map=");
|
prints("sys·mapaccess1: map=");
|
||||||
@ -754,10 +775,8 @@ sys·mapaccess1(Hmap *h, ...)
|
|||||||
h->keyalg->print(h->keysize, ak);
|
h->keyalg->print(h->keysize, ak);
|
||||||
prints("; val=");
|
prints("; val=");
|
||||||
h->valalg->print(h->valsize, av);
|
h->valalg->print(h->valsize, av);
|
||||||
prints("; hit=");
|
prints("; pres=");
|
||||||
sys·printint(hit);
|
sys·printbool(pres);
|
||||||
prints("; res=");
|
|
||||||
sys·printpointer(res);
|
|
||||||
prints("\n");
|
prints("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -767,22 +786,12 @@ void
|
|||||||
sys·mapaccess2(Hmap *h, ...)
|
sys·mapaccess2(Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av, *ap;
|
byte *ak, *av, *ap;
|
||||||
byte *res;
|
|
||||||
int32 hit;
|
|
||||||
|
|
||||||
ak = (byte*)&h + h->ko1;
|
ak = (byte*)&h + h->ko1;
|
||||||
av = (byte*)&h + h->vo1;
|
av = (byte*)&h + h->vo1;
|
||||||
ap = (byte*)&h + h->po1;
|
ap = (byte*)&h + h->po1;
|
||||||
|
|
||||||
res = nil;
|
mapaccess(h, ak, av, ap);
|
||||||
hit = hash_lookup(h, ak, (void**)&res);
|
|
||||||
if(!hit) {
|
|
||||||
*ap = false;
|
|
||||||
h->valalg->copy(h->valsize, av, nil);
|
|
||||||
} else {
|
|
||||||
*ap = true;
|
|
||||||
h->valalg->copy(h->valsize, av, res+h->datavo);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("sys·mapaccess2: map=");
|
prints("sys·mapaccess2: map=");
|
||||||
@ -791,23 +800,24 @@ sys·mapaccess2(Hmap *h, ...)
|
|||||||
h->keyalg->print(h->keysize, ak);
|
h->keyalg->print(h->keysize, ak);
|
||||||
prints("; val=");
|
prints("; val=");
|
||||||
h->valalg->print(h->valsize, av);
|
h->valalg->print(h->valsize, av);
|
||||||
prints("; hit=");
|
|
||||||
sys·printint(hit);
|
|
||||||
prints("; res=");
|
|
||||||
sys·printpointer(res);
|
|
||||||
prints("; pres=");
|
prints("; pres=");
|
||||||
sys·printbool(*ap);
|
sys·printbool(*ap);
|
||||||
prints("\n");
|
prints("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
mapassign(Hmap *h, byte *ak, byte *av)
|
mapassign(Hmap *h, byte *ak, byte *av)
|
||||||
{
|
{
|
||||||
byte *res;
|
byte *res;
|
||||||
int32 hit;
|
int32 hit;
|
||||||
|
|
||||||
res = nil;
|
res = nil;
|
||||||
|
if(av == nil) {
|
||||||
|
hash_remove(h, ak, (void**)&res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hit = hash_insert(h, ak, (void**)&res);
|
hit = hash_insert(h, ak, (void**)&res);
|
||||||
h->keyalg->copy(h->keysize, res, ak);
|
h->keyalg->copy(h->keysize, res, ak);
|
||||||
h->valalg->copy(h->valsize, res+h->datavo, av);
|
h->valalg->copy(h->valsize, res+h->datavo, av);
|
||||||
@ -844,31 +854,21 @@ void
|
|||||||
sys·mapassign2(Hmap *h, ...)
|
sys·mapassign2(Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av, *ap;
|
byte *ak, *av, *ap;
|
||||||
byte *res;
|
|
||||||
int32 hit;
|
|
||||||
|
|
||||||
ak = (byte*)&h + h->ko2;
|
ak = (byte*)&h + h->ko2;
|
||||||
av = (byte*)&h + h->vo2;
|
av = (byte*)&h + h->vo2;
|
||||||
ap = (byte*)&h + h->po2;
|
ap = (byte*)&h + h->po2;
|
||||||
|
|
||||||
if(*ap == true) {
|
if(*ap == false)
|
||||||
// assign
|
av = nil; // delete
|
||||||
mapassign(h, ak, av);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delete
|
mapassign(h, ak, av);
|
||||||
hit = hash_remove(h, ak, (void**)&res);
|
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("mapassign2: map=");
|
prints("mapassign2: map=");
|
||||||
sys·printpointer(h);
|
sys·printpointer(h);
|
||||||
prints("; key=");
|
prints("; key=");
|
||||||
h->keyalg->print(h->keysize, ak);
|
h->keyalg->print(h->keysize, ak);
|
||||||
prints("; hit=");
|
|
||||||
sys·printint(hit);
|
|
||||||
prints("; res=");
|
|
||||||
sys·printpointer(res);
|
|
||||||
prints("\n");
|
prints("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -894,6 +894,16 @@ sys·mapiterinit(Hmap *h, struct hash_iter *it)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct hash_iter*
|
||||||
|
mapiterinit(Hmap *h)
|
||||||
|
{
|
||||||
|
struct hash_iter *it;
|
||||||
|
|
||||||
|
it = mal(sizeof *it);
|
||||||
|
sys·mapiterinit(h, it);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
// mapiternext(hiter *any);
|
// mapiternext(hiter *any);
|
||||||
void
|
void
|
||||||
sys·mapiternext(struct hash_iter *it)
|
sys·mapiternext(struct hash_iter *it)
|
||||||
@ -908,6 +918,12 @@ sys·mapiternext(struct hash_iter *it)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
mapiternext(struct hash_iter *it)
|
||||||
|
{
|
||||||
|
sys·mapiternext(it);
|
||||||
|
}
|
||||||
|
|
||||||
// mapiter1(hiter *any) (key any);
|
// mapiter1(hiter *any) (key any);
|
||||||
void
|
void
|
||||||
sys·mapiter1(struct hash_iter *it, ...)
|
sys·mapiter1(struct hash_iter *it, ...)
|
||||||
@ -933,6 +949,20 @@ sys·mapiter1(struct hash_iter *it, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
mapiterkey(struct hash_iter *it, void *ak)
|
||||||
|
{
|
||||||
|
Hmap *h;
|
||||||
|
byte *res;
|
||||||
|
|
||||||
|
h = it->h;
|
||||||
|
res = it->data;
|
||||||
|
if(res == nil)
|
||||||
|
return false;
|
||||||
|
h->keyalg->copy(h->keysize, ak, res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// mapiter2(hiter *any) (key any, val any);
|
// mapiter2(hiter *any) (key any, val any);
|
||||||
void
|
void
|
||||||
sys·mapiter2(struct hash_iter *it, ...)
|
sys·mapiter2(struct hash_iter *it, ...)
|
||||||
|
51
src/pkg/runtime/reflect.cgo
Normal file
51
src/pkg/runtime/reflect.cgo
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// 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"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
// typ is a *runtime.MapType, but the MapType
|
||||||
|
// defined in type.h includes an interface value header
|
||||||
|
// in front of the raw MapType. the -2 below backs up
|
||||||
|
// to the interface value header.
|
||||||
|
t = (MapType*)((void**)typ - 2);
|
||||||
|
|
||||||
|
map = (byte*)makemap(t->key->size, t->elem->size, t->key->alg, t->elem->alg, 0);
|
||||||
|
}
|
@ -60,6 +60,7 @@ typedef struct Itab Itab;
|
|||||||
typedef struct Eface Eface;
|
typedef struct Eface Eface;
|
||||||
typedef struct Type Type;
|
typedef struct Type Type;
|
||||||
typedef struct Defer Defer;
|
typedef struct Defer Defer;
|
||||||
|
typedef struct hash Hmap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* per cpu declaration
|
* per cpu declaration
|
||||||
@ -457,3 +458,10 @@ float64 ldexp(float64 d, int32 e);
|
|||||||
float64 modf(float64 d, float64 *ip);
|
float64 modf(float64 d, float64 *ip);
|
||||||
void semacquire(uint32*);
|
void semacquire(uint32*);
|
||||||
void semrelease(uint32*);
|
void semrelease(uint32*);
|
||||||
|
void mapassign(Hmap*, byte*, byte*);
|
||||||
|
void mapaccess(Hmap*, byte*, byte*, bool*);
|
||||||
|
struct hash_iter* mapiterinit(Hmap*);
|
||||||
|
void mapiternext(struct hash_iter*);
|
||||||
|
bool mapiterkey(struct hash_iter*, void*);
|
||||||
|
void mapiterkeyvalue(struct hash_iter*, void*, void*);
|
||||||
|
Hmap* makemap(uint32, uint32, uint32, uint32, uint32);
|
||||||
|
@ -11,6 +11,7 @@ typedef struct UncommonType UncommonType;
|
|||||||
typedef struct InterfaceType InterfaceType;
|
typedef struct InterfaceType InterfaceType;
|
||||||
typedef struct Method Method;
|
typedef struct Method Method;
|
||||||
typedef struct IMethod IMethod;
|
typedef struct IMethod IMethod;
|
||||||
|
typedef struct MapType MapType;
|
||||||
|
|
||||||
struct CommonType
|
struct CommonType
|
||||||
{
|
{
|
||||||
@ -63,3 +64,10 @@ struct InterfaceType
|
|||||||
Array mhdr;
|
Array mhdr;
|
||||||
IMethod m[];
|
IMethod m[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MapType
|
||||||
|
{
|
||||||
|
Type;
|
||||||
|
Type *key;
|
||||||
|
Type *elem;
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user