mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-24 19:33:59 +08:00
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
This commit is contained in:
parent
285b1f01ac
commit
730f6d1425
@ -1,4 +1,4 @@
|
||||
11e249a59e8c627fe9c2938c38e39cb1efefb1fb
|
||||
57da43e8159bfe1a31e49683c371cf36e2fb6051
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
@ -1197,19 +1197,29 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
|
||||
|
||||
Gogo* gogo = context->gogo();
|
||||
std::string var_name;
|
||||
if (no->package() == NULL)
|
||||
var_name = gogo->pkgpath_symbol();
|
||||
bool is_descriptor = false;
|
||||
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
|
||||
var_name = no->package()->pkgpath_symbol();
|
||||
var_name.push_back('.');
|
||||
var_name.append(Gogo::unpack_hidden_name(no->name()));
|
||||
var_name.append("$descriptor");
|
||||
{
|
||||
if (no->package() == NULL)
|
||||
var_name = gogo->pkgpath_symbol();
|
||||
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);
|
||||
|
||||
Bvariable* bvar;
|
||||
if (no->package() != NULL
|
||||
|| Linemap::is_predeclared_location(no->location()))
|
||||
if (no->package() != NULL || is_descriptor)
|
||||
bvar = context->backend()->immutable_struct_reference(var_name, btype,
|
||||
loc);
|
||||
else
|
||||
|
@ -1474,6 +1474,27 @@ Type::make_type_descriptor_type()
|
||||
Type* void_type = Type::make_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.
|
||||
Named_object* named_type_descriptor_type =
|
||||
Named_object::make_type_declaration("commonType", NULL, bloc);
|
||||
@ -1514,8 +1535,8 @@ Type::make_type_descriptor_type()
|
||||
"fieldAlign", uint8_type,
|
||||
"size", uintptr_type,
|
||||
"hash", uint32_type,
|
||||
"hashfn", uintptr_type,
|
||||
"equalfn", uintptr_type,
|
||||
"hashfn", hash_fntype,
|
||||
"equalfn", equal_fntype,
|
||||
"gc", uintptr_type,
|
||||
"string", pointer_string_type,
|
||||
"", pointer_uncommon_type,
|
||||
@ -1852,6 +1873,10 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name,
|
||||
gogo->add_block(b, bloc);
|
||||
gogo->lower_block(equal_fn, b);
|
||||
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
|
||||
@ -2009,8 +2034,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
|
||||
Named_object* equal_fn;
|
||||
this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn,
|
||||
&equal_fn);
|
||||
vals->push_back(Expression::make_func_code_reference(hash_fn, bloc));
|
||||
vals->push_back(Expression::make_func_code_reference(equal_fn, bloc));
|
||||
vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc));
|
||||
vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc));
|
||||
|
||||
++p;
|
||||
go_assert(p->is_field_name("gc"));
|
||||
|
@ -255,8 +255,8 @@ type rtype struct {
|
||||
size uintptr
|
||||
hash uint32 // hash of type; avoids computation in hash tables
|
||||
|
||||
hashfn uintptr // hash function code
|
||||
equalfn uintptr // equality function code
|
||||
hashfn func(unsafe.Pointer, uintptr) // hash function
|
||||
equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function
|
||||
|
||||
gc unsafe.Pointer // garbage collection data
|
||||
string *string // string form; unnecessary but undeniably useful
|
||||
|
@ -28,8 +28,8 @@ __go_empty_interface_compare (struct __go_empty_interface left,
|
||||
return 1;
|
||||
if (__go_is_pointer_type (left_descriptor))
|
||||
return left.__object == right.__object ? 0 : 1;
|
||||
if (!left_descriptor->__equalfn (left.__object, right.__object,
|
||||
left_descriptor->__size))
|
||||
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
|
||||
right.__object, left_descriptor->__size))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ __go_empty_interface_value_compare (
|
||||
return 1;
|
||||
if (__go_is_pointer_type (left_descriptor))
|
||||
return left.__object == val ? 0 : 1;
|
||||
if (!left_descriptor->__equalfn (left.__object, val,
|
||||
left_descriptor->__size))
|
||||
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
|
||||
left_descriptor->__size))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ __go_interface_compare (struct __go_interface left,
|
||||
return 1;
|
||||
if (__go_is_pointer_type (left_descriptor))
|
||||
return left.__object == right.__object ? 0 : 1;
|
||||
if (!left_descriptor->__equalfn (left.__object, right.__object,
|
||||
left_descriptor->__size))
|
||||
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
|
||||
right.__object, left_descriptor->__size))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ __go_interface_empty_compare (struct __go_interface left,
|
||||
return 1;
|
||||
if (__go_is_pointer_type (left_descriptor))
|
||||
return left.__object == right.__object ? 0 : 1;
|
||||
if (!left_descriptor->__equalfn (left.__object, right.__object,
|
||||
left_descriptor->__size))
|
||||
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
|
||||
right.__object, left_descriptor->__size))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ __go_interface_value_compare (
|
||||
return 1;
|
||||
if (__go_is_pointer_type (left_descriptor))
|
||||
return left.__object == val ? 0 : 1;
|
||||
if (!left_descriptor->__equalfn (left.__object, val,
|
||||
left_descriptor->__size))
|
||||
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
|
||||
left_descriptor->__size))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ __go_map_delete (struct __go_map *map, const void *key)
|
||||
const struct __go_map_descriptor *descriptor;
|
||||
const struct __go_type_descriptor *key_descriptor;
|
||||
uintptr_t key_offset;
|
||||
_Bool (*equalfn) (const void*, const void*, uintptr_t);
|
||||
const FuncVal *equalfn;
|
||||
size_t key_hash;
|
||||
size_t key_size;
|
||||
size_t bucket_index;
|
||||
@ -41,14 +41,14 @@ __go_map_delete (struct __go_map *map, const void *key)
|
||||
__go_assert (key_size != -1UL);
|
||||
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;
|
||||
|
||||
pentry = map->__buckets + bucket_index;
|
||||
while (*pentry != NULL)
|
||||
{
|
||||
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;
|
||||
if (descriptor->__entry_size >= TinySize)
|
||||
|
@ -22,7 +22,7 @@ __go_map_rehash (struct __go_map *map)
|
||||
const struct __go_type_descriptor *key_descriptor;
|
||||
uintptr_t key_offset;
|
||||
size_t key_size;
|
||||
uintptr_t (*hashfn) (const void *, uintptr_t);
|
||||
const FuncVal *hashfn;
|
||||
uintptr_t old_bucket_count;
|
||||
void **old_buckets;
|
||||
uintptr_t new_bucket_count;
|
||||
@ -55,7 +55,7 @@ __go_map_rehash (struct __go_map *map)
|
||||
|
||||
/* We could speed up rehashing at the cost of memory space
|
||||
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;
|
||||
|
||||
next = *(char **) entry;
|
||||
@ -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_type_descriptor *key_descriptor;
|
||||
uintptr_t key_offset;
|
||||
_Bool (*equalfn) (const void*, const void*, uintptr_t);
|
||||
const FuncVal *equalfn;
|
||||
size_t key_hash;
|
||||
size_t key_size;
|
||||
size_t bucket_index;
|
||||
@ -103,13 +103,13 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert)
|
||||
__go_assert (key_size != -1UL);
|
||||
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;
|
||||
|
||||
entry = (char *) map->__buckets[bucket_index];
|
||||
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;
|
||||
entry = *(char **) entry;
|
||||
}
|
||||
|
@ -151,5 +151,6 @@ extern _Bool ismapkey (const struct __go_type_descriptor *)
|
||||
_Bool
|
||||
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)
|
||||
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. */
|
||||
|
||||
_Bool
|
||||
@ -112,3 +115,6 @@ __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size)
|
||||
else
|
||||
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,
|
||||
return 0;
|
||||
size = descriptor->__size;
|
||||
if (__go_is_pointer_type (descriptor))
|
||||
return descriptor->__hashfn (&val->__object, size);
|
||||
return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
|
||||
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. */
|
||||
|
||||
_Bool
|
||||
@ -51,6 +54,9 @@ __go_type_equal_empty_interface (const void *vv1, const void *vv2,
|
||||
if (__go_is_pointer_type (v1_descriptor))
|
||||
return v1->__object == v2->__object;
|
||||
else
|
||||
return v1_descriptor->__equalfn (v1->__object, v2->__object,
|
||||
v1_descriptor->__size);
|
||||
return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
|
||||
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)),
|
||||
runtime_panicstring ("hash of unhashable type");
|
||||
}
|
||||
|
||||
const FuncVal __go_type_hash_error_descriptor =
|
||||
{ (void *) __go_type_hash_error };
|
||||
|
||||
/* An equality function for an interface. */
|
||||
|
||||
_Bool
|
||||
@ -26,3 +29,6 @@ __go_type_equal_error (const void *v1 __attribute__ ((unused)),
|
||||
{
|
||||
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)
|
||||
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. */
|
||||
|
||||
_Bool
|
||||
@ -84,3 +87,6 @@ __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size)
|
||||
else
|
||||
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)
|
||||
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
|
||||
where we can check for equality by checking that the values have
|
||||
the same bits. */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
const FuncVal __go_type_equal_identity_descriptor =
|
||||
{ (void *) __go_type_equal_identity };
|
||||
|
@ -24,11 +24,14 @@ __go_type_hash_interface (const void *vval,
|
||||
descriptor = (const struct __go_type_descriptor *) val->__methods[0];
|
||||
size = descriptor->__size;
|
||||
if (__go_is_pointer_type (descriptor))
|
||||
return descriptor->__hashfn (&val->__object, size);
|
||||
return __go_call_hashfn (descriptor->__hashfn, &val->__object, size);
|
||||
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. */
|
||||
|
||||
_Bool
|
||||
@ -51,6 +54,9 @@ __go_type_equal_interface (const void *vv1, const void *vv2,
|
||||
if (__go_is_pointer_type (v1_descriptor))
|
||||
return v1->__object == v2->__object;
|
||||
else
|
||||
return v1_descriptor->__equalfn (v1->__object, v2->__object,
|
||||
v1_descriptor->__size);
|
||||
return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object,
|
||||
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,
|
||||
return ret;
|
||||
}
|
||||
|
||||
const FuncVal __go_type_hash_string_descriptor =
|
||||
{ (void *) __go_type_hash_string };
|
||||
|
||||
/* A string equality function for a map. */
|
||||
|
||||
_Bool
|
||||
@ -41,3 +44,6 @@ __go_type_equal_string (const void *vk1, const void *vk2,
|
||||
k2 = (const String *) vk2;
|
||||
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
|
||||
size of this type, and returns a hash code. We pass the size
|
||||
explicitly becaues it means that we can share a single instance
|
||||
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
|
||||
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. */
|
||||
const uintptr *__gc;
|
||||
@ -316,21 +316,52 @@ __go_is_pointer_type (const struct __go_type_descriptor *td)
|
||||
|| (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
|
||||
__go_type_descriptors_equal(const struct __go_type_descriptor*,
|
||||
const struct __go_type_descriptor*);
|
||||
|
||||
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 const FuncVal __go_type_equal_identity_descriptor;
|
||||
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 const FuncVal __go_type_equal_string_descriptor;
|
||||
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 const FuncVal __go_type_equal_float_descriptor;
|
||||
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 const FuncVal __go_type_equal_complex_descriptor;
|
||||
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 const FuncVal __go_type_equal_interface_descriptor;
|
||||
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 const FuncVal __go_type_equal_error_descriptor;
|
||||
|
||||
#endif /* !defined(LIBGO_GO_TYPE_H) */
|
||||
|
@ -54,9 +54,9 @@ const struct __go_type_descriptor unsafe_Pointer =
|
||||
/* __hash */
|
||||
78501163U,
|
||||
/* __hashfn */
|
||||
__go_type_hash_identity,
|
||||
&__go_type_hash_identity_descriptor,
|
||||
/* __equalfn */
|
||||
__go_type_equal_identity,
|
||||
&__go_type_equal_identity_descriptor,
|
||||
/* __gc */
|
||||
unsafe_Pointer_gc,
|
||||
/* __reflection */
|
||||
@ -99,9 +99,9 @@ const struct __go_ptr_type pointer_unsafe_Pointer =
|
||||
/* __hash */
|
||||
1256018616U,
|
||||
/* __hashfn */
|
||||
__go_type_hash_identity,
|
||||
&__go_type_hash_identity_descriptor,
|
||||
/* __equalfn */
|
||||
__go_type_equal_identity,
|
||||
&__go_type_equal_identity_descriptor,
|
||||
/* __gc */
|
||||
unsafe_Pointer_gc,
|
||||
/* __reflection */
|
||||
|
@ -528,9 +528,9 @@ static struct __go_channel_type chan_bool_type_descriptor =
|
||||
/* __hash */
|
||||
0, /* This value doesn't matter. */
|
||||
/* __hashfn */
|
||||
__go_type_hash_error,
|
||||
&__go_type_hash_error_descriptor,
|
||||
/* __equalfn */
|
||||
__go_type_equal_error,
|
||||
&__go_type_equal_error_descriptor,
|
||||
/* __gc */
|
||||
NULL, /* This value doesn't matter */
|
||||
/* __reflection */
|
||||
|
Loading…
Reference in New Issue
Block a user