Skip to content

Commit

Permalink
Make sure mutations are captured across yield points
Browse files Browse the repository at this point in the history
  • Loading branch information
chriso committed Dec 14, 2023
1 parent 89fc415 commit 67101be
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 16 deletions.
2 changes: 1 addition & 1 deletion compiler/coroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ func TestCoroutineYield(t *testing.T) {
{
name: "generic struct closure",
coro: func() { IdentityGenericStructClosureInt(11) },
yields: []int{11, 100, 11, 100},
yields: []int{11, 100, 23, 12, 101, 45},
},
}

Expand Down
17 changes: 12 additions & 5 deletions compiler/testdata/coroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,11 @@ func IdentityGenericClosureInt(n int) {
IdentityGenericClosure[int](n)
}

type IdentityGenericStruct[T any] struct {
type integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

type IdentityGenericStruct[T integer] struct {
n T
}

Expand All @@ -594,10 +598,13 @@ func (i *IdentityGenericStruct[T]) Run() {
}

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

Expand All @@ -607,6 +614,6 @@ func IdentityGenericStructInt(n int) {

func IdentityGenericStructClosureInt(n int) {
fn := (&IdentityGenericStruct[int]{n: n}).Closure(100)
fn()
fn()
fn(23)
fn(45)
}
27 changes: 17 additions & 10 deletions compiler/testdata/coroutine_durable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3293,18 +3293,25 @@ func buildClosure[T any](n T) func() {
//go:noinline
func IdentityGenericClosureInt(n int) { IdentityGenericClosure[int](n) }

type IdentityGenericStruct[T any] struct {
type integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}

type IdentityGenericStruct[T integer] 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() {
func (i *IdentityGenericStruct[T]) Closure(n T) func(T) {
return func(x T) {
coroutine.Yield[T, any](i.n)
i.n++
coroutine.Yield[T, any](n)
n++
coroutine.Yield[T, any](x)
}
}

Expand All @@ -3317,17 +3324,17 @@ func IdentityGenericStructClosureInt(_fn0 int) {
var _f0 *struct {
IP int
X0 int
X1 func()
X1 func(int)
} = coroutine.Push[struct {
IP int
X0 int
X1 func()
X1 func(int)
}](&_c.Stack)
if _f0.IP == 0 {
*_f0 = struct {
IP int
X0 int
X1 func()
X1 func(int)
}{X0: _fn0}
}
defer func() {
Expand All @@ -3341,16 +3348,16 @@ func IdentityGenericStructClosureInt(_fn0 int) {
_f0.IP = 2
fallthrough
case _f0.IP < 3:
_f0.X1()
_f0.X1(23)
_f0.IP = 3
fallthrough
case _f0.IP < 4:
_f0.X1()
_f0.X1(45)
}
}
func init() {
_types.RegisterFunc[func(n int) func()]("github.com/stealthrocket/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Closure")
_types.RegisterClosure[func(), struct {
_types.RegisterFunc[func(n int) func(T)]("github.com/stealthrocket/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Closure")

Check failure on line 3359 in compiler/testdata/coroutine_durable.go

View workflow job for this annotation

GitHub Actions / Test

undefined: T
_types.RegisterClosure[func(x int), struct {
F uintptr
D uintptr
X0 int
Expand Down

0 comments on commit 67101be

Please sign in to comment.