diff options
author | Ian Lance Taylor <iant@google.com> | 2013-06-18 23:49:49 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2013-06-18 23:49:49 +0000 |
commit | fdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2 (patch) | |
tree | 1a7d38cd8be5484451189338ed6f4b76d8521f31 /gcc/go/gofrontend/expressions.h | |
parent | 25e00ab67444a01dce446e95308521d1a73f8232 (diff) | |
download | gcc-fdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2.zip gcc-fdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2.tar.gz gcc-fdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2.tar.bz2 |
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.
From-SVN: r200181
Diffstat (limited to 'gcc/go/gofrontend/expressions.h')
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 36f4c0d..ed3909c 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -67,6 +67,8 @@ class Expression EXPRESSION_SET_AND_USE_TEMPORARY, EXPRESSION_SINK, EXPRESSION_FUNC_REFERENCE, + EXPRESSION_FUNC_DESCRIPTOR, + EXPRESSION_FUNC_CODE_REFERENCE, EXPRESSION_UNKNOWN_REFERENCE, EXPRESSION_BOOLEAN, EXPRESSION_STRING, @@ -150,10 +152,25 @@ class Expression static Expression* make_sink(Location); - // Make a reference to a function in an expression. + // Make a reference to a function in an expression. This returns a + // pointer to the struct holding the address of the function + // followed by any closed-over variables. static Expression* make_func_reference(Named_object*, Expression* closure, Location); + // Make a function descriptor, an immutable struct with a single + // field that points to the function code. This may only be used + // with functions that do not have closures. FN is the function for + // which we are making the descriptor. DFN is the descriptor + // function wrapper. + static Expression* + make_func_descriptor(Named_object* fn, Named_object* dfn); + + // Make a reference to the code of a function. This is used to set + // descriptor and closure fields. + static Expression* + make_func_code_reference(Named_object*, Location); + // Make a reference to an unknown name. In a correct program this // will always be lowered to a real const/var/func reference. static Unknown_expression* @@ -523,6 +540,11 @@ class Expression bool is_local_variable() const; + // Make the builtin function descriptor type, so that it can be + // converted. + static void + make_func_descriptor_type(); + // Traverse an expression. static int traverse(Expression**, Traverse*); @@ -1484,7 +1506,7 @@ class Func_expression : public Expression { } // Return the object associated with the function. - const Named_object* + Named_object* named_object() const { return this->function_; } @@ -1494,14 +1516,17 @@ class Func_expression : public Expression closure() { return this->closure_; } - // Return a tree for this function without evaluating the closure. - tree - get_tree_without_closure(Gogo*); + // Return a tree for the code for a function. + static tree + get_code_pointer(Gogo*, Named_object* function, Location loc); protected: int do_traverse(Traverse*); + Expression* + do_lower(Gogo*, Named_object*, Statement_inserter*, int); + Type* do_type(); @@ -1532,8 +1557,8 @@ class Func_expression : public Expression // The function itself. Named_object* function_; // A closure. This is normally NULL. For a nested function, it may - // be a heap-allocated struct holding pointers to all the variables - // referenced by this function and defined in enclosing functions. + // be a struct holding pointers to all the variables referenced by + // this function and defined in enclosing functions. Expression* closure_; }; |