zend_object must be the last struct member
authorMichael Wallner <mike@php.net>
Wed, 17 Dec 2014 07:29:46 +0000 (08:29 +0100)
committerMichael Wallner <mike@php.net>
Wed, 17 Dec 2014 07:29:46 +0000 (08:29 +0100)
php_propro.c
php_propro.h

index 8d96e948118e19bfd7a222bdd7c37816130f6352..8c9e94512eea810188987dd10598cbe368ecea54 100644 (file)
@@ -156,9 +156,9 @@ static php_property_proxy_object_t *new_propro(zend_class_entry *ce,
                ce = php_property_proxy_class_entry;
        }
 
-       o = ecalloc(1, sizeof(*o) + sizeof(zval) * ce->default_properties_count);
-       zend_object_std_init((zend_object *) o, ce TSRMLS_CC);
-       object_properties_init((zend_object *) o, ce);
+       o = ecalloc(1, sizeof(*o) + sizeof(zval) * (ce->default_properties_count - 1));
+       zend_object_std_init(&o->zo, ce TSRMLS_CC);
+       object_properties_init(&o->zo, ce);
 
        o->proxy = proxy;
        o->zo.handlers = &php_property_proxy_object_handlers;
@@ -170,12 +170,12 @@ static php_property_proxy_object_t *new_propro(zend_class_entry *ce,
 
 static zend_object *create_obj(zend_class_entry *ce TSRMLS_DC)
 {
-       return (zend_object *) new_propro(ce, NULL TSRMLS_CC);
+       return &new_propro(ce, NULL TSRMLS_CC)->zo;
 }
 
 static void destroy_obj(zend_object *object TSRMLS_DC)
 {
-       php_property_proxy_object_t *o = (php_property_proxy_object_t *) object;
+       php_property_proxy_object_t *o = PHP_PROPRO_PTR(object);
 
        debug_propro(0, "dtor", o, NULL, NULL TSRMLS_CC);
 
@@ -197,7 +197,7 @@ static inline php_property_proxy_object_t *get_propro(zval *object)
 
        EMPTY_SWITCH_DEFAULT_CASE();
        }
-       return (php_property_proxy_object_t *) Z_OBJ_P(object);
+       return PHP_PROPRO_PTR(Z_OBJ_P(object));
 }
 
 static inline zend_bool got_value(zval *container, zval *value TSRMLS_DC)
@@ -393,7 +393,7 @@ static zval *read_dimension(zval *object, zval *offset, int type, zval *return_v
 
                proxy_obj = new_propro(NULL, proxy TSRMLS_CC);
                ZVAL_COPY(&proxy_obj->parent, object);
-               RETVAL_OBJ((zend_object *) proxy_obj);
+               RETVAL_OBJ(&proxy_obj->zo);
        }
 
        if (o && o != offset) {
@@ -558,10 +558,11 @@ static PHP_MINIT_FUNCTION(propro)
                        php_property_proxy_method_entry);
        php_property_proxy_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
        php_property_proxy_class_entry->create_object = create_obj;
-       php_property_proxy_class_entry->ce_flags |= ZEND_ACC_FINAL_CLASS;
+       php_property_proxy_class_entry->ce_flags |= ZEND_ACC_FINAL;
 
        memcpy(&php_property_proxy_object_handlers, zend_get_std_object_handlers(),
                        sizeof(zend_object_handlers));
+       php_property_proxy_object_handlers.offset = XtOffsetOf(php_property_proxy_object_t, zo);
        php_property_proxy_object_handlers.dtor_obj = destroy_obj;
        php_property_proxy_object_handlers.set = set_proxied_value;
        php_property_proxy_object_handlers.get = get_proxied_value;
index 9d845bfaed256ed522459b3f76de16da88036961..511f468e12af73ec5206502a7955cb5eb0a84af9 100644 (file)
@@ -32,7 +32,9 @@ extern zend_module_entry propro_module_entry;
 #      include <TSRM/TSRM.h>
 #endif
 
-#endif
+#define PHP_PROPRO_PTR(zo) (void*)(((char*)(zo))-(zo)->handlers->offset)
+
+#endif /* DOXYGEN */
 
 /**
  * The internal property proxy.
@@ -93,12 +95,12 @@ typedef struct php_property_proxy php_property_proxy_t;
  * ~~~~~~~~~~
  */
 struct php_property_proxy_object {
-       /** The std zend_object */
-       zend_object zo;
        /** The actual property proxy */
        php_property_proxy_t *proxy;
        /** Any parent property proxy object */
        zval parent;
+       /** The std zend_object */
+       zend_object zo;
 };
 typedef struct php_property_proxy_object php_property_proxy_object_t;