summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--0001-review-object-management.patch1106
-rw-r--r--php-pecl-ds.spec5
2 files changed, 1111 insertions, 0 deletions
diff --git a/0001-review-object-management.patch b/0001-review-object-management.patch
new file mode 100644
index 0000000..89a6d34
--- /dev/null
+++ b/0001-review-object-management.patch
@@ -0,0 +1,1106 @@
+From 0a224885ca775ee1af7f9c8ff0e89bb8061966e1 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Thu, 15 Oct 2020 15:34:23 +0200
+Subject: [PATCH] review object management
+
+---
+ src/php/handlers/php_common_handlers.c | 4 +++-
+ src/php/handlers/php_deque_handlers.c | 23 ++++++++++---------
+ src/php/handlers/php_map_handlers.c | 22 +++++++++---------
+ .../handlers/php_priority_queue_handlers.c | 12 +++++-----
+ src/php/handlers/php_queue_handlers.c | 14 +++++------
+ src/php/handlers/php_set_handlers.c | 18 +++++++--------
+ src/php/handlers/php_stack_handlers.c | 17 ++++++++------
+ src/php/handlers/php_vector_handlers.c | 20 ++++++++--------
+ src/php/iterators/php_queue_iterator.c | 19 +++++++--------
+ src/php/iterators/php_queue_iterator.h | 3 ++-
+ src/php/iterators/php_stack_iterator.c | 19 +++++++--------
+ src/php/iterators/php_stack_iterator.h | 3 ++-
+ src/php/objects/php_deque.c | 6 ++++-
+ src/php/objects/php_deque.h | 19 +++++++--------
+ src/php/objects/php_map.c | 6 ++++-
+ src/php/objects/php_map.h | 16 ++++++++-----
+ src/php/objects/php_pair.c | 8 +++++--
+ src/php/objects/php_priority_queue.c | 6 ++++-
+ src/php/objects/php_priority_queue.h | 21 +++++++++--------
+ src/php/objects/php_queue.c | 6 ++++-
+ src/php/objects/php_queue.h | 16 ++++++++-----
+ src/php/objects/php_set.c | 6 ++++-
+ src/php/objects/php_set.h | 16 ++++++++-----
+ src/php/objects/php_stack.c | 6 ++++-
+ src/php/objects/php_stack.h | 16 ++++++++-----
+ src/php/objects/php_vector.c | 6 ++++-
+ src/php/objects/php_vector.h | 16 ++++++++-----
+ 27 files changed, 205 insertions(+), 139 deletions(-)
+
+diff --git a/src/php/handlers/php_common_handlers.c b/src/php/handlers/php_common_handlers.c
+index 7d84dfb..e2441b2 100644
+--- a/src/php/handlers/php_common_handlers.c
++++ b/src/php/handlers/php_common_handlers.c
+@@ -38,6 +38,7 @@ zval *php_ds_read_dimension_by_key_not_supported
+ (zval *obj, zval *offset, int type, zval *rv) {
+ #endif
+ ARRAY_ACCESS_BY_KEY_NOT_SUPPORTED();
++ return NULL;
+ }
+
+ int php_ds_has_dimension_by_key_not_supported
+@@ -47,6 +48,7 @@ int php_ds_has_dimension_by_key_not_supported
+ (zval *obj, zval *offset, int check_empty) {
+ #endif
+ ARRAY_ACCESS_BY_KEY_NOT_SUPPORTED();
++ return 0;
+ }
+
+ void php_ds_unset_dimension_by_key_not_supported
+@@ -56,4 +58,4 @@ void php_ds_unset_dimension_by_key_not_supported
+ (zval *obj, zval *offset) {
+ #endif
+ ARRAY_ACCESS_BY_KEY_NOT_SUPPORTED();
+-}
+\ No newline at end of file
++}
+diff --git a/src/php/handlers/php_deque_handlers.c b/src/php/handlers/php_deque_handlers.c
+index 0bfe187..07ba92c 100644
+--- a/src/php/handlers/php_deque_handlers.c
++++ b/src/php/handlers/php_deque_handlers.c
+@@ -9,7 +9,7 @@ zend_object_handlers php_deque_handlers;
+ static zval *php_ds_deque_read_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int type, zval *return_value) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, zval *offset, int type, zval *return_value) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+@@ -47,7 +47,7 @@ static zval *php_ds_deque_read_dimension
+ static void php_ds_deque_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+@@ -69,7 +69,7 @@ static void php_ds_deque_write_dimension
+ static int php_ds_deque_has_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int check_empty) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, zval *offset, int check_empty) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+@@ -86,7 +86,7 @@ static int php_ds_deque_has_dimension
+ static void php_ds_deque_unset_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, zval *offset) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+@@ -111,24 +111,25 @@ static void php_ds_deque_unset_dimension
+ static int php_ds_deque_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- *count = ((php_ds_deque_t*)obj)->deque->size; return SUCCESS;
++ *count = php_ds_deque_fetch_object(obj)->deque->size;
+ #else
+ (zval *obj, zend_long *count) {
+- *count = Z_DS_DEQUE_P(obj)->size; return SUCCESS;
++ *count = Z_DS_DEQUE_P(obj)->size;
+ #endif
++ return SUCCESS;
+ }
+
+ static void php_ds_deque_free_object(zend_object *object)
+ {
+- php_ds_deque_t *obj = (php_ds_deque_t*) object;
+- zend_object_std_dtor(&obj->std);
++ php_ds_deque_t *obj = php_ds_deque_fetch_object(object);
+ ds_deque_free(obj->deque);
++ zend_object_std_dtor(&obj->std);
+ }
+
+ static HashTable *php_ds_deque_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+@@ -142,7 +143,7 @@ static HashTable *php_ds_deque_get_debug_info
+ static zend_object *php_ds_deque_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- return php_ds_deque_create_clone(((php_ds_deque_t*)obj)->deque);
++ return php_ds_deque_create_clone(php_ds_deque_fetch_object(obj)->deque);
+ #else
+ (zval *obj) {
+ return php_ds_deque_create_clone(Z_DS_DEQUE_P(obj));
+@@ -152,7 +153,7 @@ static zend_object *php_ds_deque_clone_obj
+ static HashTable *php_ds_deque_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_count) {
+- ds_deque_t *deque = ((php_ds_deque_t*)obj)->deque;
++ ds_deque_t *deque = php_ds_deque_fetch_object(obj)->deque;
+ #else
+ (zval *obj, zval **gc_data, int *gc_count) {
+ ds_deque_t *deque = Z_DS_DEQUE_P(obj);
+diff --git a/src/php/handlers/php_map_handlers.c b/src/php/handlers/php_map_handlers.c
+index 852842e..0b46c5a 100644
+--- a/src/php/handlers/php_map_handlers.c
++++ b/src/php/handlers/php_map_handlers.c
+@@ -8,7 +8,7 @@ zend_object_handlers php_map_handlers;
+ static zval *php_ds_map_read_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int type, zval *rv) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zval *offset, int type, zval *rv) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -46,7 +46,7 @@ static zval *php_ds_map_read_dimension
+ static void php_ds_map_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -62,7 +62,7 @@ static void php_ds_map_write_dimension
+ static int php_ds_map_has_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int check_empty) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zval *offset, int check_empty) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -74,7 +74,7 @@ static int php_ds_map_has_dimension
+ static void php_ds_map_unset_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zval *offset) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -86,7 +86,7 @@ static void php_ds_map_unset_dimension
+ static int php_ds_map_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zend_long *count) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -97,15 +97,15 @@ static int php_ds_map_count_elements
+
+ static void php_ds_map_free_object(zend_object *object)
+ {
+- php_ds_map_t *intern = (php_ds_map_t*) object;
+- zend_object_std_dtor(&intern->std);
++ php_ds_map_t *intern = php_ds_map_fetch_object(object);
+ ds_map_free(intern->map);
++ zend_object_std_dtor(&intern->std);
+ }
+
+ static HashTable *php_ds_map_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -117,7 +117,7 @@ static HashTable *php_ds_map_get_debug_info
+ static zend_object *php_ds_map_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -128,7 +128,7 @@ static zend_object *php_ds_map_clone_obj
+ static HashTable *php_ds_map_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_size) {
+- ds_map_t *map = ((php_ds_map_t*)obj)->map;
++ ds_map_t *map = php_ds_map_fetch_object(obj)->map;
+ #else
+ (zval *obj, zval **gc_data, int *gc_size) {
+ ds_map_t *map = Z_DS_MAP_P(obj);
+@@ -147,7 +147,7 @@ void php_ds_register_map_handlers()
+ {
+ memcpy(&php_map_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+
+- php_map_handlers.offset = 0;
++ php_map_handlers.offset = XtOffsetOf(php_ds_map_t, std);
+ php_map_handlers.dtor_obj = zend_objects_destroy_object;
+ php_map_handlers.get_gc = php_ds_map_get_gc;
+ php_map_handlers.free_obj = php_ds_map_free_object;
+diff --git a/src/php/handlers/php_priority_queue_handlers.c b/src/php/handlers/php_priority_queue_handlers.c
+index 99cf7e6..cae059e 100644
+--- a/src/php/handlers/php_priority_queue_handlers.c
++++ b/src/php/handlers/php_priority_queue_handlers.c
+@@ -8,19 +8,19 @@ zend_object_handlers php_priority_queue_handlers;
+
+ static void php_ds_priority_queue_free_object(zend_object *object)
+ {
+- php_ds_priority_queue_t *queue = (php_ds_priority_queue_t*) object;
+- zend_object_std_dtor(&queue->std);
++ php_ds_priority_queue_t *queue = php_ds_priority_queue_fetch_object(object);
+ ds_priority_queue_free(queue->queue);
+
+ if (queue->gc_data != NULL) {
+ efree(queue->gc_data);
+ }
++ zend_object_std_dtor(&queue->std);
+ }
+
+ static int php_ds_priority_queue_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- ds_priority_queue_t *pq = ((php_ds_priority_queue_t *) obj)->queue;
++ ds_priority_queue_t *pq = php_ds_priority_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, zend_long *count) {
+ ds_priority_queue_t *pq = Z_DS_PRIORITY_QUEUE_P(obj);
+@@ -32,7 +32,7 @@ static int php_ds_priority_queue_count_elements
+ static zend_object *php_ds_priority_queue_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- ds_priority_queue_t *pq = ((php_ds_priority_queue_t *) obj)->queue;
++ ds_priority_queue_t *pq = php_ds_priority_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj) {
+ ds_priority_queue_t *pq = Z_DS_PRIORITY_QUEUE_P(obj);
+@@ -43,7 +43,7 @@ static zend_object *php_ds_priority_queue_clone_obj
+ static HashTable *php_ds_priority_queue_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_priority_queue_t *pq = ((php_ds_priority_queue_t *) obj)->queue;
++ ds_priority_queue_t *pq = php_ds_priority_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_priority_queue_t *pq = Z_DS_PRIORITY_QUEUE_P(obj);
+@@ -57,7 +57,7 @@ static HashTable *php_ds_priority_queue_get_debug_info
+ static HashTable *php_ds_priority_queue_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_size) {
+- ds_priority_queue_t *pq = ((php_ds_priority_queue_t *) obj)->queue;
++ ds_priority_queue_t *pq = php_ds_priority_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, zval **gc_data, int *gc_size) {
+ ds_priority_queue_t *pq = Z_DS_PRIORITY_QUEUE_P(obj);
+diff --git a/src/php/handlers/php_queue_handlers.c b/src/php/handlers/php_queue_handlers.c
+index 7a00c9e..cd0c78e 100644
+--- a/src/php/handlers/php_queue_handlers.c
++++ b/src/php/handlers/php_queue_handlers.c
+@@ -10,7 +10,7 @@ zend_object_handlers php_queue_handlers;
+ static void php_ds_queue_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_queue_t *queue = ((php_ds_queue_t*)obj)->queue;
++ ds_queue_t *queue = php_ds_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_queue_t *queue = Z_DS_QUEUE_P(obj);
+@@ -24,15 +24,15 @@ static void php_ds_queue_write_dimension
+
+ static void php_ds_queue_free_object(zend_object *object)
+ {
+- php_ds_queue_t *queue = (php_ds_queue_t*) object;
+- zend_object_std_dtor(&queue->std);
++ php_ds_queue_t *queue = php_ds_queue_fetch_object(object);
+ ds_queue_free(queue->queue);
++ zend_object_std_dtor(&queue->std);
+ }
+
+ static int php_ds_queue_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- ds_queue_t *queue = ((php_ds_queue_t*)obj)->queue;
++ ds_queue_t *queue = php_ds_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, zend_long *count) {
+ ds_queue_t *queue = Z_DS_QUEUE_P(obj);
+@@ -44,7 +44,7 @@ static int php_ds_queue_count_elements
+ static zend_object *php_ds_queue_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- ds_queue_t *queue = ((php_ds_queue_t*)obj)->queue;
++ ds_queue_t *queue = php_ds_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj) {
+ ds_queue_t *queue = Z_DS_QUEUE_P(obj);
+@@ -55,7 +55,7 @@ static zend_object *php_ds_queue_clone_obj
+ static HashTable *php_ds_queue_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_queue_t *queue = ((php_ds_queue_t*)obj)->queue;
++ ds_queue_t *queue = php_ds_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_queue_t *queue = Z_DS_QUEUE_P(obj);
+@@ -69,7 +69,7 @@ static HashTable *php_ds_queue_get_debug_info
+ static HashTable *php_ds_queue_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_count) {
+- ds_queue_t *queue = ((php_ds_queue_t*)obj)->queue;
++ ds_queue_t *queue = php_ds_queue_fetch_object(obj)->queue;
+ #else
+ (zval *obj, zval **gc_data, int *gc_count) {
+ ds_queue_t *queue = Z_DS_QUEUE_P(obj);
+diff --git a/src/php/handlers/php_set_handlers.c b/src/php/handlers/php_set_handlers.c
+index 93319ec..44dc001 100644
+--- a/src/php/handlers/php_set_handlers.c
++++ b/src/php/handlers/php_set_handlers.c
+@@ -9,7 +9,7 @@ zend_object_handlers php_ds_set_handlers;
+ static zval *php_ds_set_read_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int type, zval *rv) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj, zval *offset, int type, zval *rv) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -30,7 +30,7 @@ static zval *php_ds_set_read_dimension
+ static void php_ds_set_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -45,7 +45,7 @@ static void php_ds_set_write_dimension
+ static int php_ds_set_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj, zend_long *count) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -56,15 +56,15 @@ static int php_ds_set_count_elements
+
+ static void php_ds_set_free_object(zend_object *object)
+ {
+- php_ds_set_t *obj = (php_ds_set_t*) object;
+- zend_object_std_dtor(&obj->std);
++ php_ds_set_t *obj = php_ds_set_fetch_object(object);
+ ds_set_free(obj->set);
++ zend_object_std_dtor(&obj->std);
+ }
+
+ static HashTable *php_ds_set_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -79,7 +79,7 @@ static HashTable *php_ds_set_get_debug_info
+ static zend_object *php_ds_set_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -90,7 +90,7 @@ static zend_object *php_ds_set_clone_obj
+ static HashTable *php_ds_set_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_count) {
+- ds_set_t *set = ((php_ds_set_t*)obj)->set;
++ ds_set_t *set = php_ds_set_fetch_object(obj)->set;
+ #else
+ (zval *obj, zval **gc_data, int *gc_count) {
+ ds_set_t *set = Z_DS_SET_P(obj);
+@@ -110,7 +110,7 @@ void php_ds_register_set_handlers()
+ {
+ memcpy(&php_ds_set_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+
+- php_ds_set_handlers.offset = 0; // XtOffsetOf(php_ds_set_t, std);
++ php_ds_set_handlers.offset = XtOffsetOf(php_ds_set_t, std);
+
+ php_ds_set_handlers.cast_object = php_ds_default_cast_object;
+ php_ds_set_handlers.clone_obj = php_ds_set_clone_obj;
+diff --git a/src/php/handlers/php_stack_handlers.c b/src/php/handlers/php_stack_handlers.c
+index 7fe5a7c..a08f15d 100644
+--- a/src/php/handlers/php_stack_handlers.c
++++ b/src/php/handlers/php_stack_handlers.c
+@@ -8,7 +8,7 @@ zend_object_handlers php_ds_stack_handlers;
+ static void php_ds_stack_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_stack_t *stack = ((php_ds_stack_t*)obj)->stack;
++ ds_stack_t *stack = php_ds_stack_fetch_object(obj)->stack;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_stack_t *stack = Z_DS_STACK_P(obj);
+@@ -22,15 +22,18 @@ static void php_ds_stack_write_dimension
+
+ static void php_ds_stack_free_object(zend_object *object)
+ {
+- php_ds_stack_t *obj = (php_ds_stack_t*) object;
++ php_ds_stack_t *obj = php_ds_stack_fetch_object(object);
++ if (obj->stack) {
++ ds_stack_free(obj->stack);
++ obj->stack = NULL;
++ }
+ zend_object_std_dtor(&obj->std);
+- ds_stack_free(obj->stack);
+ }
+
+ static int php_ds_stack_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- ds_stack_t *stack = ((php_ds_stack_t*)obj)->stack;
++ ds_stack_t *stack = php_ds_stack_fetch_object(obj)->stack;
+ #else
+ (zval *obj, zend_long *count) {
+ ds_stack_t *stack = Z_DS_STACK_P(obj);
+@@ -42,7 +45,7 @@ static int php_ds_stack_count_elements
+ static zend_object *php_ds_stack_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- ds_stack_t *stack = ((php_ds_stack_t*)obj)->stack;
++ ds_stack_t *stack = php_ds_stack_fetch_object(obj)->stack;
+ #else
+ (zval *obj) {
+ ds_stack_t *stack = Z_DS_STACK_P(obj);
+@@ -53,7 +56,7 @@ static zend_object *php_ds_stack_clone_obj
+ static HashTable *php_ds_stack_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_stack_t *stack = ((php_ds_stack_t*)obj)->stack;
++ ds_stack_t *stack = php_ds_stack_fetch_object(obj)->stack;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_stack_t *stack = Z_DS_STACK_P(obj);
+@@ -68,7 +71,7 @@ static HashTable *php_ds_stack_get_debug_info
+ static HashTable *php_ds_stack_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_count) {
+- ds_stack_t *stack = ((php_ds_stack_t*)obj)->stack;
++ ds_stack_t *stack = php_ds_stack_fetch_object(obj)->stack;
+ #else
+ (zval *obj, zval **gc_data, int *gc_count) {
+ ds_stack_t *stack = Z_DS_STACK_P(obj);
+diff --git a/src/php/handlers/php_vector_handlers.c b/src/php/handlers/php_vector_handlers.c
+index c126be8..58fe1e7 100644
+--- a/src/php/handlers/php_vector_handlers.c
++++ b/src/php/handlers/php_vector_handlers.c
+@@ -9,7 +9,7 @@ zend_object_handlers php_vector_handlers;
+ static zval *php_ds_vector_read_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int type, zval *return_value) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, zval *offset, int type, zval *return_value) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+@@ -47,7 +47,7 @@ static zval *php_ds_vector_read_dimension
+ static void php_ds_vector_write_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, zval *value) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, zval *offset, zval *value) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+@@ -69,7 +69,7 @@ static void php_ds_vector_write_dimension
+ static int php_ds_vector_has_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset, int check_empty) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, zval *offset, int check_empty) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+@@ -85,7 +85,7 @@ static int php_ds_vector_has_dimension
+ static void php_ds_vector_unset_dimension
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval *offset) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, zval *offset) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+@@ -110,7 +110,7 @@ static void php_ds_vector_unset_dimension
+ static int php_ds_vector_count_elements
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zend_long *count) {
+- *count = ((php_ds_vector_t*)obj)->vector->size; return SUCCESS;
++ *count = php_ds_vector_fetch_object(obj)->vector->size; return SUCCESS;
+ #else
+ (zval *obj, zend_long *count) {
+ *count = Z_DS_VECTOR_P(obj)->size; return SUCCESS;
+@@ -119,15 +119,15 @@ static int php_ds_vector_count_elements
+
+ static void php_ds_vector_free_object(zend_object *obj)
+ {
+- php_ds_vector_t *vector = (php_ds_vector_t*) obj;
+- zend_object_std_dtor(&vector->std);
++ php_ds_vector_t *vector = php_ds_vector_fetch_object(obj);
+ ds_vector_free(vector->vector);
++ zend_object_std_dtor(&vector->std);
+ }
+
+ static HashTable *php_ds_vector_get_debug_info
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, int *is_temp) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, int *is_temp) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+@@ -141,7 +141,7 @@ static HashTable *php_ds_vector_get_debug_info
+ static zend_object *php_ds_vector_clone_obj
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj) {
+- return php_ds_vector_create_clone(((php_ds_vector_t*)obj)->vector);
++ return php_ds_vector_create_clone(php_ds_vector_fetch_object(obj)->vector);
+ #else
+ (zval *obj) {
+ return php_ds_vector_create_clone(Z_DS_VECTOR_P(obj));
+@@ -151,7 +151,7 @@ static zend_object *php_ds_vector_clone_obj
+ static HashTable *php_ds_vector_get_gc
+ #if PHP_VERSION_ID >= 80000
+ (zend_object *obj, zval **gc_data, int *gc_count) {
+- ds_vector_t *vector = ((php_ds_vector_t*)obj)->vector;
++ ds_vector_t *vector = php_ds_vector_fetch_object(obj)->vector;
+ #else
+ (zval *obj, zval **gc_data, int *gc_count) {
+ ds_vector_t *vector = Z_DS_VECTOR_P(obj);
+diff --git a/src/php/iterators/php_queue_iterator.c b/src/php/iterators/php_queue_iterator.c
+index 3a5ebe5..3930b72 100644
+--- a/src/php/iterators/php_queue_iterator.c
++++ b/src/php/iterators/php_queue_iterator.c
+@@ -4,9 +4,9 @@
+
+ static void php_ds_queue_iterator_dtor(zend_object_iterator *iter)
+ {
+- zval tmp;
+- ZVAL_OBJ(&tmp, (zend_object *) ((ds_queue_iterator_t *) iter)->queue);
+- zval_ptr_dtor(&tmp);
++ ds_queue_iterator_t *iterator = (ds_queue_iterator_t *) iter;
++
++ OBJ_RELEASE(iterator->object);
+ }
+
+ static int php_ds_queue_iterator_valid(zend_object_iterator *iter)
+@@ -23,12 +23,12 @@ static void php_ds_queue_iterator_get_current_key(zend_object_iterator *iter, zv
+ ZVAL_LONG(key, ((ds_queue_iterator_t *) iter)->position);
+ }
+
+-static void php_ds_queue_iterator_set_current(php_ds_queue_t *queue, zval *data)
++static void php_ds_queue_iterator_set_current(ds_queue_t *queue, zval *data)
+ {
+- if (QUEUE_IS_EMPTY(queue->queue)) {
++ if (QUEUE_IS_EMPTY(queue)) {
+ ZVAL_UNDEF(data);
+ } else {
+- ds_queue_pop(queue->queue, data);
++ ds_queue_pop(queue, data);
+ Z_TRY_DELREF_P(data);
+ }
+ }
+@@ -69,15 +69,16 @@ zend_object_iterator *php_ds_queue_get_iterator(zend_class_entry *ce, zval *obje
+ zend_iterator_init((zend_object_iterator*) iterator);
+
+ iterator->intern.funcs = &php_ds_queue_iterator_funcs;
+- iterator->queue = (php_ds_queue_t*) (Z_OBJ_P(object));
++ iterator->queue = Z_DS_QUEUE_P(object);
++ iterator->object = Z_OBJ_P(object);
+ iterator->position = 0;
+
+ // Add a reference to the object so that it doesn't get collected when
+ // the iterated object is implict, eg. foreach ($obj->getInstance() as $value){ ... }
+ #if PHP_VERSION_ID >= 70300
+- GC_ADDREF((zend_object *) iterator->queue);
++ GC_ADDREF(iterator->object);
+ #else
+- ++GC_REFCOUNT((zend_object *) iterator->queue);
++ ++GC_REFCOUNT(iterator->object);
+ #endif
+
+ return (zend_object_iterator *) iterator;
+diff --git a/src/php/iterators/php_queue_iterator.h b/src/php/iterators/php_queue_iterator.h
+index 9221827..ce4295b 100644
+--- a/src/php/iterators/php_queue_iterator.h
++++ b/src/php/iterators/php_queue_iterator.h
+@@ -7,7 +7,8 @@
+ typedef struct _ds_queue_iterator_t {
+ zend_object_iterator intern;
+ zend_long position;
+- php_ds_queue_t *queue;
++ zend_object *object;
++ ds_queue_t *queue;
+ } ds_queue_iterator_t;
+
+ zend_object_iterator *php_ds_queue_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
+diff --git a/src/php/iterators/php_stack_iterator.c b/src/php/iterators/php_stack_iterator.c
+index f53eb5b..9b62498 100644
+--- a/src/php/iterators/php_stack_iterator.c
++++ b/src/php/iterators/php_stack_iterator.c
+@@ -4,9 +4,9 @@
+
+ static void php_ds_stack_iterator_dtor(zend_object_iterator *iter)
+ {
+- zval tmp;
+- ZVAL_OBJ(&tmp, (zend_object *) ((php_ds_stack_iterator_t *) iter)->stack);
+- zval_ptr_dtor(&tmp);
++ php_ds_stack_iterator_t *iterator = (php_ds_stack_iterator_t *) iter;
++
++ OBJ_RELEASE(iterator->object);
+ }
+
+ static int php_ds_stack_iterator_valid(zend_object_iterator *iter)
+@@ -23,12 +23,12 @@ static void php_ds_stack_iterator_get_current_key(zend_object_iterator *iter, zv
+ ZVAL_LONG(key, ((php_ds_stack_iterator_t *) iter)->position);
+ }
+
+-static void php_ds_stack_iterator_set_current(php_ds_stack_t *stack, zval *data)
++static void php_ds_stack_iterator_set_current(ds_stack_t *stack, zval *data)
+ {
+- if (DS_STACK_IS_EMPTY(stack->stack)) {
++ if (DS_STACK_IS_EMPTY(stack)) {
+ ZVAL_UNDEF(data);
+ } else {
+- ds_stack_pop(stack->stack, data);
++ ds_stack_pop(stack, data);
+ Z_TRY_DELREF_P(data);
+ }
+ }
+@@ -69,15 +69,16 @@ zend_object_iterator *php_ds_stack_get_iterator(zend_class_entry *ce, zval *obje
+ zend_iterator_init((zend_object_iterator*) iterator);
+
+ iterator->intern.funcs = &php_ds_stack_iterator_funcs;
+- iterator->stack = (php_ds_stack_t *) Z_OBJ_P(object);
++ iterator->stack = Z_DS_STACK_P(object);
++ iterator->object = Z_OBJ_P(object);
+ iterator->position = 0;
+
+ // Add a reference to the object so that it doesn't get collected when
+ // the iterated object is implict, eg. foreach ($obj->getInstance() as $value){ ... }
+ #if PHP_VERSION_ID >= 70300
+- GC_ADDREF((zend_object *) iterator->stack);
++ GC_ADDREF(iterator->object);
+ #else
+- ++GC_REFCOUNT((zend_object *) iterator->stack);
++ ++GC_REFCOUNT(iterator->object);
+ #endif
+
+ return (zend_object_iterator *) iterator;
+diff --git a/src/php/iterators/php_stack_iterator.h b/src/php/iterators/php_stack_iterator.h
+index 9ea6857..78563f5 100644
+--- a/src/php/iterators/php_stack_iterator.h
++++ b/src/php/iterators/php_stack_iterator.h
+@@ -7,7 +7,8 @@
+ typedef struct _php_ds_stack_iterator_t {
+ zend_object_iterator intern;
+ zend_long position;
+- php_ds_stack_t *stack;
++ zend_object *object;
++ ds_stack_t *stack;
+ } php_ds_stack_iterator_t;
+
+ zend_object_iterator *php_ds_stack_get_iterator(zend_class_entry *ce, zval *object, int by_ref);
+diff --git a/src/php/objects/php_deque.c b/src/php/objects/php_deque.c
+index e8633bf..a27e9b4 100644
+--- a/src/php/objects/php_deque.c
++++ b/src/php/objects/php_deque.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_deque_create_object_ex(ds_deque_t *deque)
+ {
+- php_ds_deque_t *obj = ecalloc(1, sizeof(php_ds_deque_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_deque_t *obj = ecalloc(1, sizeof(php_ds_deque_t) + zend_object_properties_size(php_ds_deque_ce));
++#else
++ php_ds_deque_t *obj = zend_object_alloc(sizeof(php_ds_deque_t), php_ds_deque_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_deque_ce);
+ obj->std.handlers = &php_deque_handlers;
+ obj->deque = deque;
+diff --git a/src/php/objects/php_deque.h b/src/php/objects/php_deque.h
+index 5c95cfe..ddaf354 100644
+--- a/src/php/objects/php_deque.h
++++ b/src/php/objects/php_deque.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_deque.h"
+
+-#define Z_DS_DEQUE(z) ((php_ds_deque_t*) Z_OBJ(z))->deque
++typedef struct php_ds_deque {
++ ds_deque_t *deque;
++ zend_object std;
++} php_ds_deque_t;
++
++static inline php_ds_deque_t *php_ds_deque_fetch_object(zend_object *obj) {
++ return (php_ds_deque_t *)((char*)(obj) - XtOffsetOf(php_ds_deque_t, std));
++}
++
++#define Z_DS_DEQUE(z) (php_ds_deque_fetch_object(Z_OBJ(z))->deque)
+ #define Z_DS_DEQUE_P(z) Z_DS_DEQUE(*z)
+ #define THIS_DS_DEQUE() Z_DS_DEQUE_P(getThis())
+
+@@ -21,14 +30,6 @@ do { \
+ } while(0)
+
+
+-/**
+- *
+- */
+-typedef struct php_ds_deque {
+- zend_object std;
+- ds_deque_t *deque;
+-} php_ds_deque_t;
+-
+ /**
+ * Creates a new zend_object using an existing deque.
+ */
+diff --git a/src/php/objects/php_map.c b/src/php/objects/php_map.c
+index 820f452..e36e162 100644
+--- a/src/php/objects/php_map.c
++++ b/src/php/objects/php_map.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_map_create_object_ex(ds_map_t *map)
+ {
+- php_ds_map_t *obj = ecalloc(1, sizeof(php_ds_map_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_map_t *obj = ecalloc(1, sizeof(php_ds_map_t) + zend_object_properties_size(php_ds_map_ce));
++#else
++ php_ds_map_t *obj = zend_object_alloc(sizeof(php_ds_map_t), php_ds_map_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_map_ce);
+ obj->std.handlers = &php_map_handlers;
+ obj->map = map;
+diff --git a/src/php/objects/php_map.h b/src/php/objects/php_map.h
+index 8d5ef0a..a3805b4 100644
+--- a/src/php/objects/php_map.h
++++ b/src/php/objects/php_map.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_map.h"
+
+-#define Z_DS_MAP(z) (((php_ds_map_t*)(Z_OBJ(z)))->map)
++typedef struct _php_ds_map_t {
++ ds_map_t *map;
++ zend_object std;
++} php_ds_map_t;
++
++static inline php_ds_map_t *php_ds_map_fetch_object(zend_object *obj) {
++ return (php_ds_map_t *)((char*)(obj) - XtOffsetOf(php_ds_map_t, std));
++}
++
++#define Z_DS_MAP(z) (php_ds_map_fetch_object(Z_OBJ(z))->map)
+ #define Z_DS_MAP_P(z) Z_DS_MAP(*z)
+ #define THIS_DS_MAP() Z_DS_MAP_P(getThis())
+
+@@ -20,11 +29,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct _php_ds_map_t {
+- zend_object std;
+- ds_map_t *map;
+-} php_ds_map_t;
+-
+ zend_object *php_ds_map_create_object_ex(ds_map_t *map);
+ zend_object *php_ds_map_create_object(zend_class_entry *ce);
+ zend_object *php_ds_map_create_clone(ds_map_t *map);
+diff --git a/src/php/objects/php_pair.c b/src/php/objects/php_pair.c
+index 078b9e2..c71a92a 100644
+--- a/src/php/objects/php_pair.c
++++ b/src/php/objects/php_pair.c
+@@ -4,9 +4,13 @@
+
+ zend_object *php_ds_pair_create_object(zend_class_entry *ce)
+ {
++#if PHP_VERSION_ID < 70300
+ php_ds_pair_t *obj = ecalloc(1, sizeof(php_ds_pair_t) + zend_object_properties_size(ce));
+- zend_object_std_init(&obj->std, php_ds_pair_ce);
+- object_properties_init(&obj->std, php_ds_pair_ce);
++#else
++ php_ds_pair_t *obj = zend_object_alloc(sizeof(php_ds_pair_t), ce);
++#endif
++ zend_object_std_init(&obj->std, ce);
++ object_properties_init(&obj->std, ce);
+ obj->std.handlers = &php_pair_handlers;
+
+ return &obj->std;
+diff --git a/src/php/objects/php_priority_queue.c b/src/php/objects/php_priority_queue.c
+index 7fa50c0..7edb9f0 100644
+--- a/src/php/objects/php_priority_queue.c
++++ b/src/php/objects/php_priority_queue.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_priority_queue_create_object_ex(ds_priority_queue_t *queue)
+ {
+- php_ds_priority_queue_t *obj = ecalloc(1, sizeof(php_ds_priority_queue_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_priority_queue_t *obj = ecalloc(1, sizeof(php_ds_priority_queue_t) + zend_object_properties_size(php_ds_priority_queue_ce));
++#else
++ php_ds_priority_queue_t *obj = zend_object_alloc(sizeof(php_ds_priority_queue_t), php_ds_priority_queue_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_priority_queue_ce);
+ obj->std.handlers = &php_priority_queue_handlers;
+
+diff --git a/src/php/objects/php_priority_queue.h b/src/php/objects/php_priority_queue.h
+index f7a38dc..e26434d 100644
+--- a/src/php/objects/php_priority_queue.h
++++ b/src/php/objects/php_priority_queue.h
+@@ -3,7 +3,18 @@
+
+ #include "../../ds/ds_priority_queue.h"
+
+-#define Z_DS_PRIORITY_QUEUE(z) (((php_ds_priority_queue_t*)(Z_OBJ(z)))->queue)
++typedef struct _php_ds_priority_queue_t {
++ ds_priority_queue_t *queue;
++ zval *gc_data;
++ int gc_size;
++ zend_object std;
++} php_ds_priority_queue_t;
++
++static inline php_ds_priority_queue_t *php_ds_priority_queue_fetch_object(zend_object *obj) {
++ return (php_ds_priority_queue_t *)((char*)(obj) - XtOffsetOf(php_ds_priority_queue_t, std));
++}
++
++#define Z_DS_PRIORITY_QUEUE(z) (php_ds_priority_queue_fetch_object(Z_OBJ(z))->queue)
+ #define Z_DS_PRIORITY_QUEUE_P(z) Z_DS_PRIORITY_QUEUE(*z)
+ #define THIS_DS_PRIORITY_QUEUE() Z_DS_PRIORITY_QUEUE_P(getThis())
+
+@@ -21,14 +32,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct _php_ds_priority_queue_t {
+- zend_object std;
+- ds_priority_queue_t *queue;
+- zval *gc_data;
+- int gc_size;
+-
+-} php_ds_priority_queue_t;
+-
+ zend_object *php_ds_priority_queue_create_object_ex(ds_priority_queue_t *queue);
+ zend_object *php_ds_priority_queue_create_object(zend_class_entry *ce);
+ zend_object *php_ds_priority_queue_create_clone(ds_priority_queue_t *queue);
+diff --git a/src/php/objects/php_queue.c b/src/php/objects/php_queue.c
+index 7de656d..fc5d7d9 100644
+--- a/src/php/objects/php_queue.c
++++ b/src/php/objects/php_queue.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_queue_create_object_ex(ds_queue_t *queue)
+ {
+- php_ds_queue_t *obj = ecalloc(1, sizeof(php_ds_queue_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_queue_t *obj = ecalloc(1, sizeof(php_ds_queue_t) + zend_object_properties_size(php_ds_queue_ce));
++#else
++ php_ds_queue_t *obj = zend_object_alloc(sizeof(php_ds_queue_t), php_ds_queue_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_queue_ce);
+ obj->std.handlers = &php_queue_handlers;
+ obj->queue = queue;
+diff --git a/src/php/objects/php_queue.h b/src/php/objects/php_queue.h
+index dc76385..0d2e55c 100644
+--- a/src/php/objects/php_queue.h
++++ b/src/php/objects/php_queue.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_queue.h"
+
+-#define Z_DS_QUEUE(z) (((php_ds_queue_t*)(Z_OBJ(z)))->queue)
++typedef struct _php_ds_queue_t {
++ ds_queue_t *queue;
++ zend_object std;
++} php_ds_queue_t;
++
++static inline php_ds_queue_t *php_ds_queue_fetch_object(zend_object *obj) {
++ return (php_ds_queue_t *)((char*)(obj) - XtOffsetOf(php_ds_queue_t, std));
++}
++
++#define Z_DS_QUEUE(z) php_ds_queue_fetch_object(Z_OBJ(z))->queue
+ #define Z_DS_QUEUE_P(z) Z_DS_QUEUE(*z)
+ #define THIS_DS_QUEUE() Z_DS_QUEUE_P(getThis())
+
+@@ -21,11 +30,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct _php_ds_queue_t {
+- zend_object std;
+- ds_queue_t *queue;
+-} php_ds_queue_t;
+-
+ zend_object *php_ds_queue_create_object_ex(ds_queue_t *queue);
+ zend_object *php_ds_queue_create_object(zend_class_entry *ce);
+ zend_object *php_ds_queue_create_clone(ds_queue_t *queue);
+diff --git a/src/php/objects/php_set.c b/src/php/objects/php_set.c
+index 70d82c0..85027f7 100644
+--- a/src/php/objects/php_set.c
++++ b/src/php/objects/php_set.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_set_create_object_ex(ds_set_t *set)
+ {
+- php_ds_set_t *obj = ecalloc(1, sizeof(php_ds_set_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_set_t *obj = ecalloc(1, sizeof(php_ds_set_t) + zend_object_properties_size(php_ds_set_ce));
++#else
++ php_ds_set_t *obj = zend_object_alloc(sizeof(php_ds_set_t), php_ds_set_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_set_ce);
+ obj->std.handlers = &php_ds_set_handlers;
+ obj->set = set;
+diff --git a/src/php/objects/php_set.h b/src/php/objects/php_set.h
+index 8f94b33..5c2760d 100644
+--- a/src/php/objects/php_set.h
++++ b/src/php/objects/php_set.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_set.h"
+
+-#define Z_DS_SET(z) (((php_ds_set_t*)(Z_OBJ(z)))->set)
++typedef struct _php_ds_set_t {
++ ds_set_t *set;
++ zend_object std;
++} php_ds_set_t;
++
++static inline php_ds_set_t *php_ds_set_fetch_object(zend_object *obj) {
++ return (php_ds_set_t *)((char*)(obj) - XtOffsetOf(php_ds_set_t, std));
++}
++
++#define Z_DS_SET(z) (php_ds_set_fetch_object(Z_OBJ(z))->set)
+ #define Z_DS_SET_P(z) Z_DS_SET(*z)
+ #define THIS_DS_SET() Z_DS_SET_P(getThis())
+
+@@ -20,11 +29,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct _php_ds_set_t {
+- zend_object std;
+- ds_set_t *set;
+-} php_ds_set_t;
+-
+ zend_object *php_ds_set_create_object_ex(ds_set_t *set);
+ zend_object *php_ds_set_create_object(zend_class_entry *ce);
+ zend_object *php_ds_set_create_clone(ds_set_t *set);
+diff --git a/src/php/objects/php_stack.c b/src/php/objects/php_stack.c
+index 8b2ac61..e583ba3 100644
+--- a/src/php/objects/php_stack.c
++++ b/src/php/objects/php_stack.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_stack_create_object_ex(ds_stack_t *stack)
+ {
+- php_ds_stack_t *obj = ecalloc(1, sizeof(php_ds_stack_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_stack_t *obj = ecalloc(1, sizeof(php_ds_stack_t) + zend_object_properties_size(php_ds_stack_ce));
++#else
++ php_ds_stack_t *obj = zend_object_alloc(sizeof(php_ds_stack_t), php_ds_stack_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_stack_ce);
+ obj->std.handlers = &php_ds_stack_handlers;
+ obj->stack = stack;
+diff --git a/src/php/objects/php_stack.h b/src/php/objects/php_stack.h
+index c34934b..219f306 100644
+--- a/src/php/objects/php_stack.h
++++ b/src/php/objects/php_stack.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_stack.h"
+
+-#define Z_DS_STACK(z) (((php_ds_stack_t*)(Z_OBJ(z)))->stack)
++typedef struct _php_ds_stack_t {
++ ds_stack_t *stack;
++ zend_object std;
++} php_ds_stack_t;
++
++static inline php_ds_stack_t *php_ds_stack_fetch_object(zend_object *obj) {
++ return (php_ds_stack_t *)((char*)(obj) - XtOffsetOf(php_ds_stack_t, std));
++}
++
++#define Z_DS_STACK(z) php_ds_stack_fetch_object(Z_OBJ(z))->stack
+ #define Z_DS_STACK_P(z) Z_DS_STACK(*z)
+ #define THIS_DS_STACK() Z_DS_STACK_P(getThis())
+
+@@ -20,11 +29,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct _php_ds_stack_t {
+- zend_object std;
+- ds_stack_t *stack;
+-} php_ds_stack_t;
+-
+ zend_object *php_ds_stack_create_object_ex(ds_stack_t *stack);
+ zend_object *php_ds_stack_create_object(zend_class_entry *ce);
+ zend_object *php_ds_stack_create_clone(ds_stack_t *stack);
+diff --git a/src/php/objects/php_vector.c b/src/php/objects/php_vector.c
+index f415c43..f3402ab 100644
+--- a/src/php/objects/php_vector.c
++++ b/src/php/objects/php_vector.c
+@@ -6,7 +6,11 @@
+
+ zend_object *php_ds_vector_create_object_ex(ds_vector_t *vector)
+ {
+- php_ds_vector_t *obj = ecalloc(1, sizeof(php_ds_vector_t));
++#if PHP_VERSION_ID < 70300
++ php_ds_vector_t *obj = ecalloc(1, sizeof(php_ds_vector_t) + zend_object_properties_size(php_ds_vector_ce));
++#else
++ php_ds_vector_t *obj = zend_object_alloc(sizeof(php_ds_vector_t), php_ds_vector_ce);
++#endif
+ zend_object_std_init(&obj->std, php_ds_vector_ce);
+ obj->std.handlers = &php_vector_handlers;
+ obj->vector = vector;
+diff --git a/src/php/objects/php_vector.h b/src/php/objects/php_vector.h
+index 63b4b7f..43399e6 100644
+--- a/src/php/objects/php_vector.h
++++ b/src/php/objects/php_vector.h
+@@ -3,7 +3,16 @@
+
+ #include "../../ds/ds_vector.h"
+
+-#define Z_DS_VECTOR(z) (((php_ds_vector_t*)(Z_OBJ(z)))->vector)
++typedef struct php_ds_vector {
++ ds_vector_t *vector;
++ zend_object std;
++} php_ds_vector_t;
++
++static inline php_ds_vector_t *php_ds_vector_fetch_object(zend_object *obj) {
++ return (php_ds_vector_t *)((char*)(obj) - XtOffsetOf(php_ds_vector_t, std));
++}
++
++#define Z_DS_VECTOR(z) (php_ds_vector_fetch_object(Z_OBJ(z))->vector)
+ #define Z_DS_VECTOR_P(z) Z_DS_VECTOR(*z)
+ #define THIS_DS_VECTOR() Z_DS_VECTOR_P(getThis())
+
+@@ -20,11 +29,6 @@ do { \
+ return; \
+ } while(0)
+
+-typedef struct php_ds_vector {
+- zend_object std;
+- ds_vector_t *vector;
+-} php_ds_vector_t;
+-
+ zend_object *php_ds_vector_create_object_ex(ds_vector_t *vector);
+ zend_object *php_ds_vector_create_object(zend_class_entry *ce);
+ zend_object *php_ds_vector_create_clone(ds_vector_t *vector);
+--
+2.25.4
+
diff --git a/php-pecl-ds.spec b/php-pecl-ds.spec
index 3e4173e..4bd8e67 100644
--- a/php-pecl-ds.spec
+++ b/php-pecl-ds.spec
@@ -42,6 +42,8 @@ Source0: https://pecl.php.net/get/%{pecl_name}-%{version}.tgz
# in composer.json: "require-dev": { "php-ds/tests": "dev-master" }
Source1: https://github.com/%{gh_owner}/%{gh_project}/archive/%{gh_commit}/%{gh_project}-%{gh_short}.tar.gz
+Patch0: 0001-review-object-management.patch
+
BuildRequires: %{?dtsprefix}gcc
BuildRequires: %{?scl_prefix}php-devel >= 7
BuildRequires: %{?scl_prefix}php-pear
@@ -51,6 +53,8 @@ BuildRequires: %{?scl_prefix}php-json
BuildRequires: %{_bindir}/phpunit6
BuildRequires: %{_bindir}/phpab
%endif
+#BuildRequires: php-debuginfo
+#BuildRequires: gdb
Requires: %{?scl_prefix}php(zend-abi) = %{php_zend_api}
Requires: %{?scl_prefix}php(api) = %{php_core_api}
@@ -101,6 +105,7 @@ mv %{gh_project}-%{gh_commit} tests
%{?_licensedir:sed -e '/LICENSE/s/role="doc"/role="src"/' -i package.xml}
cd NTS
+%patch0 -p1
# Sanity check, really often broken
extver=$(sed -n '/#define PHP_DS_VERSION/{s/.* "//;s/".*$//;p}' php_ds.h)