Support nil maps.
From-SVN: r179054
This commit is contained in:
parent
bd352290bc
commit
e6f8e59016
@ -87,8 +87,8 @@ DEF_GO_RUNTIME(MAP_INDEX, "__go_map_index", P3(MAP, POINTER, BOOL),
|
|||||||
R1(POINTER))
|
R1(POINTER))
|
||||||
|
|
||||||
// Look up a key in a map returning whether it is present.
|
// Look up a key in a map returning whether it is present.
|
||||||
DEF_GO_RUNTIME(MAPACCESS2, "runtime.mapaccess2", P3(MAP, POINTER, POINTER),
|
DEF_GO_RUNTIME(MAPACCESS2, "runtime.mapaccess2",
|
||||||
R1(BOOL))
|
P4(TYPE, MAP, POINTER, POINTER), R1(BOOL))
|
||||||
|
|
||||||
// Tuple assignment to a map element.
|
// Tuple assignment to a map element.
|
||||||
DEF_GO_RUNTIME(MAPASSIGN2, "runtime.mapassign2",
|
DEF_GO_RUNTIME(MAPASSIGN2, "runtime.mapassign2",
|
||||||
|
@ -1085,14 +1085,16 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*,
|
|||||||
Statement::make_temporary(Type::lookup_bool_type(), NULL, loc);
|
Statement::make_temporary(Type::lookup_bool_type(), NULL, loc);
|
||||||
b->add_statement(present_temp);
|
b->add_statement(present_temp);
|
||||||
|
|
||||||
// present_temp = mapaccess2(MAP, &key_temp, &val_temp)
|
// present_temp = mapaccess2(DESCRIPTOR, MAP, &key_temp, &val_temp)
|
||||||
|
Expression* a1 = Expression::make_type_descriptor(map_type, loc);
|
||||||
|
Expression* a2 = map_index->map();
|
||||||
Temporary_reference_expression* ref =
|
Temporary_reference_expression* ref =
|
||||||
Expression::make_temporary_reference(key_temp, loc);
|
Expression::make_temporary_reference(key_temp, loc);
|
||||||
Expression* a1 = Expression::make_unary(OPERATOR_AND, ref, loc);
|
Expression* a3 = Expression::make_unary(OPERATOR_AND, ref, loc);
|
||||||
ref = Expression::make_temporary_reference(val_temp, loc);
|
ref = Expression::make_temporary_reference(val_temp, loc);
|
||||||
Expression* a2 = Expression::make_unary(OPERATOR_AND, ref, loc);
|
Expression* a4 = Expression::make_unary(OPERATOR_AND, ref, loc);
|
||||||
Expression* call = Runtime::make_call(Runtime::MAPACCESS2, loc, 3,
|
Expression* call = Runtime::make_call(Runtime::MAPACCESS2, loc, 4,
|
||||||
map_index->map(), a1, a2);
|
a1, a2, a3, a4);
|
||||||
|
|
||||||
ref = Expression::make_temporary_reference(present_temp, loc);
|
ref = Expression::make_temporary_reference(present_temp, loc);
|
||||||
ref->set_is_lvalue();
|
ref->set_is_lvalue();
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "go-alloc.h"
|
#include "go-alloc.h"
|
||||||
#include "go-assert.h"
|
#include "go-assert.h"
|
||||||
|
#include "go-panic.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
/* Delete the entry matching KEY from MAP. */
|
/* Delete the entry matching KEY from MAP. */
|
||||||
@ -25,6 +26,9 @@ __go_map_delete (struct __go_map *map, const void *key)
|
|||||||
size_t bucket_index;
|
size_t bucket_index;
|
||||||
void **pentry;
|
void **pentry;
|
||||||
|
|
||||||
|
if (map == NULL)
|
||||||
|
__go_panic_msg ("assignment to entry in nil map");
|
||||||
|
|
||||||
descriptor = map->__descriptor;
|
descriptor = map->__descriptor;
|
||||||
|
|
||||||
key_descriptor = descriptor->__map_descriptor->__key_type;
|
key_descriptor = descriptor->__map_descriptor->__key_type;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "go-alloc.h"
|
#include "go-alloc.h"
|
||||||
#include "go-assert.h"
|
#include "go-assert.h"
|
||||||
|
#include "go-panic.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
/* Rehash MAP to a larger size. */
|
/* Rehash MAP to a larger size. */
|
||||||
@ -85,6 +86,13 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert)
|
|||||||
size_t bucket_index;
|
size_t bucket_index;
|
||||||
char *entry;
|
char *entry;
|
||||||
|
|
||||||
|
if (map == NULL)
|
||||||
|
{
|
||||||
|
if (insert)
|
||||||
|
__go_panic_msg ("assignment to entry in nil map");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
descriptor = map->__descriptor;
|
descriptor = map->__descriptor;
|
||||||
|
|
||||||
key_descriptor = descriptor->__map_descriptor->__key_type;
|
key_descriptor = descriptor->__map_descriptor->__key_type;
|
||||||
|
@ -9,17 +9,18 @@ package runtime
|
|||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
typedef _Bool bool;
|
typedef _Bool bool;
|
||||||
|
|
||||||
typedef struct __go_map hmap;
|
typedef struct __go_map_type MapType;
|
||||||
|
typedef struct __go_map Hmap;
|
||||||
typedef struct __go_hash_iter hiter;
|
typedef struct __go_hash_iter hiter;
|
||||||
|
|
||||||
/* Access a value in a map, returning a value and a presence indicator. */
|
/* Access a value in a map, returning a value and a presence indicator. */
|
||||||
|
|
||||||
func mapaccess2(h *hmap, key *byte, val *byte) (present bool) {
|
func mapaccess2(t *MapType, h *Hmap, key *byte, val *byte) (present bool) {
|
||||||
byte *mapval;
|
byte *mapval;
|
||||||
size_t valsize;
|
size_t valsize;
|
||||||
|
|
||||||
mapval = __go_map_index(h, key, 0);
|
mapval = __go_map_index(h, key, 0);
|
||||||
valsize = h->__descriptor->__map_descriptor->__val_type->__size;
|
valsize = t->__val_type->__size;
|
||||||
if (mapval == nil) {
|
if (mapval == nil) {
|
||||||
__builtin_memset(val, 0, valsize);
|
__builtin_memset(val, 0, valsize);
|
||||||
present = 0;
|
present = 0;
|
||||||
@ -31,7 +32,7 @@ func mapaccess2(h *hmap, key *byte, val *byte) (present bool) {
|
|||||||
|
|
||||||
/* Optionally assign a value to a map (m[k] = v, p). */
|
/* Optionally assign a value to a map (m[k] = v, p). */
|
||||||
|
|
||||||
func mapassign2(h *hmap, key *byte, val *byte, p bool) {
|
func mapassign2(h *Hmap, key *byte, val *byte, p bool) {
|
||||||
if (!p) {
|
if (!p) {
|
||||||
__go_map_delete(h, key);
|
__go_map_delete(h, key);
|
||||||
} else {
|
} else {
|
||||||
@ -46,7 +47,7 @@ func mapassign2(h *hmap, key *byte, val *byte, p bool) {
|
|||||||
|
|
||||||
/* Initialize a range over a map. */
|
/* Initialize a range over a map. */
|
||||||
|
|
||||||
func mapiterinit(h *hmap, it *hiter) {
|
func mapiterinit(h *Hmap, it *hiter) {
|
||||||
__go_mapiterinit(h, it);
|
__go_mapiterinit(h, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user