-11d96c36198b75b0485d16524d521e558cf03312
+764fe6702f2bb8650622d4102de31058e484ecb5
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
&edecl);
Bexpression* btempref = gogo->backend()->var_expression(btemp,
loc);
- Bexpression* addr = gogo->backend()->address_expression(btempref, loc);
-
- Expression* td = Expression::make_type_descriptor(etype, loc);
- Type* etype_ptr = Type::make_pointer_type(etype);
space = gogo->backend()->var_expression(space_temp, loc);
+ Type* etype_ptr = Type::make_pointer_type(etype);
Expression* elhs = Expression::make_backend(space, etype_ptr, loc);
- Expression* erhs = Expression::make_backend(addr, etype_ptr, loc);
- Expression* call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
- td, elhs, erhs);
- Bexpression* bcall = call->get_backend(context);
- Bstatement* s = gogo->backend()->expression_statement(fndecl, bcall);
+ Expression* erhs;
+ Expression* call;
+ if (etype->is_direct_iface_type())
+ {
+ // Single pointer.
+ Type* uintptr_type = Type::lookup_integer_type("uintptr");
+ erhs = Expression::make_backend(btempref, etype, loc);
+ erhs = Expression::unpack_direct_iface(erhs, loc);
+ erhs = Expression::make_unsafe_cast(uintptr_type, erhs, loc);
+ call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2,
+ elhs, erhs);
+ }
+ else
+ {
+ Expression* td = Expression::make_type_descriptor(etype, loc);
+ Bexpression* addr =
+ gogo->backend()->address_expression(btempref, loc);
+ erhs = Expression::make_backend(addr, etype_ptr, loc);
+ call = Runtime::make_call(Runtime::TYPEDMEMMOVE, loc, 3,
+ td, elhs, erhs);
+ }
+ Statement* cs = Statement::make_statement(call, false);
+
+ space = gogo->backend()->var_expression(space_temp, loc);
+ Bexpression* ref =
+ gogo->backend()->indirect_expression(expr_btype, space, true, loc);
+ Expression* eref = Expression::make_backend(ref, etype, loc);
+ btempref = gogo->backend()->var_expression(btemp, loc);
+ erhs = Expression::make_backend(btempref, etype, loc);
+ Statement* as = Statement::make_assignment(eref, erhs, loc);
+
+ as = gogo->check_write_barrier(context->block(), as, cs);
+ Bstatement* s = as->get_backend(context);
+
assn = gogo->backend()->compound_statement(edecl, s);
}
decl = gogo->backend()->compound_statement(decl, assn);
// Variables that need to be declared for this function and their
// initial values.
std::vector<Bvariable*> vars;
- std::vector<Bexpression*> var_inits;
+ std::vector<Expression*> var_inits;
std::vector<Statement*> var_decls_stmts;
for (Bindings::const_definitions_iterator p =
this->block_->bindings()->begin_definitions();
loc);
if ((*p)->var_value()->is_in_heap())
parm_ref = Expression::make_heap_expression(parm_ref, loc);
- var_inits.push_back(parm_ref->get_backend(&context));
+ var_inits.push_back(parm_ref);
}
else if ((*p)->var_value()->is_in_heap())
{
Expression* var_ref =
Expression::make_var_reference(parm_no, loc);
var_ref = Expression::make_heap_expression(var_ref, loc);
- var_inits.push_back(var_ref->get_backend(&context));
+ var_inits.push_back(var_ref);
}
param_vars.push_back(parm_bvar);
}
Bvariable* bvar = (*p)->get_backend_variable(gogo, named_function);
Type* type = (*p)->result_var_value()->type();
- Bexpression* init;
+ Expression* init;
if (!(*p)->result_var_value()->is_in_heap())
{
Btype* btype = type->get_backend(gogo);
- init = gogo->backend()->zero_expression(btype);
+ Bexpression* binit = gogo->backend()->zero_expression(btype);
+ init = Expression::make_backend(binit, type, loc);
}
else
- init = Expression::make_allocation(type,
- loc)->get_backend(&context);
+ init = Expression::make_allocation(type, loc);
vars.push_back(bvar);
var_inits.push_back(init);
Bblock* code_block = this->block_->get_backend(&context);
// Initialize variables if necessary.
+ Translate_context icontext(gogo, named_function, this->block_,
+ var_decls);
std::vector<Bstatement*> init;
go_assert(vars.size() == var_inits.size());
for (size_t i = 0; i < vars.size(); ++i)
{
+ Bexpression* binit = var_inits[i]->get_backend(&icontext);
Bstatement* init_stmt =
gogo->backend()->init_statement(this->fndecl_, vars[i],
- var_inits[i]);
+ binit);
init.push_back(init_stmt);
}
Bstatement* var_init = gogo->backend()->statement_list(init);
assign_with_write_barrier(Function*, Block*, Statement_inserter*,
Expression* lhs, Expression* rhs, Location);
+ // Return a statement that tests whether write barriers are enabled
+ // and executes either the efficient code (WITHOUT) or the write
+ // barrier function call (WITH), depending.
+ Statement*
+ check_write_barrier(Block*, Statement* without, Statement* with);
+
// Flatten parse tree.
void
flatten();
Named_object*
write_barrier_variable();
- Statement*
- check_write_barrier(Block*, Statement*, Statement*);
-
// Type used to map import names to packages.
typedef std::map<std::string, Package*> Imports;