Tags: dispatchrun/coroutine
Tags
Allow go statements in certain circumstances (#150) We don't currently allow `go` statements when compiling functions because there's no structured concurrency in Go; goroutines are executed independently (there's no hierarchy; no concept of ownership), and we are unable to suspend execution of related goroutines when another goroutine explicitly yields. The compiler only needs to compile a subset of functions in the program; those that yield, those that may be on the call stack of a coroutine that yields, or those that contain a function literal that yields or may end up on the call stack of a coroutine that yields. All other functions are allowed to use `go`. This PR relaxes the restrictions a bit so that certain functions are now allowed to use `go`. The major use case we unlock is to allow patterns like this, which seems to come up a lot: ```go func outer() { coroutine := func(...) { /* e.g. explicitly yields here */ } go func() { /* do something unrelated */ }() } ``` If the compiler determines that the `coroutine` function literal yields explicitly, or may end up on the call stack of a coroutine that yields explicitly, it needs to compile both the inner function literal and the outer function (since #135). We currently reject the `go` statement in the outer function, even though it may not interact with any coroutines. This PR relaxes the restriction; we allow `go` statements in this one instance. The goroutine could still mutate state from the outer function which is then read/mutated within the inner function literal. Given that we do not support serializing synchronization primitives at this time (e.g. channels, mutexes), the assumption is that the user isn't doing anything unsafe and that it's fine to allow the `go` statement. It prints a warning just in case.
Allow go statements in certain circumstances (#150) We don't currently allow `go` statements when compiling functions because there's no structured concurrency in Go; goroutines are executed independently (there's no hierarchy; no concept of ownership), and we are unable to suspend execution of related goroutines when another goroutine explicitly yields. The compiler only needs to compile a subset of functions in the program; those that yield, those that may be on the call stack of a coroutine that yields, or those that contain a function literal that yields or may end up on the call stack of a coroutine that yields. All other functions are allowed to use `go`. This PR relaxes the restrictions a bit so that certain functions are now allowed to use `go`. The major use case we unlock is to allow patterns like this, which seems to come up a lot: ```go func outer() { coroutine := func(...) { /* e.g. explicitly yields here */ } go func() { /* do something unrelated */ }() } ``` If the compiler determines that the `coroutine` function literal yields explicitly, or may end up on the call stack of a coroutine that yields explicitly, it needs to compile both the inner function literal and the outer function (since #135). We currently reject the `go` statement in the outer function, even though it may not interact with any coroutines. This PR relaxes the restriction; we allow `go` statements in this one instance. The goroutine could still mutate state from the outer function which is then read/mutated within the inner function literal. Given that we do not support serializing synchronization primitives at this time (e.g. channels, mutexes), the assumption is that the user isn't doing anything unsafe and that it's fine to allow the `go` statement. It prints a warning just in case.
Fixes (part 2) (#149) Following on from #148, this PR contains various fixes: * we now support generic type parameters that are structs * we now conservatively register type info for all function decls/lits in the module, and mark functions/methods in the module that contain function literals as `noinline`, in case they create a closure that needs to be serialized * tweaks the logging so it generates more useful output
Fixes (part 2) (#149) Following on from #148, this PR contains various fixes: * we now support generic type parameters that are structs * we now conservatively register type info for all function decls/lits in the module, and mark functions/methods in the module that contain function literals as `noinline`, in case they create a closure that needs to be serialized * tweaks the logging so it generates more useful output
Fixes (#148) This PR contains various fixes: * underscore imports are now preserved * interfaces with embeddeds are now supported * `ast.Ellipsis` is now handled correctly when used in a closure struct * `ast.IndexListExpr` is now supported * generic type params are now translated correctly when they're present in an anonymous function return value * `reflect.Type` can now be serialized
Fixes (#148) This PR contains various fixes: * underscore imports are now preserved * interfaces with embeddeds are now supported * `ast.Ellipsis` is now handled correctly when used in a closure struct * `ast.IndexListExpr` is now supported * generic type params are now translated correctly when they're present in an anonymous function return value * `reflect.Type` can now be serialized
PreviousNext