Skip to content

Commit

Permalink
Exercise some of the changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chriso committed Jun 17, 2024
1 parent fbd5d8c commit 0f722c3
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 1 deletion.
5 changes: 5 additions & 0 deletions compiler/coroutine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ func TestCoroutineYield(t *testing.T) {
coro: func() { StructClosure(3) },
yields: []int{10, 100, 1000, 11, 101, 1000, 12, 102, 1000},
},
{
name: "generic closure capturing receiver and param",
coro: func() { StructGenericClosure(3) },
yields: []int{10, 100, 1000, 11, 101, 1000, 12, 102, 1000},
},
{
name: "generic function",
coro: func() { IdentityGenericInt(11) },
Expand Down
28 changes: 28 additions & 0 deletions compiler/testdata/coroutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,34 @@ func StructClosure(n int) {
}
}

type GenericBox[T integer] struct {
x T
}

func (b *GenericBox[T]) YieldAndInc() {
coroutine.Yield[T, any](b.x)
b.x++
}

func (b *GenericBox[T]) Closure(y T) func(T) {
return func(z T) {
coroutine.Yield[T, any](b.x)
coroutine.Yield[T, any](y)
coroutine.Yield[T, any](z)
b.x++
y++
z++ // mutation is lost
}
}

func StructGenericClosure(n int) {
box := GenericBox[int]{10}
fn := box.Closure(100)
for i := 0; i < n; i++ {
fn(1000)
}
}

func IdentityGeneric[T any](n T) {
coroutine.Yield[T, any](n)
}
Expand Down
134 changes: 133 additions & 1 deletion compiler/testdata/coroutine_durable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3385,6 +3385,127 @@ func StructClosure(_fn0 int) {
}
}

type GenericBox[T integer] struct {
x T
}

func (b *GenericBox[T]) YieldAndInc() {
coroutine.Yield[T, any](b.x)
b.x++
}

//go:noinline
func (_fn0 *GenericBox[T]) Closure(_fn1 T) (_ func(T)) {
var _f0 *struct {
IP int
X0 *GenericBox[T]
X1 T
} = &struct {
IP int
X0 *GenericBox[T]
X1 T
}{X0: _fn0, X1: _fn1}
return func(_fn0 T) {
_c := coroutine.LoadContext[int, any]()
var _f1 *struct {
IP int
X0 T
} = coroutine.Push[struct {
IP int
X0 T
}](&_c.Stack)
if _f1.IP == 0 {
*_f1 = struct {
IP int
X0 T
}{X0: _fn0}
}
defer func() {
if !_c.Unwinding() {
coroutine.Pop(&_c.Stack)
}
}()
switch {
case _f1.IP < 2:
coroutine.Yield[T, any](_f0.X0.x)
_f1.IP = 2
fallthrough
case _f1.IP < 3:
coroutine.Yield[T, any](_f0.X1)
_f1.IP = 3
fallthrough
case _f1.IP < 4:
coroutine.Yield[T, any](_f1.X0)
_f1.IP = 4
fallthrough
case _f1.IP < 5:
_f0.X0.
x++
_f1.IP = 5
fallthrough
case _f1.IP < 6:
_f0.X1++
_f1.IP = 6
fallthrough
case _f1.IP < 7:
_f1.X0++
}
}
}

//go:noinline
func StructGenericClosure(_fn0 int) {
_c := coroutine.LoadContext[int, any]()
var _f0 *struct {
IP int
X0 int
X1 GenericBox[int]
X2 func(int)
X3 int
} = coroutine.Push[struct {
IP int
X0 int
X1 GenericBox[int]
X2 func(int)
X3 int
}](&_c.Stack)
if _f0.IP == 0 {
*_f0 = struct {
IP int
X0 int
X1 GenericBox[int]
X2 func(int)
X3 int
}{X0: _fn0}
}
defer func() {
if !_c.Unwinding() {
coroutine.Pop(&_c.Stack)
}
}()
switch {
case _f0.IP < 2:
_f0.X1 = GenericBox[int]{10}
_f0.IP = 2
fallthrough
case _f0.IP < 3:
_f0.X2 = _f0.X1.Closure(100)
_f0.IP = 3
fallthrough
case _f0.IP < 5:
switch {
case _f0.IP < 4:
_f0.X3 = 0
_f0.IP = 4
fallthrough
case _f0.IP < 5:
for ; _f0.X3 < _f0.X0; _f0.X3, _f0.IP = _f0.X3+1, 4 {
_f0.X2(1000)
}
}
}
}

//go:noinline
func IdentityGeneric[T any](n T) { coroutine.Yield[T, any](n) }

Expand Down Expand Up @@ -3692,6 +3813,16 @@ func init() {
}
}]("github.com/dispatchrun/coroutine/compiler/testdata.(*Box).Closure.func1")
_types.RegisterFunc[func()]("github.com/dispatchrun/coroutine/compiler/testdata.(*Box).YieldAndInc")
_types.RegisterFunc[func(_fn1 int) (_ func(int))]("github.com/dispatchrun/coroutine/compiler/testdata.(*GenericBox[go.shape.int]).Closure")
_types.RegisterClosure[func(_fn0 int), struct {
F uintptr
X0 *struct {
IP int
X0 *GenericBox[int]
X1 int
}
D uintptr
}]("github.com/dispatchrun/coroutine/compiler/testdata.(*GenericBox[go.shape.int]).Closure.func1")
_types.RegisterFunc[func(_fn1 int) (_ func(int))]("github.com/dispatchrun/coroutine/compiler/testdata.(*IdentityGenericStruct[go.shape.int]).Closure")
_types.RegisterClosure[func(_fn0 int), struct {
F uintptr
Expand Down Expand Up @@ -3746,7 +3877,7 @@ func init() {
}
}]("github.com/dispatchrun/coroutine/compiler/testdata.Range10ClosureCapturingValues.func2")
_types.RegisterFunc[func()]("github.com/dispatchrun/coroutine/compiler/testdata.Range10ClosureHeterogenousCapture")
_types.RegisterClosure[func() int, struct {
_types.RegisterClosure[func() (_ int), struct {
F uintptr
X0 *struct {
IP int
Expand Down Expand Up @@ -3814,6 +3945,7 @@ func init() {
_types.RegisterFunc[func(_fn0 int)]("github.com/dispatchrun/coroutine/compiler/testdata.SquareGeneratorTwice")
_types.RegisterFunc[func(_fn0 int)]("github.com/dispatchrun/coroutine/compiler/testdata.SquareGeneratorTwiceLoop")
_types.RegisterFunc[func(_fn0 int)]("github.com/dispatchrun/coroutine/compiler/testdata.StructClosure")
_types.RegisterFunc[func(_fn0 int)]("github.com/dispatchrun/coroutine/compiler/testdata.StructGenericClosure")
_types.RegisterFunc[func(_ int)]("github.com/dispatchrun/coroutine/compiler/testdata.TypeSwitchingGenerator")
_types.RegisterFunc[func(_fn0 int)]("github.com/dispatchrun/coroutine/compiler/testdata.VarArgs")
_types.RegisterFunc[func(_fn0 *int, _fn1, _fn2 int)]("github.com/dispatchrun/coroutine/compiler/testdata.YieldAndDeferAssign")
Expand Down

0 comments on commit 0f722c3

Please sign in to comment.