current(); if (!$yielded instanceof Promise) { if (!$generator->valid()) { $this->resolve($generator->getReturn()); return; } $yielded = self::transform($yielded, $generator); } } catch (\Throwable $exception) { $this->fail($exception); return; } /** * @param \Throwable|null $e Exception to be thrown into the generator. * @param mixed $v Value to be sent into the generator. */ $onResolve = function ($e, $v) use ($generator, &$onResolve) { /** @var bool Used to control iterative coroutine continuation. */ static $immediate = true; /** @var \Throwable|null Promise failure reason when executing next coroutine step, null at all other times. */ static $exception; /** @var mixed Promise success value when executing next coroutine step, null at all other times. */ static $value; $exception = $e; $value = $v; if (!$immediate) { $immediate = true; return; } try { try { do { if ($exception) { // Throw exception at current execution point. $yielded = $generator->throw($exception); } else { // Send the new value and execute to next yield statement. $yielded = $generator->send($value); } if (!$yielded instanceof Promise) { if (!$generator->valid()) { $this->resolve($generator->getReturn()); $onResolve = null; return; } $yielded = self::transform($yielded, $generator); } $immediate = false; $yielded->onResolve($onResolve); } while ($immediate); $immediate = true; } catch (\Throwable $exception) { $this->fail($exception); $onResolve = null; } finally { $exception = null; $value = null; } } catch (\Throwable $e) { Loop::defer(static function () use ($e) { throw $e; }); } }; try { $yielded->onResolve($onResolve); unset($generator, $yielded, $onResolve); } catch (\Throwable $e) { Loop::defer(static function () use ($e) { throw $e; }); } } }