summaryrefslogtreecommitdiffstats
path: root/gcc/go/gofrontend/statements.cc
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-18 23:49:49 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-18 23:49:49 +0000
commit8381eda7ff1e5a2874d708573654e64a4efcfb4f (patch)
tree1a7d38cd8be5484451189338ed6f4b76d8521f31 /gcc/go/gofrontend/statements.cc
parent2851d736ebf1e8cceebb9106cab69d2c3fdc7624 (diff)
downloadppe42-gcc-8381eda7ff1e5a2874d708573654e64a4efcfb4f.tar.gz
ppe42-gcc-8381eda7ff1e5a2874d708573654e64a4efcfb4f.zip
compiler, runtime: Use function descriptors.
This changes the representation of a Go value of function type from being a pointer to function code (like a C function pointer) to being a pointer to a struct. The first field of the struct points to the function code. The remaining fields, if any, are the addresses of variables referenced in enclosing functions. For each call to a function, the address of the function descriptor is passed as the last argument. This lets us avoid generating trampolines, and removes the use of writable/executable sections of the heap. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200181 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/go/gofrontend/statements.cc')
-rw-r--r--gcc/go/gofrontend/statements.cc15
1 files changed, 12 insertions, 3 deletions
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index c9c62cedaaf..7e4c56181f1 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -1959,10 +1959,15 @@ Thunk_statement::is_simple(Function_type* fntype) const
&& results->begin()->type()->points_to() == NULL)))
return false;
- // If this calls something which is not a simple function, then we
+ // If this calls something that is not a simple function, then we
// need a thunk.
Expression* fn = this->call_->call_expression()->fn();
- if (fn->interface_field_reference_expression() != NULL)
+ if (fn->func_expression() == NULL)
+ return false;
+
+ // If the function uses a closure, then we need a thunk. FIXME: We
+ // could accept a zero argument function with a closure.
+ if (fn->func_expression()->closure() != NULL)
return false;
return true;
@@ -2502,7 +2507,11 @@ Thunk_statement::get_fn_and_arg(Expression** pfn, Expression** parg)
Call_expression* ce = this->call_->call_expression();
- *pfn = ce->fn();
+ Expression* fn = ce->fn();
+ Func_expression* fe = fn->func_expression();
+ go_assert(fe != NULL);
+ *pfn = Expression::make_func_code_reference(fe->named_object(),
+ fe->location());
const Expression_list* args = ce->args();
if (args == NULL || args->empty())
OpenPOWER on IntegriCloud