summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-09-09 15:02:22 -0700
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-09-09 15:02:22 -0700
commite220af8dc07d845efb81082f3159460406ece9ca (patch)
tree0730a4d27a0aea3e826674c237cb581b56a9dcdc /src
parent49e349c494e0134570a158e56ba8b5b9f26b94f6 (diff)
work in progress
Diffstat (limited to 'src')
-rw-r--r--src/arginfo.h105
-rw-r--r--src/callable.cpp175
-rw-r--r--src/callable.h157
-rw-r--r--src/extension.cpp67
-rw-r--r--src/function.cpp5
-rw-r--r--src/includes.h4
-rw-r--r--src/nativefunction.h88
7 files changed, 140 insertions, 461 deletions
diff --git a/src/arginfo.h b/src/arginfo.h
deleted file mode 100644
index 39e0e99..0000000
--- a/src/arginfo.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * ArgInfo.h
- *
- * Internal class that wraps the Zend information about an argument
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class ArgInfo
-{
-public:
- /**
- * Constructor if this argument should be an instance of a certain class
- * @param name Name of the argument
- * @param classname If a specific class is required, the class type
- * @param null Are NULL values allowed in stead of an instance?
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, const std::string &classname, bool null = true, bool ref = false) :
- _name(name), _classname(name), _type(objectType), _null(null), _ref(ref) {}
-
- /**
- * Constructor if this argument can be anything
- * @param name Name of the argument
- * @param type Type hint (arrayType or callableType)
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, Type type = nullType, bool ref = false) :
- _name(name), _type(type), _null(false), _ref(ref) {}
-
- /**
- * Constructor if this argument can be anything
- * @param name Name of the argument
- * @param ref Is this a pass-by-reference argument?
- */
- ArgInfo(const std::string &name, bool ref = false) :
- _name(name), _type(nullType), _null(false), _ref(ref) {}
-
- /**
- * Destructor
- */
- virtual ~ArgInfo() {}
-
- /**
- * Fill a zend_arg_info structure
- * @param info
- */
- void fill(zend_arg_info *info)
- {
- // fill all members
- info->name = _name.c_str();
- info->name_len = _name.size();
- info->class_name = _classname.size() ? _classname.c_str() : NULL;
- info->class_name_len = _classname.size();
- info->type_hint = _type;
- info->allow_null = _null;
- info->pass_by_reference = _ref;
- }
-
-private:
- /**
- * The argument name
- * @var string
- */
- std::string _name;
-
- /**
- * The class name
- * @var string
- */
- std::string _classname;
-
- /**
- * Type of the argument
- * @var Type
- */
- Type _type;
-
- /**
- * Can this argument be set to NULL?
- * @var bool
- */
- bool _null;
-
- /**
- * Is this a pass-by-reference argument?
- * @var bool
- */
- bool _ref;
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/callable.cpp b/src/callable.cpp
deleted file mode 100644
index 4db463c..0000000
--- a/src/callable.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Callable.cpp
- *
- * Implementation for the Callable class
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-#include "includes.h"
-
-/**
- * Namespace
- */
-namespace Php {
-
-/**
- * Function that is called by the Zend engine every time that a function gets called
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
-void invoke_callable(INTERNAL_FUNCTION_PARAMETERS)
-{
- // find the function name
- const char *function = get_active_function_name(TSRMLS_C);
-
- // uncover the hidden pointer inside the function name
- Callable *callable = HiddenPointer<Callable>(function);
-
- // call the appropriate object
- callable->invoke(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-
-/**
- * Fill a function entry
- *
- * This method is called when the extension is registering itself, when the
- * function or method introces himself
- *
- * @param entry
- */
-void Callable::fill(zend_function_entry *entry)
-{
- // fill the members of the entity, and hide a pointer to the current object in the name
- entry->fname = HiddenPointer<Callable>(this, _name);
- entry->handler = invoke_callable;
- entry->arg_info = _argv;
- entry->num_args = _argc;
- entry->flags = _flags;
-}
-
-/**
- * Another attempt to fill internal function info
- *
- * This method is called when the extension is registering itself, when the
- * function or method introces himself
- *
- * @param entry
- */
-void Callable::fill(zend_internal_function_info *info)
-{
- // fill in all the members, note that return reference is false by default,
- // because we do want to return references, inside the name we hide a pointer
- // to the current object
- info->_name = HiddenPointer<Callable>(this, _name);
- info->_name_len = _name.size();
- info->_class_name = _classname.size() ? _classname.c_str() : NULL;
- info->required_num_args = _required;
- info->_type_hint = _type;
- info->return_reference = false;
- info->pass_rest_by_reference = false;
-}
-
-/**
- * Process the arguments
- *
- * The arguments are called by the user of the PhpCpp library when he
- *
- * @param arguments
- */
-void Callable::process(const std::initializer_list<Argument> &arguments)
-{
- // store counters
- _argc = arguments.size();
- _required = arguments.size();
-
- // allocate memory for the arguments, with one extra record to hold information
- _argv = new zend_arg_info[_argc + 1];
-
- // fill the info
- fill((zend_internal_function_info *)_argv);
-
- // iteration counter
- int i = 0;
-
- // loop through the arguments
- for (auto it = begin(arguments); it != arguments.end(); it++)
- {
- // fill the argument structure
-// it->internal()->fill(&_argv[++i]);
- }
-}
-
-int do_test(int a, int b)
-{
- std::cout << "do_test: " << a << " " << b << std::endl;
-
- return 77;
-}
-
-/**
- * Invoke the method
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
-int Callable::invoke(INTERNAL_FUNCTION_PARAMETERS)
-{
- std::cout << "args: " << ZEND_NUM_ARGS() << std::endl;
- std::cout << "required: " << _required << std::endl;
- std::cout << "argc: " << _argc << std::endl;
-
- // number of arguments should be sufficient // @todo show error message
-// if (ZEND_NUM_ARGS() < _required) return FAILURE;
-
- // and not be too much // @todo show error message
-// if (ZEND_NUM_ARGS() > _argc) return FAILURE;
-
- // number of arguments on the stack
- int arg_count = (int)(zend_uintptr_t) *(zend_vm_stack_top(TSRMLS_C) - 1);
-
-// // loop through the arguments
-// Arguments args(ZEND_NUM_ARGS());
-//
-// for (auto iter = args.begin(); iter != args.end(); iter++)
-// {
-// Value val = *iter;
-//
-// val = 1234;
-// }
-//
-// int result = do_test(args[1], args[2]);
-//
- Value ret(return_value, true);
-
- std::cout << "set property 1" << std::endl;
-
-// ret["b"] = "hallo";
-
- ret["x"]["c"]["d"] = "test 123";
-
- std::cout << "done setting properties" << std::endl;
-
-
-//
-// // done
- return SUCCESS;
-}
-
-
-
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/callable.h b/src/callable.h
deleted file mode 100644
index 293e3aa..0000000
--- a/src/callable.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * Callable.h
- *
- * This is an internal class that is used internally by the Function and Method
- * classes, and that wraps the Zend function entry into a CPP object.
- *
- * This is an internal class, that is not supposed to be used or called from
- * outside the PhpCpp library.
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class Callable
-{
-public:
- /**
- * Constructor
- * @param classname Name of the class
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &classname, const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- _classname(classname), _name(function), _type(type), _flags(flags)
- {
- // process the arguments
- process(arguments);
- }
-
- /**
- * Constructor
- * @param classname Name of the class
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &classname, const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable(classname, function, nullType, arguments, flags) {}
-
- /**
- * Constructor
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &function, Type type = nullType, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable("", function, type, arguments, flags) {}
-
- /**
- * Constructor
- * @param function Name of the function or method
- * @param type Hint for the return type
- * @param arguments The arguments that are passed to the function
- * @param flags Optional flags to be passed to the function
- */
- Callable(const std::string &function, const std::initializer_list<Argument> &arguments = {}, int flags = 0) :
- Callable("", function, nullType, arguments, flags) {}
-
- /**
- * Destructor
- */
- virtual ~Callable()
- {
- delete[] _argv;
- }
-
- /**
- * Fill a function entry
- * @param entry
- */
- void fill(zend_function_entry *entry);
-
- /**
- * Invoke the method
- * @param ht
- * @param return_value
- * @param return_value_ptr
- * @param this_ptr
- * @param return_value_used
- * @param tsrm_ls
- * @return integer
- */
- int invoke(INTERNAL_FUNCTION_PARAMETERS);
-
-private:
- /**
- * Classname (in case of a member function)
- * @var string
- */
- std::string _classname;
-
- /**
- * The function name
- * @var string
- */
- std::string _name;
-
- /**
- * The return type
- * @var Type
- */
- Type _type;
-
- /**
- * Function flags (like deprecated, abstract, private, etc)
- * @var int
- */
- int _flags;
-
- /**
- * The number of arguments
- * @var int
- */
- int _argc;
-
- /**
- * The number of required arguments
- * @var int
- */
- int _required;
-
- /**
- * The arguments
- * @var zend_arg_info[]
- */
- zend_arg_info *_argv;
-
- /**
- * Another attempt to fill internal function info
- * @param entry
- */
- void fill(zend_internal_function_info *info);
-
- /**
- * Process the arguments
- * @param arguments
- */
- void process(const std::initializer_list<Argument> &arguments);
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/extension.cpp b/src/extension.cpp
index 2d9ef9f..1fd4b65 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -23,13 +23,13 @@ namespace Php {
* The way how PHP C API deals with "global" variables is stupid.
*
* This is supposed to turn into a structure that is going to be
- * instantiated for each parallel running request, and for which the
- * PHP engine allocates a certain amount of memory, and a magic
+ * instantiated for each parallel running request, and for which the
+ * PHP engine allocates a certain amount of memory, and a magic
* pointer that is passed and should be forwarded to every thinkable
- * PHP function.
+ * PHP function.
*
- * We don't like this architecture. We have our own request object
- * that makes much more sense, and that we use. However, we need
+ * We don't like this architecture. We have our own request object
+ * that makes much more sense, and that we use. However, we need
* to assign this object somewhere, so that's what we do in this
* one and only global variable
*/
@@ -39,7 +39,7 @@ ZEND_END_MODULE_GLOBALS(phpcpp)
/**
* And now we're going to define a macro. This also is a ridiculous
- * architecture from PHP to get access to a variable from the
+ * architecture from PHP to get access to a variable from the
* structure above.
*/
#ifdef ZTS
@@ -61,7 +61,7 @@ static ZEND_DECLARE_MODULE_GLOBALS(phpcpp)
* Function that must be defined to initialize the "globals"
* We do not have to initialize anything, but PHP needs to call this
* method (crazy)
- * @param globals
+ * @param globals
*/
static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {}
@@ -69,17 +69,17 @@ static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {}
/**
* Helper method to get back the current extension object
- * @return Extension
+ * @return Extension
*/
static Extension *get_extension()
{
- // retrieve the extension or module name (because PHP of course does
- // not pass such extremely useful information as they've no clue how
- // to make a decent API
- zend_module_entry *module = EG(current_module);
+ // retrieve the extension or module name (because PHP of course does
+ // not pass such extremely useful information as they've no clue how
+ // to make a decent API
+ zend_module_entry *module = EG(current_module);
- // the pointer to the extension is hidden in front of the name
- return HiddenPointer<Extension>(module->name);
+ // the pointer to the extension is hidden in front of the name
+ return HiddenPointer<Extension>(module->name);
}
/**
@@ -90,12 +90,12 @@ static Extension *get_extension()
*/
static int extension_startup(INIT_FUNC_ARGS)
{
-
-
-
- // initialize and allocate the "global" variables
-// ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL);
-
+
+
+
+ // initialize and allocate the "global" variables
+// ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL);
+
// initialize the extension
return BOOL2SUCCESS(get_extension()->initialize());
}
@@ -108,6 +108,11 @@ static int extension_startup(INIT_FUNC_ARGS)
*/
static int extension_shutdown(SHUTDOWN_FUNC_ARGS)
{
+ std::cout << "extension_shutdown" << std::endl;
+
+ // @todo the get_extension() call crashes, we need a different way to find the extension
+ return 0;
+
// finalize the extension
return BOOL2SUCCESS(get_extension()->finalize());
}
@@ -132,6 +137,11 @@ static int request_startup(INIT_FUNC_ARGS)
*/
static int request_shutdown(INIT_FUNC_ARGS)
{
+ std::cout << "request_shutdown" << std::endl;
+
+ // @todo the get_extension() call crashes, we need a different way to find the extension
+ return 0;
+
// end the request
return BOOL2SUCCESS(get_extension()->endRequest());
}
@@ -190,6 +200,8 @@ Extension::Extension(const char *name, const char *version) : _ptr(this, name)
*/
Extension::~Extension()
{
+ std::cout << "destruct extension" << std::endl;
+
// deallocate functions
if (_entry->functions) delete[] _entry->functions;
@@ -210,6 +222,21 @@ Function &Extension::add(const char *name, const Function &function)
}
/**
+ * Add a native function directly to the extension
+ * @param name Name of the function
+ * @param function The function to add
+ * @return Function The added function
+ */
+Function &Extension::add(const char *name, native_callback_0 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_1 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_2 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_3 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_4 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_5 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_6 function) { add(name, NativeFunction(function)); }
+Function &Extension::add(const char *name, native_callback_7 function) { add(name, NativeFunction(function)); }
+
+/**
* Retrieve the module entry
* @return zend_module_entry
*/
diff --git a/src/function.cpp b/src/function.cpp
index 8612cf1..13d4d27 100644
--- a/src/function.cpp
+++ b/src/function.cpp
@@ -37,8 +37,11 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS)
// construct parameters
Parameters params(ZEND_NUM_ARGS());
+ // @todo get the appropriate request (or environment)
+ Request request(NULL);
+
// call the appropriate object
- ret = function->invoke(params);
+ ret = function->invoke(request, params);
}
/**
diff --git a/src/includes.h b/src/includes.h
index 1a464e0..8d83752 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -42,11 +42,9 @@
#include "../include/arguments.h"
#include "../include/parameters.h"
#include "../include/function.h"
-#include "../include/functions.h"
#include "../include/extension.h"
/**
* Interface files for internal use only
*/
-#include "callable.h"
-#include "arginfo.h"
+#include "nativefunction.h"
diff --git a/src/nativefunction.h b/src/nativefunction.h
new file mode 100644
index 0000000..7f36608
--- /dev/null
+++ b/src/nativefunction.h
@@ -0,0 +1,88 @@
+/**
+ * NativeFunction.h
+ *
+ * The NativeFunction class is an extension of the Function class that
+ * forwards the function call directly to a native function in C/C++
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Set up namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class NativeFunction : public Function
+{
+public:
+ /**
+ * Constructor
+ * @param function
+ */
+ NativeFunction(native_callback_0 function) : _type(0) { _function.f0 = function; }
+ NativeFunction(native_callback_1 function) : _type(1) { _function.f1 = function; }
+ NativeFunction(native_callback_2 function) : _type(2) { _function.f2 = function; }
+ NativeFunction(native_callback_3 function) : _type(3) { _function.f3 = function; }
+ NativeFunction(native_callback_4 function) : _type(4) { _function.f4 = function; }
+ NativeFunction(native_callback_5 function) : _type(5) { _function.f5 = function; }
+ NativeFunction(native_callback_6 function) : _type(6) { _function.f6 = function; }
+ NativeFunction(native_callback_7 function) : _type(7) { _function.f7 = function; }
+
+ /**
+ * Destructor
+ */
+ virtual ~NativeFunction() {}
+
+ /**
+ * Method that gets called every time the function is executed
+ * @param request Request environment
+ * @param params The parameters that were passed
+ * @return Variable Return value
+ */
+ virtual Value invoke(Request &request, Parameters &params)
+ {
+ switch (_type) {
+ case 0: _function.f0(); return Value();
+ case 1: _function.f1(params); return Value();
+ case 2: _function.f2(request); return Value();
+ case 3: _function.f3(request, params); return Value();
+ case 4: return _function.f4();
+ case 5: return _function.f5(params);
+ case 6: return _function.f6(request);
+ case 7: return _function.f7(request, params);
+ default: return Value();
+ }
+ }
+
+private:
+ /**
+ * Union of supported callbacks
+ * One of the callbacks will be set
+ */
+ union {
+ native_callback_0 f0;
+ native_callback_1 f1;
+ native_callback_2 f2;
+ native_callback_3 f3;
+ native_callback_4 f4;
+ native_callback_5 f5;
+ native_callback_6 f6;
+ native_callback_7 f7;
+ } _function;
+
+ /**
+ * The callback that is set
+ * @var integer
+ */
+ int _type;
+};
+
+/**
+ * End of namespace
+ */
+}
+