diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-09-09 15:02:22 -0700 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2013-09-09 15:02:22 -0700 |
commit | e220af8dc07d845efb81082f3159460406ece9ca (patch) | |
tree | 0730a4d27a0aea3e826674c237cb581b56a9dcdc /src | |
parent | 49e349c494e0134570a158e56ba8b5b9f26b94f6 (diff) |
work in progress
Diffstat (limited to 'src')
-rw-r--r-- | src/arginfo.h | 105 | ||||
-rw-r--r-- | src/callable.cpp | 175 | ||||
-rw-r--r-- | src/callable.h | 157 | ||||
-rw-r--r-- | src/extension.cpp | 67 | ||||
-rw-r--r-- | src/function.cpp | 5 | ||||
-rw-r--r-- | src/includes.h | 4 | ||||
-rw-r--r-- | src/nativefunction.h | 88 |
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 ¶ms) + { + 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 + */ +} + |