From fdbc38a6e8d7c920eea6c6231c7fe2c987fa8aa2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 18 Jun 2013 23:49:49 +0000 Subject: 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 --- gcc/go/gofrontend/expressions.h | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'gcc/go/gofrontend/expressions.h') 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_; }; -- cgit v1.1