diff options
Diffstat (limited to 'zend/callable.cpp')
-rw-r--r-- | zend/callable.cpp | 84 |
1 files changed, 32 insertions, 52 deletions
diff --git a/zend/callable.cpp b/zend/callable.cpp index f0dc3e8..cf0dd64 100644 --- a/zend/callable.cpp +++ b/zend/callable.cpp @@ -14,6 +14,16 @@ namespace Php { /** + * Map function names to their implementation + * + * This is braindead, there should be a way to get this information + * from the "This" zval in the execute_data, I just can't find it + * @todo Find a better way for this + * @var std::map<std::string, Callable*> + */ +static std::map<std::string, Callable*> callables; + +/** * Function that is called by the Zend engine every time that a function gets called * @param ht * @param return_value @@ -27,9 +37,9 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) { // find the function name const char *name = get_active_function_name(TSRMLS_C); - - // uncover the hidden pointer inside the function name - Callable *callable = HiddenPointer<Callable>(name); + + // retrieve the callable from the map + auto *callable = callables.find(name)->second; // check if sufficient parameters were passed (for some reason this check // is not done by Zend, so we do it here ourselves) @@ -44,7 +54,7 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) else { // construct parameters - ParametersImpl params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); + ParametersImpl params(getThis(), ZEND_NUM_ARGS() TSRMLS_CC); // the function could throw an exception try @@ -52,11 +62,6 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) // get the result Value result(callable->invoke(params)); - // we're ready if the return value is not even used - if (!return_value_used) return; - - // @todo php 5.6 has a RETVAL_ZVAL_FAST macro that can be used instead (and is faster) - // return a full copy of the zval, and do not destruct it RETVAL_ZVAL(result._val, 1, 0); } @@ -70,25 +75,28 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) /** * Fill a function entry - * - * This method is called when the extension is registering itself, when the - * function or method introces himself - * + * + * This method is called when the extension is registering itself, when the + * function or method introduces himself + * * @param entry Entry to be filled * @param classname Optional class name * @param flags Is this a public property? */ void Callable::initialize(zend_function_entry *entry, const char *classname, int flags) const { + // track the callable + callables[_name] = const_cast<Callable*>(this); + // fill the members of the entity, and hide a pointer to the current object in the name - entry->fname = (const char *)_ptr; + entry->fname = _name.data(); entry->handler = &Callable::invoke; - entry->arg_info = _argv; + entry->arg_info = _argv.get(); entry->num_args = _argc; entry->flags = flags; // we should fill the first argument as well - initialize((zend_arg_info *)entry->arg_info, classname); + initialize((zend_internal_function_info*)_argv.get(), classname); } /** @@ -96,51 +104,23 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int * @param info Info to be filled * @param classname Optional classname */ -void Callable::initialize(zend_arg_info *info, const char *classname) const +void Callable::initialize(zend_internal_function_info *info, const char *classname) const { -#if PHP_VERSION_ID >= 50400 - // up until php 5.3, the first info object is filled with alternative information, - // later it is casted to a zend_internal_function object - auto *finfo = (zend_internal_function_info *)info; - - // fill in all the members, note that return reference is false by default, - // because we do not support returning references in PHP-CPP, although Zend - // engine allows it. Inside the name we hide a pointer to the current object - finfo->_name = _ptr; - finfo->_name_len = ::strlen(_ptr); - finfo->_class_name = classname; + // store the classname + info->class_name = classname; // number of required arguments, and the expected return type - finfo->required_num_args = _required; - finfo->_type_hint = (unsigned char)_return; + info->required_num_args = _required; + info->type_hint = (unsigned char)_return; // we do not support return-by-reference - finfo->return_reference = false; - -# if PHP_VERSION_ID >= 50600 + info->return_reference = false; + // since php 5.6 there are _allow_null and _is_variadic properties. It's // not exactly clear what they do (@todo find this out) so for now we set // them to false - finfo->_allow_null = false; - finfo->_is_variadic = false; - -# else - // passing by reference is not used (only for php 5.4 and php 5.5) - finfo->pass_rest_by_reference = false; -# endif - -#else - // php 5.3 code - info->name = nullptr; - info->name_len = 0; - info->class_name = nullptr; - info->class_name_len = 0; - info->array_type_hint = false; info->allow_null = false; - info->pass_by_reference = false; - info->return_reference = false; - info->required_num_args = _required; -#endif + info->_is_variadic = false; } /** |