coroutine
coroutine copied to clipboard
coroc: support bounds and thunks
Go generates wrappers for method functions when a reference is taken to either a bound or unbound method. The SSA library calls these bounds and thunks, respectively.
Here's a test case. BoundAndThunk(1) should yield 1, 2, 3, 4, 5, 6:
type Box struct { x int }
func (b *Box) YieldAndInc() {
coroutine.Yield[int, any](b.x)
b.x++
}
func BoundAndThunk(n int) {
box := &Box{n}
box.YieldAndInc()
box.YieldAndInc()
bound := box.YieldAndInc
bound()
bound()
thunk := (*Box).YieldAndInc
thunk(box)
thunk(box)
}
See also the TestSyntheticFuncs test cases from the SSA library.
I had a go at doing this, thinking it would be a simple matter of generating func/closure types and registering them for the runtime with a $bound or $thunk name suffix. However, the Go compiler (as of 1.21) seems to do something completely different to the SSA library when generating wrappers. If you run the test case above, there'll be a runtime panic because type information is not available for the closure with a name that has a -fm suffix. Here's what I could find in the Go compiler: https://github.com/golang/go/blob/e44b8b15b19058b7a22a859ab4159f924856f688/src/cmd/compile/internal/noder/reader.go#L3756