@@ -52,8 +52,12 @@ struct promise_base : kphp::coro::async_stack_element {
5252 // read the m_next pointer before resuming the coroutine
5353 // since resuming the coroutine may destroy the shared_task_waiter value
5454 auto * next{awaiter->m_next };
55- auto * async_stack_root{promise.get_async_stack_frame ().async_stack_root };
56- kphp::coro::resume_with_new_root (awaiter->m_continuation , async_stack_root);
55+ auto & async_stack_frame{promise.get_async_stack_frame ()};
56+
57+ kphp::coro::async_stack_root root{};
58+ root.top_async_stack_frame = std::addressof (async_stack_frame);
59+ async_stack_frame.async_stack_root = std::addressof (root);
60+ kphp::coro::resume_with_new_root (awaiter->m_continuation , std::addressof (root));
5761 awaiter = next;
5862 }
5963 // return last awaiter's coroutine_handle to allow it to potentially be compiled as a tail-call
@@ -100,8 +104,12 @@ struct promise_base : kphp::coro::async_stack_element {
100104 if (m_awaiters == NOT_STARTED_VAL) {
101105 m_awaiters = STARTED_NO_WAITERS_VAL;
102106 const auto & handle{std::coroutine_handle<promise_type>::from_promise (*static_cast <promise_type*>(this ))};
103- auto * async_stack_root{get_async_stack_frame ().async_stack_root };
104- kphp::coro::resume_with_new_root (handle, async_stack_root);
107+ auto & async_stack_frame{get_async_stack_frame ()};
108+
109+ kphp::coro::async_stack_root root{};
110+ root.top_async_stack_frame = std::addressof (async_stack_frame);
111+ async_stack_frame.async_stack_root = std::addressof (root);
112+ kphp::coro::resume_with_new_root (handle, std::addressof (root));
105113 }
106114 // coroutine already completed, don't suspend
107115 if (done ()) {
@@ -169,24 +177,13 @@ template<typename promise_type>
169177class awaiter_base {
170178 bool m_suspended{};
171179
172- void set_async_top_frame (async_stack_frame& caller_frame, void * return_address) noexcept {
180+ void set_async_top_frame (void * return_address) noexcept {
173181 /* *
174182 * shared_task is the top of the stack for calls from it.
175183 * Therefore, it's awaiter doesn't store caller_frame, but it save `await_suspend()` return address
176184 * */
177185 async_stack_frame& callee_frame{m_coro.promise ().get_async_stack_frame ()};
178-
179186 callee_frame.return_address = return_address;
180- auto * async_stack_root{caller_frame.async_stack_root };
181- kphp::log::assertion (async_stack_root != nullptr );
182- callee_frame.async_stack_root = async_stack_root;
183- async_stack_root->top_async_stack_frame = std::addressof (callee_frame);
184- }
185-
186- void reset_async_top_frame (async_stack_frame& caller_frame) noexcept {
187- auto * async_stack_root{caller_frame.async_stack_root };
188- kphp::log::assertion (async_stack_root != nullptr );
189- async_stack_root->top_async_stack_frame = std::addressof (caller_frame);
190187 }
191188
192189protected:
@@ -218,10 +215,9 @@ class awaiter_base {
218215
219216 template <std::derived_from<kphp::coro::async_stack_element> caller_promise_type>
220217 [[clang::noinline]] auto await_suspend (std::coroutine_handle<caller_promise_type> awaiting_coroutine) noexcept -> bool {
221- set_async_top_frame (awaiting_coroutine. promise (). get_async_stack_frame (), STACK_RETURN_ADDRESS);
218+ set_async_top_frame (STACK_RETURN_ADDRESS);
222219 m_awaiter.m_continuation = awaiting_coroutine;
223220 m_suspended = m_coro.promise ().suspend_awaiter (m_awaiter);
224- reset_async_top_frame (awaiting_coroutine.promise ().get_async_stack_frame ());
225221 return m_suspended;
226222 }
227223
0 commit comments