diff options
author | Ayke van Laethem <[email protected]> | 2018-12-01 17:31:36 +0100 |
---|---|---|
committer | Ayke van Laethem <[email protected]> | 2018-12-01 17:41:20 +0100 |
commit | e54a1c4dc048ffbee5ed6bb5ad65c9460b7dc9d9 (patch) | |
tree | 8c13dba828cc9afe2840887a0a035f8cb873119f | |
parent | da0a02d128f70f8fa811ff496f0aa02fe4241200 (diff) | |
download | tinygo-e54a1c4dc048ffbee5ed6bb5ad65c9460b7dc9d9.tar.gz tinygo-e54a1c4dc048ffbee5ed6bb5ad65c9460b7dc9d9.zip |
compiler: disallow exporting functions that have their address taken
This simplifies the ABI a lot and makes future changes easier.
In the future, determining which functions need a context parameter
should be moved from IR generation into an optimization pass, avoiding
the need for recursively scanning the Go SSA.
-rw-r--r-- | compiler/compiler.go | 3 | ||||
-rw-r--r-- | docs/internals.rst | 17 |
2 files changed, 3 insertions, 17 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go index e2e6f3b14..6d357fd7a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -2280,6 +2280,9 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { return c.builder.CreateGEP(val, indices, ""), nil case *ssa.Function: fn := c.ir.GetFunction(expr) + if fn.IsExported() { + return llvm.Value{}, c.makeError(expr.Pos(), "cannot use an exported function as value") + } ptr := fn.LLVMFn if c.ir.FunctionNeedsContext(fn) { // Create closure for function pointer. diff --git a/docs/internals.rst b/docs/internals.rst index 4e3879ad2..a1b3016c2 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -155,23 +155,6 @@ somewhat compatible with the C calling convention but with a few quirks: This is the calling convention as implemented by LLVM, with the extension that ``i64`` return values are returned in the same way as aggregate types. - * Some functions have an extra context parameter appended at the end of the - argument list. This only happens when both of these conditions hold: - - * The address of the function is taken, for example when passing the - function as function pointer to another function or storing it in a - global variable. - - * This function or another function somewhere in the compiled code has the - exact same signature and is used in a closure or bound method. Signature - matching is very strict: it is based on Go types including named types - and return types, although parameter names or the function name itself - are not included in the match. - - Whether a function needs this is determined by `FunctionNeedsContext - <https://godoc.org/github.com/aykevl/tinygo/ir#Program.FunctionNeedsContext>`_, - which bases itself on analysis done by AnalyseFunctionPointers. - * Blocking functions have a coroutine pointer prepended to the argument list, see `src/runtime/scheduler.go <https://github.com/aykevl/tinygo/blob/master/src/runtime/scheduler.go>`_ |