mirror of
https://github.com/golang/go
synced 2024-11-22 08:44:41 -07:00
gc: implement nil map support
The spec has defined nil maps this way for months. I'm behind. R=ken2 CC=golang-dev https://golang.org/cl/4901052
This commit is contained in:
parent
cf79411b1d
commit
65bde087ae
@ -57,12 +57,12 @@ char *runtimeimport =
|
|||||||
"func \"\".efaceeq (i1 any, i2 any) bool\n"
|
"func \"\".efaceeq (i1 any, i2 any) bool\n"
|
||||||
"func \"\".ifacethash (i1 any) uint32\n"
|
"func \"\".ifacethash (i1 any) uint32\n"
|
||||||
"func \"\".efacethash (i1 any) uint32\n"
|
"func \"\".efacethash (i1 any) uint32\n"
|
||||||
"func \"\".makemap (key *uint8, val *uint8, hint int64) map[any] any\n"
|
"func \"\".makemap (mapType *uint8, hint int64) map[any] any\n"
|
||||||
"func \"\".mapaccess1 (hmap map[any] any, key any) any\n"
|
"func \"\".mapaccess1 (mapType *uint8, hmap map[any] any, key any) any\n"
|
||||||
"func \"\".mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n"
|
"func \"\".mapaccess2 (mapType *uint8, hmap map[any] any, key any) (val any, pres bool)\n"
|
||||||
"func \"\".mapassign1 (hmap map[any] any, key any, val any)\n"
|
"func \"\".mapassign1 (mapType *uint8, hmap map[any] any, key any, val any)\n"
|
||||||
"func \"\".mapassign2 (hmap map[any] any, key any, val any, pres bool)\n"
|
"func \"\".mapassign2 (mapType *uint8, hmap map[any] any, key any, val any, pres bool)\n"
|
||||||
"func \"\".mapiterinit (hmap map[any] any, hiter *any)\n"
|
"func \"\".mapiterinit (mapType *uint8, hmap map[any] any, hiter *any)\n"
|
||||||
"func \"\".mapiternext (hiter *any)\n"
|
"func \"\".mapiternext (hiter *any)\n"
|
||||||
"func \"\".mapiter1 (hiter *any) any\n"
|
"func \"\".mapiter1 (hiter *any) any\n"
|
||||||
"func \"\".mapiter2 (hiter *any) (key any, val any)\n"
|
"func \"\".mapiter2 (hiter *any) (key any, val any)\n"
|
||||||
|
@ -175,7 +175,7 @@ walkrange(Node *n)
|
|||||||
argtype(fn, t->down);
|
argtype(fn, t->down);
|
||||||
argtype(fn, t->type);
|
argtype(fn, t->type);
|
||||||
argtype(fn, th);
|
argtype(fn, th);
|
||||||
init = list(init, mkcall1(fn, T, nil, ha, nod(OADDR, hit, N)));
|
init = list(init, mkcall1(fn, T, nil, typename(t), ha, nod(OADDR, hit, N)));
|
||||||
n->ntest = nod(ONE, nod(OINDEX, hit, nodintconst(0)), nodnil());
|
n->ntest = nod(ONE, nod(OINDEX, hit, nodintconst(0)), nodnil());
|
||||||
|
|
||||||
fn = syslook("mapiternext", 1);
|
fn = syslook("mapiternext", 1);
|
||||||
|
@ -80,12 +80,12 @@ func ifacethash(i1 any) (ret uint32)
|
|||||||
func efacethash(i1 any) (ret uint32)
|
func efacethash(i1 any) (ret uint32)
|
||||||
|
|
||||||
// *byte is really *runtime.Type
|
// *byte is really *runtime.Type
|
||||||
func makemap(key, val *byte, hint int64) (hmap map[any]any)
|
func makemap(mapType *byte, hint int64) (hmap map[any]any)
|
||||||
func mapaccess1(hmap map[any]any, key any) (val any)
|
func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any)
|
||||||
func mapaccess2(hmap map[any]any, key any) (val any, pres bool)
|
func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool)
|
||||||
func mapassign1(hmap map[any]any, key any, val any)
|
func mapassign1(mapType *byte, hmap map[any]any, key any, val any)
|
||||||
func mapassign2(hmap map[any]any, key any, val any, pres bool)
|
func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool)
|
||||||
func mapiterinit(hmap map[any]any, hiter *any)
|
func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)
|
||||||
func mapiternext(hiter *any)
|
func mapiternext(hiter *any)
|
||||||
func mapiter1(hiter *any) (key any)
|
func mapiter1(hiter *any) (key any)
|
||||||
func mapiter2(hiter *any) (key any, val any)
|
func mapiter2(hiter *any) (key any, val any)
|
||||||
|
@ -604,7 +604,7 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
walkexprlistsafe(n->list, init);
|
walkexprlistsafe(n->list, init);
|
||||||
walkexpr(&r->left, init);
|
walkexpr(&r->left, init);
|
||||||
fn = mapfn("mapaccess2", r->left->type);
|
fn = mapfn("mapaccess2", r->left->type);
|
||||||
r = mkcall1(fn, getoutargx(fn->type), init, r->left, r->right);
|
r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left, r->right);
|
||||||
n->rlist = list1(r);
|
n->rlist = list1(r);
|
||||||
n->op = OAS2FUNC;
|
n->op = OAS2FUNC;
|
||||||
goto as2func;
|
goto as2func;
|
||||||
@ -617,7 +617,7 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
walkexprlistsafe(n->list, init);
|
walkexprlistsafe(n->list, init);
|
||||||
l = n->list->n;
|
l = n->list->n;
|
||||||
t = l->left->type;
|
t = l->left->type;
|
||||||
n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n);
|
n = mkcall1(mapfn("mapassign2", t), T, init, typename(t), l->left, l->right, n->rlist->n, n->rlist->next->n);
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case OAS2DOTTYPE:
|
case OAS2DOTTYPE:
|
||||||
@ -852,7 +852,7 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
t = n->left->type;
|
t = n->left->type;
|
||||||
n = mkcall1(mapfn("mapaccess1", t), t->type, init, n->left, n->right);
|
n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case ORECV:
|
case ORECV:
|
||||||
@ -1090,8 +1090,7 @@ walkexpr(Node **np, NodeList **init)
|
|||||||
argtype(fn, t->type); // any-2
|
argtype(fn, t->type); // any-2
|
||||||
|
|
||||||
n = mkcall1(fn, n->type, init,
|
n = mkcall1(fn, n->type, init,
|
||||||
typename(t->down), // key type
|
typename(n->type),
|
||||||
typename(t->type), // value type
|
|
||||||
conv(n->left, types[TINT64]));
|
conv(n->left, types[TINT64]));
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
@ -1697,6 +1696,7 @@ convas(Node *n, NodeList **init)
|
|||||||
|
|
||||||
if(n->left->op == OINDEXMAP) {
|
if(n->left->op == OINDEXMAP) {
|
||||||
n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
|
n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init,
|
||||||
|
typename(n->left->left->type),
|
||||||
n->left->left, n->left->right, n->right);
|
n->left->left, n->left->right, n->right);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -977,7 +977,7 @@ func (v Value) MapIndex(key Value) Value {
|
|||||||
|
|
||||||
flag := (iv.flag | ikey.flag) & flagRO
|
flag := (iv.flag | ikey.flag) & flagRO
|
||||||
elemType := typ.Elem()
|
elemType := typ.Elem()
|
||||||
elemWord, ok := mapaccess(iv.word, ikey.word)
|
elemWord, ok := mapaccess(typ.runtimeType(), iv.word, ikey.word)
|
||||||
if !ok {
|
if !ok {
|
||||||
return Value{}
|
return Value{}
|
||||||
}
|
}
|
||||||
@ -999,7 +999,7 @@ func (v Value) MapKeys() []Value {
|
|||||||
if m != 0 {
|
if m != 0 {
|
||||||
mlen = maplen(m)
|
mlen = maplen(m)
|
||||||
}
|
}
|
||||||
it := mapiterinit(m)
|
it := mapiterinit(iv.typ.runtimeType(), m)
|
||||||
a := make([]Value, mlen)
|
a := make([]Value, mlen)
|
||||||
var i int
|
var i int
|
||||||
for i = 0; i < len(a); i++ {
|
for i = 0; i < len(a); i++ {
|
||||||
@ -1309,7 +1309,7 @@ func (v Value) SetMapIndex(key, val Value) {
|
|||||||
ival = convertForAssignment("reflect.Value.SetMapIndex", nil, iv.typ.Elem(), ival)
|
ival = convertForAssignment("reflect.Value.SetMapIndex", nil, iv.typ.Elem(), ival)
|
||||||
}
|
}
|
||||||
|
|
||||||
mapassign(iv.word, ikey.word, ival.word, ival.kind != Invalid)
|
mapassign(iv.typ.runtimeType(), iv.word, ikey.word, ival.word, ival.kind != Invalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetUint sets v's underlying value to x.
|
// SetUint sets v's underlying value to x.
|
||||||
@ -1725,9 +1725,9 @@ func chansend(ch iword, val iword, nb bool) bool
|
|||||||
|
|
||||||
func makechan(typ *runtime.Type, size uint32) (ch iword)
|
func makechan(typ *runtime.Type, size uint32) (ch iword)
|
||||||
func makemap(t *runtime.Type) iword
|
func makemap(t *runtime.Type) iword
|
||||||
func mapaccess(m iword, key iword) (val iword, ok bool)
|
func mapaccess(t *runtime.Type, m iword, key iword) (val iword, ok bool)
|
||||||
func mapassign(m iword, key, val iword, ok bool)
|
func mapassign(t *runtime.Type, m iword, key, val iword, ok bool)
|
||||||
func mapiterinit(m iword) *byte
|
func mapiterinit(t *runtime.Type, m iword) *byte
|
||||||
func mapiterkey(it *byte) (key iword, ok bool)
|
func mapiterkey(it *byte) (key iword, ok bool)
|
||||||
func mapiternext(it *byte)
|
func mapiternext(it *byte)
|
||||||
func maplen(m iword) int32
|
func maplen(m iword) int32
|
||||||
|
@ -690,13 +690,17 @@ hash_indirect(Hmap *h, void *p)
|
|||||||
|
|
||||||
static int32 debug = 0;
|
static int32 debug = 0;
|
||||||
|
|
||||||
// makemap(key, val *Type, hint uint32) (hmap *map[any]any);
|
// makemap(typ *Type, hint uint32) (hmap *map[any]any);
|
||||||
Hmap*
|
Hmap*
|
||||||
runtime·makemap_c(Type *key, Type *val, int64 hint)
|
runtime·makemap_c(MapType *typ, int64 hint)
|
||||||
{
|
{
|
||||||
Hmap *h;
|
Hmap *h;
|
||||||
int32 keyalg, valalg, keysize, valsize, valsize_in_hash;
|
int32 keyalg, valalg, keysize, valsize, valsize_in_hash;
|
||||||
void (*data_del)(uint32, void*, void*);
|
void (*data_del)(uint32, void*, void*);
|
||||||
|
Type *key, *val;
|
||||||
|
|
||||||
|
key = typ->key;
|
||||||
|
val = typ->elem;
|
||||||
|
|
||||||
if(hint < 0 || (int32)hint != hint)
|
if(hint < 0 || (int32)hint != hint)
|
||||||
runtime·panicstring("makemap: size out of range");
|
runtime·panicstring("makemap: size out of range");
|
||||||
@ -770,9 +774,9 @@ runtime·makemap_c(Type *key, Type *val, int64 hint)
|
|||||||
|
|
||||||
// makemap(key, val *Type, hint int64) (hmap *map[any]any);
|
// makemap(key, val *Type, hint int64) (hmap *map[any]any);
|
||||||
void
|
void
|
||||||
runtime·makemap(Type *key, Type *val, int64 hint, Hmap *ret)
|
runtime·makemap(MapType *typ, int64 hint, Hmap *ret)
|
||||||
{
|
{
|
||||||
ret = runtime·makemap_c(key, val, hint);
|
ret = runtime·makemap_c(typ, hint);
|
||||||
FLUSH(&ret);
|
FLUSH(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,17 +785,22 @@ runtime·makemap(Type *key, Type *val, int64 hint, Hmap *ret)
|
|||||||
void
|
void
|
||||||
reflect·makemap(MapType *t, Hmap *ret)
|
reflect·makemap(MapType *t, Hmap *ret)
|
||||||
{
|
{
|
||||||
ret = runtime·makemap_c(t->key, t->elem, 0);
|
ret = runtime·makemap_c(t, 0);
|
||||||
FLUSH(&ret);
|
FLUSH(&ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·mapaccess(Hmap *h, byte *ak, byte *av, bool *pres)
|
runtime·mapaccess(MapType *t, Hmap *h, byte *ak, byte *av, bool *pres)
|
||||||
{
|
{
|
||||||
byte *res;
|
byte *res;
|
||||||
|
Type *elem;
|
||||||
|
|
||||||
if(h == nil)
|
if(h == nil) {
|
||||||
runtime·panicstring("lookup in nil map");
|
elem = t->elem;
|
||||||
|
runtime·algarray[elem->alg].copy(elem->size, av, nil);
|
||||||
|
*pres = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(runtime·gcwaiting)
|
if(runtime·gcwaiting)
|
||||||
runtime·gosched();
|
runtime·gosched();
|
||||||
@ -809,18 +818,20 @@ runtime·mapaccess(Hmap *h, byte *ak, byte *av, bool *pres)
|
|||||||
// mapaccess1(hmap *map[any]any, key any) (val any);
|
// mapaccess1(hmap *map[any]any, key any) (val any);
|
||||||
#pragma textflag 7
|
#pragma textflag 7
|
||||||
void
|
void
|
||||||
runtime·mapaccess1(Hmap *h, ...)
|
runtime·mapaccess1(MapType *t, Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av;
|
byte *ak, *av;
|
||||||
bool pres;
|
bool pres;
|
||||||
|
|
||||||
if(h == nil)
|
if(h == nil) {
|
||||||
runtime·panicstring("lookup in nil map");
|
ak = (byte*)(&h + 1);
|
||||||
|
av = ak + runtime·rnd(t->key->size, Structrnd);
|
||||||
|
} else {
|
||||||
ak = (byte*)&h + h->ko1;
|
ak = (byte*)&h + h->ko1;
|
||||||
av = (byte*)&h + h->vo1;
|
av = (byte*)&h + h->vo1;
|
||||||
|
}
|
||||||
|
|
||||||
runtime·mapaccess(h, ak, av, &pres);
|
runtime·mapaccess(t, h, ak, av, &pres);
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
runtime·prints("runtime.mapaccess1: map=");
|
runtime·prints("runtime.mapaccess1: map=");
|
||||||
@ -838,18 +849,21 @@ runtime·mapaccess1(Hmap *h, ...)
|
|||||||
// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
|
// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
|
||||||
#pragma textflag 7
|
#pragma textflag 7
|
||||||
void
|
void
|
||||||
runtime·mapaccess2(Hmap *h, ...)
|
runtime·mapaccess2(MapType *t, Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av, *ap;
|
byte *ak, *av, *ap;
|
||||||
|
|
||||||
if(h == nil)
|
if(h == nil) {
|
||||||
runtime·panicstring("lookup in nil map");
|
ak = (byte*)(&h + 1);
|
||||||
|
av = ak + runtime·rnd(t->key->size, Structrnd);
|
||||||
|
ap = av + t->elem->size;
|
||||||
|
} else {
|
||||||
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;
|
||||||
|
}
|
||||||
|
|
||||||
runtime·mapaccess(h, ak, av, ap);
|
runtime·mapaccess(t, h, ak, av, ap);
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
runtime·prints("runtime.mapaccess2: map=");
|
runtime·prints("runtime.mapaccess2: map=");
|
||||||
@ -865,39 +879,39 @@ runtime·mapaccess2(Hmap *h, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For reflect:
|
// For reflect:
|
||||||
// func mapaccess(h map, key iword) (val iword, pres bool)
|
// func mapaccess(t type, h map, key iword) (val iword, pres bool)
|
||||||
// where an iword is the same word an interface value would use:
|
// where an iword is the same word an interface value would use:
|
||||||
// the actual data if it fits, or else a pointer to the data.
|
// the actual data if it fits, or else a pointer to the data.
|
||||||
void
|
void
|
||||||
reflect·mapaccess(Hmap *h, uintptr key, uintptr val, bool pres)
|
reflect·mapaccess(MapType *t, Hmap *h, uintptr key, uintptr val, bool pres)
|
||||||
{
|
{
|
||||||
byte *ak, *av;
|
byte *ak, *av;
|
||||||
|
|
||||||
if(h == nil)
|
if(t->key->size <= sizeof(key))
|
||||||
runtime·panicstring("lookup in nil map");
|
|
||||||
if(h->keysize <= sizeof(key))
|
|
||||||
ak = (byte*)&key;
|
ak = (byte*)&key;
|
||||||
else
|
else
|
||||||
ak = (byte*)key;
|
ak = (byte*)key;
|
||||||
val = 0;
|
val = 0;
|
||||||
pres = false;
|
pres = false;
|
||||||
if(h->valsize <= sizeof(val))
|
if(t->elem->size <= sizeof(val))
|
||||||
av = (byte*)&val;
|
av = (byte*)&val;
|
||||||
else {
|
else {
|
||||||
av = runtime·mal(h->valsize);
|
av = runtime·mal(t->elem->size);
|
||||||
val = (uintptr)av;
|
val = (uintptr)av;
|
||||||
}
|
}
|
||||||
runtime·mapaccess(h, ak, av, &pres);
|
runtime·mapaccess(t, h, ak, av, &pres);
|
||||||
FLUSH(&val);
|
FLUSH(&val);
|
||||||
FLUSH(&pres);
|
FLUSH(&pres);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
runtime·mapassign(Hmap *h, byte *ak, byte *av)
|
runtime·mapassign(MapType *t, Hmap *h, byte *ak, byte *av)
|
||||||
{
|
{
|
||||||
byte *res;
|
byte *res;
|
||||||
int32 hit;
|
int32 hit;
|
||||||
|
|
||||||
|
USED(t);
|
||||||
|
|
||||||
if(h == nil)
|
if(h == nil)
|
||||||
runtime·panicstring("assignment to entry in nil map");
|
runtime·panicstring("assignment to entry in nil map");
|
||||||
|
|
||||||
@ -931,10 +945,10 @@ runtime·mapassign(Hmap *h, byte *ak, byte *av)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapassign1(hmap *map[any]any, key any, val any);
|
// mapassign1(mapType *type, hmap *map[any]any, key any, val any);
|
||||||
#pragma textflag 7
|
#pragma textflag 7
|
||||||
void
|
void
|
||||||
runtime·mapassign1(Hmap *h, ...)
|
runtime·mapassign1(MapType *t, Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av;
|
byte *ak, *av;
|
||||||
|
|
||||||
@ -944,13 +958,13 @@ runtime·mapassign1(Hmap *h, ...)
|
|||||||
ak = (byte*)&h + h->ko2;
|
ak = (byte*)&h + h->ko2;
|
||||||
av = (byte*)&h + h->vo2;
|
av = (byte*)&h + h->vo2;
|
||||||
|
|
||||||
runtime·mapassign(h, ak, av);
|
runtime·mapassign(t, h, ak, av);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapassign2(hmap *map[any]any, key any, val any, pres bool);
|
// mapassign2(mapType *type, hmap *map[any]any, key any, val any, pres bool);
|
||||||
#pragma textflag 7
|
#pragma textflag 7
|
||||||
void
|
void
|
||||||
runtime·mapassign2(Hmap *h, ...)
|
runtime·mapassign2(MapType *t, Hmap *h, ...)
|
||||||
{
|
{
|
||||||
byte *ak, *av, *ap;
|
byte *ak, *av, *ap;
|
||||||
|
|
||||||
@ -964,7 +978,7 @@ runtime·mapassign2(Hmap *h, ...)
|
|||||||
if(*ap == false)
|
if(*ap == false)
|
||||||
av = nil; // delete
|
av = nil; // delete
|
||||||
|
|
||||||
runtime·mapassign(h, ak, av);
|
runtime·mapassign(t, h, ak, av);
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
runtime·prints("mapassign2: map=");
|
runtime·prints("mapassign2: map=");
|
||||||
@ -976,16 +990,16 @@ runtime·mapassign2(Hmap *h, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For reflect:
|
// For reflect:
|
||||||
// func mapassign(h map, key, val iword, pres bool)
|
// func mapassign(t type h map, key, val iword, pres bool)
|
||||||
// where an iword is the same word an interface value would use:
|
// where an iword is the same word an interface value would use:
|
||||||
// the actual data if it fits, or else a pointer to the data.
|
// the actual data if it fits, or else a pointer to the data.
|
||||||
void
|
void
|
||||||
reflect·mapassign(Hmap *h, uintptr key, uintptr val, bool pres)
|
reflect·mapassign(MapType *t, Hmap *h, uintptr key, uintptr val, bool pres)
|
||||||
{
|
{
|
||||||
byte *ak, *av;
|
byte *ak, *av;
|
||||||
|
|
||||||
if(h == nil)
|
if(h == nil)
|
||||||
runtime·panicstring("lookup in nil map");
|
runtime·panicstring("assignment to entry in nil map");
|
||||||
if(h->keysize <= sizeof(key))
|
if(h->keysize <= sizeof(key))
|
||||||
ak = (byte*)&key;
|
ak = (byte*)&key;
|
||||||
else
|
else
|
||||||
@ -996,12 +1010,12 @@ reflect·mapassign(Hmap *h, uintptr key, uintptr val, bool pres)
|
|||||||
av = (byte*)val;
|
av = (byte*)val;
|
||||||
if(!pres)
|
if(!pres)
|
||||||
av = nil;
|
av = nil;
|
||||||
runtime·mapassign(h, ak, av);
|
runtime·mapassign(t, h, ak, av);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapiterinit(hmap *map[any]any, hiter *any);
|
// mapiterinit(mapType *type, hmap *map[any]any, hiter *any);
|
||||||
void
|
void
|
||||||
runtime·mapiterinit(Hmap *h, struct hash_iter *it)
|
runtime·mapiterinit(MapType*, Hmap *h, struct hash_iter *it)
|
||||||
{
|
{
|
||||||
if(h == nil) {
|
if(h == nil) {
|
||||||
it->data = nil;
|
it->data = nil;
|
||||||
@ -1023,11 +1037,11 @@ runtime·mapiterinit(Hmap *h, struct hash_iter *it)
|
|||||||
// For reflect:
|
// For reflect:
|
||||||
// func mapiterinit(h map) (it iter)
|
// func mapiterinit(h map) (it iter)
|
||||||
void
|
void
|
||||||
reflect·mapiterinit(Hmap *h, struct hash_iter *it)
|
reflect·mapiterinit(MapType *t, Hmap *h, struct hash_iter *it)
|
||||||
{
|
{
|
||||||
it = runtime·mal(sizeof *it);
|
it = runtime·mal(sizeof *it);
|
||||||
FLUSH(&it);
|
FLUSH(&it);
|
||||||
runtime·mapiterinit(h, it);
|
runtime·mapiterinit(t, h, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapiternext(hiter *any);
|
// mapiternext(hiter *any);
|
||||||
|
@ -62,6 +62,7 @@ typedef struct Iface Iface;
|
|||||||
typedef struct Itab Itab;
|
typedef struct Itab Itab;
|
||||||
typedef struct Eface Eface;
|
typedef struct Eface Eface;
|
||||||
typedef struct Type Type;
|
typedef struct Type Type;
|
||||||
|
typedef struct MapType MapType;
|
||||||
typedef struct Defer Defer;
|
typedef struct Defer Defer;
|
||||||
typedef struct Panic Panic;
|
typedef struct Panic Panic;
|
||||||
typedef struct Hmap Hmap;
|
typedef struct Hmap Hmap;
|
||||||
@ -616,12 +617,12 @@ int32 runtime·gomaxprocsfunc(int32 n);
|
|||||||
void runtime·procyield(uint32);
|
void runtime·procyield(uint32);
|
||||||
void runtime·osyield(void);
|
void runtime·osyield(void);
|
||||||
|
|
||||||
void runtime·mapassign(Hmap*, byte*, byte*);
|
void runtime·mapassign(MapType*, Hmap*, byte*, byte*);
|
||||||
void runtime·mapaccess(Hmap*, byte*, byte*, bool*);
|
void runtime·mapaccess(MapType*, Hmap*, byte*, byte*, bool*);
|
||||||
void runtime·mapiternext(struct hash_iter*);
|
void runtime·mapiternext(struct hash_iter*);
|
||||||
bool runtime·mapiterkey(struct hash_iter*, void*);
|
bool runtime·mapiterkey(struct hash_iter*, void*);
|
||||||
void runtime·mapiterkeyvalue(struct hash_iter*, void*, void*);
|
void runtime·mapiterkeyvalue(struct hash_iter*, void*, void*);
|
||||||
Hmap* runtime·makemap_c(Type*, Type*, int64);
|
Hmap* runtime·makemap_c(MapType*, int64);
|
||||||
|
|
||||||
Hchan* runtime·makechan_c(Type*, int64);
|
Hchan* runtime·makechan_c(Type*, int64);
|
||||||
void runtime·chansend(Hchan*, void*, bool*);
|
void runtime·chansend(Hchan*, void*, bool*);
|
||||||
|
@ -16,7 +16,6 @@ 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;
|
|
||||||
typedef struct ChanType ChanType;
|
typedef struct ChanType ChanType;
|
||||||
typedef struct SliceType SliceType;
|
typedef struct SliceType SliceType;
|
||||||
typedef struct FuncType FuncType;
|
typedef struct FuncType FuncType;
|
||||||
|
Loading…
Reference in New Issue
Block a user