This repository has been archived on 2018-04-01. You can view files and clone it, but cannot push or open issues or pull requests.
php-asio/src/generator.hpp

64 lines
2.0 KiB
C++

/**
* php-asio/generator.hpp
*
* Several functions copied from zend_generators.c,
* which provides PHP's generator functionalities.
* Used by Future when coroutine is enabled.
*
* @author CismonX<admin@cismon.net>
*/
#pragma once
#include "common.hpp"
#include <zend_generators.h>
#ifdef ENABLE_COROUTINE
namespace asio
{
/// Ensure that the generator is initialized.
inline void zend_generator_ensure_initialized(zend_generator* generator)
{
if (UNEXPECTED(Z_TYPE(generator->value) == IS_UNDEF) &&
EXPECTED(generator->execute_data) &&
EXPECTED(generator->node.parent == nullptr)) {
generator->flags |= ZEND_GENERATOR_DO_INIT;
zend_generator_resume(generator);
generator->flags &= ~ZEND_GENERATOR_DO_INIT;
generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
}
}
/// Check whether the generator is valid.
inline bool generator_valid(zend_generator* generator)
{
zend_generator_ensure_initialized(generator);
zend_generator_get_current(generator);
return EXPECTED(generator->execute_data != nullptr);
}
/// Get current yield value of the generator.
inline zval* generator_current(zend_generator* generator)
{
zend_generator_ensure_initialized(generator);
const auto root = zend_generator_get_current(generator);
if (EXPECTED(generator->execute_data != NULL && Z_TYPE(root->value) != IS_UNDEF))
return &root->value;
return nullptr;
}
/// Send a value to the generator.
inline void generator_send(zend_generator* generator, zval* value)
{
zend_generator_ensure_initialized(generator);
if (UNEXPECTED(!generator->execute_data))
return;
const auto root = zend_generator_get_current(generator);
if (root->send_target)
ZVAL_COPY(root->send_target, value);
zend_generator_resume(generator);
}
}
#endif // ENABLE_COROUTINE