diff options
author | Ayke van Laethem <[email protected]> | 2021-10-14 01:26:11 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-10-30 15:55:20 +0200 |
commit | afd49e7cdd358eda85a7fcf615d768ecf04d62ce (patch) | |
tree | d63e5d1058c1a0886fb9c41966bf32edfcba23df /testdata/calls.go | |
parent | 4199be97807bde2145e251cae8704d02e5390ebf (diff) | |
download | tinygo-afd49e7cdd358eda85a7fcf615d768ecf04d62ce.tar.gz tinygo-afd49e7cdd358eda85a7fcf615d768ecf04d62ce.zip |
compiler: add support for recursive function types
This adds support for a construct like this:
type foo func(fn foo)
Unfortunately, LLVM cannot create function pointers that look like this.
LLVM only supports named types for structs (not for pointers) and thus
can't add a pointer to a function type of the same type to a parameter
of that function type.
The fix is simple: cast all function pointers to a void function, in
LLVM IR:
void ()*
Raw function pointers are cast to this type before storing, and cast
back to the regular function type before calling. This means that
function parameters will never refer to its own type because raw
function types are fixed at that one type.
Somehow, this does have an effect on binary size in some cases. The
effect is small and goes both ways. On top of that, there is work
underway in LLVM which would make all pointer types opaque (without a
pointee type). This would make this whole commit useless and therefore
should fix any size increases that might happen.
https://llvm.org/docs/OpaquePointers.html
Diffstat (limited to 'testdata/calls.go')
-rw-r--r-- | testdata/calls.go | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/testdata/calls.go b/testdata/calls.go index 94e6c0df7..b8b10c2c9 100644 --- a/testdata/calls.go +++ b/testdata/calls.go @@ -228,3 +228,7 @@ type issue1304 struct { func (x issue1304) call() { // nothing to do } + +type recursiveFuncType func(recursiveFuncType) + +var recursiveFunction recursiveFuncType |