diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-06 21:53:24 +0200 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2014-04-06 21:53:24 +0200 |
commit | 35fd3ccbeb4def71b4d8a59dfbb5c31201b099b9 (patch) | |
tree | 915223360aed4743aa6127fde4836aa413a260e5 /zend/callable.h | |
parent | da4710512865e6816585ac4ab8edab2fa125e2d8 (diff) |
renamed src directory to zend directory, disabled TSRM debug code
Diffstat (limited to 'zend/callable.h')
-rw-r--r-- | zend/callable.h | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/zend/callable.h b/zend/callable.h new file mode 100644 index 0000000..65ce719 --- /dev/null +++ b/zend/callable.h @@ -0,0 +1,190 @@ +/** + * Callable.h + * + * Object represents a callable function or method that is defined with the CPP + * API. + * + * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com> + * @copyright 2013 Copernica BV + */ + +/** + * Set up namespace + */ +namespace Php { + +/** + * Class definition + */ +class Callable +{ +public: + /** + * Constructor + * @param name Function or method name + * @param arguments Information about the arguments + */ + Callable(const char *name, const Arguments &arguments = {}) : _ptr(this, name) + { + // construct vector for arguments + _argc = arguments.size(); + _argv = new zend_arg_info[_argc+1]; + + // the first record is initialized with information about the function, + // so we skip that here + int i=1; + + // loop through the arguments + for (auto it = arguments.begin(); it != arguments.end(); it++) + { + // increment counter with number of required parameters + if (it->required()) _required++; + + // fill the arg info + fill(&_argv[i], *it); + } + } + + /** + * Copy constructor + * @param that + */ + Callable(const Callable &that) : + _ptr(that._ptr), + _return(that._return), + _required(that._required), + _argc(that._argc), + _argv(nullptr) {} + + /** + * Move constructor + * @param that + */ + Callable(Callable &&that) : + _ptr(std::move(that._ptr)), + _return(that._return), + _required(that._required), + _argc(that._argc), + _argv(that._argv) + { + // invalidate other object + that._argv = nullptr; + } + + /** + * Destructor + */ + virtual ~Callable() + { + if (_argv) delete[] _argv; + } + + /** + * Method that gets called every time the function is executed + * @param params The parameters that were passed + * @return Variable Return value + */ + virtual Value invoke(Parameters ¶ms) = 0; + + /** + * Fill a function entry + * @param entry Entry to be filled + * @param ns Active namespace + * @param classname Optional class name + * @param flags Access flags + */ + void initialize(zend_function_entry *entry, const char *classname = nullptr, int flags = 0) const; + + /** + * Fill function info + * @param info Info object to be filled + * @param ns Active namespace + * @param classname Optional class name + */ + void initialize(zend_arg_info *info, const char *classname = nullptr) const; + + +protected: + /** + * Hidden pointer to the name and the function + * @var HiddenPointer + */ + HiddenPointer<Callable> _ptr; + + /** + * Suggestion for the return type + * @var Type + */ + Type _return = Type::Null; + + /** + * Required number of arguments + * @var integer + */ + int _required = 0; + + /** + * Total number of arguments + * @var integer + */ + int _argc = 0; + + /** + * The arguments + * @var zend_arg_info[] + */ + zend_arg_info *_argv = nullptr; + + /** + * Private helper method to fill an argument object + * @param info object from the zend engine + * @param arg original object + */ + void fill(zend_arg_info *info, const Argument &arg) const + { + // fill members + info->name = arg.name().c_str(); + info->name_len = arg.name().size(); + +#if PHP_VERSION_ID >= 50400 + + // since php 5.4 there is a type-hint, but we only support arrays, objects and callables + switch (arg.type()) { + case Type::Array: info->type_hint = IS_ARRAY; break; + case Type::Callable: info->type_hint = IS_CALLABLE; break; + case Type::Object: info->type_hint = IS_OBJECT; break; + default: info->type_hint = IS_NULL; break; + } + +# if PHP_VERSION_ID >= 50600 + + // from PHP 5.6 and onwards, an is_variadic property can be set, this + // specifies whether this argument is the first argument that specifies + // the type for a variable length list of arguments. For now we only + // support methods and functions with a fixed number of arguments. + info->is_variadic = false; + +# endif + +#else + + // php 5.3 code + info->array_type_hint = type == Type::Array; + info->return_reference = false; + info->required_num_args = 0; // @todo is this correct? + +#endif + + // this parameter is a regular type + info->class_name = arg.type() == Type::Object ? arg.classname().c_str() : nullptr; + info->class_name_len = arg.type() == Type::Object ? arg.classname().size() : 0; + info->allow_null = arg.allowNull(); + info->pass_by_reference = arg.byReference(); + } +}; + +/** + * End of namespace + */ +} + |