Skip to content

Commit

Permalink
Add a test for a generic function that we must register type informat…
Browse files Browse the repository at this point in the history
…ion for
  • Loading branch information
chriso committed Dec 12, 2023
1 parent 069cac4 commit f9bc0ca
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
6 changes: 6 additions & 0 deletions compiler/coroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ func TestCoroutineYield(t *testing.T) {
coro: func() { IdentityGenericStructInt(11) },
yields: []int{11},
},

{
name: "identity generic (4)",
coro: func() { IdentityGenericClosureInt(11) },
yields: []int{11, 11},
},
}

// This emulates the installation of function type information by the
Expand Down
19 changes: 19 additions & 0 deletions compiler/testdata/coroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,3 +577,22 @@ func IdentityGenericInt(n int) {
func IdentityGenericStructInt(n int) {
(&IdentityGenericStruct[int]{n: n}).Run()
}

func IdentityGenericClosure[T any](n T) {
fn := buildClosure(n)
fn()
fn()
}

// TODO: add this go:noinline directive automatically
//
//go:noinline
func buildClosure[T any](n T) func() {
return func() {
coroutine.Yield[T, any](n)
}
}

func IdentityGenericClosureInt(n int) {
IdentityGenericClosure[int](n)
}
51 changes: 51 additions & 0 deletions compiler/testdata/coroutine_durable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3252,12 +3252,63 @@ func IdentityGenericInt(n int) { IdentityGeneric[int](n) }

//go:noinline
func IdentityGenericStructInt(n int) { (&IdentityGenericStruct[int]{n: n}).Run() }

//go:noinline
func IdentityGenericClosure[T any](_fn0 T) {
_c := coroutine.LoadContext[int, any]()
var _f0 *struct {
IP int
X0 T
X1 func()
} = coroutine.Push[struct {
IP int
X0 T
X1 func()
}](&_c.Stack)
if _f0.IP == 0 {
*_f0 = struct {
IP int
X0 T
X1 func()
}{X0: _fn0}
}
defer func() {
if !_c.Unwinding() {
coroutine.Pop(&_c.Stack)
}
}()
switch {
case _f0.IP < 2:
_f0.X1 = buildClosure(_f0.X0)
_f0.IP = 2
fallthrough
case _f0.IP < 3:
_f0.X1()
_f0.IP = 3
fallthrough
case _f0.IP < 4:
_f0.X1()
}
}

// TODO: add this go:noinline directive automatically
//
//go:noinline
func buildClosure[T any](n T) func() {
return func() {
coroutine.Yield[T, any](n)
}
}

//go:noinline
func IdentityGenericClosureInt(n int) { IdentityGenericClosure[int](n) }
func init() {
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.Double")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.EvenSquareGenerator")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.FizzBuzzIfGenerator")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.FizzBuzzSwitchGenerator")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.Identity")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosureInt")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericInt")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericStructInt")
_types.RegisterFunc[func(_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.LoopBreakAndContinue")
Expand Down

0 comments on commit f9bc0ca

Please sign in to comment.