2010-12-03 05:34:57 +01:00
|
|
|
// Copyright 2010 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 runtime
|
2011-11-30 01:21:52 +01:00
|
|
|
#include "runtime.h"
|
2010-12-03 05:34:57 +01:00
|
|
|
#include "go-type.h"
|
|
|
|
#include "interface.h"
|
|
|
|
|
|
|
|
typedef struct __go_type_descriptor descriptor;
|
|
|
|
typedef const struct __go_type_descriptor const_descriptor;
|
|
|
|
typedef struct __go_interface interface;
|
|
|
|
typedef struct __go_empty_interface empty_interface;
|
|
|
|
|
|
|
|
// Compare two type descriptors.
|
|
|
|
func ifacetypeeq(a *descriptor, b *descriptor) (eq bool) {
|
|
|
|
eq = __go_type_descriptors_equal(a, b);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the descriptor for an empty interface type.n
|
|
|
|
func efacetype(e empty_interface) (d *const_descriptor) {
|
|
|
|
return e.__type_descriptor;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return the descriptor for a non-empty interface type.
|
|
|
|
func ifacetype(i interface) (d *const_descriptor) {
|
|
|
|
if (i.__methods == nil) {
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
d = i.__methods[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert an empty interface to an empty interface.
|
|
|
|
func ifaceE2E2(e empty_interface) (ret empty_interface, ok bool) {
|
2011-05-20 02:18:15 +02:00
|
|
|
if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
|
2011-11-30 01:21:52 +01:00
|
|
|
runtime_panicstring("invalid interface value");
|
2010-12-03 05:34:57 +01:00
|
|
|
ret = e;
|
|
|
|
ok = ret.__type_descriptor != nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert a non-empty interface to an empty interface.
|
|
|
|
func ifaceI2E2(i interface) (ret empty_interface, ok bool) {
|
|
|
|
if (i.__methods == nil) {
|
|
|
|
ret.__type_descriptor = nil;
|
|
|
|
ret.__object = nil;
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
ret.__type_descriptor = i.__methods[0];
|
|
|
|
ret.__object = i.__object;
|
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert an empty interface to a non-empty interface.
|
|
|
|
func ifaceE2I2(inter *descriptor, e empty_interface) (ret interface, ok bool) {
|
2011-05-20 02:18:15 +02:00
|
|
|
if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
|
2011-11-30 01:21:52 +01:00
|
|
|
runtime_panicstring("invalid interface value");
|
2010-12-03 05:34:57 +01:00
|
|
|
if (e.__type_descriptor == nil) {
|
|
|
|
ret.__methods = nil;
|
|
|
|
ret.__object = nil;
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
ret.__methods = __go_convert_interface_2(inter,
|
|
|
|
e.__type_descriptor,
|
|
|
|
1);
|
|
|
|
ret.__object = e.__object;
|
|
|
|
ok = ret.__methods != nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert a non-empty interface to a non-empty interface.
|
|
|
|
func ifaceI2I2(inter *descriptor, i interface) (ret interface, ok bool) {
|
|
|
|
if (i.__methods == nil) {
|
|
|
|
ret.__methods = nil;
|
|
|
|
ret.__object = nil;
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
ret.__methods = __go_convert_interface_2(inter,
|
|
|
|
i.__methods[0], 1);
|
|
|
|
ret.__object = i.__object;
|
|
|
|
ok = ret.__methods != nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert an empty interface to a pointer type.
|
|
|
|
func ifaceE2T2P(inter *descriptor, e empty_interface) (ret *void, ok bool) {
|
2011-05-20 02:18:15 +02:00
|
|
|
if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
|
2011-11-30 01:21:52 +01:00
|
|
|
runtime_panicstring("invalid interface value");
|
2010-12-03 05:34:57 +01:00
|
|
|
if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
|
|
|
|
ret = nil;
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
ret = e.__object;
|
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert a non-empty interface to a pointer type.
|
|
|
|
func ifaceI2T2P(inter *descriptor, i interface) (ret *void, ok bool) {
|
|
|
|
if (i.__methods == nil
|
|
|
|
|| !__go_type_descriptors_equal(inter, i.__methods[0])) {
|
|
|
|
ret = nil;
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
ret = i.__object;
|
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert an empty interface to a non-pointer type.
|
|
|
|
func ifaceE2T2(inter *descriptor, e empty_interface, ret *void) (ok bool) {
|
2011-05-20 02:18:15 +02:00
|
|
|
if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0)
|
2011-11-30 01:21:52 +01:00
|
|
|
runtime_panicstring("invalid interface value");
|
2010-12-03 05:34:57 +01:00
|
|
|
if (!__go_type_descriptors_equal(inter, e.__type_descriptor)) {
|
|
|
|
__builtin_memset(ret, 0, inter->__size);
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
__builtin_memcpy(ret, e.__object, inter->__size);
|
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert a non-empty interface to a non-pointer type.
|
|
|
|
func ifaceI2T2(inter *descriptor, i interface, ret *void) (ok bool) {
|
|
|
|
if (i.__methods == nil
|
|
|
|
|| !__go_type_descriptors_equal(inter, i.__methods[0])) {
|
|
|
|
__builtin_memset(ret, 0, inter->__size);
|
|
|
|
ok = 0;
|
|
|
|
} else {
|
|
|
|
__builtin_memcpy(ret, i.__object, inter->__size);
|
|
|
|
ok = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return whether we can convert an interface to a type.
|
|
|
|
func ifaceI2Tp(to *descriptor, from *descriptor) (ok bool) {
|
|
|
|
ok = __go_can_convert_to_interface(to, from);
|
|
|
|
}
|