aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.h
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2013-06-18 23:49:49 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-06-18 23:49:49 +0000
commitfdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2 (patch)
tree1a7d38cd8be5484451189338ed6f4b76d8521f31 /gcc/go/gofrontend/expressions.h
parent25e00ab67444a01dce446e95308521d1a73f8232 (diff)
downloadgcc-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.h39
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_;
};