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.
Этот коммит содержится в:
родитель
da0a02d128
коммит
e54a1c4dc0
2 изменённых файлов: 3 добавлений и 17 удалений
|
@ -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.
|
||||
|
|
|
@ -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>`_
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче