int a = 0; int b = 1; while (true) co_yield a + b; b = a + b; a = b - a;
int main() auto generator = fibonacci(); for (int i = 0; i < 10; ++i) if (generator.has_next()) std::cout << generator.next() << " " << std::endl; else break;
void (*resume_fn)(__fibonacciFrame *); void (*destroy_fn)(__fibonacciFrame *); std::__coroutine_traits_impl<Generator>::promise_type __promise; int __suspend_index; bool __initial_await_suspend_called; int a; int b; std::suspend_always __suspend_71_11; std::suspend_always __suspend_72_3; std::suspend_always __suspend_73_3; std::suspend_always __suspend_78_5; std::suspend_always __suspend_71_11_1; ;
Generator fibonacci()
/* Allocate the frame including the promise */ __fibonacciFrame * __f = reinterpret_cast<__fibonacciFrame *>(operator new(__builtin_coro_size())); __f->__suspend_index = 0; __f->__initial_await_suspend_called = false;
/* Construct the promise. */ new (&__f->__promise)std::__coroutine_traits_impl<Generator>::promise_type;
/* Forward declare the resume and destroy function. */ void __fibonacciResume(__fibonacciFrame * __f); void __fibonacciDestroy(__fibonacciFrame * __f);
/* Assign the resume and destroy function pointers. */ __f->resume_fn = &__fibonacciResume; __f->destroy_fn = &__fibonacciDestroy;
/* Call the made up function with the coroutine body for initial suspend. This function will be called subsequently by coroutine_handle<>::resume() which calls __builtin_coro_resume(__handle_) */ __fibonacciResume(__f);
return __promise.get_return_object();
/* This function invoked by coroutine_handle<>::destroy() */ void __fibonacciDestroy(__fibonacciFrame * __f)
/* destroy all variables with dtors */ __f->~__fibonacciFrame(); /* Deallocating the coroutine frame */ operator delete(__builtin_coro_free(static_cast<void *>(__f)));
方便分析,上边代码已经删除了一部分,首先我们先回答第一个问题,这两个变量存放位置,
struct __fibonacciFrame 里边有int a; int b;两个成员,在fibonacci(),可以看到使用了new 关键字分配对象,也就是说int a;int b;被编译器放到堆里边了,
第二个问题:
为什么要定义struct promise_type,通过上边的代码也可以看出来, new (&__f->__promise) std::__coroutine_traits_impl<Generator>::promise_type; 萃取机已经明确要求,里边要含有promise_type, 并且这个里边要有明确的几个协程必备的方法定义。另外通过__promise.get_return_object()可以构建Generator 对象,
C++ /* This function invoked by coroutine_handle<>::resume() */ void __fibonacciResume(__fibonacciFrame * __f)
try
/* Create a switch to get to the correct resume point */ switch(__f->__suspend_index) case 0: break; case 1: goto __resume_fibonacci_1; case 2: goto __resume_fibonacci_2; case 3: goto __resume_fibonacci_3; case 4: goto __resume_fibonacci_4;