coroutine icon indicating copy to clipboard operation
coroutine copied to clipboard

coroc: support bounds and thunks

Open chriso opened this issue 1 year ago • 0 comments

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

chriso avatar Dec 14 '23 22:12 chriso