aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2018-12-01 17:31:36 +0100
committerAyke van Laethem <[email protected]>2018-12-01 17:41:20 +0100
commite54a1c4dc048ffbee5ed6bb5ad65c9460b7dc9d9 (patch)
tree8c13dba828cc9afe2840887a0a035f8cb873119f
parentda0a02d128f70f8fa811ff496f0aa02fe4241200 (diff)
downloadtinygo-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.go3
-rw-r--r--docs/internals.rst17
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>`_