summaryrefslogtreecommitdiff
path: root/zend/classimpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zend/classimpl.cpp')
-rw-r--r--zend/classimpl.cpp185
1 files changed, 44 insertions, 141 deletions
diff --git a/zend/classimpl.cpp b/zend/classimpl.cpp
index 5c339e9..84e23ef 100644
--- a/zend/classimpl.cpp
+++ b/zend/classimpl.cpp
@@ -21,10 +21,8 @@ ClassImpl::~ClassImpl()
// destruct the entries
if (_entries) delete[] _entries;
-#if PHP_VERSION_ID >= 50400
- // on newer php versions, we have allocated the command to hide a pointer in it
- if (_self) free(_self);
-#endif
+ // free the stored pointer
+ free(_self);
}
/**
@@ -38,8 +36,6 @@ ClassImpl::~ClassImpl()
*/
static ClassImpl *self(zend_class_entry *entry)
{
-#if PHP_VERSION_ID >= 50400
-
/**
* somebody could have extended this class from PHP userland, in which
* case trying to dereference the doc_comment would result in a disaster
@@ -70,25 +66,6 @@ static ClassImpl *self(zend_class_entry *entry)
// the first byte of the comment is an empty string (null character), but
// the next bytes contain a pointer to the ClassBase class
return *((ClassImpl **)(comment + 1));
-#else
-
- /**
- * This is likely not correct: If the class was extended using PHP-CPP
- * itself, we should retrieve the ClassImpl directly, however there is
- * no sane way to check this here, unlike in PHP 5.4.
- *
- * We therefore always go to the very base, of which we are sure that
- * we are the implementers. This way - at least - we don't cause any
- * segfaults.
- */
- while (entry->parent) entry = entry->parent;
-
- // on php 5.3 we store the pointer to impl after the name in the entry
- ClassImpl** impl = (ClassImpl**)(entry->name + 1 + entry->name_length);
-
- // return the actual implementation
- return *impl;
-#endif
}
/**
@@ -203,17 +180,14 @@ void ClassImpl::callInvoke(INTERNAL_FUNCTION_PARAMETERS)
/**
* Method that returns the function definition of the __call function
- * @param object_ptr
- * @param method_name
- * @param method_len
+ *
+ * @param object_ptr Pointer to the object from which we want to retrieve the member function
+ * @param method The method that we want information about
+ * @param key ???
* @param tsrm_ls
* @return zend_function
*/
-#if PHP_VERSION_ID < 50399
-zend_function *ClassImpl::getMethod(zval **object_ptr, char *method_name, int method_len TSRMLS_DC)
-#else
-zend_function *ClassImpl::getMethod(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC)
-#endif
+zend_function *ClassImpl::getMethod(zval **object_ptr, zend_string *method, const zval *key TSRMLS_DC)
{
// something strange about the Zend engine (once more). The structure with
// object-handlers has a get_method and call_method member. When a function is
@@ -224,11 +198,7 @@ zend_function *ClassImpl::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 TSRMLS_CC);
-#else
- auto *defaultFunction = std_object_handlers.get_method(object_ptr, method_name, method_len, key TSRMLS_CC);
-#endif
+ auto *defaultFunction = std_object_handlers.get_method(object_ptr, method, key TSRMLS_CC);
// did the default implementation do anything?
if (defaultFunction) return defaultFunction;
@@ -254,7 +224,7 @@ zend_function *ClassImpl::getMethod(zval **object_ptr, char *method_name, int me
function->required_num_args = 0;
function->scope = entry;
function->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
- function->function_name = method_name;
+ function->function_name = method;
// store pointer to ourselves
data->self = self(entry);
@@ -266,21 +236,18 @@ zend_function *ClassImpl::getMethod(zval **object_ptr, char *method_name, int me
/**
* Method that is called right before a static method call is attempted
- * @param entry
- * @param method
- * @param method_len
+ *
+ * @param entry The class entry to find the static function in
+ * @param method The method to get information about
+ * @param key ???
* @param tsrm_ls
* @return zend_function
*/
-zend_function *ClassImpl::getStaticMethod(zend_class_entry *entry, char* method, int method_len TSRMLS_DC)
+zend_function *ClassImpl::getStaticMethod(zend_class_entry *entry, zend_string *method, const zval *key 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 TSRMLS_CC);
-#else
- auto *defaultFunction = zend_std_get_static_method(entry, method, method_len, nullptr TSRMLS_CC);
-#endif
+ auto *defaultFunction = zend_std_get_static_method(entry, method, key TSRMLS_CC);
// did the default implementation do anything?
if (defaultFunction) return defaultFunction;
@@ -542,7 +509,7 @@ int ClassImpl::cast(zval *val, zval *retval, int type TSRMLS_DC)
* @param val The object to be cloned
* @return zend_obejct_value The object to be created
*/
-zend_object_value ClassImpl::cloneObject(zval *val TSRMLS_DC)
+zend_object ClassImpl::cloneObject(zval *val TSRMLS_DC)
{
// retrieve the class entry linked to this object
auto *entry = zend_get_class_entry(val TSRMLS_CC);
@@ -564,17 +531,8 @@ zend_object_value ClassImpl::cloneObject(zval *val TSRMLS_DC)
// an exception back to the Zend engine)
if (!cpp) zend_error(E_ERROR, "Unable to clone %s", entry->name);
- // the thing we're going to return
- zend_object_value result;
-
- // set the handlers
- result.handlers = impl->objectHandlers();
-
// store the object
- ObjectImpl *new_object = new ObjectImpl(entry, cpp, 1 TSRMLS_CC);
-
- // store the object in the object cache
- result.handle = new_object->handle();
+ auto *new_object = new ObjectImpl(entry, cpp, impl->objectHandlers, 1 TSRMLS_CC);
// clone the members (this will also call the __clone() function if the user
// had registered that as a visible method)
@@ -584,7 +542,7 @@ zend_object_value ClassImpl::cloneObject(zval *val TSRMLS_DC)
if (!entry->clone) meta->callClone(cpp);
// done
- return result;
+ return new_object->object();
}
/**
@@ -856,18 +814,16 @@ zval *ClassImpl::toZval(Value &&value, int type)
/**
* Function that is called when a property is read
- * @param object
- * @param name
- * @param type
- * @param key
+ *
+ * @param object The object on which it is called
+ * @param offset The name of the property
+ * @param type The type of the variable???
+ * @param cache_slot The cache slot used
+ * @param rv The "return value" (for errors
* @param tsrm_ls
* @return val
*/
-#if PHP_VERSION_ID < 50399
-zval *ClassImpl::readProperty(zval *object, zval *name, int type TSRMLS_DC)
-#else
-zval *ClassImpl::readProperty(zval *object, zval *name, int type, const zend_literal *key TSRMLS_DC)
-#endif
+zval *ClassImpl::readProperty(zval *object, zval *name, int type, void **cache_slot, zval *rv TSRMLS_DC)
{
// what to do with the type?
//
@@ -924,11 +880,7 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, const zend_lit
if (!std_object_handlers.read_property) return nullptr;
// call default
-#if PHP_VERSION_ID < 50399
- return std_object_handlers.read_property(object, name, type TSRMLS_CC);
-#else
return std_object_handlers.read_property(object, name, type, key TSRMLS_CC);
-#endif
}
catch (Exception &exception)
{
@@ -950,15 +902,11 @@ zval *ClassImpl::readProperty(zval *object, zval *name, int type, const zend_lit
* @param object The object on which it is called
* @param name The name of the property
* @param value The new value
- * @param key ???
+ * @param cache_slot The cache slot used
* @param tsrm_ls
* @return zval
*/
-#if PHP_VERSION_ID < 50399
-void ClassImpl::writeProperty(zval *object, zval *name, zval *value TSRMLS_DC)
-#else
-void ClassImpl::writeProperty(zval *object, zval *name, zval *value, const zend_literal *key TSRMLS_DC)
-#endif
+void ClassImpl::writeProperty(zval *object, zval *name, zval *value, void **cache_slot TSRMLS_DC)
{
// retrieve the object and class
Base *base = ObjectImpl::find(object TSRMLS_CC)->object();
@@ -1001,11 +949,7 @@ void ClassImpl::writeProperty(zval *object, zval *name, zval *value, const zend_
if (!std_object_handlers.write_property) return;
// call the default
-#if PHP_VERSION_ID < 50399
- std_object_handlers.write_property(object, name, value TSRMLS_CC);
-#else
std_object_handlers.write_property(object, name, value, key TSRMLS_CC);
-#endif
}
catch (Exception &exception)
{
@@ -1031,15 +975,11 @@ void ClassImpl::writeProperty(zval *object, zval *name, zval *value, const zend_
* @param object The object on which it is called
* @param name The name of the property to check
* @param has_set_exists See above
- * @param key ???
+ * @param cache_slot The cache slot used
* @param tsrm_ls
* @return bool
*/
-#if PHP_VERSION_ID < 50399
-int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists TSRMLS_DC)
-#else
-int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, const zend_literal *key TSRMLS_DC)
-#endif
+int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, void **cache_slot TSRMLS_DC)
{
// the default implementation throws an exception, if we catch that
// we know for sure that the user has not overridden the __isset method
@@ -1082,11 +1022,7 @@ int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, const z
if (!std_object_handlers.has_property) return 0;
// call default
-#if PHP_VERSION_ID < 50399
- 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 TSRMLS_CC);
-#endif
}
catch (Exception &exception)
{
@@ -1106,14 +1042,10 @@ int ClassImpl::hasProperty(zval *object, zval *name, int has_set_exists, const z
*
* @param object The object on which it is called
* @param member The member to remove
- * @param key
+ * @param cache_slot The cache slot used
* @param tsrm_ls
*/
-#if PHP_VERSION_ID < 50399
-void ClassImpl::unsetProperty(zval *object, zval *member TSRMLS_DC)
-#else
-void ClassImpl::unsetProperty(zval *object, zval *member, const zend_literal *key TSRMLS_DC)
-#endif
+void ClassImpl::unsetProperty(zval *object, zval *member, void **cache_slot TSRMLS_DC)
{
// the default implementation throws an exception, if we catch that
// we know for sure that the user has not overridden the __unset method
@@ -1143,11 +1075,7 @@ void ClassImpl::unsetProperty(zval *object, zval *member, const zend_literal *ke
if (!std_object_handlers.unset_property) return;
// call the default
-#if PHP_VERSION_ID < 50399
- std_object_handlers.unset_property(object, member TSRMLS_CC);
-#else
std_object_handlers.unset_property(object, member, key TSRMLS_CC);
-#endif
}
catch (Exception &exception)
{
@@ -1164,7 +1092,7 @@ void ClassImpl::unsetProperty(zval *object, zval *member, const zend_literal *ke
* @param handle
* @param tsrm_ls
*/
-void ClassImpl::destructObject(zend_object *object, zend_object_handle handle TSRMLS_DC)
+void ClassImpl::destructObject(zend_object *object TSRMLS_DC)
{
// find object
ObjectImpl *obj = ObjectImpl::find(object);
@@ -1212,7 +1140,7 @@ void ClassImpl::freeObject(zend_object *object TSRMLS_DC)
* @param tsrm_ls
* @return zend_object_value The newly created object
*/
-zend_object_value ClassImpl::createObject(zend_class_entry *entry TSRMLS_DC)
+zend_object ClassImpl::createObject(zend_class_entry *entry TSRMLS_DC)
{
// we need the C++ class meta-information object
ClassImpl *impl = self(entry);
@@ -1225,20 +1153,11 @@ zend_object_value ClassImpl::createObject(zend_class_entry *entry TSRMLS_DC)
// the Zend engine)
if (!cpp) zend_error(E_ERROR, "Unable to instantiate %s", entry->name);
- // the thing we're going to return
- zend_object_value result;
-
- // set the handlers
- result.handlers = impl->objectHandlers();
-
// create the object in the zend engine
- ObjectImpl *object = new ObjectImpl(entry, cpp, 1 TSRMLS_CC);
+ auto *object = new ObjectImpl(entry, cpp, impl->objectHandlers(), 1 TSRMLS_CC);
- // store the object in the object cache
- result.handle = object->handle();
-
- // done
- return result;
+ // return the php object stored in the implementation
+ return object->object();
}
/**
@@ -1427,6 +1346,14 @@ zend_class_entry *ClassImpl::initialize(ClassBase *base, const std::string &pref
// we need a special constructor
entry.create_object = &ClassImpl::createObject;
+ // register destructor and deallocator
+ entry.dtor_obj = &ClassImpl::destructObject;
+ entry.free_obj = &ClassImpl::freeObject;
+
+ // set the offset for the zend_object, to allow PHP to
+ // locate the original point of the allocated memory
+ entry.offset = ObjectImpl::offset();
+
// register function that is called for static method calls
entry.get_static_method = &ClassImpl::getStaticMethod;
@@ -1478,30 +1405,6 @@ zend_class_entry *ClassImpl::initialize(ClassBase *base, const std::string &pref
// this pointer has to be copied to temporary pointer, as &this causes compiler error
ClassImpl *impl = this;
-#if PHP_VERSION_ID >= 50400
-
- // allocate doc comment to contain an empty string + a hidden pointer
- _self = (char *)malloc(1 + sizeof(ClassImpl *));
-
- // empty string on first position
- _self[0] = '\0';
-
- // copy the 'this' pointer to the doc-comment
- memcpy(_self+1, &impl, sizeof(ClassImpl *));
-
- // set our comment in the actual class entry
- _entry->info.user.doc_comment = _self;
-
-#else
-
- // Reallocate some extra space in the name in the zend_class_entry so we can fit a pointer behind it
- _entry->name = (char *) realloc(_entry->name, _entry->name_length + 1 + sizeof(ClassImpl *));
-
- // Copy the pointer after it
- memcpy(_entry->name + _entry->name_length + 1, &impl, sizeof(ClassImpl *));
-
-#endif
-
// set access types flags for class
_entry->ce_flags = (int)_type;