public function __construct(\Generator $generator)
{
$this->generator = $generator;
/**
* @param \Throwable|null $exception Exception to be thrown into the generator.
* @param mixed $value Value to be sent into the generator.
*/
$this->when = function ($exception, $value) {
if ($this->depth > self::MAX_CONTINUATION_DEPTH) {
// Defer continuation to avoid blowing up call stack.
Loop::defer(function () use($exception, $value) {
($this->when)($exception, $value);
});
return;
}
try {
if ($exception) {
// Throw exception at current execution point.
$yielded = $this->generator->throw($exception);
} else {
// Send the new value and execute to next yield statement.
$yielded = $this->generator->send($value);
}
if ($yielded instanceof Promise) {
++$this->depth;
$yielded->when($this->when);
--$this->depth;
return;
}
if ($this->generator->valid()) {
$got = \is_object($yielded) ? \get_class($yielded) : \gettype($yielded);
throw new InvalidYieldError($this->generator, \sprintf("Unexpected yield (%s expected, got %s)", Promise::class, $got));
}
$this->resolve($this->generator->getReturn());
} catch (\Throwable $exception) {
$this->dispose($exception);
}
};
try {
$yielded = $this->generator->current();
if ($yielded instanceof Promise) {
++$this->depth;
$yielded->when($this->when);
--$this->depth;
return;
}
if ($this->generator->valid()) {
$got = \is_object($yielded) ? \get_class($yielded) : \gettype($yielded);
throw new InvalidYieldError($this->generator, \sprintf("Unexpected yield (%s expected, got %s)", Promise::class, $got));
}
$this->resolve($this->generator->getReturn());
} catch (\Throwable $exception) {
$this->dispose($exception);
}
}