From 07d23c9d8338c877a7bc68299000307a539cf7bc Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Sun, 6 Oct 2024 17:47:48 +0200 Subject: [PATCH] runtime: implement newcoro, coroswitch to support package iter --- src/runtime/coro.go | 31 +++++++++++++++++++++++++++++++ testdata/go1.23/main.go | 21 ++++++++++++++++++--- testdata/go1.23/out.txt | 10 ++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 src/runtime/coro.go diff --git a/src/runtime/coro.go b/src/runtime/coro.go new file mode 100644 index 000000000..204a5c2be --- /dev/null +++ b/src/runtime/coro.go @@ -0,0 +1,31 @@ +package runtime + +// A naive implementation of coroutines that supports +// package iter. + +type coro struct { + f func(*coro) + ch chan struct{} +} + +//go:linkname newcoro + +func newcoro(f func(*coro)) *coro { + c := &coro{ + ch: make(chan struct{}), + f: f, + } + go func() { + defer close(c.ch) + <-c.ch + f(c) + }() + return c +} + +//go:linkname coroswitch + +func coroswitch(c *coro) { + c.ch <- struct{}{} + <-c.ch +} diff --git a/testdata/go1.23/main.go b/testdata/go1.23/main.go index 01782d235..2737f68be 100644 --- a/testdata/go1.23/main.go +++ b/testdata/go1.23/main.go @@ -1,14 +1,29 @@ package main +import "iter" + func main() { testFuncRange(counter) + testIterPull(counter) + println("go1.23 has lift-off!") } -func testFuncRange(f func(yield func(int) bool)) { - for i := range f { +func testFuncRange(it iter.Seq[int]) { + for i := range it { + println(i) + } +} + +func testIterPull(it iter.Seq[int]) { + next, stop := iter.Pull(it) + defer stop() + for { + i, ok := next() + if !ok { + break + } println(i) } - println("go1.23 has lift-off!") } func counter(yield func(int) bool) { diff --git a/testdata/go1.23/out.txt b/testdata/go1.23/out.txt index aeeb7d40e..78ac56642 100644 --- a/testdata/go1.23/out.txt +++ b/testdata/go1.23/out.txt @@ -8,4 +8,14 @@ 3 2 1 +10 +9 +8 +7 +6 +5 +4 +3 +2 +1 go1.23 has lift-off!