runtime: rewrite interface code into Go

I started to copy the Go 1.7 interface code, but the gc and gccgo
    representations of interfaces are too different.  So instead I rewrote
    the gccgo interface code from C to Go.  The code is largely the same as
    it was, but the names are more like those used in the gc runtime.
    
    I also copied over the string comparison functions, and tweaked the
    compiler to use eqstring when comparing strings for equality.
    
    Reviewed-on: https://go-review.googlesource.com/31591

From-SVN: r241384
This commit is contained in:
Ian Lance Taylor 2016-10-20 18:51:35 +00:00
parent fceabe505c
commit 6b752cfac4
42 changed files with 716 additions and 1134 deletions

View File

@ -1,4 +1,4 @@
5346c7d15362a16efa0defaaeca63b1fce1c1523
14dc8052a09ad0a2226e64ab6b5af69c6923b830
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -1874,7 +1874,7 @@ Escape_analysis_assign::assign(Node* dst, Node* src)
case Runtime::IFACEI2T2P:
case Runtime::IFACEE2T2:
case Runtime::IFACEI2T2:
case Runtime::CONVERT_INTERFACE:
case Runtime::REQUIREITAB:
// All versions of interface conversion that might result
// from a type assertion. Some of these are the result of
// a tuple type assertion statement and may not be covered
@ -2633,7 +2633,7 @@ Escape_analysis_flood::flood(Level level, Node* dst, Node* src,
case Runtime::CONCATSTRING5:
case Runtime::CONSTRUCT_MAP:
case Runtime::INTSTRING:
case Runtime::CONVERT_INTERFACE:
case Runtime::REQUIREITAB:
// All runtime calls that involve allocation of memory
// except new. Runtime::NEW gets lowered into an
// allocation expression.

View File

@ -323,9 +323,8 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
if (for_type_guard)
{
// A type assertion fails when converting a nil interface.
first_field =
Runtime::make_call(Runtime::ASSERT_INTERFACE, location, 2,
lhs_type_expr, rhs_type_expr);
first_field = Runtime::make_call(Runtime::ASSERTITAB, location, 2,
lhs_type_expr, rhs_type_expr);
}
else if (lhs_is_empty)
{
@ -337,9 +336,8 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
{
// A conversion to a non-empty interface may fail, but unlike a
// type assertion converting nil will always succeed.
first_field =
Runtime::make_call(Runtime::CONVERT_INTERFACE, location, 2,
lhs_type_expr, rhs_type_expr);
first_field = Runtime::make_call(Runtime::REQUIREITAB, location, 2,
lhs_type_expr, rhs_type_expr);
}
// The second field is simply the object pointer.
@ -370,7 +368,7 @@ Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
location);
Expression* check_iface = Runtime::make_call(Runtime::CHECK_INTERFACE_TYPE,
Expression* check_iface = Runtime::make_call(Runtime::ASSERTI2T,
location, 3, lhs_type_expr,
rhs_descriptor, rhs_inter_expr);
@ -1290,7 +1288,10 @@ Func_descriptor_expression::do_get_backend(Translate_context* context)
&& !no->func_declaration_value()->asm_name().empty()
&& Linemap::is_predeclared_location(no->location()))
{
var_name = no->func_declaration_value()->asm_name() + "_descriptor";
if (no->func_declaration_value()->asm_name().substr(0, 8) != "runtime.")
var_name = no->func_declaration_value()->asm_name() + "_descriptor";
else
var_name = no->func_declaration_value()->asm_name() + "$descriptor";
is_descriptor = true;
}
else
@ -6196,9 +6197,18 @@ Expression::comparison(Translate_context* context, Type* result_type,
if (left_type->is_string_type() && right_type->is_string_type())
{
left = Runtime::make_call(Runtime::STRCMP, location, 2,
left, right);
right = zexpr;
if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ)
{
left = Runtime::make_call(Runtime::EQSTRING, location, 2,
left, right);
right = Expression::make_boolean(true, location);
}
else
{
left = Runtime::make_call(Runtime::CMPSTRING, location, 2,
left, right);
right = zexpr;
}
}
else if ((left_type->interface_type() != NULL
&& right_type->interface_type() == NULL
@ -6230,11 +6240,12 @@ Expression::comparison(Translate_context* context, Type* result_type,
Expression::make_type_descriptor(right_type, location);
left =
Runtime::make_call((left_type->interface_type()->is_empty()
? Runtime::EMPTY_INTERFACE_VALUE_COMPARE
: Runtime::INTERFACE_VALUE_COMPARE),
? Runtime::EFACEVALEQ
: Runtime::IFACEVALEQ),
location, 3, left, descriptor,
pointer_arg);
right = zexpr;
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
right = Expression::make_boolean(true, location);
}
else if (left_type->interface_type() != NULL
&& right_type->interface_type() != NULL)
@ -6242,25 +6253,25 @@ Expression::comparison(Translate_context* context, Type* result_type,
Runtime::Function compare_function;
if (left_type->interface_type()->is_empty()
&& right_type->interface_type()->is_empty())
compare_function = Runtime::EMPTY_INTERFACE_COMPARE;
compare_function = Runtime::EFACEEQ;
else if (!left_type->interface_type()->is_empty()
&& !right_type->interface_type()->is_empty())
compare_function = Runtime::INTERFACE_COMPARE;
compare_function = Runtime::IFACEEQ;
else
{
if (left_type->interface_type()->is_empty())
{
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
std::swap(left_type, right_type);
std::swap(left, right);
}
go_assert(!left_type->interface_type()->is_empty());
go_assert(right_type->interface_type()->is_empty());
compare_function = Runtime::INTERFACE_EMPTY_COMPARE;
compare_function = Runtime::IFACEEFACEEQ;
}
left = Runtime::make_call(compare_function, location, 2, left, right);
right = zexpr;
go_assert(op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ);
right = Expression::make_boolean(true, location);
}
if (left_type->is_nil_type()

View File

@ -50,8 +50,11 @@ DEF_GO_RUNTIME(CONCATSTRING4, "runtime.concatstring4",
DEF_GO_RUNTIME(CONCATSTRING5, "runtime.concatstring5",
P2(POINTER, ARRAY5STRING), R1(STRING))
// Compare two strings for equality.
DEF_GO_RUNTIME(EQSTRING, "runtime.eqstring", P2(STRING, STRING), R1(BOOL))
// Compare two strings.
DEF_GO_RUNTIME(STRCMP, "__go_strcmp", P2(STRING, STRING), R1(INT))
DEF_GO_RUNTIME(CMPSTRING, "runtime.cmpstring", P2(STRING, STRING), R1(INT))
// Take a slice of a string.
DEF_GO_RUNTIME(STRING_SLICE, "__go_string_slice", P3(STRING, INT, INT),
@ -259,22 +262,27 @@ DEF_GO_RUNTIME(IFACEE2T2, "runtime.ifaceE2T2", P3(TYPE, EFACE, POINTER),
DEF_GO_RUNTIME(IFACEI2T2, "runtime.ifaceI2T2", P3(TYPE, IFACE, POINTER),
R1(BOOL))
// A type assertion from one interface type to another. This is
// used for a type assertion.
DEF_GO_RUNTIME(ASSERT_INTERFACE, "__go_assert_interface", P2(TYPE, TYPE), R1(POINTER))
// Return the interface method table for the second type converted to
// the first type which is a (possibly empty) interface type. Panics
// if the second type is nil (indicating a nil interface value) or if
// the conversion is not possible. Used for type assertions. This is
// like REQUIREITAB, but for type assertions.
DEF_GO_RUNTIME(ASSERTITAB, "runtime.assertitab", P2(TYPE, TYPE), R1(POINTER))
// Convert one interface type to another. This is used for an
// assignment.
DEF_GO_RUNTIME(CONVERT_INTERFACE, "__go_convert_interface", P2(TYPE, TYPE),
// Return the interface method table for the second type converted to
// the first type, which is a non-empty interface type. Return nil if
// the second type is nil, indicating a nil interface value. Panics
// if the conversion is not possible. Used for assignments. This is
// like ASSERTITAB, but for assignments.
DEF_GO_RUNTIME(REQUIREITAB, "runtime.requireitab", P2(TYPE, TYPE),
R1(POINTER))
// Check whether an interface type may be converted to a
// non-interface type.
DEF_GO_RUNTIME(CHECK_INTERFACE_TYPE, "__go_check_interface_type",
P3(TYPE, TYPE, TYPE), R0())
DEF_GO_RUNTIME(ASSERTI2T, "runtime.assertI2T", P3(TYPE, TYPE, TYPE), R0())
// Return whether we can convert an interface type to a type.
DEF_GO_RUNTIME(IFACEI2TP, "runtime.ifaceI2Tp", P2(TYPE, TYPE), R1(BOOL))
// Return whether we can convert a type to an interface type.
DEF_GO_RUNTIME(IFACET2IP, "runtime.ifaceT2Ip", P2(TYPE, TYPE), R1(BOOL))
// Get the type descriptor of an empty interface.
DEF_GO_RUNTIME(EFACETYPE, "runtime.efacetype", P1(EFACE), R1(TYPE))
@ -287,25 +295,22 @@ DEF_GO_RUNTIME(IFACETYPE, "runtime.ifacetype", P1(IFACE), R1(TYPE))
DEF_GO_RUNTIME(IFACETYPEEQ, "runtime.ifacetypeeq", P2(TYPE, TYPE), R1(BOOL))
// Compare two empty interface values.
DEF_GO_RUNTIME(EMPTY_INTERFACE_COMPARE, "__go_empty_interface_compare",
P2(EFACE, EFACE), R1(INT))
DEF_GO_RUNTIME(EFACEEQ, "runtime.efaceeq", P2(EFACE, EFACE), R1(BOOL))
// Compare an empty interface value to a non-interface value.
DEF_GO_RUNTIME(EMPTY_INTERFACE_VALUE_COMPARE,
"__go_empty_interface_value_compare",
P3(EFACE, TYPE, POINTER), R1(INT))
DEF_GO_RUNTIME(EFACEVALEQ, "runtime.efacevaleq", P3(EFACE, TYPE, POINTER),
R1(BOOL))
// Compare two non-empty interface values.
DEF_GO_RUNTIME(INTERFACE_COMPARE, "__go_interface_compare",
P2(IFACE, IFACE), R1(INT))
DEF_GO_RUNTIME(IFACEEQ, "runtime.ifaceeq", P2(IFACE, IFACE), R1(BOOL))
// Compare a non-empty interface value to a non-interface value.
DEF_GO_RUNTIME(INTERFACE_VALUE_COMPARE, "__go_interface_value_compare",
P3(IFACE, TYPE, POINTER), R1(INT))
DEF_GO_RUNTIME(IFACEVALEQ, "runtime.ifacevaleq", P3(IFACE, TYPE, POINTER),
R1(BOOL))
// Compare a non-empty interface value to an interface value.
DEF_GO_RUNTIME(INTERFACE_EMPTY_COMPARE, "__go_interface_empty_compare",
P2(IFACE, EFACE), R1(INT))
DEF_GO_RUNTIME(IFACEEFACEEQ, "runtime.ifaceefaceeq", P2(IFACE, EFACE),
R1(BOOL))
// Lock the printer (for print/println).

View File

@ -3894,7 +3894,7 @@ Type_case_clauses::Type_case_clause::lower(Type* switch_val_type,
else
cond = Runtime::make_call((type->interface_type() == NULL
? Runtime::IFACETYPEEQ
: Runtime::IFACEI2TP),
: Runtime::IFACET2IP),
loc, 2,
Expression::make_type_descriptor(type, loc),
ref);

View File

@ -1710,13 +1710,13 @@ Type::type_functions(Gogo* gogo, Named_type* name, Function_type* hash_fntype,
case Type::TYPE_INTERFACE:
if (this->interface_type()->is_empty())
{
hash_fnname = "__go_type_hash_empty_interface";
equal_fnname = "__go_type_equal_empty_interface";
hash_fnname = "runtime.nilinterhash";
equal_fnname = "runtime.nilinterequal";
}
else
{
hash_fnname = "__go_type_hash_interface";
equal_fnname = "__go_type_equal_interface";
hash_fnname = "runtime.interhash";
equal_fnname = "runtime.interequal";
}
break;

View File

@ -430,26 +430,17 @@ endif
runtime_files = \
runtime/go-append.c \
runtime/go-assert.c \
runtime/go-assert-interface.c \
runtime/go-breakpoint.c \
runtime/go-caller.c \
runtime/go-callers.c \
runtime/go-can-convert-interface.c \
runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-check-interface.c \
runtime/go-construct-map.c \
runtime/go-convert-interface.c \
runtime/go-copy.c \
runtime/go-defer.c \
runtime/go-deferred-recover.c \
runtime/go-eface-compare.c \
runtime/go-eface-val-compare.c \
runtime/go-ffi.c \
runtime/go-fieldtrack.c \
runtime/go-interface-compare.c \
runtime/go-interface-eface-compare.c \
runtime/go-interface-val-compare.c \
runtime/go-make-slice.c \
runtime/go-matherr.c \
runtime/go-memclr.c \
@ -466,13 +457,10 @@ runtime_files = \
runtime/go-runtime-error.c \
runtime/go-setenv.c \
runtime/go-signal.c \
runtime/go-strcmp.c \
runtime/go-strslice.c \
runtime/go-type-complex.c \
runtime/go-type-eface.c \
runtime/go-type-float.c \
runtime/go-type-identity.c \
runtime/go-type-interface.c \
runtime/go-type-string.c \
runtime/go-typedesc-equal.c \
runtime/go-unsafe-new.c \
@ -500,10 +488,8 @@ runtime_files = \
$(runtime_thread_files) \
runtime/yield.c \
$(rtems_task_variable_add_file) \
go-iface.c \
lfstack.c \
malloc.c \
reflect.c \
runtime1.c \
sigqueue.c \
$(runtime_getncpu_file)
@ -518,10 +504,6 @@ malloc.c: $(srcdir)/runtime/malloc.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@
reflect.c: $(srcdir)/runtime/reflect.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@
runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@

View File

@ -237,29 +237,23 @@ libgo_llgo_la_DEPENDENCIES = $(am__DEPENDENCIES_4)
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_4 = \
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ getncpu-bsd.lo
@LIBGO_IS_LINUX_TRUE@am__objects_4 = getncpu-linux.lo
am__objects_5 = go-append.lo go-assert.lo go-assert-interface.lo \
go-breakpoint.lo go-caller.lo go-callers.lo \
go-can-convert-interface.lo go-cdiv.lo go-cgo.lo \
go-check-interface.lo go-construct-map.lo \
go-convert-interface.lo go-copy.lo go-defer.lo \
go-deferred-recover.lo go-eface-compare.lo \
go-eface-val-compare.lo go-ffi.lo go-fieldtrack.lo \
go-interface-compare.lo go-interface-eface-compare.lo \
go-interface-val-compare.lo go-make-slice.lo go-matherr.lo \
go-memclr.lo go-memcmp.lo go-memequal.lo go-memmove.lo \
go-nanotime.lo go-now.lo go-new.lo go-nosys.lo go-panic.lo \
go-recover.lo go-reflect-call.lo go-runtime-error.lo \
go-setenv.lo go-signal.lo go-strcmp.lo go-strslice.lo \
go-type-complex.lo go-type-eface.lo go-type-float.lo \
go-type-identity.lo go-type-interface.lo go-type-string.lo \
am__objects_5 = go-append.lo go-assert.lo go-breakpoint.lo \
go-caller.lo go-callers.lo go-cdiv.lo go-cgo.lo \
go-construct-map.lo go-copy.lo go-defer.lo \
go-deferred-recover.lo go-ffi.lo go-fieldtrack.lo \
go-make-slice.lo go-matherr.lo go-memclr.lo go-memcmp.lo \
go-memequal.lo go-memmove.lo go-nanotime.lo go-now.lo \
go-new.lo go-nosys.lo go-panic.lo go-recover.lo \
go-reflect-call.lo go-runtime-error.lo go-setenv.lo \
go-signal.lo go-strslice.lo go-type-complex.lo \
go-type-float.lo go-type-identity.lo go-type-string.lo \
go-typedesc-equal.lo go-unsafe-new.lo go-unsafe-newarray.lo \
go-unsafe-pointer.lo go-unsetenv.lo go-unwind.lo go-varargs.lo \
env_posix.lo heapdump.lo mcache.lo mcentral.lo \
$(am__objects_1) mfixalloc.lo mgc0.lo mheap.lo msize.lo \
panic.lo parfor.lo print.lo proc.lo runtime.lo signal_unix.lo \
thread.lo $(am__objects_2) yield.lo $(am__objects_3) \
go-iface.lo lfstack.lo malloc.lo reflect.lo runtime1.lo \
sigqueue.lo $(am__objects_4)
lfstack.lo malloc.lo runtime1.lo sigqueue.lo $(am__objects_4)
am_libgo_llgo_la_OBJECTS = $(am__objects_5)
libgo_llgo_la_OBJECTS = $(am_libgo_llgo_la_OBJECTS)
libgo_llgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@ -832,26 +826,17 @@ toolexeclibgounicode_DATA = \
runtime_files = \
runtime/go-append.c \
runtime/go-assert.c \
runtime/go-assert-interface.c \
runtime/go-breakpoint.c \
runtime/go-caller.c \
runtime/go-callers.c \
runtime/go-can-convert-interface.c \
runtime/go-cdiv.c \
runtime/go-cgo.c \
runtime/go-check-interface.c \
runtime/go-construct-map.c \
runtime/go-convert-interface.c \
runtime/go-copy.c \
runtime/go-defer.c \
runtime/go-deferred-recover.c \
runtime/go-eface-compare.c \
runtime/go-eface-val-compare.c \
runtime/go-ffi.c \
runtime/go-fieldtrack.c \
runtime/go-interface-compare.c \
runtime/go-interface-eface-compare.c \
runtime/go-interface-val-compare.c \
runtime/go-make-slice.c \
runtime/go-matherr.c \
runtime/go-memclr.c \
@ -868,13 +853,10 @@ runtime_files = \
runtime/go-runtime-error.c \
runtime/go-setenv.c \
runtime/go-signal.c \
runtime/go-strcmp.c \
runtime/go-strslice.c \
runtime/go-type-complex.c \
runtime/go-type-eface.c \
runtime/go-type-float.c \
runtime/go-type-identity.c \
runtime/go-type-interface.c \
runtime/go-type-string.c \
runtime/go-typedesc-equal.c \
runtime/go-unsafe-new.c \
@ -902,10 +884,8 @@ runtime_files = \
$(runtime_thread_files) \
runtime/yield.c \
$(rtems_task_variable_add_file) \
go-iface.c \
lfstack.c \
malloc.c \
reflect.c \
runtime1.c \
sigqueue.c \
$(runtime_getncpu_file)
@ -1541,28 +1521,18 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getncpu-none.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getncpu-solaris.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-append.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-assert-interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-assert.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-breakpoint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-caller.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-callers.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-can-convert-interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cdiv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-cgo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-check-interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-construct-map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-convert-interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-copy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-defer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-deferred-recover.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-eface-compare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-eface-val-compare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-fieldtrack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-iface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-compare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-eface-compare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-make-slice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-matherr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-memclr.Plo@am__quote@
@ -1579,13 +1549,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-runtime-error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-setenv.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-signal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strcmp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-strslice.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-complex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-eface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-float.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-identity.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-interface.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-type-string.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-typedesc-equal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-unsafe-new.Plo@am__quote@
@ -1612,7 +1579,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parfor.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reflect.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rtems-task-variable-add.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtime.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runtime1.Plo@am__quote@
@ -1700,13 +1666,6 @@ go-assert.lo: runtime/go-assert.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-assert.lo `test -f 'runtime/go-assert.c' || echo '$(srcdir)/'`runtime/go-assert.c
go-assert-interface.lo: runtime/go-assert-interface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-assert-interface.lo -MD -MP -MF $(DEPDIR)/go-assert-interface.Tpo -c -o go-assert-interface.lo `test -f 'runtime/go-assert-interface.c' || echo '$(srcdir)/'`runtime/go-assert-interface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-assert-interface.Tpo $(DEPDIR)/go-assert-interface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-assert-interface.c' object='go-assert-interface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-assert-interface.lo `test -f 'runtime/go-assert-interface.c' || echo '$(srcdir)/'`runtime/go-assert-interface.c
go-breakpoint.lo: runtime/go-breakpoint.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-breakpoint.lo -MD -MP -MF $(DEPDIR)/go-breakpoint.Tpo -c -o go-breakpoint.lo `test -f 'runtime/go-breakpoint.c' || echo '$(srcdir)/'`runtime/go-breakpoint.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-breakpoint.Tpo $(DEPDIR)/go-breakpoint.Plo
@ -1728,13 +1687,6 @@ go-callers.lo: runtime/go-callers.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-callers.lo `test -f 'runtime/go-callers.c' || echo '$(srcdir)/'`runtime/go-callers.c
go-can-convert-interface.lo: runtime/go-can-convert-interface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-can-convert-interface.lo -MD -MP -MF $(DEPDIR)/go-can-convert-interface.Tpo -c -o go-can-convert-interface.lo `test -f 'runtime/go-can-convert-interface.c' || echo '$(srcdir)/'`runtime/go-can-convert-interface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-can-convert-interface.Tpo $(DEPDIR)/go-can-convert-interface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-can-convert-interface.c' object='go-can-convert-interface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-can-convert-interface.lo `test -f 'runtime/go-can-convert-interface.c' || echo '$(srcdir)/'`runtime/go-can-convert-interface.c
go-cdiv.lo: runtime/go-cdiv.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-cdiv.lo -MD -MP -MF $(DEPDIR)/go-cdiv.Tpo -c -o go-cdiv.lo `test -f 'runtime/go-cdiv.c' || echo '$(srcdir)/'`runtime/go-cdiv.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-cdiv.Tpo $(DEPDIR)/go-cdiv.Plo
@ -1749,13 +1701,6 @@ go-cgo.lo: runtime/go-cgo.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-cgo.lo `test -f 'runtime/go-cgo.c' || echo '$(srcdir)/'`runtime/go-cgo.c
go-check-interface.lo: runtime/go-check-interface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-check-interface.lo -MD -MP -MF $(DEPDIR)/go-check-interface.Tpo -c -o go-check-interface.lo `test -f 'runtime/go-check-interface.c' || echo '$(srcdir)/'`runtime/go-check-interface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-check-interface.Tpo $(DEPDIR)/go-check-interface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-check-interface.c' object='go-check-interface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-check-interface.lo `test -f 'runtime/go-check-interface.c' || echo '$(srcdir)/'`runtime/go-check-interface.c
go-construct-map.lo: runtime/go-construct-map.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-construct-map.lo -MD -MP -MF $(DEPDIR)/go-construct-map.Tpo -c -o go-construct-map.lo `test -f 'runtime/go-construct-map.c' || echo '$(srcdir)/'`runtime/go-construct-map.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-construct-map.Tpo $(DEPDIR)/go-construct-map.Plo
@ -1763,13 +1708,6 @@ go-construct-map.lo: runtime/go-construct-map.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-construct-map.lo `test -f 'runtime/go-construct-map.c' || echo '$(srcdir)/'`runtime/go-construct-map.c
go-convert-interface.lo: runtime/go-convert-interface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-convert-interface.lo -MD -MP -MF $(DEPDIR)/go-convert-interface.Tpo -c -o go-convert-interface.lo `test -f 'runtime/go-convert-interface.c' || echo '$(srcdir)/'`runtime/go-convert-interface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-convert-interface.Tpo $(DEPDIR)/go-convert-interface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-convert-interface.c' object='go-convert-interface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-convert-interface.lo `test -f 'runtime/go-convert-interface.c' || echo '$(srcdir)/'`runtime/go-convert-interface.c
go-copy.lo: runtime/go-copy.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-copy.lo -MD -MP -MF $(DEPDIR)/go-copy.Tpo -c -o go-copy.lo `test -f 'runtime/go-copy.c' || echo '$(srcdir)/'`runtime/go-copy.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-copy.Tpo $(DEPDIR)/go-copy.Plo
@ -1791,20 +1729,6 @@ go-deferred-recover.lo: runtime/go-deferred-recover.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-deferred-recover.lo `test -f 'runtime/go-deferred-recover.c' || echo '$(srcdir)/'`runtime/go-deferred-recover.c
go-eface-compare.lo: runtime/go-eface-compare.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-eface-compare.lo -MD -MP -MF $(DEPDIR)/go-eface-compare.Tpo -c -o go-eface-compare.lo `test -f 'runtime/go-eface-compare.c' || echo '$(srcdir)/'`runtime/go-eface-compare.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-eface-compare.Tpo $(DEPDIR)/go-eface-compare.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-eface-compare.c' object='go-eface-compare.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-eface-compare.lo `test -f 'runtime/go-eface-compare.c' || echo '$(srcdir)/'`runtime/go-eface-compare.c
go-eface-val-compare.lo: runtime/go-eface-val-compare.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-eface-val-compare.lo -MD -MP -MF $(DEPDIR)/go-eface-val-compare.Tpo -c -o go-eface-val-compare.lo `test -f 'runtime/go-eface-val-compare.c' || echo '$(srcdir)/'`runtime/go-eface-val-compare.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-eface-val-compare.Tpo $(DEPDIR)/go-eface-val-compare.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-eface-val-compare.c' object='go-eface-val-compare.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-eface-val-compare.lo `test -f 'runtime/go-eface-val-compare.c' || echo '$(srcdir)/'`runtime/go-eface-val-compare.c
go-ffi.lo: runtime/go-ffi.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-ffi.lo -MD -MP -MF $(DEPDIR)/go-ffi.Tpo -c -o go-ffi.lo `test -f 'runtime/go-ffi.c' || echo '$(srcdir)/'`runtime/go-ffi.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-ffi.Tpo $(DEPDIR)/go-ffi.Plo
@ -1819,27 +1743,6 @@ go-fieldtrack.lo: runtime/go-fieldtrack.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-fieldtrack.lo `test -f 'runtime/go-fieldtrack.c' || echo '$(srcdir)/'`runtime/go-fieldtrack.c
go-interface-compare.lo: runtime/go-interface-compare.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-compare.Tpo -c -o go-interface-compare.lo `test -f 'runtime/go-interface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-compare.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-interface-compare.Tpo $(DEPDIR)/go-interface-compare.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-interface-compare.c' object='go-interface-compare.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-interface-compare.lo `test -f 'runtime/go-interface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-compare.c
go-interface-eface-compare.lo: runtime/go-interface-eface-compare.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-eface-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-eface-compare.Tpo -c -o go-interface-eface-compare.lo `test -f 'runtime/go-interface-eface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-eface-compare.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-interface-eface-compare.Tpo $(DEPDIR)/go-interface-eface-compare.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-interface-eface-compare.c' object='go-interface-eface-compare.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-interface-eface-compare.lo `test -f 'runtime/go-interface-eface-compare.c' || echo '$(srcdir)/'`runtime/go-interface-eface-compare.c
go-interface-val-compare.lo: runtime/go-interface-val-compare.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-interface-val-compare.lo -MD -MP -MF $(DEPDIR)/go-interface-val-compare.Tpo -c -o go-interface-val-compare.lo `test -f 'runtime/go-interface-val-compare.c' || echo '$(srcdir)/'`runtime/go-interface-val-compare.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-interface-val-compare.Tpo $(DEPDIR)/go-interface-val-compare.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-interface-val-compare.c' object='go-interface-val-compare.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-interface-val-compare.lo `test -f 'runtime/go-interface-val-compare.c' || echo '$(srcdir)/'`runtime/go-interface-val-compare.c
go-make-slice.lo: runtime/go-make-slice.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-make-slice.lo -MD -MP -MF $(DEPDIR)/go-make-slice.Tpo -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-make-slice.Tpo $(DEPDIR)/go-make-slice.Plo
@ -1952,13 +1855,6 @@ go-signal.lo: runtime/go-signal.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-signal.lo `test -f 'runtime/go-signal.c' || echo '$(srcdir)/'`runtime/go-signal.c
go-strcmp.lo: runtime/go-strcmp.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-strcmp.lo -MD -MP -MF $(DEPDIR)/go-strcmp.Tpo -c -o go-strcmp.lo `test -f 'runtime/go-strcmp.c' || echo '$(srcdir)/'`runtime/go-strcmp.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-strcmp.Tpo $(DEPDIR)/go-strcmp.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-strcmp.c' object='go-strcmp.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-strcmp.lo `test -f 'runtime/go-strcmp.c' || echo '$(srcdir)/'`runtime/go-strcmp.c
go-strslice.lo: runtime/go-strslice.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-strslice.lo -MD -MP -MF $(DEPDIR)/go-strslice.Tpo -c -o go-strslice.lo `test -f 'runtime/go-strslice.c' || echo '$(srcdir)/'`runtime/go-strslice.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-strslice.Tpo $(DEPDIR)/go-strslice.Plo
@ -1973,13 +1869,6 @@ go-type-complex.lo: runtime/go-type-complex.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-type-complex.lo `test -f 'runtime/go-type-complex.c' || echo '$(srcdir)/'`runtime/go-type-complex.c
go-type-eface.lo: runtime/go-type-eface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-type-eface.lo -MD -MP -MF $(DEPDIR)/go-type-eface.Tpo -c -o go-type-eface.lo `test -f 'runtime/go-type-eface.c' || echo '$(srcdir)/'`runtime/go-type-eface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-type-eface.Tpo $(DEPDIR)/go-type-eface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-type-eface.c' object='go-type-eface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-type-eface.lo `test -f 'runtime/go-type-eface.c' || echo '$(srcdir)/'`runtime/go-type-eface.c
go-type-float.lo: runtime/go-type-float.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-type-float.lo -MD -MP -MF $(DEPDIR)/go-type-float.Tpo -c -o go-type-float.lo `test -f 'runtime/go-type-float.c' || echo '$(srcdir)/'`runtime/go-type-float.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-type-float.Tpo $(DEPDIR)/go-type-float.Plo
@ -1994,13 +1883,6 @@ go-type-identity.lo: runtime/go-type-identity.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-type-identity.lo `test -f 'runtime/go-type-identity.c' || echo '$(srcdir)/'`runtime/go-type-identity.c
go-type-interface.lo: runtime/go-type-interface.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-type-interface.lo -MD -MP -MF $(DEPDIR)/go-type-interface.Tpo -c -o go-type-interface.lo `test -f 'runtime/go-type-interface.c' || echo '$(srcdir)/'`runtime/go-type-interface.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-type-interface.Tpo $(DEPDIR)/go-type-interface.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/go-type-interface.c' object='go-type-interface.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-type-interface.lo `test -f 'runtime/go-type-interface.c' || echo '$(srcdir)/'`runtime/go-type-interface.c
go-type-string.lo: runtime/go-type-string.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-type-string.lo -MD -MP -MF $(DEPDIR)/go-type-string.Tpo -c -o go-type-string.lo `test -f 'runtime/go-type-string.c' || echo '$(srcdir)/'`runtime/go-type-string.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/go-type-string.Tpo $(DEPDIR)/go-type-string.Plo
@ -3369,10 +3251,6 @@ malloc.c: $(srcdir)/runtime/malloc.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@
reflect.c: $(srcdir)/runtime/reflect.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@
runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c
./goc2c $< > $@.tmp
mv -f $@.tmp $@

204
libgo/go/runtime/alg.go Normal file
View File

@ -0,0 +1,204 @@
// Copyright 2014 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
import (
"runtime/internal/sys"
"unsafe"
)
// For gccgo, use go:linkname to rename compiler-called functions to
// themselves, so that the compiler will export them.
//
//go:linkname interhash runtime.interhash
//go:linkname nilinterhash runtime.nilinterhash
//go:linkname interequal runtime.interequal
//go:linkname nilinterequal runtime.nilinterequal
//go:linkname efaceeq runtime.efaceeq
//go:linkname ifaceeq runtime.ifaceeq
//go:linkname ifacevaleq runtime.ifacevaleq
//go:linkname ifaceefaceeq runtime.ifaceefaceeq
//go:linkname efacevaleq runtime.efacevaleq
//go:linkname eqstring runtime.eqstring
//go:linkname cmpstring runtime.cmpstring
const (
c0 = uintptr((8-sys.PtrSize)/4*2860486313 + (sys.PtrSize-4)/4*33054211828000289)
c1 = uintptr((8-sys.PtrSize)/4*3267000013 + (sys.PtrSize-4)/4*23344194077549503)
)
func interhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr {
a := (*iface)(p)
tab := a.tab
if tab == nil {
return h
}
t := *(**_type)(tab)
fn := t.hashfn
if fn == nil {
panic(errorString("hash of unhashable type " + *t.string))
}
if isDirectIface(t) {
return c1 * fn(unsafe.Pointer(&a.data), h^c0, t.size)
} else {
return c1 * fn(a.data, h^c0, t.size)
}
}
func nilinterhash(p unsafe.Pointer, h uintptr, size uintptr) uintptr {
a := (*eface)(p)
t := a._type
if t == nil {
return h
}
fn := t.hashfn
if fn == nil {
panic(errorString("hash of unhashable type " + *t.string))
}
if isDirectIface(t) {
return c1 * fn(unsafe.Pointer(&a.data), h^c0, t.size)
} else {
return c1 * fn(a.data, h^c0, t.size)
}
}
func interequal(p, q unsafe.Pointer, size uintptr) bool {
return ifaceeq(*(*iface)(p), *(*iface)(q))
}
func nilinterequal(p, q unsafe.Pointer, size uintptr) bool {
return efaceeq(*(*eface)(p), *(*eface)(q))
}
func efaceeq(x, y eface) bool {
t := x._type
if !eqtype(t, y._type) {
return false
}
if t == nil {
return true
}
eq := t.equalfn
if eq == nil {
panic(errorString("comparing uncomparable type " + *t.string))
}
if isDirectIface(t) {
return x.data == y.data
}
return eq(x.data, y.data, t.size)
}
func ifaceeq(x, y iface) bool {
xtab := x.tab
if xtab == nil && y.tab == nil {
return true
}
if xtab == nil || y.tab == nil {
return false
}
t := *(**_type)(xtab)
if !eqtype(t, *(**_type)(y.tab)) {
return false
}
eq := t.equalfn
if eq == nil {
panic(errorString("comparing uncomparable type " + *t.string))
}
if isDirectIface(t) {
return x.data == y.data
}
return eq(x.data, y.data, t.size)
}
func ifacevaleq(x iface, t *_type, p unsafe.Pointer) bool {
if x.tab == nil {
return false
}
xt := *(**_type)(x.tab)
if !eqtype(xt, t) {
return false
}
eq := t.equalfn
if eq == nil {
panic(errorString("comparing uncomparable type " + *t.string))
}
if isDirectIface(t) {
return x.data == p
}
return eq(x.data, p, t.size)
}
func ifaceefaceeq(x iface, y eface) bool {
if x.tab == nil && y._type == nil {
return true
}
if x.tab == nil || y._type == nil {
return false
}
xt := *(**_type)(x.tab)
if !eqtype(xt, y._type) {
return false
}
eq := xt.equalfn
if eq == nil {
panic(errorString("comparing uncomparable type " + *xt.string))
}
if isDirectIface(xt) {
return x.data == y.data
}
return eq(x.data, y.data, xt.size)
}
func efacevaleq(x eface, t *_type, p unsafe.Pointer) bool {
if x._type == nil {
return false
}
if !eqtype(x._type, t) {
return false
}
eq := t.equalfn
if eq == nil {
panic(errorString("comparing uncomparable type " + *t.string))
}
if isDirectIface(t) {
return x.data == p
}
return eq(x.data, p, t.size)
}
func eqstring(x, y string) bool {
a := stringStructOf(&x)
b := stringStructOf(&y)
if a.len != b.len {
return false
}
return memcmp(unsafe.Pointer(a.str), unsafe.Pointer(b.str), uintptr(a.len)) == 0
}
func cmpstring(x, y string) int {
a := stringStructOf(&x)
b := stringStructOf(&y)
l := a.len
if l > b.len {
l = b.len
}
i := memcmp(unsafe.Pointer(a.str), unsafe.Pointer(b.str), uintptr(l))
if i != 0 {
return int(i)
}
if a.len < b.len {
return -1
} else if a.len > b.len {
return 1
}
return 0
}
// Force the creation of function descriptors for equality and hash
// functions. These will be referenced directly by the compiler.
var _ = interhash
var _ = interequal
var _ = nilinterhash
var _ = nilinterequal

334
libgo/go/runtime/iface.go Normal file
View File

@ -0,0 +1,334 @@
// Copyright 2014 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
import (
"unsafe"
)
// For gccgo, use go:linkname to rename compiler-called functions to
// themselves, so that the compiler will export them.
//
//go:linkname requireitab runtime.requireitab
//go:linkname assertitab runtime.assertitab
//go:linkname assertI2T runtime.assertI2T
//go:linkname ifacetypeeq runtime.ifacetypeeq
//go:linkname efacetype runtime.efacetype
//go:linkname ifacetype runtime.ifacetype
//go:linkname ifaceE2E2 runtime.ifaceE2E2
//go:linkname ifaceI2E2 runtime.ifaceI2E2
//go:linkname ifaceE2I2 runtime.ifaceE2I2
//go:linkname ifaceI2I2 runtime.ifaceI2I2
//go:linkname ifaceE2T2P runtime.ifaceE2T2P
//go:linkname ifaceI2T2P runtime.ifaceI2T2P
//go:linkname ifaceE2T2 runtime.ifaceE2T2
//go:linkname ifaceI2T2 runtime.ifaceI2T2
//go:linkname ifaceT2Ip runtime.ifaceT2Ip
// Temporary for C code to call:
//go:linkname getitab runtime.getitab
// The gccgo itab structure is different than the gc one.
//
// Both gccgo and gc represent empty interfaces the same way:
// a two field struct, where the first field points to a type descriptor
// (a *_type) and the second field is the data pointer.
//
// Non-empty interfaces are also two-field structs, and the second
// field is the data pointer. However, for gccgo, the first field, the
// itab field, is different. The itab field points to the interface
// method table, which is the implemention of a specific interface
// type for a specific dynamic non-interface type. An interface
// method table is a list of pointer values. The first pointer is the
// type descriptor (a *_type) for the dynamic type. The subsequent
// pointers are pointers to function code, which implement the methods
// required by the interface. The pointers are sorted by name.
//
// The method pointers in the itab are C function pointers, not Go
// function pointers; they may be called directly, and they have no
// closures. The receiver is always passed as a pointer, and it is
// always the same pointer stored in the interface value. A value
// method starts by copying the receiver value out of the pointer into
// a local variable.
//
// A method call on an interface value is by definition calling a
// method at a known index m in the list of methods. Given a non-empty
// interface value i, the call i.m(args) looks like
// i.itab[m+1](i.iface, args)
// Both an empty interface and a non-empty interface have a data
// pointer field. The meaning of this field is determined by the
// kindDirectIface bit in the `kind` field of the type descriptor of
// the value stored in the interface. If kindDirectIface is set, then
// the data pointer field in the interface value is exactly the value
// stored in the interface. Otherwise, the data pointer field is a
// pointer to memory that holds the value. It follows from this that
// kindDirectIface can only be set for a type whose representation is
// simply a pointer. In the current gccgo implementation, this is set
// only for pointer types (including unsafe.Pointer). In the future it
// could also be set for other types: channels, maps, functions,
// single-field structs and single-element arrays whose single field
// is simply a pointer.
// For a nil interface value both fields in the interface struct are nil.
// Return the interface method table for a value of type rhs converted
// to an interface of type lhs.
func getitab(lhs, rhs *_type, canfail bool) unsafe.Pointer {
if rhs == nil {
return nil
}
if lhs.kind&kindMask != kindInterface {
throw("getitab called for non-interface type")
}
lhsi := (*interfacetype)(unsafe.Pointer(lhs))
if len(lhsi.methods) == 0 {
throw("getitab called for empty interface type")
}
if rhs.uncommontype == nil || len(rhs.methods) == 0 {
if canfail {
return nil
}
panic(&TypeAssertionError{"", *rhs.string, *lhs.string, *lhsi.methods[0].name})
}
methods := make([]unsafe.Pointer, len(lhsi.methods)+1)
methods[0] = unsafe.Pointer(rhs)
ri := 0
for li := range lhsi.methods {
lhsMethod := &lhsi.methods[li]
var rhsMethod *method
for {
if ri >= len(rhs.methods) {
if canfail {
return nil
}
panic(&TypeAssertionError{"", *rhs.string, *lhs.string, *lhsMethod.name})
}
rhsMethod = &rhs.methods[ri]
if (lhsMethod.name == rhsMethod.name || *lhsMethod.name == *rhsMethod.name) &&
(lhsMethod.pkgPath == rhsMethod.pkgPath || *lhsMethod.pkgPath == *rhsMethod.pkgPath) {
break
}
ri++
}
if !eqtype(lhsMethod.typ, rhsMethod.mtyp) {
if canfail {
return nil
}
panic(&TypeAssertionError{"", *rhs.string, *lhs.string, *lhsMethod.name})
}
methods[li+1] = unsafe.Pointer(rhsMethod.tfn)
ri++
}
return unsafe.Pointer(&methods[0])
}
// Return the interface method table for a value of type rhs converted
// to an interface of type lhs. Panics if the conversion is impossible.
func requireitab(lhs, rhs *_type) unsafe.Pointer {
return getitab(lhs, rhs, false)
}
// Return the interface method table for a value of type rhs converted
// to an interface of type lhs. Panics if the conversion is
// impossible or if the rhs type is nil.
func assertitab(lhs, rhs *_type) unsafe.Pointer {
if rhs == nil {
panic(&TypeAssertionError{"", "", *lhs.string, ""})
}
if lhs.kind&kindMask != kindInterface {
throw("assertitab called for non-interface type")
}
lhsi := (*interfacetype)(unsafe.Pointer(lhs))
if len(lhsi.methods) == 0 {
return unsafe.Pointer(rhs)
}
return getitab(lhs, rhs, false)
}
// Check whether an interface type may be converted to a non-interface
// type, panicing if not.
func assertI2T(lhs, rhs, inter *_type) {
if rhs == nil {
panic(&TypeAssertionError{"", "", *lhs.string, ""})
}
if !eqtype(lhs, rhs) {
panic(&TypeAssertionError{*inter.string, *rhs.string, *lhs.string, ""})
}
}
// Compare two type descriptors for equality.
func ifacetypeeq(a, b *_type) bool {
return eqtype(a, b)
}
// Return the type descriptor of an empty interface.
// FIXME: This should be inlined by the compiler.
func efacetype(e eface) *_type {
return e._type
}
// Return the type descriptor of a non-empty interface.
// FIXME: This should be inlined by the compiler.
func ifacetype(i iface) *_type {
if i.tab == nil {
return nil
}
return *(**_type)(i.tab)
}
// Convert an empty interface to an empty interface, for a comma-ok
// type assertion.
func ifaceE2E2(e eface) (eface, bool) {
return e, e._type != nil
}
// Convert a non-empty interface to an empty interface, for a comma-ok
// type assertion.
func ifaceI2E2(i iface) (eface, bool) {
if i.tab == nil {
return eface{nil, nil}, false
} else {
return eface{*(**_type)(i.tab), i.data}, true
}
}
// Convert an empty interface to a non-empty interface, for a comma-ok
// type assertion.
func ifaceE2I2(inter *_type, e eface) (iface, bool) {
if e._type == nil {
return iface{nil, nil}, false
} else {
itab := getitab(inter, e._type, true)
if itab == nil {
return iface{nil, nil}, false
} else {
return iface{itab, e.data}, true
}
}
}
// Convert a non-empty interface to a non-empty interface, for a
// comma-ok type assertion.
func ifaceI2I2(inter *_type, i iface) (iface, bool) {
if i.tab == nil {
return iface{nil, nil}, false
} else {
itab := getitab(inter, *(**_type)(i.tab), true)
if itab == nil {
return iface{nil, nil}, false
} else {
return iface{itab, i.data}, true
}
}
}
// Convert an empty interface to a pointer non-interface type.
func ifaceE2T2P(t *_type, e eface) (unsafe.Pointer, bool) {
if !eqtype(t, e._type) {
return nil, false
} else {
return e.data, true
}
}
// Convert a non-empty interface to a pointer non-interface type.
func ifaceI2T2P(t *_type, i iface) (unsafe.Pointer, bool) {
if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
return nil, false
} else {
return i.data, true
}
}
// Convert an empty interface to a non-pointer non-interface type.
func ifaceE2T2(t *_type, e eface, ret unsafe.Pointer) bool {
if !eqtype(t, e._type) {
memclr(ret, t.size)
return false
} else {
typedmemmove(t, ret, e.data)
return true
}
}
// Convert a non-empty interface to a non-pointer non-interface type.
func ifaceI2T2(t *_type, i iface, ret unsafe.Pointer) bool {
if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
memclr(ret, t.size)
return false
} else {
typedmemmove(t, ret, i.data)
return true
}
}
// Return whether we can convert a type to an interface type.
func ifaceT2Ip(to, from *_type) bool {
if from == nil {
return false
}
if to.kind&kindMask != kindInterface {
throw("ifaceT2Ip called with non-interface type")
}
toi := (*interfacetype)(unsafe.Pointer(to))
if from.uncommontype == nil || len(from.methods) == 0 {
return len(toi.methods) == 0
}
ri := 0
for li := range toi.methods {
toMethod := &toi.methods[li]
var fromMethod *method
for {
if ri >= len(from.methods) {
return false
}
fromMethod = &from.methods[ri]
if (toMethod.name == fromMethod.name || *toMethod.name == *fromMethod.name) &&
(toMethod.pkgPath == fromMethod.pkgPath || *toMethod.pkgPath == *fromMethod.pkgPath) {
break
}
ri++
}
if !eqtype(fromMethod.mtyp, toMethod.typ) {
return false
}
ri++
}
return true
}
//go:linkname reflect_ifaceE2I reflect.ifaceE2I
func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
t := e._type
if t == nil {
panic(TypeAssertionError{"", "", *inter.typ.string, ""})
}
dst.tab = requireitab((*_type)(unsafe.Pointer(inter)), t)
dst.data = e.data
}

View File

@ -138,11 +138,15 @@ type funcval struct {
// variable-size, fn-specific data here
}
// The representation of a non-empty interface.
// See comment in iface.go for more details on this struct.
type iface struct {
tab unsafe.Pointer
data unsafe.Pointer
}
// The representation of an empty interface.
// See comment in iface.go for more details on this struct.
type eface struct {
_type *_type
data unsafe.Pointer

View File

@ -73,7 +73,6 @@ func reflect_memclr(ptr unsafe.Pointer, n uintptr) {
}
// memmove copies n bytes from "from" to "to".
// in memmove_*.s
//go:noescape
func memmove(to, from unsafe.Pointer, n uintptr)
@ -82,6 +81,10 @@ func reflect_memmove(to, from unsafe.Pointer, n uintptr) {
memmove(to, from, n)
}
//go:noescape
//extern __builtin_memcmp
func memcmp(a, b unsafe.Pointer, size uintptr) int32
// exported value for testing
var hashLoad = loadFactor
@ -466,3 +469,8 @@ func setMaxThreads(in int) (out int) {
func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
atomic.StorepNoWB(noescape(ptr), new)
}
// Temporary for gccgo until we port mbarrier.go
func writebarrierptr(dst *uintptr, src uintptr) {
*dst = src
}

View File

@ -25,6 +25,22 @@ type _type struct {
ptrToThis *_type
}
// Return whether two type descriptors are equal.
// This is gccgo-specific, as gccgo, unlike gc, permits multiple
// independent descriptors for a single type.
func eqtype(t1, t2 *_type) bool {
switch {
case t1 == t2:
return true
case t1 == nil || t2 == nil:
return false
case t1.kind != t2.kind || t1.hash != t2.hash:
return false
default:
return *t1.string == *t2.string
}
}
type method struct {
name *string
pkgPath *string

View File

@ -1,45 +0,0 @@
/* go-assert-interface.c -- interface type assertion for Go.
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. */
#include "runtime.h"
#include "go-alloc.h"
#include "go-assert.h"
#include "go-panic.h"
#include "go-type.h"
#include "interface.h"
/* This is called by the compiler to implement a type assertion from
one interface type to another. This returns the value that should
go in the first field of the result tuple. The result may be an
empty or a non-empty interface. */
const void *
__go_assert_interface (const struct __go_type_descriptor *lhs_descriptor,
const struct __go_type_descriptor *rhs_descriptor)
{
const struct __go_interface_type *lhs_interface;
if (rhs_descriptor == NULL)
{
struct __go_empty_interface panic_arg;
/* A type assertion is not permitted with a nil interface. */
runtime_newTypeAssertionError (NULL, NULL, lhs_descriptor->__reflection,
NULL, &panic_arg);
__go_panic (panic_arg);
}
/* A type assertion to an empty interface just returns the object
descriptor. */
__go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE);
lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
if (lhs_interface->__methods.__count == 0)
return rhs_descriptor;
return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
}

View File

@ -1,78 +0,0 @@
/* go-can-convert-interface.c -- can we convert to an interface?
Copyright 2009 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. */
#include "runtime.h"
#include "go-assert.h"
#include "go-string.h"
#include "go-type.h"
#include "interface.h"
/* Return whether we can convert from the type in FROM_DESCRIPTOR to
the interface in TO_DESCRIPTOR. This is used for type
switches. */
_Bool
__go_can_convert_to_interface (
const struct __go_type_descriptor *to_descriptor,
const struct __go_type_descriptor *from_descriptor)
{
const struct __go_interface_type *to_interface;
int to_method_count;
const struct __go_interface_method *to_method;
const struct __go_uncommon_type *from_uncommon;
int from_method_count;
const struct __go_method *from_method;
int i;
/* In a type switch FROM_DESCRIPTOR can be NULL. */
if (from_descriptor == NULL)
return 0;
__go_assert ((to_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE);
to_interface = (const struct __go_interface_type *) to_descriptor;
to_method_count = to_interface->__methods.__count;
to_method = ((const struct __go_interface_method *)
to_interface->__methods.__values);
from_uncommon = from_descriptor->__uncommon;
if (from_uncommon == NULL)
{
from_method_count = 0;
from_method = NULL;
}
else
{
from_method_count = from_uncommon->__methods.__count;
from_method = ((const struct __go_method *)
from_uncommon->__methods.__values);
}
for (i = 0; i < to_method_count; ++i)
{
while (from_method_count > 0
&& (!__go_ptr_strings_equal (from_method->__name,
to_method->__name)
|| !__go_ptr_strings_equal (from_method->__pkg_path,
to_method->__pkg_path)))
{
++from_method;
--from_method_count;
}
if (from_method_count == 0)
return 0;
if (!__go_type_descriptors_equal (from_method->__mtype,
to_method->__type))
return 0;
++to_method;
++from_method;
--from_method_count;
}
return 1;
}

View File

@ -6,7 +6,6 @@
#include "runtime.h"
#include "go-alloc.h"
#include "interface.h"
#include "go-panic.h"
#include "go-type.h"
@ -170,7 +169,8 @@ _cgo_panic (const char *p)
intgo len;
unsigned char *data;
String *ps;
struct __go_empty_interface e;
Eface e;
const struct __go_type_descriptor *td;
runtime_exitsyscall (0);
len = __builtin_strlen (p);
@ -179,8 +179,9 @@ _cgo_panic (const char *p)
ps = alloc_saved (sizeof *ps);
ps->str = data;
ps->len = len;
e.__type_descriptor = &string_type_descriptor;
e.__object = ps;
td = &string_type_descriptor;
memcpy(&e._type, &td, sizeof td); /* This is a const_cast. */
e.data = ps;
/* We don't call runtime_entersyscall here, because normally what
will happen is that we will walk up the stack to a Go deferred

View File

@ -1,46 +0,0 @@
/* go-check-interface.c -- check an interface type for a conversion
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. */
#include "runtime.h"
#include "go-panic.h"
#include "go-type.h"
#include "interface.h"
/* Check that an interface type matches for a conversion to a
non-interface type. This panics if the types are bad. The actual
extraction of the object is inlined. */
void
__go_check_interface_type (
const struct __go_type_descriptor *lhs_descriptor,
const struct __go_type_descriptor *rhs_descriptor,
const struct __go_type_descriptor *rhs_inter_descriptor)
{
if (rhs_descriptor == NULL)
{
struct __go_empty_interface panic_arg;
runtime_newTypeAssertionError(NULL, NULL, lhs_descriptor->__reflection,
NULL, &panic_arg);
__go_panic(panic_arg);
}
if (lhs_descriptor != rhs_descriptor
&& !__go_type_descriptors_equal (lhs_descriptor, rhs_descriptor)
&& ((lhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER
|| !__go_is_pointer_type (rhs_descriptor))
&& ((rhs_descriptor->__code & GO_CODE_MASK) != GO_UNSAFE_POINTER
|| !__go_is_pointer_type (lhs_descriptor)))
{
struct __go_empty_interface panic_arg;
runtime_newTypeAssertionError(rhs_inter_descriptor->__reflection,
rhs_descriptor->__reflection,
lhs_descriptor->__reflection,
NULL, &panic_arg);
__go_panic(panic_arg);
}
}

View File

@ -1,132 +0,0 @@
/* go-convert-interface.c -- convert interfaces for Go.
Copyright 2009 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. */
#include "runtime.h"
#include "go-alloc.h"
#include "go-assert.h"
#include "go-panic.h"
#include "go-string.h"
#include "go-type.h"
#include "interface.h"
/* This is called when converting one interface type into another
interface type. LHS_DESCRIPTOR is the type descriptor of the
resulting interface. RHS_DESCRIPTOR is the type descriptor of the
object being converted. This builds and returns a new interface
method table. If any method in the LHS_DESCRIPTOR interface is not
implemented by the object, the conversion fails. If the conversion
fails, then if MAY_FAIL is true this returns NULL; otherwise, it
panics. */
void *
__go_convert_interface_2 (const struct __go_type_descriptor *lhs_descriptor,
const struct __go_type_descriptor *rhs_descriptor,
_Bool may_fail)
{
const struct __go_interface_type *lhs_interface;
int lhs_method_count;
const struct __go_interface_method* lhs_methods;
const void **methods;
const struct __go_uncommon_type *rhs_uncommon;
int rhs_method_count;
const struct __go_method *p_rhs_method;
int i;
if (rhs_descriptor == NULL)
{
/* A nil value always converts to nil. */
return NULL;
}
__go_assert ((lhs_descriptor->__code & GO_CODE_MASK) == GO_INTERFACE);
lhs_interface = (const struct __go_interface_type *) lhs_descriptor;
lhs_method_count = lhs_interface->__methods.__count;
lhs_methods = ((const struct __go_interface_method *)
lhs_interface->__methods.__values);
/* This should not be called for an empty interface. */
__go_assert (lhs_method_count > 0);
rhs_uncommon = rhs_descriptor->__uncommon;
if (rhs_uncommon == NULL || rhs_uncommon->__methods.__count == 0)
{
struct __go_empty_interface panic_arg;
if (may_fail)
return NULL;
runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
lhs_descriptor->__reflection,
lhs_methods[0].__name,
&panic_arg);
__go_panic (panic_arg);
}
rhs_method_count = rhs_uncommon->__methods.__count;
p_rhs_method = ((const struct __go_method *)
rhs_uncommon->__methods.__values);
methods = NULL;
for (i = 0; i < lhs_method_count; ++i)
{
const struct __go_interface_method *p_lhs_method;
p_lhs_method = &lhs_methods[i];
while (rhs_method_count > 0
&& (!__go_ptr_strings_equal (p_lhs_method->__name,
p_rhs_method->__name)
|| !__go_ptr_strings_equal (p_lhs_method->__pkg_path,
p_rhs_method->__pkg_path)))
{
++p_rhs_method;
--rhs_method_count;
}
if (rhs_method_count == 0
|| !__go_type_descriptors_equal (p_lhs_method->__type,
p_rhs_method->__mtype))
{
struct __go_empty_interface panic_arg;
if (methods != NULL)
__go_free (methods);
if (may_fail)
return NULL;
runtime_newTypeAssertionError (NULL, rhs_descriptor->__reflection,
lhs_descriptor->__reflection,
p_lhs_method->__name, &panic_arg);
__go_panic (panic_arg);
}
if (methods == NULL)
{
methods = (const void **) __go_alloc ((lhs_method_count + 1)
* sizeof (void *));
/* The first field in the method table is always the type of
the object. */
methods[0] = rhs_descriptor;
}
methods[i + 1] = p_rhs_method->__function;
}
return methods;
}
/* This is called by the compiler to convert a value from one
interface type to another. */
void *
__go_convert_interface (const struct __go_type_descriptor *lhs_descriptor,
const struct __go_type_descriptor *rhs_descriptor)
{
return __go_convert_interface_2 (lhs_descriptor, rhs_descriptor, 0);
}

View File

@ -75,7 +75,7 @@
because you are not permitted to take the address of a predeclared
function like recover. */
struct __go_empty_interface
Eface
__go_deferred_recover ()
{
G *g;
@ -83,10 +83,10 @@ __go_deferred_recover ()
g = runtime_g ();
if (g->_defer == NULL || g->_defer->_panic != g->_panic)
{
struct __go_empty_interface ret;
Eface ret;
ret.__type_descriptor = NULL;
ret.__object = NULL;
ret._type = NULL;
ret.data = NULL;
return ret;
}
return __go_recover ();

View File

@ -1,37 +0,0 @@
/* go-eface-compare.c -- compare two empty values.
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. */
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
/* Compare two interface values. Return 0 for equal, not zero for not
equal (return value is like strcmp). */
intgo
__go_empty_interface_compare (struct __go_empty_interface left,
struct __go_empty_interface right)
{
const struct __go_type_descriptor *left_descriptor;
left_descriptor = left.__type_descriptor;
if (left_descriptor == NULL && right.__type_descriptor == NULL)
return 0;
if (left_descriptor == NULL || right.__type_descriptor == NULL)
return 1;
if (!__go_type_descriptors_equal (left_descriptor,
right.__type_descriptor))
return 1;
if (left_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1;
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
right.__object, left_descriptor->__size))
return 1;
return 0;
}

View File

@ -1,35 +0,0 @@
/* go-eface-val-compare.c -- compare an empty interface with a value.
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. */
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
/* Compare an empty interface with a value. Return 0 for equal, not
zero for not equal (return value is like strcmp). */
intgo
__go_empty_interface_value_compare (
struct __go_empty_interface left,
const struct __go_type_descriptor *right_descriptor,
const void *val)
{
const struct __go_type_descriptor *left_descriptor;
left_descriptor = left.__type_descriptor;
if (left_descriptor == NULL)
return 1;
if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
return 1;
if (left_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (left_descriptor))
return left.__object == val ? 0 : 1;
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
left_descriptor->__size))
return 1;
return 0;
}

View File

@ -1,130 +0,0 @@
// 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) {
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 (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 (!__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 (!__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);
}

View File

@ -1,37 +0,0 @@
/* go-interface-compare.c -- compare two interface values.
Copyright 2009 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. */
#include <stddef.h>
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
/* Compare two interface values. Return 0 for equal, not zero for not
equal (return value is like strcmp). */
int
__go_interface_compare (struct __go_interface left,
struct __go_interface right)
{
const struct __go_type_descriptor *left_descriptor;
if (left.__methods == NULL && right.__methods == NULL)
return 0;
if (left.__methods == NULL || right.__methods == NULL)
return 1;
left_descriptor = left.__methods[0];
if (!__go_type_descriptors_equal (left_descriptor, right.__methods[0]))
return 1;
if (left_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1;
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
right.__object, left_descriptor->__size))
return 1;
return 0;
}

View File

@ -1,36 +0,0 @@
/* go-interface-eface-compare.c -- compare non-empty and empty interface.
Copyright 2011 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. */
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
/* Compare a non-empty interface value with an empty interface value.
Return 0 for equal, not zero for not equal (return value is like
strcmp). */
intgo
__go_interface_empty_compare (struct __go_interface left,
struct __go_empty_interface right)
{
const struct __go_type_descriptor *left_descriptor;
if (left.__methods == NULL && right.__type_descriptor == NULL)
return 0;
if (left.__methods == NULL || right.__type_descriptor == NULL)
return 1;
left_descriptor = left.__methods[0];
if (!__go_type_descriptors_equal (left_descriptor, right.__type_descriptor))
return 1;
if (left_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (left_descriptor))
return left.__object == right.__object ? 0 : 1;
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object,
right.__object, left_descriptor->__size))
return 1;
return 0;
}

View File

@ -1,35 +0,0 @@
/* go-interface-val-compare.c -- compare an interface to a value.
Copyright 2009 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. */
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
/* Compare two interface values. Return 0 for equal, not zero for not
equal (return value is like strcmp). */
intgo
__go_interface_value_compare (
struct __go_interface left,
const struct __go_type_descriptor *right_descriptor,
const void *val)
{
const struct __go_type_descriptor *left_descriptor;
if (left.__methods == NULL)
return 1;
left_descriptor = left.__methods[0];
if (!__go_type_descriptors_equal (left_descriptor, right_descriptor))
return 1;
if (left_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (left_descriptor))
return left.__object == val ? 0 : 1;
if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val,
left_descriptor->__size))
return 1;
return 0;
}

View File

@ -12,7 +12,6 @@
#include "malloc.h"
#include "go-alloc.h"
#include "go-panic.h"
#include "interface.h"
/* Print the panic stack. This is used when there is no recover. */
@ -35,7 +34,7 @@ __printpanics (Panic *p)
function. */
void
__go_panic (struct __go_empty_interface arg)
__go_panic (Eface arg)
{
G *g;
Panic *n;

View File

@ -7,24 +7,18 @@
#ifndef LIBGO_GO_PANIC_H
#define LIBGO_GO_PANIC_H
#include "interface.h"
struct String;
struct __go_type_descriptor;
extern void __go_panic (struct __go_empty_interface)
extern void __go_panic (Eface)
__attribute__ ((noreturn));
extern void __go_print_string (struct String);
extern void __go_print_string (String);
extern struct __go_empty_interface __go_recover (void);
extern Eface __go_recover (void);
extern _Bool __go_can_recover (void *);
extern void __go_makefunc_can_recover (void *retaddr);
struct location;
extern void __go_makefunc_ffi_can_recover (struct location *, int);
extern void __go_makefunc_ffi_can_recover (Location*, int);
extern void __go_makefunc_returning (void);

View File

@ -5,7 +5,6 @@
license that can be found in the LICENSE file. */
#include "runtime.h"
#include "interface.h"
#include "go-panic.h"
/* If the top of the defer stack can be recovered, then return it.
@ -200,7 +199,7 @@ __go_makefunc_can_recover (void *retaddr)
make the same decision. */
void
__go_makefunc_ffi_can_recover (struct location *loc, int n)
__go_makefunc_ffi_can_recover (Location *loc, int n)
{
Defer *d;
const byte *name;
@ -252,7 +251,7 @@ __go_makefunc_returning (void)
/* This is only called when it is valid for the caller to recover the
value on top of the panic stack, if there is one. */
struct __go_empty_interface
Eface
__go_recover ()
{
G *g;
@ -262,10 +261,10 @@ __go_recover ()
if (g->_panic == NULL || g->_panic->recovered)
{
struct __go_empty_interface ret;
Eface ret;
ret.__type_descriptor = NULL;
ret.__object = NULL;
ret._type = NULL;
ret.data = NULL;
return ret;
}
p = g->_panic;

View File

@ -1,25 +0,0 @@
/* go-strcmp.c -- the go string comparison function.
Copyright 2009 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. */
#include "runtime.h"
intgo
__go_strcmp(String s1, String s2)
{
int i;
i = __builtin_memcmp(s1.str, s2.str,
(s1.len < s2.len ? s1.len : s2.len));
if (i != 0)
return i;
if (s1.len < s2.len)
return -1;
else if (s1.len > s2.len)
return 1;
else
return 0;
}

View File

@ -4,8 +4,8 @@
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file. */
#include "go-panic.h"
#include "runtime.h"
#include "go-panic.h"
#include "arch.h"
#include "malloc.h"

View File

@ -1,66 +0,0 @@
/* go-type-eface.c -- hash and equality empty interface functions.
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. */
#include "runtime.h"
#include "interface.h"
#include "go-type.h"
/* A hash function for an empty interface. */
uintptr_t
__go_type_hash_empty_interface (const void *vval, uintptr_t seed,
uintptr_t key_size __attribute__ ((unused)))
{
const struct __go_empty_interface *val;
const struct __go_type_descriptor *descriptor;
uintptr_t size;
val = (const struct __go_empty_interface *) vval;
descriptor = val->__type_descriptor;
if (descriptor == NULL)
return 0;
if (descriptor->__hashfn == NULL)
runtime_panicstring ("hash of unhashable type");
size = descriptor->__size;
if (__go_is_pointer_type (descriptor))
return __go_call_hashfn (descriptor->__hashfn, &val->__object, seed, size);
else
return __go_call_hashfn (descriptor->__hashfn, val->__object, seed, size);
}
const FuncVal __go_type_hash_empty_interface_descriptor =
{ (void *) __go_type_hash_empty_interface };
/* An equality function for an empty interface. */
_Bool
__go_type_equal_empty_interface (const void *vv1, const void *vv2,
uintptr_t key_size __attribute__ ((unused)))
{
const struct __go_empty_interface *v1;
const struct __go_empty_interface *v2;
const struct __go_type_descriptor* v1_descriptor;
const struct __go_type_descriptor* v2_descriptor;
v1 = (const struct __go_empty_interface *) vv1;
v2 = (const struct __go_empty_interface *) vv2;
v1_descriptor = v1->__type_descriptor;
v2_descriptor = v2->__type_descriptor;
if (v1_descriptor == NULL || v2_descriptor == NULL)
return v1_descriptor == v2_descriptor;
if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
return 0;
if (v1_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (v1_descriptor))
return v1->__object == v2->__object;
else
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 };

View File

@ -1,66 +0,0 @@
/* go-type-interface.c -- hash and equality interface functions.
Copyright 2009 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. */
#include "runtime.h"
#include "interface.h"
#include "go-type.h"
/* A hash function for an interface. */
uintptr_t
__go_type_hash_interface (const void *vval, uintptr_t seed,
uintptr_t key_size __attribute__ ((unused)))
{
const struct __go_interface *val;
const struct __go_type_descriptor *descriptor;
uintptr_t size;
val = (const struct __go_interface *) vval;
if (val->__methods == NULL)
return 0;
descriptor = (const struct __go_type_descriptor *) val->__methods[0];
if (descriptor->__hashfn == NULL)
runtime_panicstring ("hash of unhashable type");
size = descriptor->__size;
if (__go_is_pointer_type (descriptor))
return __go_call_hashfn (descriptor->__hashfn, &val->__object, seed, size);
else
return __go_call_hashfn (descriptor->__hashfn, val->__object, seed, size);
}
const FuncVal __go_type_hash_interface_descriptor =
{ (void *) __go_type_hash_interface };
/* An equality function for an interface. */
_Bool
__go_type_equal_interface (const void *vv1, const void *vv2,
uintptr_t key_size __attribute__ ((unused)))
{
const struct __go_interface *v1;
const struct __go_interface *v2;
const struct __go_type_descriptor* v1_descriptor;
const struct __go_type_descriptor* v2_descriptor;
v1 = (const struct __go_interface *) vv1;
v2 = (const struct __go_interface *) vv2;
if (v1->__methods == NULL || v2->__methods == NULL)
return v1->__methods == v2->__methods;
v1_descriptor = (const struct __go_type_descriptor *) v1->__methods[0];
v2_descriptor = (const struct __go_type_descriptor *) v2->__methods[0];
if (!__go_type_descriptors_equal (v1_descriptor, v2_descriptor))
return 0;
if (v1_descriptor->__equalfn == NULL)
runtime_panicstring ("comparing uncomparable types");
if (__go_is_pointer_type (v1_descriptor))
return v1->__object == v2->__object;
else
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 };

View File

@ -8,7 +8,6 @@
#include "arch.h"
#include "malloc.h"
#include "go-type.h"
#include "interface.h"
/* Implement unsafe_New, called from the reflect package. */

View File

@ -8,7 +8,6 @@
#include "arch.h"
#include "malloc.h"
#include "go-type.h"
#include "interface.h"
/* Implement unsafe_NewArray, called from the reflect package. */

View File

@ -67,8 +67,8 @@ __go_check_defer (_Bool *frame)
n = (Panic *) __go_alloc (sizeof (Panic));
n->arg.__type_descriptor = NULL;
n->arg.__object = NULL;
n->arg._type = NULL;
n->arg.data = NULL;
n->recovered = 0;
n->isforeign = 1;
n->next = g->_panic;

View File

@ -298,8 +298,8 @@ dumpgoroutine(G *gp)
dumpint(TagPanic);
dumpint((uintptr)p);
dumpint((uintptr)gp);
dumpint((uintptr)p->arg.__type_descriptor);
dumpint((uintptr)p->arg.__object);
dumpint((uintptr)p->arg._type);
dumpint((uintptr)p->arg.data);
dumpint((uintptr)0);
dumpint((uintptr)p->next);
}

View File

@ -1,57 +0,0 @@
/* interface.h -- the interface type for Go.
Copyright 2009 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. */
#ifndef LIBGO_INTERFACE_H
#define LIBGO_INTERFACE_H
struct __go_type_descriptor;
/* A variable of interface type is an instance of this struct, if the
interface has any methods. */
struct __go_interface
{
/* A pointer to the interface method table. The first pointer is
the type descriptor of the object. Subsequent pointers are
pointers to functions. This is effectively the vtable for this
interface. The function pointers are in the same order as the
list in the internal representation of the interface, which sorts
them by name. */
const void **__methods;
/* The object. If the object is a pointer--if the type descriptor
code is GO_PTR or GO_UNSAFE_POINTER--then this field is the value
of the object itself. Otherwise this is a pointer to memory
which holds the value. */
void *__object;
};
/* A variable of an empty interface type is an instance of this
struct. */
struct __go_empty_interface
{
/* The type descriptor of the object. */
const struct __go_type_descriptor *__type_descriptor;
/* The object. This is the same as __go_interface above. */
void *__object;
};
extern void *
__go_convert_interface (const struct __go_type_descriptor *,
const struct __go_type_descriptor *);
extern void *
__go_convert_interface_2 (const struct __go_type_descriptor *,
const struct __go_type_descriptor *,
_Bool may_fail);
extern _Bool
__go_can_convert_to_interface(const struct __go_type_descriptor *,
const struct __go_type_descriptor *);
#endif /* !defined(LIBGO_INTERFACE_H) */

View File

@ -14,12 +14,9 @@ package runtime
#include "runtime.h"
#include "arch.h"
#include "malloc.h"
#include "interface.h"
#include "go-type.h"
// Map gccgo field names to gc field names.
// Eface aka __go_empty_interface.
#define type __type_descriptor
// Type aka __go_type_descriptor
#define kind __code
#define string __reflection
@ -917,15 +914,15 @@ func SetFinalizer(obj Eface, finalizer Eface) {
const Type *fint;
const PtrType *ot;
if(obj.__type_descriptor == nil) {
if((Type*)obj._type == nil) {
runtime_printf("runtime.SetFinalizer: first argument is nil interface\n");
goto throw;
}
if((obj.__type_descriptor->kind&kindMask) != GO_PTR) {
runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.__type_descriptor->__reflection);
if((((Type*)obj._type)->kind&kindMask) != GO_PTR) {
runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *((Type*)obj._type)->__reflection);
goto throw;
}
ot = (const PtrType*)obj.type;
ot = (const PtrType*)obj._type;
// As an implementation detail we do not run finalizers for zero-sized objects,
// because we use &runtime_zerobase for all such allocations.
if(ot->__element_type != nil && ot->__element_type->__size == 0)
@ -937,49 +934,49 @@ func SetFinalizer(obj Eface, finalizer Eface) {
// runtime.SetFinalizer(Foo, nil)
// }
// See issue 7656.
if((byte*)obj.__object < runtime_mheap.arena_start || runtime_mheap.arena_used <= (byte*)obj.__object)
if((byte*)obj.data < runtime_mheap.arena_start || runtime_mheap.arena_used <= (byte*)obj.data)
return;
if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object != base) {
if(!runtime_mlookup(obj.data, &base, &size, nil) || obj.data != base) {
// As an implementation detail we allow to set finalizers for an inner byte
// of an object if it could come from tiny alloc (see mallocgc for details).
if(ot->__element_type == nil || (ot->__element_type->kind&kindNoPointers) == 0 || ot->__element_type->__size >= TinySize) {
runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.__object);
runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.data);
goto throw;
}
}
if(finalizer.__type_descriptor != nil) {
if((Type*)finalizer._type != nil) {
runtime_createfing();
if((finalizer.__type_descriptor->kind&kindMask) != GO_FUNC)
if((((Type*)finalizer._type)->kind&kindMask) != GO_FUNC)
goto badfunc;
ft = (const FuncType*)finalizer.__type_descriptor;
ft = (const FuncType*)finalizer._type;
if(ft->__dotdotdot || ft->__in.__count != 1)
goto badfunc;
fint = *(Type**)ft->__in.__values;
if(__go_type_descriptors_equal(fint, obj.__type_descriptor)) {
if(__go_type_descriptors_equal(fint, (Type*)obj._type)) {
// ok - same type
} else if((fint->kind&kindMask) == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || obj.type->__uncommon == nil || obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) {
} else if((fint->kind&kindMask) == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || ((Type*)obj._type)->__uncommon == nil || ((Type*)obj._type)->__uncommon->__name == nil) && __go_type_descriptors_equal(((const PtrType*)fint)->__element_type, ((const PtrType*)obj._type)->__element_type)) {
// ok - not same type, but both pointers,
// one or the other is unnamed, and same element type, so assignable.
} else if((fint->kind&kindMask) == GO_INTERFACE && ((const InterfaceType*)fint)->__methods.__count == 0) {
// ok - satisfies empty interface
} else if((fint->kind&kindMask) == GO_INTERFACE && __go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) {
} else if((fint->kind&kindMask) == GO_INTERFACE && getitab(fint, (Type*)obj._type, true) != nil) {
// ok - satisfies non-empty interface
} else
goto badfunc;
ot = (const PtrType*)obj.__type_descriptor;
if(!runtime_addfinalizer(obj.__object, *(FuncVal**)finalizer.__object, ft, ot)) {
ot = (const PtrType*)obj._type;
if(!runtime_addfinalizer(obj.data, *(FuncVal**)finalizer.data, ft, ot)) {
runtime_printf("runtime.SetFinalizer: finalizer already set\n");
goto throw;
}
} else {
// NOTE: asking to remove a finalizer when there currently isn't one set is OK.
runtime_removefinalizer(obj.__object);
runtime_removefinalizer(obj.data);
}
return;
badfunc:
runtime_printf("runtime.SetFinalizer: cannot pass %S to finalizer %S\n", *obj.__type_descriptor->__reflection, *finalizer.__type_descriptor->__reflection);
runtime_printf("runtime.SetFinalizer: cannot pass %S to finalizer %S\n", *((Type*)obj._type)->__reflection, *((Type*)finalizer._type)->__reflection);
throw:
runtime_throw("runtime.SetFinalizer");
}

View File

@ -62,8 +62,6 @@
// Slice aka __go_open_array.
#define array __values
#define cap __capacity
// Iface aka __go_interface
#define tab __methods
// Hmap aka __go_map
typedef struct __go_map Hmap;
// Type aka __go_type_descriptor
@ -907,12 +905,12 @@ scanblock(Workbuf *wbuf, bool keepworking)
eface = (Eface*)(stack_top.b + pc[1]);
pc += 2;
if(Debug > 2)
runtime_printf("gc_eface @%p: %p %p\n", stack_top.b+pc[1], eface->__type_descriptor, eface->__object);
if(eface->__type_descriptor == nil)
runtime_printf("gc_eface @%p: %p %p\n", stack_top.b+pc[1], eface->_type, eface->data);
if(eface->_type == nil)
continue;
// eface->type
t = eface->__type_descriptor;
t = eface->_type;
if((const byte*)t >= arena_start && (const byte*)t < arena_used) {
union { const Type *tc; Type *tr; } u;
u.tc = t;
@ -921,13 +919,13 @@ scanblock(Workbuf *wbuf, bool keepworking)
flushptrbuf(&sbuf);
}
// eface->__object
if((byte*)eface->__object >= arena_start && (byte*)eface->__object < arena_used) {
// eface->data
if((byte*)eface->data >= arena_start && (byte*)eface->data < arena_used) {
if(__go_is_pointer_type(t)) {
if((t->__code & kindNoPointers))
continue;
obj = eface->__object;
obj = eface->data;
if((t->__code & kindMask) == kindPtr) {
// Only use type information if it is a pointer-containing type.
// This matches the GC programs written by cmd/gc/reflect.c's
@ -937,7 +935,7 @@ scanblock(Workbuf *wbuf, bool keepworking)
objti = (uintptr)((const PtrType*)t)->elem->__gc;
}
} else {
obj = eface->__object;
obj = eface->data;
objti = (uintptr)t->__gc;
}
}
@ -947,7 +945,7 @@ scanblock(Workbuf *wbuf, bool keepworking)
iface = (Iface*)(stack_top.b + pc[1]);
pc += 2;
if(Debug > 2)
runtime_printf("gc_iface @%p: %p/%p %p\n", stack_top.b+pc[1], iface->__methods[0], nil, iface->__object);
runtime_printf("gc_iface @%p: %p/%p %p\n", stack_top.b+pc[1], *(Type**)iface->tab, nil, iface->data);
if(iface->tab == nil)
continue;
@ -959,13 +957,13 @@ scanblock(Workbuf *wbuf, bool keepworking)
}
// iface->data
if((byte*)iface->__object >= arena_start && (byte*)iface->__object < arena_used) {
t = (const Type*)iface->tab[0];
if((byte*)iface->data >= arena_start && (byte*)iface->data < arena_used) {
t = *(Type**)iface->tab;
if(__go_is_pointer_type(t)) {
if((t->__code & kindNoPointers))
continue;
obj = iface->__object;
obj = iface->data;
if((t->__code & kindMask) == kindPtr) {
// Only use type information if it is a pointer-containing type.
// This matches the GC programs written by cmd/gc/reflect.c's
@ -975,7 +973,7 @@ scanblock(Workbuf *wbuf, bool keepworking)
objti = (uintptr)((const PtrType*)t)->elem->__gc;
}
} else {
obj = iface->__object;
obj = iface->data;
objti = (uintptr)t->__gc;
}
}
@ -2448,8 +2446,8 @@ runfinq(void* dummy __attribute__ ((unused)))
fb = nil;
next = nil;
i = 0;
ef.__type_descriptor = nil;
ef.__object = nil;
ef._type = nil;
ef.data = nil;
// force flush to memory
USED(&f);
@ -2483,16 +2481,18 @@ runfinq(void* dummy __attribute__ ((unused)))
param = &f->arg;
} else if(((const InterfaceType*)fint)->__methods.__count == 0) {
// convert to empty interface
ef.__type_descriptor = (const Type*)f->ot;
ef.__object = f->arg;
// using memcpy as const_cast.
memcpy(&ef._type, &f->ot,
sizeof ef._type);
ef.data = f->arg;
param = &ef;
} else {
// convert to interface with methods
iface.__methods = __go_convert_interface_2((const Type*)fint,
(const Type*)f->ot,
1);
iface.__object = f->arg;
if(iface.__methods == nil)
iface.tab = getitab(fint,
(const Type*)f->ot,
true);
iface.data = f->arg;
if(iface.data == nil)
runtime_throw("invalid type conversion in runfinq");
param = &iface;
}
@ -2514,8 +2514,8 @@ runfinq(void* dummy __attribute__ ((unused)))
fb = nil;
next = nil;
i = 0;
ef.__type_descriptor = nil;
ef.__object = nil;
ef._type = nil;
ef.data = nil;
runtime_gc(1); // trigger another gc to clean up the finalized objects, if possible
}
}

View File

@ -1,25 +0,0 @@
// 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 reflect
#include "runtime.h"
#include "go-type.h"
#include "interface.h"
#include "go-panic.h"
func ifaceE2I(inter *Type, e Eface, ret *Iface) {
const Type *t;
Eface err;
t = e.__type_descriptor;
if(t == nil) {
// explicit conversions require non-nil interface value.
runtime_newTypeAssertionError(
nil, nil, inter->__reflection,
nil, &err);
runtime_panic(err);
}
ret->__object = e.__object;
ret->__methods = __go_convert_interface(inter, t);
}

View File

@ -22,7 +22,6 @@
#include <sys/mman.h>
#endif
#include "interface.h"
#include "go-alloc.h"
#define _STRINGIFY2_(x) #x
@ -76,8 +75,8 @@ typedef struct PollDesc PollDesc;
typedef struct sudog SudoG;
typedef struct __go_open_array Slice;
typedef struct __go_interface Iface;
typedef struct __go_empty_interface Eface;
typedef struct iface Iface;
typedef struct eface Eface;
typedef struct __go_type_descriptor Type;
typedef struct _defer Defer;
typedef struct _panic Panic;
@ -105,7 +104,6 @@ struct FuncVal
};
#include "array.h"
#include "interface.h"
// Rename Go types generated by mkrsysinfo.sh from C types, to avoid
// the name conflict.
@ -587,3 +585,7 @@ extern _Bool runtime_iscgo;
extern _Bool runtime_cgoHasExtraM;
extern Hchan *runtime_main_init_done;
extern uintptr __go_end __attribute__ ((weak));
extern void *getitab(const struct __go_type_descriptor *,
const struct __go_type_descriptor *,
_Bool)
__asm__ (GOSYM_PREFIX "runtime.getitab");

View File

@ -40,7 +40,7 @@ func parForIters(desc *ParFor, tid uintptr) (start uintptr, end uintptr) {
}
func typestring(e Eface) (s String) {
s = *e.__type_descriptor->__reflection;
s = *((Type*)e._type)->__reflection;
}
func golockedOSThread() (ret bool) {