// 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 #include "runtime.h" #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) { if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0) runtime_panicstring("invalid interface value"); 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) { if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0) runtime_panicstring("invalid interface value"); 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) { if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0) runtime_panicstring("invalid interface value"); 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) { if(((uintptr_t)e.__type_descriptor&reflectFlags) != 0) runtime_panicstring("invalid interface value"); 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); }