<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/91123>91123</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
coroutine frame from lambda
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
kelbon
</td>
</tr>
</table>
<pre>
I think there are should be a way to create coroutine frame from lambda. There are use cases:
* when we sure dont need allocation here, just create a handle and pass into function which accepts coroutine handles
* when coroutine handle may be invoked concurrently from different threads ('when_any' implementation), but its not possible in standard C++ to handle this (calling .resume concurrently will lead to UB). With lambdas calling .resume concurrently may be handled with simple mutex
* to create 'always done' coroutine, just like std::noop_coroutine, but .done always returns true
* to create special coroutines, such as generator, which is always empty (without allocatons). This may be used in std::generator move operator (there are no default constructor for std::generator, but move constructor is present, so to create "default" state for such generator we can use some global generator object, which .resume does nothing and .destroy does nothing too)
I have "implementation", but for obvious reasons it is not good: it contains undefined behavior. And i dont know is it intentional, but clang ignores all noinline and std::launder hacks and just optimizes out all code every time (with O1/O2/O3):
https://godbolt.org/z/EP1b8Eb9x
```cpp
template <typename F>
struct alignas(__STDCPP_DEFAULT_NEW_ALIGNMENT__) coroutine_frame {
void (*resume)(void*) = &do_resume<std::decay_t<coroutine_frame>>;
void (*destroy)(void*) = &do_destroy<std::decay_t<coroutine_frame>>;
F f;
coroutine_frame(F value) : f(std::move(value)) {}
[[gnu::noinline]] std::coroutine_handle<> handle() noexcept {
return std::coroutine_handle<>::from_address(std::launder(this));
}
};
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVk2P2zgM_TXKhWiQyJlJcsghn4sC3bbATtFjIFtMrI4sGqKcNP31C9rOxwyKLrDAwINIJB_5-EjbMLtjQFyop5V62gxMk0qKi1f0OYVBTvay-AipdOEVUokRwUQELqnxFnIEA2dzgURQRDQJoaBITXIB4RBNJU-qwJsqt2YIL7cADSMUhpFVtlSjjRpdn3oJ5xIDnBG4iQiWQoKAaMF4T4VJjgJIGKXX8KPhdAU2UJpgPYIJFmrDDC4kgkMTitbnXLqiBFMUWCd-SLPz4nfw7--hMhcp14UTvaKFgkLRxIgh-UtXo3WHA8oBpDKisQxKz5SeSri9CRelp-Cq2mOFIbVlKD2XIvImgUsMgRLUxOxyLzjAyQRrooW10iulV0Jyn0wqXRu-MN67cIRhRG4qfJvV2XkPHo0Vx28rpedD-O5S2XeD4Y_efb0doIWzOHKbP1RNwp93vu69V3pq_NlcWLqGUvCNxlu3vHtF4GSl79kyENX7N0bCxlDcoQ8VMTUxMKTY4O9AucbCGX-HYgnDjTSb4YgBo0kU5bCTgONraKzqdBEepTpq0lViFLhl60Vo7oloGG3XlT71W2So6IRAdf9L6dl9TgKBxYNpfBJ2OcWmEJsDxd8Eupbfxns0dwx1RMaQ2tLoDeW6B1Bai2QSdtGl_nuKZ5m20E4dU4Vw9JQb_2BA-Q8s0p2kqyYsYavMUoQikzW0yCnS5e1NIhI1PwzyRyjNqc3vvej1tc5Di3ty1EiXDVNgcEmqlVE4EglBclJQSMYFhiZYPLiAsnlKc3IUh7AMFly3Jl4DncVdgoSEQfCMv8IV3oQjuGOgiCIBD4Fc8DLjUtitH94ITITSFK_cXrXCpTq5yv1Chl4pUJBFwBPGCyRX4VVI8GWs9O6LlkcmrFw3XJlS3e47vVN6dySbk09Dikeld7-U3m2_jvPZNp__fLMQn0fdX1HX3UnCqvZt77N1utQYZM3uVLbtrjvVgPHuGAwrPdvv_3nZrL9-3W-2u-W3Ty_7z9vv--Wnj399_nv7-WW_V3p-H559t7XVdNVFAziRs90qW3aaaNfWTI6VXoqzyjag9LOlfW-QrW9kWizMZZ9Utn4HIfnK3-9weon9Aehq8b-QdnC4_erP3rvo2Q5OxjfYwS7hoPTsBiUDKpn1Bq3NdKWmmzcxoX2hro6hue66Tm3qaaOeNne93bG7Zauytcq2_eZtCZlDIPwpL67HxkC_Gv8rUncn76i9sTYi82MtvdrbreW4q-bO1b2m6ebO2VWSj-UO7CKz82xuBrgYT8eT-Xj-_DwblIuJHY8PxXiGxmTzyWR-mGST0WRcTEd5Ye18NHALPdKT0dPoaTzJJno21M-YHUZmhGOTzezzRE1GWBnnh96fKpmXgWNucDEfj3U28CZHz-3Xi9YBZQGwtEXLx0xciM-HvDmymoy848T3KMklj4s_fLAMmugX76bWpbLJhwVVSu8kUv_vQx2p26C7Fp-V3rX5_RsAAP__lNMS8w">