From 3b9b1cedb2975de1576023de13436376293c74dc Mon Sep 17 00:00:00 2001 From: "Nathanael d. Noblet" Date: Thu, 12 Sep 2019 09:59:21 -0600 Subject: [PATCH] Add support for php7.4 --- zend/classimpl.cpp | 32 ++++++++++++++++++++++++++------ zend/classimpl.h | 10 ++++++++-- zend/value.cpp | 5 ++++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/zend/classimpl.cpp b/zend/classimpl.cpp index 2228eb81..b134bc17 100644 --- a/zend/classimpl.cpp +++ b/zend/classimpl.cpp @@ -527,7 +527,7 @@ zend_object *ClassImpl::cloneObject(zval *val) // a copy constructor). Because this function is directly called from the // Zend engine, we can call zend_error() (which does a longjmp()) to throw // an exception back to the Zend engine) - if (!cpp) zend_error(E_ERROR, "Unable to clone %s", entry->name); + if (!cpp) zend_error(E_ERROR, "Unable to clone %s", entry->name->val); // store the object auto *new_object = new ObjectImpl(entry, cpp, impl->objectHandlers(), 1); @@ -915,7 +915,7 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, void **cache_s * @param cache_slot The cache slot used * @return zval */ -void ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cache_slot) +PHP_WRITE_PROP_HANDLER_TYPE ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cache_slot) { // retrieve the object and class Base *base = ObjectImpl::find(object)->object(); @@ -946,7 +946,13 @@ void ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cach else { // check if it could be set - if (iter->second->set(base, value)) return; + if (iter->second->set(base, value)) { +#if PHP_VERSION_ID >= 70400 + return value; +#else + return; +#endif + } // read-only property zend_error(E_ERROR, "Unable to write to read-only property %s", (const char *)key); @@ -955,16 +961,30 @@ void ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cach catch (const NotImplemented &exception) { // __set() function was not overridden by user, check if there is a default - if (!std_object_handlers.write_property) return; + if (!std_object_handlers.write_property) { +#if PHP_VERSION_ID >= 70400 + return value; +#else + return; +#endif + } // call the default std_object_handlers.write_property(object, name, value, cache_slot); +#if PHP_VERSION_ID >= 70400 + return value; +#else + return; +#endif } catch (Throwable &throwable) { // object was not caught by the extension, let it end up in user space throwable.rethrow(); } +#if PHP_VERSION_ID >= 70400 + return value; +#endif } /** @@ -1150,7 +1170,7 @@ zend_object *ClassImpl::createObject(zend_class_entry *entry) // report error on failure, because this function is called directly from the // Zend engine, we can call zend_error() here (which does a longjmp() back to // the Zend engine) - if (!cpp) zend_error(E_ERROR, "Unable to instantiate %s", entry->name); + if (!cpp) zend_error(E_ERROR, "Unable to instantiate %s", entry->name->val); // create the object in the zend engine auto *object = new ObjectImpl(entry, cpp, impl->objectHandlers(), 1); @@ -1428,7 +1448,7 @@ zend_class_entry *ClassImpl::initialize(ClassBase *base, const std::string &pref _entry->info.user.doc_comment = _self; // set access types flags for class - _entry->ce_flags = (int)_type; + _entry->ce_flags |= (int)_type; // declare all member variables for (auto &member : _members) member->initialize(_entry); diff --git a/zend/classimpl.h b/zend/classimpl.h index e9c4ef89..225c3ad7 100644 --- a/zend/classimpl.h +++ b/zend/classimpl.h @@ -13,6 +13,12 @@ */ namespace Php { +#if PHP_VERSION_ID >= 70400 +# define PHP_WRITE_PROP_HANDLER_TYPE zval * +#else +# define PHP_WRITE_PROP_HANDLER_TYPE void +#endif + /** * Class definition */ @@ -257,9 +263,9 @@ class ClassImpl * @param name The name of the property * @param value The new value * @param cache_slot The cache slot used - * @return zval + * @return zval* */ - static void writeProperty(zval *object, zval *name, zval *value, void **cache_slot); + static PHP_WRITE_PROP_HANDLER_TYPE writeProperty(zval *object, zval *name, zval *value, void **cache_slot); /** * Function that is called to check whether a certain property is set diff --git a/zend/value.cpp b/zend/value.cpp index 5f43dcc1..6ded9556 100644 --- a/zend/value.cpp +++ b/zend/value.cpp @@ -1499,9 +1499,12 @@ bool Value::contains(const char *key, int size) const } else if (isObject()) { +#if PHP_VERSION_ID >= 70400 // retrieve the object pointer and check whether the property we are trying to retrieve + if (zend_check_property_access(Z_OBJ_P(_val), String(key, size), 0) == FAILURE) return false; +#else if (zend_check_property_access(Z_OBJ_P(_val), String(key, size)) == FAILURE) return false; - +#endif // check if the 'has_property' method is available for this object auto *has_property = Z_OBJ_HT_P(_val)->has_property;