diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-18 23:49:49 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-18 23:49:49 +0000 |
commit | 8381eda7ff1e5a2874d708573654e64a4efcfb4f (patch) | |
tree | 1a7d38cd8be5484451189338ed6f4b76d8521f31 /gcc/go/gofrontend/statements.cc | |
parent | 2851d736ebf1e8cceebb9106cab69d2c3fdc7624 (diff) | |
download | ppe42-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.cc | 15 |
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()) |