From cd047b9bb786166485ec21d83d047428f561e6eb Mon Sep 17 00:00:00 2001 From: Martijn Otto Date: Wed, 18 May 2016 11:25:55 +0200 Subject: Store all callables in a map because the hidden pointer trick no longer works --- zend/callable.cpp | 19 ++++++++++++++++--- zend/callable.h | 17 +++++++++++------ zend/nativefunction.h | 8 ++++---- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/zend/callable.cpp b/zend/callable.cpp index 1231b55..cf0dd64 100644 --- a/zend/callable.cpp +++ b/zend/callable.cpp @@ -13,6 +13,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 + */ +static std::map callables; + /** * Function that is called by the Zend engine every time that a function gets called * @param ht @@ -28,8 +38,8 @@ 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(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) @@ -75,8 +85,11 @@ void Callable::invoke(INTERNAL_FUNCTION_PARAMETERS) */ void Callable::initialize(zend_function_entry *entry, const char *classname, int flags) const { + // track the callable + callables[_name] = const_cast(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.get(); entry->num_args = _argc; diff --git a/zend/callable.h b/zend/callable.h index b2a7047..789d129 100644 --- a/zend/callable.h +++ b/zend/callable.h @@ -8,6 +8,11 @@ * @copyright 2013 Copernica BV */ +/** + * Dependencies + */ +#include + /** * Set up namespace */ @@ -25,7 +30,7 @@ public: * @param arguments Information about the arguments */ Callable(const char *name, const Arguments &arguments = {}) : - _ptr(this, name), + _name(name), _argc(arguments.size()), _argv(new zend_internal_arg_info[_argc + 1]) { @@ -49,7 +54,7 @@ public: * @param that */ Callable(const Callable &that) : - _ptr(that._ptr), + _name(that._name), _return(that._return), _required(that._required), _argc(that._argc), @@ -62,7 +67,7 @@ public: * @param that */ Callable(Callable &&that) : - _ptr(std::move(that._ptr)), + _name(std::move(that._name)), _return(that._return), _required(that._required), _argc(that._argc), @@ -100,10 +105,10 @@ public: protected: /** - * Hidden pointer to the name and the function - * @var HiddenPointer + * Name of the function + * @var std::string */ - HiddenPointer _ptr; + std::string _name; /** * Suggestion for the return type diff --git a/zend/nativefunction.h b/zend/nativefunction.h index 073e69b..e661112 100644 --- a/zend/nativefunction.h +++ b/zend/nativefunction.h @@ -70,8 +70,8 @@ public: void initialize(const std::string &prefix, zend_function_entry *entry) { // if there is a namespace prefix, we should adjust the name - if (prefix.size()) _ptr = HiddenPointer(this, prefix+"\\"+(const char *)_ptr); - + if (!prefix.empty()) _name = prefix + '\\' + _name; + // call base initialize Callable::initialize(entry); } @@ -79,7 +79,7 @@ public: private: /** * Union of supported callbacks - * One of the callbacks will be set + * One of the callbacks will be set */ union { native_callback_0 f0; @@ -87,7 +87,7 @@ private: native_callback_2 f2; native_callback_3 f3; } _function; - + /** * The callback that is set * @var integer -- cgit v1.2.3