diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-10 23:13:39 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-10-10 23:13:39 +0000 |
commit | 65180edc5661b1324a53ac9ebbe03f44cda524e4 (patch) | |
tree | 661f2ef36aee0c3ee5866edd2bcf540260a98506 /gcc/go | |
parent | 73f01cca846d729848e793689389bcaa0dec3045 (diff) | |
download | gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.zip gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.tar.gz gcc-65180edc5661b1324a53ac9ebbe03f44cda524e4.tar.bz2 |
runtime: copy print/println support from Go 1.7
Update the compiler to use the new names. Add calls to printlock and
printunlock around print statements. Move expression evaluation before
the call to printlock. Update g's writebuf field to a slice, and adjust
C code accordingly.
Reviewed-on: https://go-review.googlesource.com/30717
From-SVN: r240956
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 71 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 31 |
3 files changed, 61 insertions, 43 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e22f79e..c987dc9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -f3658aea2493c7f1c4a72502f9e7da562c7764c4 +ecf9b645cefc5c3b4e6339adeb452b2d8642cf3e The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 36000ea..4f8a519 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7018,6 +7018,26 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, } } break; + + case BUILTIN_PRINT: + case BUILTIN_PRINTLN: + // Force all the arguments into temporary variables, so that we + // don't try to evaluate something while holding the print lock. + if (this->args() == NULL) + break; + for (Expression_list::iterator pa = this->args()->begin(); + pa != this->args()->end(); + ++pa) + { + if (!(*pa)->is_variable()) + { + Temporary_statement* temp = + Statement::make_temporary(NULL, *pa, loc); + inserter->insert(temp); + *pa = Expression::make_temporary_reference(temp, loc); + } + } + break; } return this; @@ -8336,7 +8356,9 @@ Builtin_call_expression::do_get_backend(Translate_context* context) case BUILTIN_PRINTLN: { const bool is_ln = this->code_ == BUILTIN_PRINTLN; - Expression* print_stmts = NULL; + + Expression* print_stmts = Runtime::make_call(Runtime::PRINTLOCK, + location, 0); const Expression_list* call_args = this->args(); if (call_args != NULL) @@ -8348,8 +8370,7 @@ Builtin_call_expression::do_get_backend(Translate_context* context) if (is_ln && p != call_args->begin()) { Expression* print_space = - Runtime::make_call(Runtime::PRINT_SPACE, - this->location(), 0); + Runtime::make_call(Runtime::PRINTSP, location, 0); print_stmts = Expression::make_compound(print_stmts, print_space, @@ -8360,51 +8381,51 @@ Builtin_call_expression::do_get_backend(Translate_context* context) Type* type = arg->type(); Runtime::Function code; if (type->is_string_type()) - code = Runtime::PRINT_STRING; + code = Runtime::PRINTSTRING; else if (type->integer_type() != NULL && type->integer_type()->is_unsigned()) { Type* itype = Type::lookup_integer_type("uint64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_UINT64; + code = Runtime::PRINTUINT; } else if (type->integer_type() != NULL) { Type* itype = Type::lookup_integer_type("int64"); arg = Expression::make_cast(itype, arg, location); - code = Runtime::PRINT_INT64; + code = Runtime::PRINTINT; } else if (type->float_type() != NULL) { Type* dtype = Type::lookup_float_type("float64"); arg = Expression::make_cast(dtype, arg, location); - code = Runtime::PRINT_DOUBLE; + code = Runtime::PRINTFLOAT; } else if (type->complex_type() != NULL) { Type* ctype = Type::lookup_complex_type("complex128"); arg = Expression::make_cast(ctype, arg, location); - code = Runtime::PRINT_COMPLEX; + code = Runtime::PRINTCOMPLEX; } else if (type->is_boolean_type()) - code = Runtime::PRINT_BOOL; + code = Runtime::PRINTBOOL; else if (type->points_to() != NULL || type->channel_type() != NULL || type->map_type() != NULL || type->function_type() != NULL) { arg = Expression::make_cast(type, arg, location); - code = Runtime::PRINT_POINTER; + code = Runtime::PRINTPOINTER; } else if (type->interface_type() != NULL) { if (type->interface_type()->is_empty()) - code = Runtime::PRINT_EMPTY_INTERFACE; + code = Runtime::PRINTEFACE; else - code = Runtime::PRINT_INTERFACE; + code = Runtime::PRINTIFACE; } else if (type->is_slice_type()) - code = Runtime::PRINT_SLICE; + code = Runtime::PRINTSLICE; else { go_assert(saw_errors()); @@ -8412,30 +8433,22 @@ Builtin_call_expression::do_get_backend(Translate_context* context) } Expression* call = Runtime::make_call(code, location, 1, arg); - if (print_stmts == NULL) - print_stmts = call; - else - print_stmts = Expression::make_compound(print_stmts, call, - location); + print_stmts = Expression::make_compound(print_stmts, call, + location); } } if (is_ln) { Expression* print_nl = - Runtime::make_call(Runtime::PRINT_NL, location, 0); - if (print_stmts == NULL) - print_stmts = print_nl; - else - print_stmts = Expression::make_compound(print_stmts, print_nl, - location); + Runtime::make_call(Runtime::PRINTNL, location, 0); + print_stmts = Expression::make_compound(print_stmts, print_nl, + location); } - // There aren't any arguments to the print builtin. The compiler - // issues a warning for this so we should avoid getting the backend - // representation for this call. Instead, perform a no-op. - if (print_stmts == NULL) - return context->backend()->boolean_constant_expression(false); + Expression* unlock = Runtime::make_call(Runtime::PRINTUNLOCK, + location, 0); + print_stmts = Expression::make_compound(print_stmts, unlock, location); return print_stmts->get_backend(context); } diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 168f473..e7edfa6 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -299,42 +299,47 @@ DEF_GO_RUNTIME(INTERFACE_EMPTY_COMPARE, "__go_interface_empty_compare", P2(IFACE, EFACE), R1(INT)) +// Lock the printer (for print/println). +DEF_GO_RUNTIME(PRINTLOCK, "runtime.printlock", P0(), R0()) + +// Unlock the printer (for print/println). +DEF_GO_RUNTIME(PRINTUNLOCK, "runtime.printunlock", P0(), R0()) + // Print a string (for print/println). -DEF_GO_RUNTIME(PRINT_STRING, "__go_print_string", P1(STRING), R0()) +DEF_GO_RUNTIME(PRINTSTRING, "runtime.printstring", P1(STRING), R0()) // Print a uint64 (for print/println). -DEF_GO_RUNTIME(PRINT_UINT64, "__go_print_uint64", P1(UINT64), R0()) +DEF_GO_RUNTIME(PRINTUINT, "runtime.printuint", P1(UINT64), R0()) // Print a int64 (for print/println). -DEF_GO_RUNTIME(PRINT_INT64, "__go_print_int64", P1(INT64), R0()) +DEF_GO_RUNTIME(PRINTINT, "runtime.printint", P1(INT64), R0()) // Print a float64 (for print/println). -DEF_GO_RUNTIME(PRINT_DOUBLE, "__go_print_double", P1(FLOAT64), R0()) +DEF_GO_RUNTIME(PRINTFLOAT, "runtime.printfloat", P1(FLOAT64), R0()) // Print a complex128 (for print/println). -DEF_GO_RUNTIME(PRINT_COMPLEX, "__go_print_complex", P1(COMPLEX128), R0()) +DEF_GO_RUNTIME(PRINTCOMPLEX, "runtime.printcomplex", P1(COMPLEX128), R0()) // Print a bool (for print/println). -DEF_GO_RUNTIME(PRINT_BOOL, "__go_print_bool", P1(BOOL), R0()) +DEF_GO_RUNTIME(PRINTBOOL, "runtime.printbool", P1(BOOL), R0()) // Print a pointer/map/channel/function (for print/println). -DEF_GO_RUNTIME(PRINT_POINTER, "__go_print_pointer", P1(POINTER), R0()) +DEF_GO_RUNTIME(PRINTPOINTER, "runtime.printpointer", P1(POINTER), R0()) // Print an empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_EMPTY_INTERFACE, "__go_print_empty_interface", - P1(EFACE), R0()) +DEF_GO_RUNTIME(PRINTEFACE, "runtime.printeface", P1(EFACE), R0()) // Print a non-empty interface (for print/println). -DEF_GO_RUNTIME(PRINT_INTERFACE, "__go_print_interface", P1(IFACE), R0()) +DEF_GO_RUNTIME(PRINTIFACE, "runtime.printiface", P1(IFACE), R0()) // Print a slice (for print/println). -DEF_GO_RUNTIME(PRINT_SLICE, "__go_print_slice", P1(SLICE), R0()) +DEF_GO_RUNTIME(PRINTSLICE, "runtime.printslice", P1(SLICE), R0()) // Print a space (for println). -DEF_GO_RUNTIME(PRINT_SPACE, "__go_print_space", P0(), R0()) +DEF_GO_RUNTIME(PRINTSP, "runtime.printsp", P0(), R0()) // Print a newline (for println). -DEF_GO_RUNTIME(PRINT_NL, "__go_print_nl", P0(), R0()) +DEF_GO_RUNTIME(PRINTNL, "runtime.printnl", P0(), R0()) // Used for field tracking for data analysis. |