Commit 730f6d14 by Ian Lance Taylor

compiler, runtime: change type hash/equal to Go funcs

    
    Change the type descriptor hash and equal functions from C code pointers
    to Go func values.  This permits them to be set to a Go function
    closure.  This is in preparation for the Go 1.5, so that we can use a
    closure for the hash/equal functions returned by the new reflect.ArrayOf
    function.
    
    Reviewed-on: https://go-review.googlesource.com/16485

From-SVN: r229541
parent 285b1f01
11e249a59e8c627fe9c2938c38e39cb1efefb1fb 57da43e8159bfe1a31e49683c371cf36e2fb6051
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -1197,19 +1197,29 @@ Func_descriptor_expression::do_get_backend(Translate_context* context) ...@@ -1197,19 +1197,29 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
std::string var_name; std::string var_name;
if (no->package() == NULL) bool is_descriptor = false;
var_name = gogo->pkgpath_symbol(); if (no->is_function_declaration()
&& !no->func_declaration_value()->asm_name().empty()
&& Linemap::is_predeclared_location(no->location()))
{
var_name = no->func_declaration_value()->asm_name() + "_descriptor";
is_descriptor = true;
}
else else
var_name = no->package()->pkgpath_symbol(); {
var_name.push_back('.'); if (no->package() == NULL)
var_name.append(Gogo::unpack_hidden_name(no->name())); var_name = gogo->pkgpath_symbol();
var_name.append("$descriptor"); else
var_name = no->package()->pkgpath_symbol();
var_name.push_back('.');
var_name.append(Gogo::unpack_hidden_name(no->name()));
var_name.append("$descriptor");
}
Btype* btype = this->type()->get_backend(gogo); Btype* btype = this->type()->get_backend(gogo);
Bvariable* bvar; Bvariable* bvar;
if (no->package() != NULL if (no->package() != NULL || is_descriptor)
|| Linemap::is_predeclared_location(no->location()))
bvar = context->backend()->immutable_struct_reference(var_name, btype, bvar = context->backend()->immutable_struct_reference(var_name, btype,
loc); loc);
else else
......
...@@ -1474,6 +1474,27 @@ Type::make_type_descriptor_type() ...@@ -1474,6 +1474,27 @@ Type::make_type_descriptor_type()
Type* void_type = Type::make_void_type(); Type* void_type = Type::make_void_type();
Type* unsafe_pointer_type = Type::make_pointer_type(void_type); Type* unsafe_pointer_type = Type::make_pointer_type(void_type);
Typed_identifier_list *params = new Typed_identifier_list();
params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc));
params->push_back(Typed_identifier("key_size", uintptr_type, bloc));
Typed_identifier_list* results = new Typed_identifier_list();
results->push_back(Typed_identifier("", uintptr_type, bloc));
Type* hash_fntype = Type::make_function_type(NULL, params, results,
bloc);
params = new Typed_identifier_list();
params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc));
params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc));
params->push_back(Typed_identifier("key_size", uintptr_type, bloc));
results = new Typed_identifier_list();
results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc));
Type* equal_fntype = Type::make_function_type(NULL, params, results,
bloc);
// Forward declaration for the type descriptor type. // Forward declaration for the type descriptor type.
Named_object* named_type_descriptor_type = Named_object* named_type_descriptor_type =
Named_object::make_type_declaration("commonType", NULL, bloc); Named_object::make_type_declaration("commonType", NULL, bloc);
...@@ -1514,8 +1535,8 @@ Type::make_type_descriptor_type() ...@@ -1514,8 +1535,8 @@ Type::make_type_descriptor_type()
"fieldAlign", uint8_type, "fieldAlign", uint8_type,
"size", uintptr_type, "size", uintptr_type,
"hash", uint32_type, "hash", uint32_type,
"hashfn", uintptr_type, "hashfn", hash_fntype,
"equalfn", uintptr_type, "equalfn", equal_fntype,
"gc", uintptr_type, "gc", uintptr_type,
"string", pointer_string_type, "string", pointer_string_type,
"", pointer_uncommon_type, "", pointer_uncommon_type,
...@@ -1852,6 +1873,10 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name, ...@@ -1852,6 +1873,10 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name,
gogo->add_block(b, bloc); gogo->add_block(b, bloc);
gogo->lower_block(equal_fn, b); gogo->lower_block(equal_fn, b);
gogo->finish_function(bloc); gogo->finish_function(bloc);
// Build the function descriptors for the type descriptor to refer to.
hash_fn->func_value()->descriptor(gogo, hash_fn);
equal_fn->func_value()->descriptor(gogo, equal_fn);
} }
// Write a hash function that simply calls the hash function for a // Write a hash function that simply calls the hash function for a
...@@ -2009,8 +2034,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind, ...@@ -2009,8 +2034,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
Named_object* equal_fn; Named_object* equal_fn;
this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn, this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn,
&equal_fn); &equal_fn);
vals->push_back(Expression::make_func_code_reference(hash_fn, bloc)); vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc));
vals->push_back(Expression::make_func_code_reference(equal_fn, bloc)); vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc));
++p; ++p;
go_assert(p->is_field_name("gc")); go_assert(p->is_field_name("gc"));
......
...@@ -255,8 +255,8 @@ type rtype struct { ...@@ -255,8 +255,8 @@ type rtype struct {
size uintptr size uintptr
hash uint32 // hash of type; avoids computation in hash tables hash uint32 // hash of type; avoids computation in hash tables
hashfn uintptr // hash function code hashfn func(unsafe.Pointer, uintptr) // hash function
equalfn uintptr // equality function code equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function
gc unsafe.Pointer // garbage collection data gc unsafe.Pointer // garbage collection data
string *string // string form; unnecessary but undeniably useful string *string // string form; unnecessary but undeniably useful
......
...@@ -28,8 +28,8 @@ __go_empty_interface_compare (struct __go_empty_interface left, ...@@ -28,8 +28,8 @@ __go_empty_interface_compare (struct __go_empty_interface left,
return 1; return 1;
if (__go_is_pointer_type (left_descriptor)) if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1; return left.__object == right.__object ? 0 : 1;
if (!left_descriptor->__equalfn (left.__object, right.__object, if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
left_descriptor->__size)) right.__object, left_descriptor->__size))
return 1; return 1;
return 0; return 0;
} }
...@@ -26,8 +26,8 @@ __go_empty_interface_value_compare ( ...@@ -26,8 +26,8 @@ __go_empty_interface_value_compare (
return 1; return 1;
if (__go_is_pointer_type (left_descriptor)) if (__go_is_pointer_type (left_descriptor))
return left.__object == val ? 0 : 1; return left.__object == val ? 0 : 1;
if (!left_descriptor->__equalfn (left.__object, val, if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
left_descriptor->__size)) left_descriptor->__size))
return 1; return 1;
return 0; return 0;
} }
...@@ -28,8 +28,8 @@ __go_interface_compare (struct __go_interface left, ...@@ -28,8 +28,8 @@ __go_interface_compare (struct __go_interface left,
return 1; return 1;
if (__go_is_pointer_type (left_descriptor)) if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1; return left.__object == right.__object ? 0 : 1;
if (!left_descriptor->__equalfn (left.__object, right.__object, if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
left_descriptor->__size)) right.__object, left_descriptor->__size))
return 1; return 1;
return 0; return 0;
} }
...@@ -27,8 +27,8 @@ __go_interface_empty_compare (struct __go_interface left, ...@@ -27,8 +27,8 @@ __go_interface_empty_compare (struct __go_interface left,
return 1; return 1;
if (__go_is_pointer_type (left_descriptor)) if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1; return left.__object == right.__object ? 0 : 1;
if (!left_descriptor->__equalfn (left.__object, right.__object, if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
left_descriptor->__size)) right.__object, left_descriptor->__size))
return 1; return 1;
return 0; return 0;
} }
...@@ -26,8 +26,8 @@ __go_interface_value_compare ( ...@@ -26,8 +26,8 @@ __go_interface_value_compare (
return 1; return 1;
if (__go_is_pointer_type (left_descriptor)) if (__go_is_pointer_type (left_descriptor))
return left.__object == val ? 0 : 1; return left.__object == val ? 0 : 1;
if (!left_descriptor->__equalfn (left.__object, val, if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
left_descriptor->__size)) left_descriptor->__size))
return 1; return 1;
return 0; return 0;
} }
...@@ -21,7 +21,7 @@ __go_map_delete (struct __go_map *map, const void *key) ...@@ -21,7 +21,7 @@ __go_map_delete (struct __go_map *map, const void *key)
const struct __go_map_descriptor *descriptor; const struct __go_map_descriptor *descriptor;
const struct __go_type_descriptor *key_descriptor; const struct __go_type_descriptor *key_descriptor;
uintptr_t key_offset; uintptr_t key_offset;
_Bool (*equalfn) (const void*, const void*, uintptr_t); const FuncVal *equalfn;
size_t key_hash; size_t key_hash;
size_t key_size; size_t key_size;
size_t bucket_index; size_t bucket_index;
...@@ -41,14 +41,14 @@ __go_map_delete (struct __go_map *map, const void *key) ...@@ -41,14 +41,14 @@ __go_map_delete (struct __go_map *map, const void *key)
__go_assert (key_size != -1UL); __go_assert (key_size != -1UL);
equalfn = key_descriptor->__equalfn; equalfn = key_descriptor->__equalfn;
key_hash = key_descriptor->__hashfn (key, key_size); key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
bucket_index = key_hash % map->__bucket_count; bucket_index = key_hash % map->__bucket_count;
pentry = map->__buckets + bucket_index; pentry = map->__buckets + bucket_index;
while (*pentry != NULL) while (*pentry != NULL)
{ {
char *entry = (char *) *pentry; char *entry = (char *) *pentry;
if (equalfn (key, entry + key_offset, key_size)) if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
{ {
*pentry = *(void **) entry; *pentry = *(void **) entry;
if (descriptor->__entry_size >= TinySize) if (descriptor->__entry_size >= TinySize)
......
...@@ -22,7 +22,7 @@ __go_map_rehash (struct __go_map *map) ...@@ -22,7 +22,7 @@ __go_map_rehash (struct __go_map *map)
const struct __go_type_descriptor *key_descriptor; const struct __go_type_descriptor *key_descriptor;
uintptr_t key_offset; uintptr_t key_offset;
size_t key_size; size_t key_size;
uintptr_t (*hashfn) (const void *, uintptr_t); const FuncVal *hashfn;
uintptr_t old_bucket_count; uintptr_t old_bucket_count;
void **old_buckets; void **old_buckets;
uintptr_t new_bucket_count; uintptr_t new_bucket_count;
...@@ -55,7 +55,7 @@ __go_map_rehash (struct __go_map *map) ...@@ -55,7 +55,7 @@ __go_map_rehash (struct __go_map *map)
/* We could speed up rehashing at the cost of memory space /* We could speed up rehashing at the cost of memory space
by caching the hash code. */ by caching the hash code. */
key_hash = hashfn (entry + key_offset, key_size); key_hash = __go_call_hashfn (hashfn, entry + key_offset, key_size);
new_bucket_index = key_hash % new_bucket_count; new_bucket_index = key_hash % new_bucket_count;
next = *(char **) entry; next = *(char **) entry;
...@@ -82,7 +82,7 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert) ...@@ -82,7 +82,7 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert)
const struct __go_map_descriptor *descriptor; const struct __go_map_descriptor *descriptor;
const struct __go_type_descriptor *key_descriptor; const struct __go_type_descriptor *key_descriptor;
uintptr_t key_offset; uintptr_t key_offset;
_Bool (*equalfn) (const void*, const void*, uintptr_t); const FuncVal *equalfn;
size_t key_hash; size_t key_hash;
size_t key_size; size_t key_size;
size_t bucket_index; size_t bucket_index;
...@@ -103,13 +103,13 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert) ...@@ -103,13 +103,13 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert)
__go_assert (key_size != -1UL); __go_assert (key_size != -1UL);
equalfn = key_descriptor->__equalfn; equalfn = key_descriptor->__equalfn;
key_hash = key_descriptor->__hashfn (key, key_size); key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size);
bucket_index = key_hash % map->__bucket_count; bucket_index = key_hash % map->__bucket_count;
entry = (char *) map->__buckets[bucket_index]; entry = (char *) map->__buckets[bucket_index];
while (entry != NULL) while (entry != NULL)
{ {
if (equalfn (key, entry + key_offset, key_size)) if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size))
return entry + descriptor->__val_offset; return entry + descriptor->__val_offset;
entry = *(char **) entry; entry = *(char **) entry;
} }
......
...@@ -151,5 +151,6 @@ extern _Bool ismapkey (const struct __go_type_descriptor *) ...@@ -151,5 +151,6 @@ extern _Bool ismapkey (const struct __go_type_descriptor *)
_Bool _Bool
ismapkey (const struct __go_type_descriptor *typ) ismapkey (const struct __go_type_descriptor *typ)
{ {
return typ != NULL && typ->__hashfn != __go_type_hash_error; return (typ != NULL
&& (void *) typ->__hashfn->fn != (void *) __go_type_hash_error);
} }
...@@ -84,6 +84,9 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size) ...@@ -84,6 +84,9 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size)
runtime_throw ("__go_type_hash_complex: invalid complex size"); runtime_throw ("__go_type_hash_complex: invalid complex size");
} }
const FuncVal __go_type_hash_complex_descriptor =
{ (void *) __go_type_hash_complex };
/* Equality function for complex types. */ /* Equality function for complex types. */
_Bool _Bool
...@@ -112,3 +115,6 @@ __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size) ...@@ -112,3 +115,6 @@ __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
else else
runtime_throw ("__go_type_equal_complex: invalid complex size"); runtime_throw ("__go_type_equal_complex: invalid complex size");
} }
const FuncVal __go_type_equal_complex_descriptor =
{ (void *) __go_type_equal_complex };
...@@ -24,11 +24,14 @@ __go_type_hash_empty_interface (const void *vval, ...@@ -24,11 +24,14 @@ __go_type_hash_empty_interface (const void *vval,
return 0; return 0;
size = descriptor->__size; size = descriptor->__size;
if (__go_is_pointer_type (descriptor)) if (__go_is_pointer_type (descriptor))
return descriptor->__hashfn (&val->__object, size); return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
else else
return descriptor->__hashfn (val->__object, size); return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
} }
const FuncVal __go_type_hash_empty_interface_descriptor =
{ (void *) __go_type_hash_empty_interface };
/* An equality function for an empty interface. */ /* An equality function for an empty interface. */
_Bool _Bool
...@@ -51,6 +54,9 @@ __go_type_equal_empty_interface (const void *vv1, const void *vv2, ...@@ -51,6 +54,9 @@ __go_type_equal_empty_interface (const void *vv1, const void *vv2,
if (__go_is_pointer_type (v1_descriptor)) if (__go_is_pointer_type (v1_descriptor))
return v1->__object == v2->__object; return v1->__object == v2->__object;
else else
return v1_descriptor->__equalfn (v1->__object, v2->__object, return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
v1_descriptor->__size); v2->__object, v1_descriptor->__size);
} }
const FuncVal __go_type_equal_empty_interface_descriptor =
{ (void *) __go_type_equal_empty_interface };
...@@ -17,6 +17,9 @@ __go_type_hash_error (const void *val __attribute__ ((unused)), ...@@ -17,6 +17,9 @@ __go_type_hash_error (const void *val __attribute__ ((unused)),
runtime_panicstring ("hash of unhashable type"); runtime_panicstring ("hash of unhashable type");
} }
const FuncVal __go_type_hash_error_descriptor =
{ (void *) __go_type_hash_error };
/* An equality function for an interface. */ /* An equality function for an interface. */
_Bool _Bool
...@@ -26,3 +29,6 @@ __go_type_equal_error (const void *v1 __attribute__ ((unused)), ...@@ -26,3 +29,6 @@ __go_type_equal_error (const void *v1 __attribute__ ((unused)),
{ {
runtime_panicstring ("comparing uncomparable types"); runtime_panicstring ("comparing uncomparable types");
} }
const FuncVal __go_type_equal_error_descriptor =
{ (void *) __go_type_equal_error };
...@@ -56,6 +56,9 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size) ...@@ -56,6 +56,9 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size)
runtime_throw ("__go_type_hash_float: invalid float size"); runtime_throw ("__go_type_hash_float: invalid float size");
} }
const FuncVal __go_type_hash_float_descriptor =
{ (void *) __go_type_hash_float };
/* Equality function for float types. */ /* Equality function for float types. */
_Bool _Bool
...@@ -84,3 +87,6 @@ __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size) ...@@ -84,3 +87,6 @@ __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
else else
runtime_throw ("__go_type_equal_float: invalid float size"); runtime_throw ("__go_type_equal_float: invalid float size");
} }
const FuncVal __go_type_equal_float_descriptor =
{ (void *) __go_type_equal_float };
...@@ -45,6 +45,9 @@ __go_type_hash_identity (const void *key, uintptr_t key_size) ...@@ -45,6 +45,9 @@ __go_type_hash_identity (const void *key, uintptr_t key_size)
return ret; return ret;
} }
const FuncVal __go_type_hash_identity_descriptor =
{ (void *) __go_type_hash_identity };
/* An identity equality function for a type. This is used for types /* An identity equality function for a type. This is used for types
where we can check for equality by checking that the values have where we can check for equality by checking that the values have
the same bits. */ the same bits. */
...@@ -54,3 +57,6 @@ __go_type_equal_identity (const void *k1, const void *k2, uintptr_t key_size) ...@@ -54,3 +57,6 @@ __go_type_equal_identity (const void *k1, const void *k2, uintptr_t key_size)
{ {
return __builtin_memcmp (k1, k2, key_size) == 0; return __builtin_memcmp (k1, k2, key_size) == 0;
} }
const FuncVal __go_type_equal_identity_descriptor =
{ (void *) __go_type_equal_identity };
...@@ -24,11 +24,14 @@ __go_type_hash_interface (const void *vval, ...@@ -24,11 +24,14 @@ __go_type_hash_interface (const void *vval,
descriptor = (const struct __go_type_descriptor *) val->__methods[0]; descriptor = (const struct __go_type_descriptor *) val->__methods[0];
size = descriptor->__size; size = descriptor->__size;
if (__go_is_pointer_type (descriptor)) if (__go_is_pointer_type (descriptor))
return descriptor->__hashfn (&val->__object, size); return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
else else
return descriptor->__hashfn (val->__object, size); return __go_call_hashfn (descriptor->__hashfn, val->__object, size);
} }
const FuncVal __go_type_hash_interface_descriptor =
{ (void *) __go_type_hash_interface };
/* An equality function for an interface. */ /* An equality function for an interface. */
_Bool _Bool
...@@ -51,6 +54,9 @@ __go_type_equal_interface (const void *vv1, const void *vv2, ...@@ -51,6 +54,9 @@ __go_type_equal_interface (const void *vv1, const void *vv2,
if (__go_is_pointer_type (v1_descriptor)) if (__go_is_pointer_type (v1_descriptor))
return v1->__object == v2->__object; return v1->__object == v2->__object;
else else
return v1_descriptor->__equalfn (v1->__object, v2->__object, return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
v1_descriptor->__size); v2->__object, v1_descriptor->__size);
} }
const FuncVal __go_type_equal_interface_descriptor =
{ (void *) __go_type_equal_interface };
...@@ -28,6 +28,9 @@ __go_type_hash_string (const void *vkey, ...@@ -28,6 +28,9 @@ __go_type_hash_string (const void *vkey,
return ret; return ret;
} }
const FuncVal __go_type_hash_string_descriptor =
{ (void *) __go_type_hash_string };
/* A string equality function for a map. */ /* A string equality function for a map. */
_Bool _Bool
...@@ -41,3 +44,6 @@ __go_type_equal_string (const void *vk1, const void *vk2, ...@@ -41,3 +44,6 @@ __go_type_equal_string (const void *vk1, const void *vk2,
k2 = (const String *) vk2; k2 = (const String *) vk2;
return __go_ptr_strings_equal (k1, k2); return __go_ptr_strings_equal (k1, k2);
} }
const FuncVal __go_type_equal_string_descriptor =
{ (void *) __go_type_equal_string };
...@@ -89,11 +89,11 @@ struct __go_type_descriptor ...@@ -89,11 +89,11 @@ struct __go_type_descriptor
size of this type, and returns a hash code. We pass the size size of this type, and returns a hash code. We pass the size
explicitly becaues it means that we can share a single instance explicitly becaues it means that we can share a single instance
of this function for various different types. */ of this function for various different types. */
uintptr_t (*__hashfn) (const void *, uintptr_t); const FuncVal *__hashfn;
/* This function takes two pointers to values of this type, and the /* This function takes two pointers to values of this type, and the
size of this type, and returns whether the values are equal. */ size of this type, and returns whether the values are equal. */
_Bool (*__equalfn) (const void *, const void *, uintptr_t); const FuncVal *__equalfn;
/* The garbage collection data. */ /* The garbage collection data. */
const uintptr *__gc; const uintptr *__gc;
...@@ -316,21 +316,52 @@ __go_is_pointer_type (const struct __go_type_descriptor *td) ...@@ -316,21 +316,52 @@ __go_is_pointer_type (const struct __go_type_descriptor *td)
|| (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER); || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER);
} }
/* Call a type hash function, given the __hashfn value. */
static inline uintptr_t
__go_call_hashfn (const FuncVal *hashfn, const void *p, uintptr_t size)
{
uintptr_t (*h) (const void *, uintptr_t) = (void *) hashfn->fn;
return __builtin_call_with_static_chain (h (p, size), hashfn);
}
/* Call a type equality function, given the __equalfn value. */
static inline _Bool
__go_call_equalfn (const FuncVal *equalfn, const void *p1, const void *p2,
uintptr_t size)
{
_Bool (*e) (const void *, const void *, uintptr_t) = (void *) equalfn->fn;
return __builtin_call_with_static_chain (e (p1, p2, size), equalfn);
}
extern _Bool extern _Bool
__go_type_descriptors_equal(const struct __go_type_descriptor*, __go_type_descriptors_equal(const struct __go_type_descriptor*,
const struct __go_type_descriptor*); const struct __go_type_descriptor*);
extern uintptr_t __go_type_hash_identity (const void *, uintptr_t); extern uintptr_t __go_type_hash_identity (const void *, uintptr_t);
extern const FuncVal __go_type_hash_identity_descriptor;
extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_identity_descriptor;
extern uintptr_t __go_type_hash_string (const void *, uintptr_t); extern uintptr_t __go_type_hash_string (const void *, uintptr_t);
extern const FuncVal __go_type_hash_string_descriptor;
extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_string_descriptor;
extern uintptr_t __go_type_hash_float (const void *, uintptr_t); extern uintptr_t __go_type_hash_float (const void *, uintptr_t);
extern const FuncVal __go_type_hash_float_descriptor;
extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_float_descriptor;
extern uintptr_t __go_type_hash_complex (const void *, uintptr_t); extern uintptr_t __go_type_hash_complex (const void *, uintptr_t);
extern const FuncVal __go_type_hash_complex_descriptor;
extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_complex_descriptor;
extern uintptr_t __go_type_hash_interface (const void *, uintptr_t); extern uintptr_t __go_type_hash_interface (const void *, uintptr_t);
extern const FuncVal __go_type_hash_interface_descriptor;
extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_interface_descriptor;
extern uintptr_t __go_type_hash_error (const void *, uintptr_t); extern uintptr_t __go_type_hash_error (const void *, uintptr_t);
extern const FuncVal __go_type_hash_error_descriptor;
extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t); extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t);
extern const FuncVal __go_type_equal_error_descriptor;
#endif /* !defined(LIBGO_GO_TYPE_H) */ #endif /* !defined(LIBGO_GO_TYPE_H) */
...@@ -54,9 +54,9 @@ const struct __go_type_descriptor unsafe_Pointer = ...@@ -54,9 +54,9 @@ const struct __go_type_descriptor unsafe_Pointer =
/* __hash */ /* __hash */
78501163U, 78501163U,
/* __hashfn */ /* __hashfn */
__go_type_hash_identity, &__go_type_hash_identity_descriptor,
/* __equalfn */ /* __equalfn */
__go_type_equal_identity, &__go_type_equal_identity_descriptor,
/* __gc */ /* __gc */
unsafe_Pointer_gc, unsafe_Pointer_gc,
/* __reflection */ /* __reflection */
...@@ -99,9 +99,9 @@ const struct __go_ptr_type pointer_unsafe_Pointer = ...@@ -99,9 +99,9 @@ const struct __go_ptr_type pointer_unsafe_Pointer =
/* __hash */ /* __hash */
1256018616U, 1256018616U,
/* __hashfn */ /* __hashfn */
__go_type_hash_identity, &__go_type_hash_identity_descriptor,
/* __equalfn */ /* __equalfn */
__go_type_equal_identity, &__go_type_equal_identity_descriptor,
/* __gc */ /* __gc */
unsafe_Pointer_gc, unsafe_Pointer_gc,
/* __reflection */ /* __reflection */
......
...@@ -528,9 +528,9 @@ static struct __go_channel_type chan_bool_type_descriptor = ...@@ -528,9 +528,9 @@ static struct __go_channel_type chan_bool_type_descriptor =
/* __hash */ /* __hash */
0, /* This value doesn't matter. */ 0, /* This value doesn't matter. */
/* __hashfn */ /* __hashfn */
__go_type_hash_error, &__go_type_hash_error_descriptor,
/* __equalfn */ /* __equalfn */
__go_type_equal_error, &__go_type_equal_error_descriptor,
/* __gc */ /* __gc */
NULL, /* This value doesn't matter */ NULL, /* This value doesn't matter */
/* __reflection */ /* __reflection */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment