Skip to content

Commit

Permalink
Write a test that fails since receiver isn't captured
Browse files Browse the repository at this point in the history
  • Loading branch information
chriso committed Dec 14, 2023
1 parent c3f527f commit 89fc415
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 32 deletions.
18 changes: 9 additions & 9 deletions compiler/coroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,28 +216,28 @@ func TestCoroutineYield(t *testing.T) {
},

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

{
name: "identity generic (2)",
name: "generic function",
coro: func() { IdentityGenericInt(11) },
yields: []int{11},
},

{
name: "identity generic (3)",
name: "generic struct",
coro: func() { IdentityGenericStructInt(11) },
yields: []int{11},
},

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

{
name: "generic struct closure",
coro: func() { IdentityGenericStructClosureInt(11) },
yields: []int{11, 100, 11, 100},
},
}

// This emulates the installation of function type information by the
Expand Down
38 changes: 26 additions & 12 deletions compiler/testdata/coroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,22 +562,10 @@ func IdentityGeneric[T any](n T) {
coroutine.Yield[T, any](n)
}

type IdentityGenericStruct[T any] struct {
n T
}

func (i *IdentityGenericStruct[T]) Run() {
coroutine.Yield[T, any](i.n)
}

func IdentityGenericInt(n int) {
IdentityGeneric[int](n)
}

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

func IdentityGenericClosure[T any](n T) {
fn := buildClosure(n)
fn()
Expand All @@ -596,3 +584,29 @@ func buildClosure[T any](n T) func() {
func IdentityGenericClosureInt(n int) {
IdentityGenericClosure[int](n)
}

type IdentityGenericStruct[T any] struct {
n T
}

func (i *IdentityGenericStruct[T]) Run() {
coroutine.Yield[T, any](i.n)
}

//go:noinline
func (i *IdentityGenericStruct[T]) Closure(n T) func() {
return func() {
coroutine.Yield[T, any](i.n)
coroutine.Yield[T, any](n)
}
}

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

func IdentityGenericStructClosureInt(n int) {
fn := (&IdentityGenericStruct[int]{n: n}).Closure(100)
fn()
fn()
}
75 changes: 64 additions & 11 deletions compiler/testdata/coroutine_durable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3240,19 +3240,9 @@ func ReturnNamedValue() (_fn0 int) {
//go:noinline
func IdentityGeneric[T any](n T) { coroutine.Yield[T, any](n) }

type IdentityGenericStruct[T any] struct {
n T
}

//go:noinline
func (i *IdentityGenericStruct[T]) Run() { coroutine.Yield[T, any](i.n) }

//go:noinline
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[T, any]()
Expand Down Expand Up @@ -3291,7 +3281,7 @@ func IdentityGenericClosure[T any](_fn0 T) {
}
}

// TODO: add this go:noinline directive automatically
// TODO: add this go:noinline directive automatically (once stealthrocket/coroutine#84 is fixed)
//
//go:noinline
func buildClosure[T any](n T) func() {
Expand All @@ -3302,7 +3292,69 @@ func buildClosure[T any](n T) func() {

//go:noinline
func IdentityGenericClosureInt(n int) { IdentityGenericClosure[int](n) }

type IdentityGenericStruct[T any] struct {
n T
}

//go:noinline
func (i *IdentityGenericStruct[T]) Run() { coroutine.Yield[T, any](i.n) }

//go:noinline
func (i *IdentityGenericStruct[T]) Closure(n T) func() {
return func() {
coroutine.Yield[T, any](i.n)
coroutine.Yield[T, any](n)
}
}

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

//go:noinline
func IdentityGenericStructClosureInt(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
var _f0 *struct {
IP int
X0 int
X1 func()
} = coroutine.Push[struct {
IP int
X0 int
X1 func()
}](&_c.Stack)
if _f0.IP == 0 {
*_f0 = struct {
IP int
X0 int
X1 func()
}{X0: _fn0}
}
defer func() {
if !_c.Unwinding() {
coroutine.Pop(&_c.Stack)
}
}()
switch {
case _f0.IP < 2:
_f0.X1 = (&IdentityGenericStruct[int]{n: _f0.X0}).Closure(100)
_f0.IP = 2
fallthrough
case _f0.IP < 3:
_f0.X1()
_f0.IP = 3
fallthrough
case _f0.IP < 4:
_f0.X1()
}
}
func init() {
_types.RegisterFunc[func(n int) func()]("github.com/stealthrocket/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Closure")
_types.RegisterClosure[func(), struct {
F uintptr
D uintptr
X0 int
}]("github.com/stealthrocket/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Closure.func1")
_types.RegisterFunc[func()]("github.com/stealthrocket/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Run")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.Double")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.EvenSquareGenerator")
Expand All @@ -3312,6 +3364,7 @@ func init() {
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosureInt")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericClosure[go.shape.int]")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericInt")
_types.RegisterFunc[func(_fn0 int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericStructClosureInt")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGenericStructInt")
_types.RegisterFunc[func(n int)]("github.com/stealthrocket/coroutine/compiler/testdata.IdentityGeneric[go.shape.int]")
_types.RegisterFunc[func(_ int)]("github.com/stealthrocket/coroutine/compiler/testdata.LoopBreakAndContinue")
Expand Down

0 comments on commit 89fc415

Please sign in to comment.