From 2fd4198b78358cf2ba527296fafb5b1728e28ea8 Mon Sep 17 00:00:00 2001 From: Emiel Bruijntjes Date: Mon, 24 Mar 2014 13:43:47 +0100 Subject: added tsrm parameter to all methods to make it compile on tsrm platforms --- src/base.cpp | 5 +- src/boolmember.h | 10 ++- src/callable.cpp | 4 +- src/classbase.cpp | 209 +++++++++++++++++++++++++++---------------------- src/exception.cpp | 6 +- src/extension.cpp | 28 ++++--- src/floatmember.h | 12 +-- src/global.cpp | 3 + src/globals.cpp | 6 ++ src/hashiterator.h | 5 +- src/includes.h | 8 +- src/invaliditerator.h | 2 + src/iterator.cpp | 21 +++-- src/iteratorimpl.h | 2 + src/member.h | 13 +-- src/namespace.cpp | 18 +++++ src/nullmember.h | 10 ++- src/numericmember.h | 10 ++- src/object.cpp | 10 ++- src/origexception.cpp | 5 +- src/origexception.h | 4 +- src/parameters.cpp | 23 ++---- src/stringmember.h | 9 ++- src/super.cpp | 6 ++ src/traverseiterator.h | 53 +++++++++---- src/value.cpp | 56 ++++++++++--- src/valueiterator.cpp | 1 + 27 files changed, 341 insertions(+), 198 deletions(-) (limited to 'src') diff --git a/src/base.cpp b/src/base.cpp index fd8e462..cefffd8 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -15,9 +15,10 @@ namespace Php { /** * Store the object in the PHP object cache * @param entry Class entry + * @param tsrm_ls * @return MixedObject */ -MixedObject *Base::store(zend_class_entry *entry) +MixedObject *Base::store(zend_class_entry *entry TSRMLS_DC) { // allocate memory for the object MixedObject *result = (MixedObject *)emalloc(sizeof(MixedObject)); @@ -29,7 +30,7 @@ MixedObject *Base::store(zend_class_entry *entry) result->php.ce = entry; // initialize the object - zend_object_std_init(&result->php, entry); + zend_object_std_init(&result->php, entry TSRMLS_CC); #if PHP_VERSION_ID < 50399 diff --git a/src/boolmember.h b/src/boolmember.h index 3dd4466..5b5d43d 100644 --- a/src/boolmember.h +++ b/src/boolmember.h @@ -41,20 +41,22 @@ public: /** * Virtual method to declare a class constant * @param entry Class entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) override + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override { - zend_declare_class_constant_bool(entry, _name.c_str(), _name.size(), _value); + zend_declare_class_constant_bool(entry, _name.c_str(), _name.size(), _value TSRMLS_CC); } /** * Virtual method to declare the property * @param entry Class entry + * @param tsrm_ls */ - virtual void declare(struct _zend_class_entry *entry) override + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override { // char* cast is necessary for php 5.3 - zend_declare_property_bool(entry, (char *)_name.c_str(), _name.size(), _value, _flags); + zend_declare_property_bool(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC); } }; diff --git a/src/callable.cpp b/src/callable.cpp index e68ab98..55f2833 100644 --- a/src/callable.cpp +++ b/src/callable.cpp @@ -35,7 +35,7 @@ static void invoke_callable(INTERNAL_FUNCTION_PARAMETERS) Value result(return_value, true); // construct parameters - Parameters params(this_ptr, ZEND_NUM_ARGS()); + Parameters params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); // the function could throw an exception try @@ -46,7 +46,7 @@ static void invoke_callable(INTERNAL_FUNCTION_PARAMETERS) catch (Exception &exception) { // process the exception - exception.process(); + exception.process(TSRMLS_C); } } diff --git a/src/classbase.cpp b/src/classbase.cpp index fbc6ed2..21d33ba 100644 --- a/src/classbase.cpp +++ b/src/classbase.cpp @@ -42,10 +42,10 @@ static ClassBase *cpp_class(zend_class_entry *entry) * @param val * @return Base */ -static Base *cpp_object(const zval *val) +static Base *cpp_object(const zval *val TSRMLS_DC) { // retrieve the old object, which we are going to copy - MixedObject *object = (MixedObject *)zend_object_store_get_object(val); + MixedObject *object = (MixedObject *)zend_object_store_get_object(val TSRMLS_CC); // return the cpp object return object->cpp; @@ -119,7 +119,7 @@ void ClassBase::callMethod(INTERNAL_FUNCTION_PARAMETERS) Value result(return_value, true); // construct parameters - Parameters params(this_ptr, ZEND_NUM_ARGS()); + Parameters params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); // retrieve the base object Base *base = params.object(); @@ -136,7 +136,7 @@ void ClassBase::callMethod(INTERNAL_FUNCTION_PARAMETERS) catch (Exception &exception) { // process the exception - exception.process(); + exception.process(TSRMLS_C); } } @@ -165,7 +165,7 @@ void ClassBase::callInvoke(INTERNAL_FUNCTION_PARAMETERS) Value result(return_value, true); // construct parameters - Parameters params(this_ptr, ZEND_NUM_ARGS()); + Parameters params(this_ptr, ZEND_NUM_ARGS() TSRMLS_CC); // retrieve the base object Base *base = params.object(); @@ -182,7 +182,7 @@ void ClassBase::callInvoke(INTERNAL_FUNCTION_PARAMETERS) catch (Exception &exception) { // process the exception - exception.process(); + exception.process(TSRMLS_C); } } @@ -191,12 +191,13 @@ void ClassBase::callInvoke(INTERNAL_FUNCTION_PARAMETERS) * @param object_ptr * @param method_name * @param method_len + * @param tsrm_ls * @return zend_function */ #if PHP_VERSION_ID < 50399 -zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len) +zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) #else -zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len, const struct _zend_literal *key) +zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int method_len, const struct _zend_literal *key TSRMLS_DC) #endif { // something strange about the Zend engine (once more). The structure with @@ -209,16 +210,16 @@ zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int me // first we'll check if the default handler does not have an implementation, // in that case the method is probably already implemented as a regular method #if PHP_VERSION_ID < 50399 - auto *defaultFunction = std_object_handlers.get_method(object_ptr, method_name, method_len); + auto *defaultFunction = std_object_handlers.get_method(object_ptr, method_name, method_len TSRMLS_CC); #else - auto *defaultFunction = std_object_handlers.get_method(object_ptr, method_name, method_len, key); + auto *defaultFunction = std_object_handlers.get_method(object_ptr, method_name, method_len, key TSRMLS_CC); #endif // did the default implementation do anything? if (defaultFunction) return defaultFunction; // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(*object_ptr); + auto *entry = zend_get_class_entry(*object_ptr TSRMLS_CC); // this is peculiar behavior of the zend engine, we first are going to dynamically // allocate memory holding all the properties of the __call method (we initially @@ -253,16 +254,17 @@ zend_function *ClassBase::getMethod(zval **object_ptr, char *method_name, int me * @param entry * @param method * @param method_len + * @param tsrm_ls * @return zend_function */ -zend_function *ClassBase::getStaticMethod(zend_class_entry *entry, char* method, int method_len) +zend_function *ClassBase::getStaticMethod(zend_class_entry *entry, char* method, int method_len TSRMLS_DC) { // first we'll check if the default handler does not have an implementation, // in that case the method is probably already implemented as a regular method #if PHP_VERSION_ID < 50399 - auto *defaultFunction = zend_std_get_static_method(entry, method, method_len); + auto *defaultFunction = zend_std_get_static_method(entry, method, method_len TSRMLS_CC); #else - auto *defaultFunction = zend_std_get_static_method(entry, method, method_len, nullptr); + auto *defaultFunction = zend_std_get_static_method(entry, method, method_len, nullptr TSRMLS_CC); #endif // did the default implementation do anything? @@ -298,9 +300,10 @@ zend_function *ClassBase::getStaticMethod(zend_class_entry *entry, char* method, * @param entry_ptr * @param func * @param object_ptr + * @param tsrm_ls * @return int */ -int ClassBase::getClosure(zval *object, zend_class_entry **entry_ptr, zend_function **func, zval **object_ptr) +int ClassBase::getClosure(zval *object, zend_class_entry **entry_ptr, zend_function **func, zval **object_ptr TSRMLS_DC) { // it is really unbelievable how the Zend engine manages to implement every feature // in a complete different manner. You would expect the __invoke() and the @@ -310,7 +313,7 @@ int ClassBase::getClosure(zval *object, zend_class_entry **entry_ptr, zend_funct // method that is going to get called // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // just like we did for getMethod(), we're going to dynamically allocate memory // with all information about the function @@ -363,7 +366,8 @@ zend_object_handlers *ClassBase::objectHandlers() memcpy(&handlers, &std_object_handlers, sizeof(zend_object_handlers)); // install custom clone function - handlers.clone_obj = clonable() ? &ClassBase::cloneObject : nullptr; + if (!clonable()) handlers.clone_obj = nullptr; + else handlers.clone_obj = &ClassBase::cloneObject; // functions for the Countable interface handlers.count_elements = &ClassBase::countElements; @@ -401,25 +405,26 @@ zend_object_handlers *ClassBase::objectHandlers() * Function to compare two objects * @param object1 * @param object2 + * @param tsrm_ls * @return int */ -int ClassBase::compare(zval *object1, zval *object2) +int ClassBase::compare(zval *object1, zval *object2 TSRMLS_DC) { // prevent exceptions try { // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object1); + auto *entry = zend_get_class_entry(object1 TSRMLS_CC); // other object must be of the same type - if (entry != zend_get_class_entry(object2)) throw NotImplemented(); + if (entry != zend_get_class_entry(object2 TSRMLS_CC)) throw NotImplemented(); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); // get the base objects - Base *base1 = cpp_object(object1); - Base *base2 = cpp_object(object2); + Base *base1 = cpp_object(object1 TSRMLS_CC); + Base *base2 = cpp_object(object2 TSRMLS_CC); // run the compare method return meta->callCompare(base1, base2); @@ -430,13 +435,13 @@ int ClassBase::compare(zval *object1, zval *object2) if (!std_object_handlers.compare_objects) return 1; // call default - return std_object_handlers.compare_objects(object1, object2); + return std_object_handlers.compare_objects(object1, object2 TSRMLS_CC); } catch (Exception &exception) { // a Php::Exception was thrown by the extension __compare function, // pass this on to user space - exception.process(); + exception.process(TSRMLS_C); // what shall we return here... return 1; @@ -448,15 +453,16 @@ int ClassBase::compare(zval *object1, zval *object2) * @param object * @param retval * @param type + * @param tsrm_ls * @return int */ -int ClassBase::cast(zval *object, zval *retval, int type) +int ClassBase::cast(zval *object, zval *retval, int type TSRMLS_DC) { // get the base object - Base *base = cpp_object(object); + Base *base = cpp_object(object TSRMLS_CC); // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); @@ -503,12 +509,12 @@ int ClassBase::cast(zval *object, zval *retval, int type) if (!std_object_handlers.cast_object) return FAILURE; // call default - return std_object_handlers.cast_object(object, retval, type); + return std_object_handlers.cast_object(object, retval, type TSRMLS_CC); } catch (Exception &exception) { // pass on the exception to php userspace - exception.process(); + exception.process(TSRMLS_C); // done return FAILURE; @@ -523,13 +529,13 @@ int ClassBase::cast(zval *object, zval *retval, int type) zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC) { // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(val); + auto *entry = zend_get_class_entry(val TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); // retrieve the old object, which we are going to copy - MixedObject *old_object = (MixedObject *)zend_object_store_get_object(val); + MixedObject *old_object = (MixedObject *)zend_object_store_get_object(val TSRMLS_CC); // create a new base c++ object auto *cpp = meta->clone(old_object->cpp); @@ -553,7 +559,7 @@ zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC) // clone the members (this will also call the __clone() function if the user // had registered that as a visible method) - zend_objects_clone_members(&new_object->php, result, &old_object->php, Z_OBJ_HANDLE_P(val)); + zend_objects_clone_members(&new_object->php, result, &old_object->php, Z_OBJ_HANDLE_P(val) TSRMLS_CC); // was a custom clone method installed? If not we call the magic c++ __clone method if (!entry->clone) meta->callClone(cpp); @@ -575,7 +581,7 @@ zend_object_value ClassBase::cloneObject(zval *val TSRMLS_DC) int ClassBase::countElements(zval *object, long *count TSRMLS_DC) { // does it implement the countable interface? - Countable *countable = dynamic_cast(cpp_object(object)); + Countable *countable = dynamic_cast(cpp_object(object TSRMLS_CC)); // if it does not implement the Countable interface, we rely on the default implementation if (countable) @@ -592,7 +598,7 @@ int ClassBase::countElements(zval *object, long *count TSRMLS_DC) catch (Exception &exception) { // process the exception - exception.process(); + exception.process(TSRMLS_C); // unreachable return FAILURE; @@ -604,7 +610,7 @@ int ClassBase::countElements(zval *object, long *count TSRMLS_DC) if (!std_object_handlers.count_elements) return FAILURE; // call default - return std_object_handlers.count_elements(object, count); + return std_object_handlers.count_elements(object, count TSRMLS_CC); } } @@ -617,9 +623,10 @@ int ClassBase::countElements(zval *object, long *count TSRMLS_DC) * @param object The object on which it is called * @param offset The name of the property * @param type The type of the variable??? + * @param tsrm_ls * @return zval */ -zval *ClassBase::readDimension(zval *object, zval *offset, int type) +zval *ClassBase::readDimension(zval *object, zval *offset, int type TSRMLS_DC) { // what to do with the type? // @@ -640,7 +647,7 @@ zval *ClassBase::readDimension(zval *object, zval *offset, int type) // does it implement the arrayaccess interface? - ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object)); + ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object TSRMLS_CC)); // if it does not implement the ArrayAccess interface, we rely on the default implementation if (arrayaccess) @@ -654,7 +661,7 @@ zval *ClassBase::readDimension(zval *object, zval *offset, int type) catch (Exception &exception) { // process the exception (send it to user space) - exception.process(); + exception.process(TSRMLS_C); // unreachable return Value(nullptr).detach(); @@ -666,7 +673,7 @@ zval *ClassBase::readDimension(zval *object, zval *offset, int type) if (!std_object_handlers.read_dimension) return nullptr; // call default - return std_object_handlers.read_dimension(object, offset, type); + return std_object_handlers.read_dimension(object, offset, type TSRMLS_CC); } } @@ -679,12 +686,13 @@ zval *ClassBase::readDimension(zval *object, zval *offset, int type) * @param object The object on which it is called * @param offset The name of the property * @param value The new value + * @param tsrm_ls * @return zval */ -void ClassBase::writeDimension(zval *object, zval *offset, zval *value) +void ClassBase::writeDimension(zval *object, zval *offset, zval *value TSRMLS_DC) { // does it implement the arrayaccess interface? - ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object)); + ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object TSRMLS_CC)); // if it does not implement the ArrayAccess interface, we rely on the default implementation if (arrayaccess) @@ -698,7 +706,7 @@ void ClassBase::writeDimension(zval *object, zval *offset, zval *value) catch (Exception &exception) { // process the exception (send it to user space - exception.process(); + exception.process(TSRMLS_C); } } else @@ -707,7 +715,7 @@ void ClassBase::writeDimension(zval *object, zval *offset, zval *value) if (!std_object_handlers.write_dimension) return; // call the default - std_object_handlers.write_dimension(object, offset, value); + std_object_handlers.write_dimension(object, offset, value TSRMLS_CC); } } @@ -720,12 +728,13 @@ void ClassBase::writeDimension(zval *object, zval *offset, zval *value) * @param object The object on which it is called * @param member The member to check * @param check_empty Was this an isset() call, or an empty() call? + * @param tsrm_ls * @return bool */ -int ClassBase::hasDimension(zval *object, zval *member, int check_empty) +int ClassBase::hasDimension(zval *object, zval *member, int check_empty TSRMLS_DC) { // does it implement the arrayaccess interface? - ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object)); + ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object TSRMLS_CC)); // if it does not implement the ArrayAccess interface, we rely on the default implementation if (arrayaccess) @@ -746,7 +755,7 @@ int ClassBase::hasDimension(zval *object, zval *member, int check_empty) catch (Exception &exception) { // process the exception (send it to user space) - exception.process(); + exception.process(TSRMLS_C); // unreachable return false; @@ -758,7 +767,7 @@ int ClassBase::hasDimension(zval *object, zval *member, int check_empty) if (!std_object_handlers.has_dimension) return 0; // call default - return std_object_handlers.has_dimension(object, member, check_empty); + return std_object_handlers.has_dimension(object, member, check_empty TSRMLS_CC); } } @@ -770,11 +779,12 @@ int ClassBase::hasDimension(zval *object, zval *member, int check_empty) * * @param object The object on which it is called * @param member The member to remove + * @param tsrm_ls */ -void ClassBase::unsetDimension(zval *object, zval *member) +void ClassBase::unsetDimension(zval *object, zval *member TSRMLS_DC) { // does it implement the arrayaccess interface? - ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object)); + ArrayAccess *arrayaccess = dynamic_cast(cpp_object(object TSRMLS_CC)); // if it does not implement the ArrayAccess interface, we rely on the default implementation if (arrayaccess) @@ -788,7 +798,7 @@ void ClassBase::unsetDimension(zval *object, zval *member) catch (Exception &exception) { // process the exception (send it to user space) - exception.process(); + exception.process(TSRMLS_C); } } else @@ -797,7 +807,7 @@ void ClassBase::unsetDimension(zval *object, zval *member) if (!std_object_handlers.unset_dimension) return; // call the default - std_object_handlers.unset_dimension(object, member); + std_object_handlers.unset_dimension(object, member TSRMLS_CC); } } @@ -831,12 +841,13 @@ zval *ClassBase::toZval(Value &&value, int type) * @param name * @param type * @param key + * @param tsrm_ls * @return val */ #if PHP_VERSION_ID < 50399 -zval *ClassBase::readProperty(zval *object, zval *name, int type) +zval *ClassBase::readProperty(zval *object, zval *name, int type TSRMLS_DC) #else -zval *ClassBase::readProperty(zval *object, zval *name, int type, const struct _zend_literal *key) +zval *ClassBase::readProperty(zval *object, zval *name, int type, const struct _zend_literal *key TSRMLS_DC) #endif { // what to do with the type? @@ -857,10 +868,10 @@ zval *ClassBase::readProperty(zval *object, zval *name, int type, const struct _ // that is in most cases simply impossible. // retrieve the object and class - Base *base = cpp_object(object); + Base *base = cpp_object(object TSRMLS_CC); // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); @@ -894,16 +905,16 @@ zval *ClassBase::readProperty(zval *object, zval *name, int type, const struct _ // call default #if PHP_VERSION_ID < 50399 - return std_object_handlers.read_property(object, name, type); + return std_object_handlers.read_property(object, name, type TSRMLS_CC); #else - return std_object_handlers.read_property(object, name, type, key); + return std_object_handlers.read_property(object, name, type, key TSRMLS_CC); #endif } catch (Exception &exception) { // user threw an exception in its magic method // implementation, send it to user space - exception.process(); + exception.process(TSRMLS_C); // unreachable return Value(nullptr).detach(); @@ -920,19 +931,20 @@ zval *ClassBase::readProperty(zval *object, zval *name, int type, const struct _ * @param name The name of the property * @param value The new value * @param key ??? + * @param tsrm_ls * @return zval */ #if PHP_VERSION_ID < 50399 -void ClassBase::writeProperty(zval *object, zval *name, zval *value) +void ClassBase::writeProperty(zval *object, zval *name, zval *value TSRMLS_DC) #else -void ClassBase::writeProperty(zval *object, zval *name, zval *value, const struct _zend_literal *key) +void ClassBase::writeProperty(zval *object, zval *name, zval *value, const struct _zend_literal *key TSRMLS_DC) #endif { // retrieve the object and class - Base *base = cpp_object(object); + Base *base = cpp_object(object TSRMLS_CC); // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); @@ -969,16 +981,16 @@ void ClassBase::writeProperty(zval *object, zval *name, zval *value, const struc // call the default #if PHP_VERSION_ID < 50399 - std_object_handlers.write_property(object, name, value); + std_object_handlers.write_property(object, name, value TSRMLS_CC); #else - std_object_handlers.write_property(object, name, value, key); + std_object_handlers.write_property(object, name, value, key TSRMLS_CC); #endif } catch (Exception &exception) { // user threw an exception in its magic method // implementation, send it to user space - exception.process(); + exception.process(TSRMLS_C); } } @@ -999,12 +1011,13 @@ void ClassBase::writeProperty(zval *object, zval *name, zval *value, const struc * @param name The name of the property to check * @param has_set_exists See above * @param key ??? + * @param tsrm_ls * @return bool */ #if PHP_VERSION_ID < 50399 -int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists) +int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, void ***tsrm_ls) #else -int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, const struct _zend_literal *key) +int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, const struct _zend_literal *key, void ***tsrm_ls) #endif { // the default implementation throws an exception, if we catch that @@ -1012,10 +1025,10 @@ int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, const s try { // get the cpp object - Base *base = cpp_object(object); + Base *base = cpp_object(object TSRMLS_CC); // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); @@ -1048,16 +1061,16 @@ int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, const s // call default #if PHP_VERSION_ID < 50399 - return std_object_handlers.has_property(object, name, has_set_exists); + return std_object_handlers.has_property(object, name, has_set_exists TSRMLS_CC); #else - return std_object_handlers.has_property(object, name, has_set_exists, key); + return std_object_handlers.has_property(object, name, has_set_exists, key TSRMLS_CC); #endif } catch (Exception &exception) { // user threw an exception in its magic method // implementation, send it to user space - exception.process(); + exception.process(TSRMLS_C); // unreachable return false; @@ -1072,11 +1085,12 @@ int ClassBase::hasProperty(zval *object, zval *name, int has_set_exists, const s * @param object The object on which it is called * @param member The member to remove * @param key + * @param tsrm_ls */ #if PHP_VERSION_ID < 50399 -void ClassBase::unsetProperty(zval *object, zval *member) +void ClassBase::unsetProperty(zval *object, zval *member TSRMLS_DC) #else -void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_literal *key) +void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_literal *key TSRMLS_DC) #endif { // the default implementation throws an exception, if we catch that @@ -1084,7 +1098,7 @@ void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_lit try { // retrieve the class entry linked to this object - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // we need the C++ class meta-information object ClassBase *meta = cpp_class(entry); @@ -1096,7 +1110,7 @@ void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_lit auto iter = meta->_properties.find(name); // if the property does not exist, we forward to the __unset - if (iter == meta->_properties.end()) meta->callUnset(cpp_object(object), member); + if (iter == meta->_properties.end()) meta->callUnset(cpp_object(object TSRMLS_CC), member); // callback properties cannot be unset zend_error(E_ERROR, "Property %s can not be unset", (const char *)name); @@ -1108,24 +1122,27 @@ void ClassBase::unsetProperty(zval *object, zval *member, const struct _zend_lit // call the default #if PHP_VERSION_ID < 50399 - std_object_handlers.unset_property(object, member); + std_object_handlers.unset_property(object, member TSRMLS_CC); #else - std_object_handlers.unset_property(object, member, key); + std_object_handlers.unset_property(object, member, key TSRMLS_CC); #endif } catch (Exception &exception) { // user threw an exception in its magic method // implementation, send it to user space - exception.process(); + exception.process(TSRMLS_C); } } /** * Function that is called when an object is about to be destructed * This will call the magic __destruct method + * @param object + * @param handle + * @param tsrm_ls */ -void ClassBase::destructObject(zend_object *object, zend_object_handle handle) +void ClassBase::destructObject(zend_object *object, zend_object_handle handle TSRMLS_DC) { // allocate memory for the object MixedObject *obj = (MixedObject *)object; @@ -1142,21 +1159,22 @@ void ClassBase::destructObject(zend_object *object, zend_object_handle handle) catch (const NotImplemented &exception) { // fallback on the default destructor call - zend_objects_destroy_object(object, handle); + zend_objects_destroy_object(object, handle TSRMLS_CC); } catch (Exception &exception) { // a regular Php::Exception was thrown by the extension, pass it on // to PHP user space - exception.process(); + exception.process(TSRMLS_C); } } /** * Function that is called to clean up space that is occupied by the object * @param object The object to be deallocated + * @param tsrm_ls */ -void ClassBase::freeObject(zend_object *object) +void ClassBase::freeObject(zend_object *object TSRMLS_DC) { // allocate memory for the object MixedObject *obj = (MixedObject *)object; @@ -1165,13 +1183,14 @@ void ClassBase::freeObject(zend_object *object) if (obj->cpp) delete obj->cpp; // pass on to the default destructor - zend_objects_free_object_storage(object); + zend_objects_free_object_storage(object TSRMLS_CC); } /** * Function that is called when an instance of the class needs to be created. * This function will create the C++ class, and the PHP object * @param entry Pointer to the class information + * @param tsrm_ls * @return zend_object_value The newly created object */ zend_object_value ClassBase::createObject(zend_class_entry *entry TSRMLS_DC) @@ -1206,15 +1225,16 @@ zend_object_value ClassBase::createObject(zend_class_entry *entry TSRMLS_DC) * @param entry The class entry * @param object The object to iterate over * @param by_ref ????? + * @param tsrm_ls * @return zend_object_iterator* Pointer to the iterator */ -zend_object_iterator *ClassBase::getIterator(zend_class_entry *entry, zval *object, int by_ref) +zend_object_iterator *ClassBase::getIterator(zend_class_entry *entry, zval *object, int by_ref TSRMLS_DC) { // by-ref is not possible (copied from SPL) if (by_ref) throw Php::Exception("Foreach by ref is not possible"); // retrieve the traversable object - Traversable *traversable = dynamic_cast(cpp_object(object)); + Traversable *traversable = dynamic_cast(cpp_object(object TSRMLS_CC)); // user may throw an exception in the getIterator() function try @@ -1229,7 +1249,7 @@ zend_object_iterator *ClassBase::getIterator(zend_class_entry *entry, zval *obje { // user threw an exception in its method // implementation, send it to user space - exception.process(); + exception.process(TSRMLS_C); // unreachable return nullptr; @@ -1242,12 +1262,13 @@ zend_object_iterator *ClassBase::getIterator(zend_class_entry *entry, zval *obje * @param buffer Buffer in which to store the data * @param buf_len Size of the bufffer * @param data ?? + * @param tsrm_ls * @return int */ -int ClassBase::serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data) +int ClassBase::serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) { // get the serializable object - Serializable *serializable = dynamic_cast(cpp_object(object)); + Serializable *serializable = dynamic_cast(cpp_object(object TSRMLS_CC)); // call the serialize method on the object auto value = serializable->serialize(); @@ -1268,15 +1289,16 @@ int ClassBase::serialize(zval *object, unsigned char **buffer, zend_uint *buf_le * @param entry The class entry to which is belongs * @param buffer Buffer holding the unserialized data * @param data All the unserialize data + * @param tsrm_ls * @return int */ -int ClassBase::unserialize(zval **object, zend_class_entry *entry, const unsigned char *buffer, zend_uint buf_len, zend_unserialize_data *data) +int ClassBase::unserialize(zval **object, zend_class_entry *entry, const unsigned char *buffer, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) { // create the PHP object object_init_ex(*object, entry); // turn this into a serializale - Serializable *serializable = dynamic_cast(cpp_object(*object)); + Serializable *serializable = dynamic_cast(cpp_object(*object TSRMLS_CC)); // call the unserialize method on it serializable->unserialize((const char *)buffer, buf_len); @@ -1334,8 +1356,9 @@ const struct _zend_function_entry *ClassBase::entries() * class. * * @param prefix namespace prefix + * @param tsrm_ls */ -void ClassBase::initialize(const std::string &prefix) +void ClassBase::initialize(const std::string &prefix TSRMLS_DC) { // the class entry zend_class_entry entry; @@ -1394,7 +1417,7 @@ void ClassBase::initialize(const std::string &prefix) _entry->ce_flags = (int)_type; // declare all member variables - for (auto &member : _members) member->initialize(_entry); + for (auto &member : _members) member->initialize(_entry TSRMLS_CC); } /** diff --git a/src/exception.cpp b/src/exception.cpp index 83c1d12..d409e1a 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -18,11 +18,13 @@ namespace Php { * * This method is called only from withing the PHP-CPP library, * and will turn the exception into a PHP exception + * + * @param tsrm_ls */ -void Exception::process() +void Exception::process(TSRMLS_D) { // an exception originally thrown by C++ should be passed on to PHP - zend_throw_exception(zend_exception_get_default(), (char*)message().c_str(), 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), (char*)message().c_str(), 0 TSRMLS_CC); } /** diff --git a/src/extension.cpp b/src/extension.cpp index 4c6a46f..949efa9 100644 --- a/src/extension.cpp +++ b/src/extension.cpp @@ -79,16 +79,17 @@ static int match_module(_zend_module_entry *entry) /** * Find an extension based on the module number * @param number + * @param tsrm_ls * @return Extension* */ -static Extension *find(int number) +static Extension *find(int number TSRMLS_DC) { // do we already have an extension with this number? auto iter = number2extension.find(number); if (iter != number2extension.end()) return iter->second; // no, not yet, loop through all modules - zend_hash_apply(&module_registry, (apply_func_t)match_module); + zend_hash_apply(&module_registry, (apply_func_t)match_module TSRMLS_CC); // find again iter = number2extension.find(number); @@ -102,18 +103,19 @@ static Extension *find(int number) * Function that is called when the extension initializes * @param type Module type * @param number Module number + * @param tsrm_ls * @return int 0 on success */ -int Extension::onStartup(int type, int module_number) +int Extension::onStartup(int type, int module_number TSRMLS_DC) { // initialize and allocate the "global" variables ZEND_INIT_MODULE_GLOBALS(phpcpp, init_globals, NULL); // get the extension - Extension *extension = find(module_number); + Extension *extension = find(module_number TSRMLS_CC); // initialize namespace - extension->initialize(""); + extension->initialize("" TSRMLS_CC); // is the callback registered? if (extension->_onStartup) extension->_onStartup(); @@ -126,12 +128,13 @@ int Extension::onStartup(int type, int module_number) * Function that is called when the extension is about to be stopped * @param type Module type * @param number Module number + * @param tsrm_ls * @return int */ -int Extension::onShutdown(int type, int module_number) +int Extension::onShutdown(int type, int module_number TSRMLS_DC) { // get the extension - Extension *extension = find(module_number); + Extension *extension = find(module_number TSRMLS_CC); // is the callback registered? if (extension->_onShutdown) extension->_onShutdown(); @@ -144,12 +147,13 @@ int Extension::onShutdown(int type, int module_number) * Function that is called when a request starts * @param type Module type * @param number Module number + * @param tsrm_ls * @return int 0 on success */ -int Extension::onRequest(int type, int module_number) +int Extension::onRequest(int type, int module_number TSRMLS_DC) { // get the extension - Extension *extension = find(module_number); + Extension *extension = find(module_number TSRMLS_CC); // is the callback registered? if (extension->_onRequest) extension->_onRequest(); @@ -162,12 +166,13 @@ int Extension::onRequest(int type, int module_number) * Function that is called when a request is ended * @param type Module type * @param number Module number + * @param tsrm_ls * @return int 0 on success */ -int Extension::onIdle(int type, int module_number) +int Extension::onIdle(int type, int module_number TSRMLS_DC) { // get the extension - Extension *extension = find(module_number); + Extension *extension = find(module_number TSRMLS_CC); // is the callback registered? if (extension->_onIdle) extension->_onIdle(); @@ -210,7 +215,6 @@ Extension::Extension(const char *name, const char *version) : Namespace("") _entry->info_func = NULL; // information for retrieving info _entry->version = version; // version string _entry->globals_size = 0; // size of the global variables - _entry->globals_ptr = NULL; // pointer to the globals _entry->globals_ctor = NULL; // constructor for global variables _entry->globals_dtor = NULL; // destructor for global variables _entry->post_deactivate_func = NULL; // unknown function diff --git a/src/floatmember.h b/src/floatmember.h index 8136fc2..9b5d4f2 100644 --- a/src/floatmember.h +++ b/src/floatmember.h @@ -41,20 +41,22 @@ public: /** * Virtual method to declare class constant * @param entry Class entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) override + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override { - zend_declare_class_constant_double(entry, _name.c_str(), _name.size(), _value); + zend_declare_class_constant_double(entry, _name.c_str(), _name.size(), _value TSRMLS_CC); } /** * Virtual method to declare the property - * @param entry Class entry + * @param entry Class entry' + * @param tsrm_ls */ - virtual void declare(struct _zend_class_entry *entry) override + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override { // converstion to char* necessary for php 5.3 - zend_declare_property_double(entry, (char *)_name.c_str(), _name.size(), _value, _flags); + zend_declare_property_double(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC); } }; diff --git a/src/global.cpp b/src/global.cpp index af72bc0..7eea8e7 100644 --- a/src/global.cpp +++ b/src/global.cpp @@ -22,6 +22,9 @@ Global &Global::update() // skip if the variable already exists if (_exists) return *this; + // we need the TSRMLS variable + TSRMLS_FETCH(); + // add the variable to the globals zend_hash_add(EG(active_symbol_table), _name.c_str(), _name.size()+1, &_val, sizeof(zval*), NULL); diff --git a/src/globals.cpp b/src/globals.cpp index 6c7af86..8132ef3 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -39,6 +39,9 @@ Global Globals::operator[](const char *name) // pointer to a zval zval **varvalue; + // we need the TSRMLS variable + TSRMLS_FETCH(); + // check if the variable already exists if (zend_hash_find(&EG(symbol_table), name, strlen(name)+1, (void**)&varvalue) == FAILURE) { @@ -63,6 +66,9 @@ Global Globals::operator[](const std::string &name) { // pointer to a zval zval **varvalue; + + // we need the TSRMLS variable + TSRMLS_FETCH(); // check if the variable already exists if (zend_hash_find(&EG(symbol_table), name.c_str(), name.size()+1, (void**)&varvalue) == FAILURE) diff --git a/src/hashiterator.h b/src/hashiterator.h index 8573a03..d68ad4e 100644 --- a/src/hashiterator.h +++ b/src/hashiterator.h @@ -27,6 +27,7 @@ public: * Constructor * @param hashtable The hashtable to iterate over * @param first Should it start on the first position? + * @param tsrm_ls */ HashIterator(HashTable *hashtable, bool first) : _table(hashtable) { @@ -52,8 +53,9 @@ public: /** * Copy constructor * @param that + * @param tsrm_ls */ - HashIterator(const HashIterator &that) : + HashIterator(const HashIterator &that TSRMLS_DC) : _table(that._table), _position(that._position) { // read current position @@ -67,6 +69,7 @@ public: /** * Clone the object + * @param tsrm_ls * @return IteratorImpl */ virtual IteratorImpl *clone() diff --git a/src/includes.h b/src/includes.h index 97ede79..4bd0aaa 100644 --- a/src/includes.h +++ b/src/includes.h @@ -25,16 +25,18 @@ /** * @todo: if ZTS defined many errors appear. need debug. + * @todo this should come from some external source */ -//#define ZTS 1 +// #define ZTS 1 +// #define PTHREADS 1 /** * PHP includes */ #pragma GCC system_header #include -#include "zend_exceptions.h" -#include "zend_interfaces.h" +#include +#include /** * Macro to convert results to success status diff --git a/src/invaliditerator.h b/src/invaliditerator.h index 61815ff..7531d7d 100644 --- a/src/invaliditerator.h +++ b/src/invaliditerator.h @@ -21,6 +21,7 @@ class InvalidIterator : public IteratorImpl public: /** * Clone the object + * @param tsrm_ls * @return IteratorImpl */ virtual IteratorImpl *clone() @@ -31,6 +32,7 @@ public: /** * Increment position (pre-increment) + * @param tsrm_ls * @return bool */ virtual bool increment() override diff --git a/src/iterator.cpp b/src/iterator.cpp index a6c7e01..6242440 100644 --- a/src/iterator.cpp +++ b/src/iterator.cpp @@ -16,8 +16,9 @@ namespace Php { /** * Iterator destructor method * @param iter + * @param tsrm_ls */ -void Iterator::destructor(zend_object_iterator *iter) +void Iterator::destructor(zend_object_iterator *iter TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -33,9 +34,10 @@ void Iterator::destructor(zend_object_iterator *iter) * Iterator valid function * Returns FAILURE or SUCCESS * @param iter + * @param tsrm_ls * @return int */ -int Iterator::valid(zend_object_iterator *iter) +int Iterator::valid(zend_object_iterator *iter TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -48,8 +50,9 @@ int Iterator::valid(zend_object_iterator *iter) * Fetch the current item * @param iter * @param data + * @param tsrm_ls */ -void Iterator::current(zend_object_iterator *iter, zval ***data) +void Iterator::current(zend_object_iterator *iter, zval ***data TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -69,8 +72,9 @@ void Iterator::current(zend_object_iterator *iter, zval ***data) * used. * @param iter * @param key + * @param tsrm_ls */ -void Iterator::key(zend_object_iterator *iter, zval *key) +void Iterator::key(zend_object_iterator *iter, zval *key TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -91,9 +95,10 @@ void Iterator::key(zend_object_iterator *iter, zval *key) * @param str_key * @param str_key_len * @param int_key + * @param tsrm_ls * @return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG */ -int Iterator::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key) +int Iterator::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -124,8 +129,9 @@ int Iterator::key(zend_object_iterator *iter, char **str_key, uint *str_key_len, /** * Step forwards to the next element * @param iter + * @param tsrm_ls */ -void Iterator::next(zend_object_iterator *iter) +void Iterator::next(zend_object_iterator *iter TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; @@ -137,8 +143,9 @@ void Iterator::next(zend_object_iterator *iter) /** * Rewind the iterator back to the start * @param iter + * @param tsrm_ls */ -void Iterator::rewind(zend_object_iterator *iter) +void Iterator::rewind(zend_object_iterator *iter TSRMLS_DC) { // get the actual iterator Iterator *iterator = (Iterator *)iter->data; diff --git a/src/iteratorimpl.h b/src/iteratorimpl.h index a88282a..babf9f0 100644 --- a/src/iteratorimpl.h +++ b/src/iteratorimpl.h @@ -32,12 +32,14 @@ public: /** * Clone the object + * @param tsrm_ls * @return IteratorImpl* */ virtual IteratorImpl *clone() = 0; /** * Increment position (pre-increment) + * @param tsrm_ls * @return bool */ virtual bool increment() = 0; diff --git a/src/member.h b/src/member.h index b465399..7aa01d8 100644 --- a/src/member.h +++ b/src/member.h @@ -33,25 +33,28 @@ public: /** * Initialize the member * @param zend_class_entry + * @param tsrm_ls */ - void initialize(struct _zend_class_entry *entry) + void initialize(struct _zend_class_entry *entry TSRMLS_DC) { - if (_flags == Const) constant(entry); - else declare(entry); + if (_flags == Const) constant(entry TSRMLS_CC); + else declare(entry TSRMLS_CC); } protected: /** * Internal method to declare the property as constant * @param zend_class_entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) = 0; + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) = 0; /** * Internal method to declare the property * @param zend_class_entry + * @param tsrm_ls */ - virtual void declare(struct _zend_class_entry *entry) = 0; + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) = 0; protected: /** diff --git a/src/namespace.cpp b/src/namespace.cpp index 8dda791..fd5b37e 100644 --- a/src/namespace.cpp +++ b/src/namespace.cpp @@ -96,6 +96,24 @@ size_t Namespace::initialize(const std::string &parent, struct _zend_function_en return count; } +/** + * Initialize the namespace after it was registered + * @param parent Parent namespace + * @param tsrm_ls + */ +void Namespace::initialize(const std::string &parent TSRMLS_DC) +{ + // the namespace to use + std::string prefix = parent.size() ? parent + "\\" + _name : _name; + + // loop through the classes in this namespace + for (auto &c : _classes) c->initialize(prefix TSRMLS_CC); + + // and loop through the other namespaces + for (auto &n : _namespaces) n->initialize(prefix TSRMLS_CC); +} + + /** * End namespace */ diff --git a/src/nullmember.h b/src/nullmember.h index 943bf31..e035897 100644 --- a/src/nullmember.h +++ b/src/nullmember.h @@ -33,20 +33,22 @@ public: /** * Internal method to declare the property as constant * @param zend_class_entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) override + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override { - zend_declare_class_constant_null(entry, _name.c_str(), _name.size()); + zend_declare_class_constant_null(entry, _name.c_str(), _name.size() TSRMLS_CC); } /** * Virtual method to declare the property * @param entry Class entry + * @param tsrm_ls */ - virtual void declare(struct _zend_class_entry *entry) override + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override { // char* cast is necessary for php 5.3 - zend_declare_property_null(entry, (char *)_name.c_str(), _name.size(), _flags); + zend_declare_property_null(entry, (char *)_name.c_str(), _name.size(), _flags TSRMLS_CC); } }; diff --git a/src/numericmember.h b/src/numericmember.h index 99889c6..0a040d3 100644 --- a/src/numericmember.h +++ b/src/numericmember.h @@ -41,20 +41,22 @@ public: /** * Declare class constant * @param entry Class entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) override + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override { - zend_declare_class_constant_long(entry, _name.c_str(), _name.size(), _value); + zend_declare_class_constant_long(entry, _name.c_str(), _name.size(), _value TSRMLS_CC); } /** * Virtual method to declare the property * @param entry Class entry + * @param tsrm_ls */ - virtual void declare(struct _zend_class_entry *entry) override + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override { // char* cast is necessary for php 5.3 - zend_declare_property_long(entry, (char *)_name.c_str(), _name.size(), _value, _flags); + zend_declare_property_long(entry, (char *)_name.c_str(), _name.size(), _value, _flags TSRMLS_CC); } }; diff --git a/src/object.cpp b/src/object.cpp index f1bcdf8..a0777fe 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -27,10 +27,13 @@ Object::Object(const char *name, Base *base) } else { + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // this is a brand new object that should be allocated, the C++ instance // is already there (created by the extension) but it is not yet stored // in PHP, find out the classname first - auto *entry = zend_fetch_class(name, strlen(name), 0); + auto *entry = zend_fetch_class(name, strlen(name), 0 TSRMLS_CC); if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); // store the object in the php object cache (this will give the object a handle) @@ -47,8 +50,11 @@ Object::Object(const char *name, Base *base) */ void Object::instantiate(const char *name) { + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // convert the name into a class_entry - auto *entry = zend_fetch_class(name, strlen(name), 0); + auto *entry = zend_fetch_class(name, strlen(name), 0 TSRMLS_CC); if (!entry) throw Php::Exception(std::string("Unknown class name ") + name); // initiate the zval (which was already allocated in the base constructor) diff --git a/src/origexception.cpp b/src/origexception.cpp index e3634e4..f64d696 100644 --- a/src/origexception.cpp +++ b/src/origexception.cpp @@ -21,8 +21,11 @@ OrigException::~OrigException() noexcept // skip if the exception was restored if (_restored) return; + // we need the tsrm_ls var + TSRMLS_FETCH(); + // clean up the exception, because it was handled in C++ code - zend_clear_exception(); + zend_clear_exception(TSRMLS_C); } /** diff --git a/src/origexception.h b/src/origexception.h index c1b2871..5cbb0e1 100644 --- a/src/origexception.h +++ b/src/origexception.h @@ -62,9 +62,11 @@ public: * * This will restore the exception so that it can be further processed * in PHP code + * + * @param tsrm_ls * @internal */ - virtual void process() override + virtual void process(TSRMLS_D) override { // mark exception as restored _restored = true; diff --git a/src/parameters.cpp b/src/parameters.cpp index b923bd5..c4ed9c7 100644 --- a/src/parameters.cpp +++ b/src/parameters.cpp @@ -17,7 +17,7 @@ namespace Php { * @param argc Number of arguments * @param tsrm_ls */ -Parameters::Parameters(zval *this_ptr, int argc TSRMLS_DC) : _this(this_ptr) +Parameters::Parameters(zval *this_ptr, int argc TSRMLS_DC) { // reserve plenty of space reserve(argc); @@ -31,24 +31,15 @@ Parameters::Parameters(zval *this_ptr, int argc TSRMLS_DC) : _this(this_ptr) // append value push_back(Value(*arg)); } -} - -/** - * The the object that is called - * @return Base - */ -Base *Parameters::object() -{ - // do we have a this pointer in the first place? The member is not set - // when static methods are being called, or when a regular function is - // called in a static context - if (!_this) return nullptr; + // skip if there is no this_ptr + if (!this_ptr) return; + // get the mixed object - MixedObject *obj = (MixedObject *)zend_object_store_get_object(_this TSRMLS_CC); + MixedObject *obj = (MixedObject *)zend_object_store_get_object(this_ptr TSRMLS_CC); - // return the CPP object - return obj->cpp; + // store the CPP object + _object = obj->cpp; } /** diff --git a/src/stringmember.h b/src/stringmember.h index c80e0a1..e58cd3d 100644 --- a/src/stringmember.h +++ b/src/stringmember.h @@ -58,20 +58,21 @@ public: /** * Virtual method to declare class constant * @param entry Class entry + * @param tsrm_ls */ - virtual void constant(struct _zend_class_entry *entry) override + virtual void constant(struct _zend_class_entry *entry TSRMLS_DC) override { - zend_declare_class_constant_stringl(entry, _name.c_str(), _name.size(), _value.c_str(), _value.size()); + zend_declare_class_constant_stringl(entry, _name.c_str(), _name.size(), _value.c_str(), _value.size() TSRMLS_CC); } /** * Virtual method to declare the property * @param entry Class entry */ - virtual void declare(struct _zend_class_entry *entry) override + virtual void declare(struct _zend_class_entry *entry TSRMLS_DC) override { // cast to char* is necessary for php 5.3 - zend_declare_property_stringl(entry, (char *)_name.c_str(), _name.size(), (char *)_value.c_str(), _value.size(), _flags); + zend_declare_property_stringl(entry, (char *)_name.c_str(), _name.size(), (char *)_value.c_str(), _value.size(), _flags TSRMLS_CC); } }; diff --git a/src/super.cpp b/src/super.cpp index 6b02916..b344159 100644 --- a/src/super.cpp +++ b/src/super.cpp @@ -30,6 +30,9 @@ Super REQUEST (TRACK_VARS_REQUEST); */ Value Super::operator[](const std::string &key) const { + // we need the tsrm_ls pointer + TSRMLS_FETCH(); + // create a value object that wraps around the actual zval Value value(PG(http_globals)[_index]); @@ -45,6 +48,9 @@ Value Super::operator[](const std::string &key) const */ Value Super::operator[](const char *key) const { + // we need the tsrm_ls pointer + TSRMLS_FETCH(); + // create a value object that wraps around the actual zval Value value(PG(http_globals)[_index]); diff --git a/src/traverseiterator.h b/src/traverseiterator.h index 6f2fce1..0dee5a7 100644 --- a/src/traverseiterator.h +++ b/src/traverseiterator.h @@ -24,30 +24,32 @@ public: * Constructor * @param object * @param begin + * @param tsrm_ls */ - TraverseIterator(zval *object, bool begin) : _object(object) + TraverseIterator(zval *object, bool begin TSRMLS_DC) : _object(object) { // leap out if this iterator starts at the end if (!begin) return; // we need the class entry - auto *entry = zend_get_class_entry(object); + auto *entry = zend_get_class_entry(object TSRMLS_CC); // create the iterator - _iter = entry->get_iterator(entry, object, false); + _iter = entry->get_iterator(entry, object, false TSRMLS_CC); // rewind the iterator - _iter->funcs->rewind(_iter); + _iter->funcs->rewind(_iter TSRMLS_CC); // read the first key/value pair - read(); + read(TSRMLS_C); } /** * Copy constructor * @param that + * @param tsrm_ls */ - TraverseIterator(const TraverseIterator &that) : TraverseIterator(that._object, that._iter != nullptr) + TraverseIterator(const TraverseIterator &that TSRMLS_DC) : TraverseIterator(that._object, that._iter != nullptr TSRMLS_CC) { // @todo this is a broken implementation, the copy is at the start // position, while we'd like to be at the same position @@ -58,33 +60,48 @@ public: */ virtual ~TraverseIterator() { + // do nothing if iterator is already invalid + if (!_iter) return; + + // we need the tsrm pointer + TSRMLS_FETCH(); + // call the iterator destructor - if (_iter) _iter->funcs->dtor(_iter); + if (_iter) _iter->funcs->dtor(_iter TSRMLS_CC); } /** * Clone the object + * @param tsrm_ls * @return IteratorImpl* */ virtual IteratorImpl *clone() override { - return new TraverseIterator(*this); + // we need the tsrm_ls variable + TSRMLS_FETCH(); + + // construct iterator + return new TraverseIterator(*this TSRMLS_CC); } /** * Increment position (pre-increment) + * @param tsrm_ls * @return bool */ virtual bool increment() override { // do we still have an iterator? if (!_iter) return false; + + // we need the tsrm_ls variable + TSRMLS_FETCH(); // movw it forward - _iter->funcs->move_forward(_iter); + _iter->funcs->move_forward(_iter TSRMLS_CC); // and read current data - read(); + read(TSRMLS_C); } /** @@ -149,15 +166,16 @@ private: /** * Read current data + * @param tsrm_ls * @return bool */ - bool read() + bool read(TSRMLS_D) { // not possible when no iterator exists if (!_iter) return false; // is the iterator at a valid position? - if (_iter->funcs->valid(_iter) == FAILURE) return invalidate(); + if (_iter->funcs->valid(_iter TSRMLS_CC) == FAILURE) return invalidate(TSRMLS_C); #if PHP_VERSION_ID >= 50400 @@ -165,7 +183,7 @@ private: Value val; // call the function to get the key - _iter->funcs->get_current_key(_iter, val._val); + _iter->funcs->get_current_key(_iter, val._val TSRMLS_CC); // store the key _data.first = val; @@ -177,7 +195,7 @@ private: char *str_key; unsigned int str_key_len; unsigned long int_key; // php 5.3 code, fetch the current key - int type = _iter->funcs->get_current_key(_iter, &str_key, &str_key_len, &int_key); + int type = _iter->funcs->get_current_key(_iter, &str_key, &str_key_len, &int_key TSRMLS_CC); // what sort of key do we have? if (type == HASH_KEY_IS_LONG) @@ -204,7 +222,7 @@ private: zval **zval; // get the current value - _iter->funcs->get_current_data(_iter, &zval); + _iter->funcs->get_current_data(_iter, &zval TSRMLS_CC); // wrap the zval in a value object _data.second = Value(*zval); @@ -215,15 +233,16 @@ private: /** * Invalidate the object + * @param tsrm_ls * @return bool */ - bool invalidate() + bool invalidate(TSRMLS_D) { // skip if already invalid if (!_iter) return false; // reset the iterator - _iter->funcs->dtor(_iter); + _iter->funcs->dtor(_iter TSRMLS_CC); // set back to null _iter = nullptr; diff --git a/src/value.cpp b/src/value.cpp index 92704a3..9ea9c1a 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -187,6 +187,9 @@ Value::Value(Base *object) MAKE_STD_ZVAL(_val); Z_TYPE_P(_val) = IS_OBJECT; Z_OBJ_HANDLE_P(_val) = handle; + + // we need the tsrm_ls variable + TSRMLS_FETCH(); // we have to lookup the object in the object-table zend_object_store_bucket *obj_bucket = &EG(objects_store).object_buckets[handle]; @@ -412,6 +415,9 @@ Value &Value::operator=(Value &&value) } else { + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // the last and only reference to the other object was // removed, we no longer need it FREE_ZVAL(value._val); @@ -1232,11 +1238,14 @@ static Value do_exec(zval **object, zval *method, int argc, zval ***params) // the return zval zval *retval = nullptr; + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // the current exception zval *oldException = EG(exception); // call the function - if (call_user_function_ex(CG(function_table), object, method, &retval, argc, params, 1, NULL) != SUCCESS) + if (call_user_function_ex(CG(function_table), object, method, &retval, argc, params, 1, NULL TSRMLS_CC) != SUCCESS) { // throw an exception, the function does not exist throw Exception("Invalid call to "+Value(method).stringValue()); @@ -1331,8 +1340,11 @@ Value &Value::setType(Type type) */ bool Value::isCallable() const { + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // we can not rely on the type, because strings can be callable as well - return zend_is_callable(_val, 0, NULL); + return zend_is_callable(_val, 0, NULL TSRMLS_CC); } /** @@ -1501,8 +1513,11 @@ int Value::size() const // create a variable to hold the result long result; + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // call the function - return Z_OBJ_HT_P(_val)->count_elements(_val, &result) == SUCCESS ? result : 0; + return Z_OBJ_HT_P(_val)->count_elements(_val, &result TSRMLS_CC) == SUCCESS ? result : 0; } // not an array, return string size if this is a string @@ -1555,20 +1570,23 @@ ValueIterator Value::createIterator(bool begin) const // get access to the hast table if (isObject()) { + // we need the TSRMLS_CC variable + TSRMLS_FETCH(); + // is a special iterator method defined in the class entry? - auto *entry = zend_get_class_entry(_val); + auto *entry = zend_get_class_entry(_val TSRMLS_CC); // check if there is an iterator if (entry->get_iterator) { // the object implements Traversable interface, we have to use a // special iterator to user that interface too - return ValueIterator(new TraverseIterator(_val, begin)); + return ValueIterator(new TraverseIterator(_val, begin TSRMLS_CC)); } else { // construct a regular iterator - return ValueIterator(new HashIterator(Z_OBJ_HT_P(_val)->get_properties(_val), begin)); + return ValueIterator(new HashIterator(Z_OBJ_HT_P(_val)->get_properties(_val TSRMLS_CC), begin)); } } @@ -1635,11 +1653,14 @@ bool Value::contains(const char *key, int size) const } else if (isObject()) { + // we need the tsrmls_cc variable + TSRMLS_FETCH(); + // retrieve the class entry - auto *entry = zend_get_class_entry(_val); + auto *entry = zend_get_class_entry(_val TSRMLS_CC); // read the property (cast necessary for php 5.3) - zval *property = zend_read_property(entry, _val, (char *)key, size, 0); + zval *property = zend_read_property(entry, _val, (char *)key, size, 0 TSRMLS_CC); // check if valid return property != nullptr; @@ -1699,11 +1720,14 @@ Value Value::get(const char *key, int size) const } else { + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // retrieve the class entry - auto *entry = zend_get_class_entry(_val); + auto *entry = zend_get_class_entry(_val TSRMLS_CC); // read the property (case necessary for php 5.3) - zval *property = zend_read_property(entry, _val, (char *)key, size, 1); + zval *property = zend_read_property(entry, _val, (char *)key, size, 1 TSRMLS_CC); // wrap in value return Value(property); @@ -1773,11 +1797,14 @@ const Value &Value::setRaw(const char *key, int size, const Value &value) // if this is not a reference variable, we should detach it to implement copy on write SEPARATE_ZVAL_IF_NOT_REF(&_val); + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // retrieve the class entry - auto *entry = zend_get_class_entry(_val); + auto *entry = zend_get_class_entry(_val TSRMLS_CC); // update the property (cast necessary for php 5.3) - zend_update_property(entry, _val, (char *)key, size, value._val); + zend_update_property(entry, _val, (char *)key, size, value._val TSRMLS_CC); } else { @@ -1867,8 +1894,11 @@ Base *Value::implementation() const // must be an object if (!isObject()) return nullptr; + // we need the tsrm_ls variable + TSRMLS_FETCH(); + // retrieve the mixed object that contains the base - MixedObject *object = (MixedObject *)zend_object_store_get_object(_val); + MixedObject *object = (MixedObject *)zend_object_store_get_object(_val TSRMLS_CC); if (!object) return nullptr; // retrieve the associated C++ class diff --git a/src/valueiterator.cpp b/src/valueiterator.cpp index c43fbbb..65c687c 100644 --- a/src/valueiterator.cpp +++ b/src/valueiterator.cpp @@ -16,6 +16,7 @@ namespace Php { /** * Copy constructor * @param that + * @param tsrm_ls */ ValueIterator::ValueIterator(const ValueIterator &that) : _impl(that._impl->clone()) {} -- cgit v1.2.3