summaryrefslogtreecommitdiff
path: root/zend/callable.h
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2014-04-06 21:53:24 +0200
commit35fd3ccbeb4def71b4d8a59dfbb5c31201b099b9 (patch)
tree915223360aed4743aa6127fde4836aa413a260e5 /zend/callable.h
parentda4710512865e6816585ac4ab8edab2fa125e2d8 (diff)
renamed src directory to zend directory, disabled TSRM debug code
Diffstat (limited to 'zend/callable.h')
-rw-r--r--zend/callable.h190
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 &params) = 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
+ */
+}
+