diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-13 21:00:59 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-13 21:00:59 +0000 |
commit | 9581e91dbb7fa66fee457ad404e908d3d4130ad6 (patch) | |
tree | 32a57ad9ca89c95394a45e92649f097c96b50924 /gcc/go/gofrontend/statements.cc | |
parent | 4c35e34cb7b64a3351bdf41eb63cffb51307fb18 (diff) | |
download | gcc-9581e91dbb7fa66fee457ad404e908d3d4130ad6.tar.gz |
Unify handling of runtime support functions.
This introduces the new approach, and rewrites the lowering
code which uses runtime functions. The code which calls
runtime functions at GENERIC conversion time is not yet
rewritten.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172396 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend/statements.cc')
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 523 |
1 files changed, 89 insertions, 434 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index f84b2d4ae92..0b22e307306 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -29,6 +29,7 @@ extern "C" #include "types.h" #include "expressions.h" #include "gogo.h" +#include "runtime.h" #include "backend.h" #include "statements.h" @@ -958,33 +959,13 @@ Tuple_map_assignment_statement::do_lower(Gogo*, Named_object*, Statement::make_temporary(Type::lookup_bool_type(), NULL, loc); b->add_statement(present_temp); - // func mapaccess2(hmap map[k]v, key *k, val *v) bool - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("hmap", map_type, bloc)); - Type* pkey_type = Type::make_pointer_type(map_type->key_type()); - param_types->push_back(Typed_identifier("key", pkey_type, bloc)); - Type* pval_type = Type::make_pointer_type(map_type->val_type()); - param_types->push_back(Typed_identifier("val", pval_type, bloc)); - - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc)); - - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); - Named_object* mapaccess2 = - Named_object::make_function_declaration("mapaccess2", NULL, fntype, bloc); - mapaccess2->func_declaration_value()->set_asm_name("runtime.mapaccess2"); - // present_temp = mapaccess2(MAP, &key_temp, &val_temp) - Expression* func = Expression::make_func_reference(mapaccess2, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(map_index->map()); Expression* ref = Expression::make_temporary_reference(key_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); + Expression* a1 = Expression::make_unary(OPERATOR_AND, ref, loc); ref = Expression::make_temporary_reference(val_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* a2 = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* call = Runtime::make_call(Runtime::MAPACCESS2, loc, 3, + map_index->map(), a1, a2); ref = Expression::make_temporary_reference(present_temp, loc); Statement* s = Statement::make_assignment(ref, call, loc); @@ -1097,31 +1078,21 @@ Map_assignment_statement::do_lower(Gogo*, Named_object*, Block* enclosing) Statement::make_temporary(map_type->val_type(), this->val_, loc); b->add_statement(val_temp); - // func mapassign2(hmap map[k]v, key *k, val *v, p) - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("hmap", map_type, bloc)); - Type* pkey_type = Type::make_pointer_type(map_type->key_type()); - param_types->push_back(Typed_identifier("key", pkey_type, bloc)); - Type* pval_type = Type::make_pointer_type(map_type->val_type()); - param_types->push_back(Typed_identifier("val", pval_type, bloc)); - param_types->push_back(Typed_identifier("p", Type::lookup_bool_type(), bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, - NULL, bloc); - Named_object* mapassign2 = - Named_object::make_function_declaration("mapassign2", NULL, fntype, bloc); - mapassign2->func_declaration_value()->set_asm_name("runtime.mapassign2"); + // var insert_temp bool = p + Temporary_statement* insert_temp = + Statement::make_temporary(Type::lookup_bool_type(), this->should_set_, + loc); + b->add_statement(insert_temp); // mapassign2(map_temp, &key_temp, &val_temp, p) - Expression* func = Expression::make_func_reference(mapassign2, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(Expression::make_temporary_reference(map_temp, loc)); + Expression* p1 = Expression::make_temporary_reference(map_temp, loc); Expression* ref = Expression::make_temporary_reference(key_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); + Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc); ref = Expression::make_temporary_reference(val_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - params->push_back(this->should_set_); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* p4 = Expression::make_temporary_reference(insert_temp, loc); + Expression* call = Runtime::make_call(Runtime::MAPASSIGN2, loc, 4, + p1, p2, p3, p4); Statement* s = Statement::make_statement(call); b->add_statement(s); @@ -1225,40 +1196,13 @@ Tuple_receive_assignment_statement::do_lower(Gogo*, Named_object*, Statement::make_temporary(Type::lookup_bool_type(), NULL, loc); b->add_statement(closed_temp); - // func chanrecv2(c chan T, val *T) bool - // func chanrecv3(c chan T, val *T) bool (if for_select) - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("c", channel_type, bloc)); - Type* pelement_type = Type::make_pointer_type(channel_type->element_type()); - param_types->push_back(Typed_identifier("val", pelement_type, bloc)); - - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc)); - - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); - Named_object* chanrecv; - if (!this->for_select_) - { - chanrecv = Named_object::make_function_declaration("chanrecv2", NULL, - fntype, bloc); - chanrecv->func_declaration_value()->set_asm_name("runtime.chanrecv2"); - } - else - { - chanrecv = Named_object::make_function_declaration("chanrecv3", NULL, - fntype, bloc); - chanrecv->func_declaration_value()->set_asm_name("runtime.chanrecv3"); - } - // closed_temp = chanrecv[23](channel, &val_temp) - Expression* func = Expression::make_func_reference(chanrecv, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(this->channel_); Expression* ref = Expression::make_temporary_reference(val_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* call = Runtime::make_call((this->for_select_ + ? Runtime::CHANRECV3 + : Runtime::CHANRECV2), + loc, 2, this->channel_, p2); ref = Expression::make_temporary_reference(closed_temp, loc); Statement* s = Statement::make_assignment(ref, call, loc); b->add_statement(s); @@ -1318,13 +1262,10 @@ class Tuple_type_guard_assignment_statement : public Statement private: Call_expression* - lower_to_empty_interface(const char*); - - Call_expression* - lower_to_type(const char*); + lower_to_type(Runtime::Function); void - lower_to_object_type(Block*, const char*); + lower_to_object_type(Block*, Runtime::Function); // The variable which recieves the converted value. Expression* val_; @@ -1377,23 +1318,32 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*, if (this->type_->interface_type() != NULL) { if (this->type_->interface_type()->is_empty()) - call = this->lower_to_empty_interface(expr_is_empty - ? "ifaceE2E2" - : "ifaceI2E2"); + call = Runtime::make_call((expr_is_empty + ? Runtime::IFACEE2E2 + : Runtime::IFACEI2E2), + loc, 1, this->expr_); else - call = this->lower_to_type(expr_is_empty ? "ifaceE2I2" : "ifaceI2I2"); + call = this->lower_to_type(expr_is_empty + ? Runtime::IFACEE2I2 + : Runtime::IFACEI2I2); } else if (this->type_->points_to() != NULL) - call = this->lower_to_type(expr_is_empty ? "ifaceE2T2P" : "ifaceI2T2P"); + call = this->lower_to_type(expr_is_empty + ? Runtime::IFACEE2T2P + : Runtime::IFACEI2T2P); else { - this->lower_to_object_type(b, expr_is_empty ? "ifaceE2T2" : "ifaceI2T2"); + this->lower_to_object_type(b, + (expr_is_empty + ? Runtime::IFACEE2T2 + : Runtime::IFACEI2T2)); call = NULL; } if (call != NULL) { Expression* res = Expression::make_call_result(call, 0); + res = Expression::make_unsafe_cast(this->type_, res, loc); Statement* s = Statement::make_assignment(this->val_, res, loc); b->add_statement(s); @@ -1405,74 +1355,23 @@ Tuple_type_guard_assignment_statement::do_lower(Gogo*, Named_object*, return Statement::make_block_statement(b, loc); } -// Lower a conversion to an empty interface type. - -Call_expression* -Tuple_type_guard_assignment_statement::lower_to_empty_interface( - const char *fnname) -{ - source_location loc = this->location(); - - // func FNNAME(interface) (empty, bool) - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("i", this->expr_->type(), bloc)); - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("ret", this->type_, bloc)); - ret_types->push_back(Typed_identifier("ok", Type::lookup_bool_type(), bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); - Named_object* fn = - Named_object::make_function_declaration(fnname, NULL, fntype, bloc); - std::string asm_name = "runtime."; - asm_name += fnname; - fn->func_declaration_value()->set_asm_name(asm_name); - - // val, ok = FNNAME(expr) - Expression* func = Expression::make_func_reference(fn, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(this->expr_); - return Expression::make_call(func, params, false, loc); -} - // Lower a conversion to a non-empty interface type or a pointer type. Call_expression* -Tuple_type_guard_assignment_statement::lower_to_type(const char* fnname) +Tuple_type_guard_assignment_statement::lower_to_type(Runtime::Function code) { source_location loc = this->location(); - - // func FNNAME(*descriptor, interface) (interface, bool) - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("inter", - Type::make_type_descriptor_ptr_type(), - bloc)); - param_types->push_back(Typed_identifier("i", this->expr_->type(), bloc)); - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("ret", this->type_, bloc)); - ret_types->push_back(Typed_identifier("ok", Type::lookup_bool_type(), bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); - Named_object* fn = - Named_object::make_function_declaration(fnname, NULL, fntype, bloc); - std::string asm_name = "runtime."; - asm_name += fnname; - fn->func_declaration_value()->set_asm_name(asm_name); - - // val, ok = FNNAME(type_descriptor, expr) - Expression* func = Expression::make_func_reference(fn, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(Expression::make_type_descriptor(this->type_, loc)); - params->push_back(this->expr_); - return Expression::make_call(func, params, false, loc); + return Runtime::make_call(code, loc, 2, + Expression::make_type_descriptor(this->type_, loc), + this->expr_); } // Lower a conversion to a non-interface non-pointer type. void -Tuple_type_guard_assignment_statement::lower_to_object_type(Block* b, - const char *fnname) +Tuple_type_guard_assignment_statement::lower_to_object_type( + Block* b, + Runtime::Function code) { source_location loc = this->location(); @@ -1481,33 +1380,11 @@ Tuple_type_guard_assignment_statement::lower_to_object_type(Block* b, NULL, loc); b->add_statement(val_temp); - // func FNNAME(*descriptor, interface, *T) bool - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("inter", - Type::make_type_descriptor_ptr_type(), - bloc)); - param_types->push_back(Typed_identifier("i", this->expr_->type(), bloc)); - Type* ptype = Type::make_pointer_type(this->type_); - param_types->push_back(Typed_identifier("v", ptype, bloc)); - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("ok", Type::lookup_bool_type(), bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); - Named_object* fn = - Named_object::make_function_declaration(fnname, NULL, fntype, bloc); - std::string asm_name = "runtime."; - asm_name += fnname; - fn->func_declaration_value()->set_asm_name(asm_name); - - // ok = FNNAME(type_descriptor, expr, &val_temp) - Expression* func = Expression::make_func_reference(fn, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(Expression::make_type_descriptor(this->type_, loc)); - params->push_back(this->expr_); + // ok = CODE(type_descriptor, expr, &val_temp) + Expression* p1 = Expression::make_type_descriptor(this->type_, loc); Expression* ref = Expression::make_temporary_reference(val_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* call = Runtime::make_call(code, loc, 3, p1, this->expr_, p3); Statement* s = Statement::make_assignment(this->ok_, call, loc); b->add_statement(s); @@ -2146,34 +2023,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name, { retaddr_label = gogo->add_label_reference("retaddr"); Expression* arg = Expression::make_label_addr(retaddr_label, location); - Expression_list* args = new Expression_list(); - args->push_back(arg); - - static Named_object* set_defer_retaddr; - if (set_defer_retaddr == NULL) - { - const source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - Type *voidptr_type = Type::make_pointer_type(Type::make_void_type()); - param_types->push_back(Typed_identifier("r", voidptr_type, bloc)); - - Typed_identifier_list* result_types = new Typed_identifier_list(); - result_types->push_back(Typed_identifier("", - Type::lookup_bool_type(), - bloc)); - - Function_type* t = Type::make_function_type(NULL, param_types, - result_types, bloc); - set_defer_retaddr = - Named_object::make_function_declaration("__go_set_defer_retaddr", - NULL, t, bloc); - const char* n = "__go_set_defer_retaddr"; - set_defer_retaddr->func_declaration_value()->set_asm_name(n); - } - - Expression* fn = Expression::make_func_reference(set_defer_retaddr, - NULL, location); - Expression* call = Expression::make_call(fn, args, false, location); + Expression* call = Runtime::make_call(Runtime::SET_DEFER_RETADDR, + location, 1, arg); // This is a hack to prevent the middle-end from deleting the // label. @@ -3610,92 +3461,24 @@ Type_case_clauses::Type_case_clause::lower(Block* b, { Type* type = this->type_; + Expression* ref = Expression::make_temporary_reference(descriptor_temp, + loc); + Expression* cond; // The language permits case nil, which is of course a constant // rather than a type. It will appear here as an invalid // forwarding type. if (type->is_nil_constant_as_type()) - { - Expression* ref = - Expression::make_temporary_reference(descriptor_temp, loc); - cond = Expression::make_binary(OPERATOR_EQEQ, ref, - Expression::make_nil(loc), - loc); - } + cond = Expression::make_binary(OPERATOR_EQEQ, ref, + Expression::make_nil(loc), + loc); else - { - Expression* func; - if (type->interface_type() == NULL) - { - // func ifacetypeeq(*descriptor, *descriptor) bool - static Named_object* ifacetypeeq; - if (ifacetypeeq == NULL) - { - const source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = - new Typed_identifier_list(); - Type* descriptor_type = Type::make_type_descriptor_ptr_type(); - param_types->push_back(Typed_identifier("a", descriptor_type, - bloc)); - param_types->push_back(Typed_identifier("b", descriptor_type, - bloc)); - Typed_identifier_list* ret_types = - new Typed_identifier_list(); - Type* bool_type = Type::lookup_bool_type(); - ret_types->push_back(Typed_identifier("", bool_type, bloc)); - Function_type* fntype = Type::make_function_type(NULL, - param_types, - ret_types, - bloc); - ifacetypeeq = - Named_object::make_function_declaration("ifacetypeeq", NULL, - fntype, bloc); - const char* n = "runtime.ifacetypeeq"; - ifacetypeeq->func_declaration_value()->set_asm_name(n); - } - - // ifacetypeeq(descriptor_temp, DESCRIPTOR) - func = Expression::make_func_reference(ifacetypeeq, NULL, loc); - } - else - { - // func ifaceI2Tp(*descriptor, *descriptor) bool - static Named_object* ifaceI2Tp; - if (ifaceI2Tp == NULL) - { - const source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = - new Typed_identifier_list(); - Type* descriptor_type = Type::make_type_descriptor_ptr_type(); - param_types->push_back(Typed_identifier("a", descriptor_type, - bloc)); - param_types->push_back(Typed_identifier("b", descriptor_type, - bloc)); - Typed_identifier_list* ret_types = - new Typed_identifier_list(); - Type* bool_type = Type::lookup_bool_type(); - ret_types->push_back(Typed_identifier("", bool_type, bloc)); - Function_type* fntype = Type::make_function_type(NULL, - param_types, - ret_types, - bloc); - ifaceI2Tp = - Named_object::make_function_declaration("ifaceI2Tp", NULL, - fntype, bloc); - const char* n = "runtime.ifaceI2Tp"; - ifaceI2Tp->func_declaration_value()->set_asm_name(n); - } - - // ifaceI2Tp(descriptor_temp, DESCRIPTOR) - func = Expression::make_func_reference(ifaceI2Tp, NULL, loc); - } - Expression_list* params = new Expression_list(); - params->push_back(Expression::make_type_descriptor(type, loc)); - Expression* ref = - Expression::make_temporary_reference(descriptor_temp, loc); - params->push_back(ref); - cond = Expression::make_call(func, params, false, loc); - } + cond = Runtime::make_call((type->interface_type() == NULL + ? Runtime::IFACETYPEEQ + : Runtime::IFACEI2TP), + loc, 2, + Expression::make_type_descriptor(type, loc), + ref); Unnamed_label* dest; if (!this->is_fallthrough_) @@ -3891,35 +3674,18 @@ Type_switch_statement::do_lower(Gogo*, Named_object*, Block* enclosing) } else { - const source_location bloc = BUILTINS_LOCATION; - - // func {efacetype,ifacetype}(*interface) *descriptor + // descriptor_temp = ifacetype(val_temp) // FIXME: This should be inlined. - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("i", val_type, bloc)); - Typed_identifier_list* ret_types = new Typed_identifier_list(); - ret_types->push_back(Typed_identifier("", descriptor_type, bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, - ret_types, bloc); bool is_empty = val_type->interface_type()->is_empty(); - const char* fnname = is_empty ? "efacetype" : "ifacetype"; - Named_object* fn = - Named_object::make_function_declaration(fnname, NULL, fntype, bloc); - const char* asm_name = (is_empty - ? "runtime.efacetype" - : "runtime.ifacetype"); - fn->func_declaration_value()->set_asm_name(asm_name); - - // descriptor_temp = ifacetype(val_temp) - Expression* func = Expression::make_func_reference(fn, NULL, loc); - Expression_list* params = new Expression_list(); Expression* ref; if (this->var_ == NULL) ref = this->expr_; else ref = Expression::make_var_reference(this->var_, loc); - params->push_back(ref); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* call = Runtime::make_call((is_empty + ? Runtime::EFACETYPE + : Runtime::IFACETYPE), + loc, 1, ref); Expression* lhs = Expression::make_temporary_reference(descriptor_temp, loc); Statement* s = Statement::make_assignment(lhs, call, loc); @@ -4935,7 +4701,7 @@ For_range_statement::lower_range_array(Gogo* gogo, // Lower a for range over a string. void -For_range_statement::lower_range_string(Gogo* gogo, +For_range_statement::lower_range_string(Gogo*, Block* enclosing, Block* body_block, Named_object* range_object, @@ -4996,66 +4762,12 @@ For_range_statement::lower_range_string(Gogo* gogo, Block* iter_init = new Block(body_block, loc); - Named_object* no; - if (value_temp == NULL) - { - static Named_object* stringiter; - if (stringiter == NULL) - { - source_location bloc = BUILTINS_LOCATION; - Type* int_type = gogo->lookup_global("int")->type_value(); - - Typed_identifier_list* params = new Typed_identifier_list(); - params->push_back(Typed_identifier("s", Type::make_string_type(), - bloc)); - params->push_back(Typed_identifier("k", int_type, bloc)); - - Typed_identifier_list* results = new Typed_identifier_list(); - results->push_back(Typed_identifier("", int_type, bloc)); - - Function_type* fntype = Type::make_function_type(NULL, params, - results, bloc); - stringiter = Named_object::make_function_declaration("stringiter", - NULL, fntype, - bloc); - const char* n = "runtime.stringiter"; - stringiter->func_declaration_value()->set_asm_name(n); - } - no = stringiter; - } - else - { - static Named_object* stringiter2; - if (stringiter2 == NULL) - { - source_location bloc = BUILTINS_LOCATION; - Type* int_type = gogo->lookup_global("int")->type_value(); - - Typed_identifier_list* params = new Typed_identifier_list(); - params->push_back(Typed_identifier("s", Type::make_string_type(), - bloc)); - params->push_back(Typed_identifier("k", int_type, bloc)); - - Typed_identifier_list* results = new Typed_identifier_list(); - results->push_back(Typed_identifier("", int_type, bloc)); - results->push_back(Typed_identifier("", int_type, bloc)); - - Function_type* fntype = Type::make_function_type(NULL, params, - results, bloc); - stringiter2 = Named_object::make_function_declaration("stringiter", - NULL, fntype, - bloc); - const char* n = "runtime.stringiter2"; - stringiter2->func_declaration_value()->set_asm_name(n); - } - no = stringiter2; - } - - Expression* func = Expression::make_func_reference(no, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(this->make_range_ref(range_object, range_temp, loc)); - params->push_back(Expression::make_temporary_reference(index_temp, loc)); - Call_expression* call = Expression::make_call(func, params, false, loc); + Expression* p1 = this->make_range_ref(range_object, range_temp, loc); + Expression* p2 = Expression::make_temporary_reference(index_temp, loc); + Call_expression* call = Runtime::make_call((value_temp == NULL + ? Runtime::STRINGITER + : Runtime::STRINGITER2), + loc, 2, p1, p2); if (value_temp == NULL) { @@ -5107,7 +4819,7 @@ For_range_statement::lower_range_string(Gogo* gogo, // Lower a for range over a map. void -For_range_statement::lower_range_map(Gogo* gogo, +For_range_statement::lower_range_map(Gogo*, Block* enclosing, Block* body_block, Named_object* range_object, @@ -5140,41 +4852,15 @@ For_range_statement::lower_range_map(Gogo* gogo, Block* init = new Block(enclosing, loc); - const unsigned long map_iteration_size = 4; - - mpz_t ival; - mpz_init_set_ui(ival, map_iteration_size); - Expression* iexpr = Expression::make_integer(&ival, NULL, loc); - mpz_clear(ival); - - Type* byte_type = gogo->lookup_global("byte")->type_value(); - Type* ptr_type = Type::make_pointer_type(byte_type); - - Type* map_iteration_type = Type::make_array_type(ptr_type, iexpr); - Type* map_iteration_ptr = Type::make_pointer_type(map_iteration_type); - + Type* map_iteration_type = Runtime::map_iteration_type(); Temporary_statement* hiter = Statement::make_temporary(map_iteration_type, NULL, loc); init->add_statement(hiter); - source_location bloc = BUILTINS_LOCATION; - Typed_identifier_list* param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("map", this->range_->type(), bloc)); - param_types->push_back(Typed_identifier("it", map_iteration_ptr, bloc)); - Function_type* fntype = Type::make_function_type(NULL, param_types, NULL, - bloc); - - Named_object* mapiterinit = - Named_object::make_function_declaration("mapiterinit", NULL, fntype, bloc); - const char* n = "runtime.mapiterinit"; - mapiterinit->func_declaration_value()->set_asm_name(n); - - Expression* func = Expression::make_func_reference(mapiterinit, NULL, loc); - Expression_list* params = new Expression_list(); - params->push_back(this->make_range_ref(range_object, range_temp, loc)); + Expression* p1 = this->make_range_ref(range_object, range_temp, loc); Expression* ref = Expression::make_temporary_reference(hiter, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - Expression* call = Expression::make_call(func, params, false, loc); + Expression* p2 = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* call = Runtime::make_call(Runtime::MAPITERINIT, loc, 2, p1, p2); init->add_statement(Statement::make_statement(call)); *pinit = init; @@ -5204,34 +4890,18 @@ For_range_statement::lower_range_map(Gogo* gogo, Block* iter_init = new Block(body_block, loc); - param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("hiter", map_iteration_ptr, bloc)); - Type* pkey_type = Type::make_pointer_type(index_temp->type()); - param_types->push_back(Typed_identifier("key", pkey_type, bloc)); - if (value_temp != NULL) - { - Type* pval_type = Type::make_pointer_type(value_temp->type()); - param_types->push_back(Typed_identifier("val", pval_type, bloc)); - } - fntype = Type::make_function_type(NULL, param_types, NULL, bloc); - n = value_temp == NULL ? "mapiter1" : "mapiter2"; - Named_object* mapiter = Named_object::make_function_declaration(n, NULL, - fntype, bloc); - n = value_temp == NULL ? "runtime.mapiter1" : "runtime.mapiter2"; - mapiter->func_declaration_value()->set_asm_name(n); - - func = Expression::make_func_reference(mapiter, NULL, loc); - params = new Expression_list(); ref = Expression::make_temporary_reference(hiter, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); + p1 = Expression::make_unary(OPERATOR_AND, ref, loc); ref = Expression::make_temporary_reference(index_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - if (value_temp != NULL) + p2 = Expression::make_unary(OPERATOR_AND, ref, loc); + if (value_temp == NULL) + call = Runtime::make_call(Runtime::MAPITER1, loc, 2, p1, p2); + else { ref = Expression::make_temporary_reference(value_temp, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); + Expression* p3 = Expression::make_unary(OPERATOR_AND, ref, loc); + call = Runtime::make_call(Runtime::MAPITER2, loc, 3, p1, p2, p3); } - call = Expression::make_call(func, params, false, loc); iter_init->add_statement(Statement::make_statement(call)); *piter_init = iter_init; @@ -5241,24 +4911,9 @@ For_range_statement::lower_range_map(Gogo* gogo, Block* post = new Block(enclosing, loc); - static Named_object* mapiternext; - if (mapiternext == NULL) - { - param_types = new Typed_identifier_list(); - param_types->push_back(Typed_identifier("it", map_iteration_ptr, bloc)); - fntype = Type::make_function_type(NULL, param_types, NULL, bloc); - mapiternext = Named_object::make_function_declaration("mapiternext", - NULL, fntype, - bloc); - const char* n = "runtime.mapiternext"; - mapiternext->func_declaration_value()->set_asm_name(n); - } - - func = Expression::make_func_reference(mapiternext, NULL, loc); - params = new Expression_list(); ref = Expression::make_temporary_reference(hiter, loc); - params->push_back(Expression::make_unary(OPERATOR_AND, ref, loc)); - call = Expression::make_call(func, params, false, loc); + p1 = Expression::make_unary(OPERATOR_AND, ref, loc); + call = Runtime::make_call(Runtime::MAPITERNEXT, loc, 1, p1); post->add_statement(Statement::make_statement(call)); *ppost = post; |