]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorXinchen Hui <laruence@gmail.com>
Sun, 16 Feb 2014 14:15:54 +0000 (22:15 +0800)
committerXinchen Hui <laruence@gmail.com>
Sun, 16 Feb 2014 14:15:54 +0000 (22:15 +0800)
Zend/zend_hash.h
ext/spl/spl_dllist.c
ext/spl/spl_fixedarray.c
ext/spl/spl_heap.c

index 0aff20c1e7afa47943be5463178692bd5e052b20..a8f4977f075a611e8b6adc3521ee946fd9e498f1 100644 (file)
@@ -159,7 +159,7 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
 #define zend_hash_move_backwards(ht) \
        zend_hash_move_backwards_ex(ht, NULL)
 #define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
-       zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
+       zend_hash_get_current_key_ex(ht, str_index, num_index, duplicate, NULL)
 #define zend_hash_get_current_key_zval(ht, key) \
        zend_hash_get_current_key_zval_ex(ht, key, NULL)
 #define zend_hash_get_current_key_type(ht) \
index 772d780e014b06ce1508a7968a01f9b5d3f816b3..1fc4f13cad9f4eba2f9e238c9afb3628e141e559 100644 (file)
@@ -67,7 +67,7 @@ typedef struct _spl_ptr_llist_element {
        struct _spl_ptr_llist_element *prev;
        struct _spl_ptr_llist_element *next;
        int                            rc;
-       void                          *data;
+       zval                           data;
 } spl_ptr_llist_element;
 
 typedef void (*spl_ptr_llist_dtor_func)(spl_ptr_llist_element * TSRMLS_DC);
@@ -89,7 +89,7 @@ struct _spl_dllist_object {
        spl_ptr_llist         *llist;
        int                    traverse_position;
        spl_ptr_llist_element *traverse_pointer;
-       zval                  *retval;
+       zval                   retval;
        int                    flags;
        zend_function         *fptr_offset_get;
        zend_function         *fptr_offset_set;
@@ -111,14 +111,15 @@ struct _spl_dllist_it {
 
 /* {{{  spl_ptr_llist */
 static void spl_ptr_llist_zval_dtor(spl_ptr_llist_element *elem TSRMLS_DC) { /* {{{ */
-       if (elem->data) {
-               zval_ptr_dtor((zval **)&elem->data);
+       if (!ZVAL_IS_UNDEF(&elem->data)) {
+               zval_ptr_dtor(&elem->data);
+               ZVAL_UNDEF(&elem->data);
        }
 }
 /* }}} */
 
 static void spl_ptr_llist_zval_ctor(spl_ptr_llist_element *elem TSRMLS_DC) { /* {{{ */
-       Z_ADDREF_P((zval *)elem->data);
+       Z_ADDREF_P(&elem->data);
 }
 /* }}} */
 
@@ -185,14 +186,14 @@ static spl_ptr_llist_element *spl_ptr_llist_offset(spl_ptr_llist *llist, long of
 }
 /* }}} */
 
-static void spl_ptr_llist_unshift(spl_ptr_llist *llist, void *data TSRMLS_DC) /* {{{ */
+static void spl_ptr_llist_unshift(spl_ptr_llist *llist, zval *data TSRMLS_DC) /* {{{ */
 {
        spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));
 
-       elem->data = data;
        elem->rc   = 1;
        elem->prev = NULL;
        elem->next = llist->head;
+       ZVAL_COPY_VALUE(&elem->data, data);
 
        if (llist->head) {
                llist->head->prev = elem;
@@ -209,14 +210,14 @@ static void spl_ptr_llist_unshift(spl_ptr_llist *llist, void *data TSRMLS_DC) /*
 }
 /* }}} */
 
-static void spl_ptr_llist_push(spl_ptr_llist *llist, void *data TSRMLS_DC) /* {{{ */
+static void spl_ptr_llist_push(spl_ptr_llist *llist, zval *data TSRMLS_DC) /* {{{ */
 {
        spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));
 
-       elem->data = data;
        elem->rc   = 1;
        elem->prev = llist->tail;
        elem->next = NULL;
+       ZVAL_COPY_VALUE(&elem->data, data);
 
        if (llist->tail) {
                llist->tail->next = elem;
@@ -233,13 +234,13 @@ static void spl_ptr_llist_push(spl_ptr_llist *llist, void *data TSRMLS_DC) /* {{
 }
 /* }}} */
 
-static void *spl_ptr_llist_pop(spl_ptr_llist *llist TSRMLS_DC) /* {{{ */
+static void spl_ptr_llist_pop(spl_ptr_llist *llist, zval *ret TSRMLS_DC) /* {{{ */
 {
-       void                     *data;
        spl_ptr_llist_element    *tail = llist->tail;
 
        if (tail == NULL) {
-               return NULL;
+               ZVAL_UNDEF(ret);
+               return;
        }
 
        if (tail->prev) {
@@ -250,51 +251,49 @@ static void *spl_ptr_llist_pop(spl_ptr_llist *llist TSRMLS_DC) /* {{{ */
 
        llist->tail = tail->prev;
        llist->count--;
-       data = tail->data;
+       ZVAL_COPY(ret, &tail->data);
 
        if (llist->dtor) {
                llist->dtor(tail TSRMLS_CC);
        }
 
-       tail->data = NULL;
+       ZVAL_UNDEF(&tail->data);
 
        SPL_LLIST_DELREF(tail);
-
-       return data;
 }
 /* }}} */
 
-static void *spl_ptr_llist_last(spl_ptr_llist *llist) /* {{{ */
+static zval *spl_ptr_llist_last(spl_ptr_llist *llist) /* {{{ */
 {
        spl_ptr_llist_element *tail = llist->tail;
 
        if (tail == NULL) {
                return NULL;
        } else {
-               return tail->data;
+               return &tail->data;
        }
 }
 /* }}} */
 
-static void *spl_ptr_llist_first(spl_ptr_llist *llist) /* {{{ */
+static zval *spl_ptr_llist_first(spl_ptr_llist *llist) /* {{{ */
 {
        spl_ptr_llist_element *head = llist->head;
 
        if (head == NULL) {
                return NULL;
        } else {
-               return head->data;
+               return &head->data;
        }
 }
 /* }}} */
 
-static void *spl_ptr_llist_shift(spl_ptr_llist *llist TSRMLS_DC) /* {{{ */
+static void spl_ptr_llist_shift(spl_ptr_llist *llist, zval *ret TSRMLS_DC) /* {{{ */
 {
-       void                    *data;
        spl_ptr_llist_element   *head = llist->head;
 
        if (head == NULL) {
-               return NULL;
+               ZVAL_UNDEF(ret);
+               return;
        }
 
        if (head->next) {
@@ -305,16 +304,14 @@ static void *spl_ptr_llist_shift(spl_ptr_llist *llist TSRMLS_DC) /* {{{ */
 
        llist->head = head->next;
        llist->count--;
-       data = head->data;
+       ZVAL_COPY(ret, &head->data);
 
        if (llist->dtor) {
                llist->dtor(head TSRMLS_CC);
        }
-       head->data = NULL;
+       ZVAL_UNDEF(&head->data);
 
        SPL_LLIST_DELREF(head);
-
-       return data;
 }
 /* }}} */
 
@@ -326,11 +323,13 @@ static void spl_ptr_llist_copy(spl_ptr_llist *from, spl_ptr_llist *to TSRMLS_DC)
        while (current) {
                next = current->next;
 
+               /*!! FIXME
                if (ctor) {
                        ctor(current TSRMLS_CC);
                }
+               */
 
-               spl_ptr_llist_push(to, current->data TSRMLS_CC);
+               spl_ptr_llist_push(to, &current->data TSRMLS_CC);
                current = next;
        }
 
@@ -339,15 +338,15 @@ static void spl_ptr_llist_copy(spl_ptr_llist *from, spl_ptr_llist *to TSRMLS_DC)
 
 /* }}} */
 
-static void spl_dllist_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void spl_dllist_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        spl_dllist_object *intern = (spl_dllist_object *)object;
-       zval              *tmp    = NULL;
+       zval tmp;
 
        zend_object_std_dtor(&intern->std TSRMLS_CC);
 
-       while(intern->llist->count > 0) {
-               tmp = (zval *)spl_ptr_llist_pop(intern->llist TSRMLS_CC);
+       while (intern->llist->count > 0) {
+               spl_ptr_llist_pop(intern->llist, &tmp TSRMLS_CC);
                zval_ptr_dtor(&tmp);
        }
 
@@ -366,16 +365,13 @@ static void spl_dllist_object_free_storage(void *object TSRMLS_DC) /* {{{ */
 
 zend_object_iterator *spl_dllist_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
 
-static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type, spl_dllist_object **obj, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
+static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
 {
-       zend_object_value  retval = {0};
        spl_dllist_object *intern;
        zend_class_entry  *parent = class_type;
        int                inherited = 0;
 
        intern = ecalloc(1, sizeof(spl_dllist_object));
-       *obj = intern;
-       ALLOC_INIT_ZVAL(intern->retval);
 
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
@@ -385,7 +381,7 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type,
        intern->debug_info = NULL;
 
        if (orig) {
-               spl_dllist_object *other = (spl_dllist_object*)zend_object_store_get_object(orig TSRMLS_CC);
+               spl_dllist_object *other = (spl_dllist_object*)Z_OBJ_P(orig);
                intern->ce_get_iterator = other->ce_get_iterator;
 
                if (clone_orig) {
@@ -409,14 +405,14 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type,
        while (parent) {
                if (parent == spl_ce_SplStack) {
                        intern->flags |= (SPL_DLLIST_IT_FIX | SPL_DLLIST_IT_LIFO);
-                       retval.handlers = &spl_handler_SplDoublyLinkedList;
+                       intern->std.handlers = &spl_handler_SplDoublyLinkedList;
                } else if (parent == spl_ce_SplQueue) {
                        intern->flags |= SPL_DLLIST_IT_FIX;
-                       retval.handlers = &spl_handler_SplDoublyLinkedList;
+                       intern->std.handlers = &spl_handler_SplDoublyLinkedList;
                }
 
                if (parent == spl_ce_SplDoublyLinkedList) {
-                       retval.handlers = &spl_handler_SplDoublyLinkedList;
+                       intern->std.handlers = &spl_handler_SplDoublyLinkedList;
                        break;
                }
 
@@ -424,76 +420,70 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type,
                inherited = 1;
        }
 
-       retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_dllist_object_free_storage, NULL TSRMLS_CC);
+       zend_objects_store_put(&intern->std);
 
        if (!parent) { /* this must never happen */
                php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplDoublyLinkedList");
        }
        if (inherited) {
-               zend_hash_find(&class_type->function_table, "offsetget",    sizeof("offsetget"),    (void **) &intern->fptr_offset_get);
+               intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1);
                if (intern->fptr_offset_get->common.scope == parent) {
                        intern->fptr_offset_get = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetset",    sizeof("offsetset"),    (void **) &intern->fptr_offset_set);
+               intern->fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1);
                if (intern->fptr_offset_set->common.scope == parent) {
                        intern->fptr_offset_set = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetexists", sizeof("offsetexists"), (void **) &intern->fptr_offset_has);
+               intern->fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1);
                if (intern->fptr_offset_has->common.scope == parent) {
                        intern->fptr_offset_has = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetunset",  sizeof("offsetunset"),  (void **) &intern->fptr_offset_del);
+               intern->fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1);
                if (intern->fptr_offset_del->common.scope == parent) {
                        intern->fptr_offset_del = NULL;
                }
-               zend_hash_find(&class_type->function_table, "count",        sizeof("count"),        (void **) &intern->fptr_count);
+               intern->fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1);
                if (intern->fptr_count->common.scope == parent) {
                        intern->fptr_count = NULL;
                }
        }
 
-       return retval;
+       return &intern->std;
 }
 /* }}} */
 
-static zend_object_value spl_dllist_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *spl_dllist_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       spl_dllist_object *tmp;
-       return spl_dllist_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC);
+       return spl_dllist_object_new_ex(class_type, NULL, 0 TSRMLS_CC);
 }
 /* }}} */
 
-static zend_object_value spl_dllist_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
+static zend_object *spl_dllist_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
 {
-       zend_object_value   new_obj_val;
        zend_object        *old_object;
        zend_object        *new_object;
-       zend_object_handle  handle = Z_OBJ_HANDLE_P(zobject);
-       spl_dllist_object  *intern;
 
-       old_object  = zend_objects_get_address(zobject TSRMLS_CC);
-       new_obj_val = spl_dllist_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC);
-       new_object  = &intern->std;
+       old_object  = Z_OBJ_P(zobject);
+       new_object = spl_dllist_object_new_ex(old_object->ce, zobject, 1 TSRMLS_CC);
 
-       zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
+       zend_objects_clone_members(new_object, old_object TSRMLS_CC);
 
-       return new_obj_val;
+       return new_object;
 }
 /* }}} */
 
 static int spl_dllist_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(object);
 
        if (intern->fptr_count) {
-               zval *rv;
-               zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv);
-               if (rv) {
+               zval rv;
+               zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+               if (!ZVAL_IS_UNDEF(&rv)) {
                        zval_ptr_dtor(&intern->retval);
-                       MAKE_STD_ZVAL(intern->retval);
-                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
-                       convert_to_long(intern->retval);
-                       *count = (long) Z_LVAL_P(intern->retval);
+                       ZVAL_ZVAL(&intern->retval, &rv, 0, 0);
+                       convert_to_long(&intern->retval);
+                       *count = (long) Z_LVAL(intern->retval);
                        return SUCCESS;
                }
                *count = 0;
@@ -507,9 +497,9 @@ static int spl_dllist_object_count_elements(zval *object, long *count TSRMLS_DC)
 
 static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */
 {
-       spl_dllist_object     *intern  = (spl_dllist_object*)zend_object_store_get_object(obj TSRMLS_CC);
+       spl_dllist_object     *intern  = (spl_dllist_object*)Z_OBJ_P(obj);
        spl_ptr_llist_element *current = intern->llist->head, *next;
-       zval *tmp, zrv, *dllist_array;
+       zval tmp, dllist_array;
        char *pnstr;
        int  pnlen;
        int  i = 0;
@@ -522,33 +512,31 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRML
        }
 
        if (intern->debug_info->nApplyCount == 0) {
-               INIT_PZVAL(&zrv);
-               Z_ARRVAL(zrv) = intern->debug_info;
 
                if (!intern->std.properties) {
                        rebuild_object_properties(&intern->std);
                }
-               zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+               zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
 
                pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC);
-               add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags);
+               ZVAL_LONG(&tmp, intern->flags);
+               zend_hash_str_add(intern->debug_info, pnstr, pnlen, &tmp);
                efree(pnstr);
 
-               ALLOC_INIT_ZVAL(dllist_array);
-               array_init(dllist_array);
+               array_init(&dllist_array);
 
                while (current) {
                        next = current->next;
 
-                       add_index_zval(dllist_array, i, (zval *)current->data);
-                       Z_ADDREF_P(current->data);
+                       add_index_zval(&dllist_array, i, &current->data);
+                       Z_ADDREF_P(&current->data);
                        i++;
 
                        current = next;
                }
 
                pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC);
-               add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array);
+               zend_hash_str_add(intern->debug_info, pnstr, pnlen, &dllist_array);
                efree(pnstr);
        }
 
@@ -556,7 +544,7 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRML
 }
 /* }}}} */
 
-/* {{{ proto bool SplDoublyLinkedList::push(mixed $value) U
+/* {{{ proto bool SplDoublyLinkedList::push(mixed $value)
           Push $value on the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, push)
 {
@@ -569,14 +557,14 @@ SPL_METHOD(SplDoublyLinkedList, push)
 
        SEPARATE_ARG_IF_REF(value);
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        spl_ptr_llist_push(intern->llist, value TSRMLS_CC);
 
        RETURN_TRUE;
 } 
 /* }}} */
 
-/* {{{ proto bool SplDoublyLinkedList::unshift(mixed $value) U
+/* {{{ proto bool SplDoublyLinkedList::unshift(mixed $value)
           Unshift $value on the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, unshift)
 {
@@ -589,60 +577,54 @@ SPL_METHOD(SplDoublyLinkedList, unshift)
 
        SEPARATE_ARG_IF_REF(value);
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        spl_ptr_llist_unshift(intern->llist, value TSRMLS_CC);
 
        RETURN_TRUE;
 }
 /* }}} */
 
-/* {{{ proto mixed SplDoublyLinkedList::pop() U
+/* {{{ proto mixed SplDoublyLinkedList::pop()
           Pop an element out of the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, pop)
 {
-       zval *value;
        spl_dllist_object *intern;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       value = (zval *)spl_ptr_llist_pop(intern->llist TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
+       spl_ptr_llist_pop(intern->llist, return_value TSRMLS_CC);
 
-       if (value == NULL) {
+       if (ZVAL_IS_UNDEF(return_value)) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't pop from an empty datastructure", 0 TSRMLS_CC);
-               return;
+               RETURN_NULL();
        }
-
-       RETURN_ZVAL(value, 1, 1);
 } 
 /* }}} */
 
-/* {{{ proto mixed SplDoublyLinkedList::shift() U
+/* {{{ proto mixed SplDoublyLinkedList::shift()
           Shift an element out of the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, shift)
 {
-       zval *value;
        spl_dllist_object *intern;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       value  = (zval *)spl_ptr_llist_shift(intern->llist TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
+       spl_ptr_llist_shift(intern->llist, return_value TSRMLS_CC);
 
-       if (value == NULL) {
+       if (ZVAL_IS_UNDEF(return_value)) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't shift from an empty datastructure", 0 TSRMLS_CC);
-               return;
+               RETURN_NULL();
        }
-
-       RETURN_ZVAL(value, 1, 1);
 } 
 /* }}} */
 
-/* {{{ proto mixed SplDoublyLinkedList::top() U
+/* {{{ proto mixed SplDoublyLinkedList::top()
           Peek at the top element of the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, top)
 {
@@ -653,10 +635,10 @@ SPL_METHOD(SplDoublyLinkedList, top)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       value  = (zval *)spl_ptr_llist_last(intern->llist);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
+       value spl_ptr_llist_last(intern->llist);
 
-       if (value == NULL) {
+       if (value == NULL || ZVAL_IS_UNDEF(value)) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty datastructure", 0 TSRMLS_CC);
                return;
        }
@@ -665,7 +647,7 @@ SPL_METHOD(SplDoublyLinkedList, top)
 }
 /* }}} */
 
-/* {{{ proto mixed SplDoublyLinkedList::bottom() U
+/* {{{ proto mixed SplDoublyLinkedList::bottom()
           Peek at the bottom element of the SplDoublyLinkedList */
 SPL_METHOD(SplDoublyLinkedList, bottom)
 {
@@ -676,10 +658,10 @@ SPL_METHOD(SplDoublyLinkedList, bottom)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       value  = (zval *)spl_ptr_llist_first(intern->llist);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
+       value  = spl_ptr_llist_first(intern->llist);
 
-       if (value == NULL) {
+       if (value == NULL || ZVAL_IS_UNDEF(value)) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty datastructure", 0 TSRMLS_CC);
                return;
        }
@@ -688,12 +670,12 @@ SPL_METHOD(SplDoublyLinkedList, bottom)
 }
 /* }}} */
 
-/* {{{ proto int SplDoublyLinkedList::count() U
+/* {{{ proto int SplDoublyLinkedList::count()
  Return the number of elements in the datastructure. */
 SPL_METHOD(SplDoublyLinkedList, count)
 {
        long count;
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -704,7 +686,7 @@ SPL_METHOD(SplDoublyLinkedList, count)
 }
 /* }}} */
 
-/* {{{ proto int SplDoublyLinkedList::isEmpty() U
+/* {{{ proto int SplDoublyLinkedList::isEmpty()
  Return true if the SplDoublyLinkedList is empty. */
 SPL_METHOD(SplDoublyLinkedList, isEmpty)
 {
@@ -715,11 +697,11 @@ SPL_METHOD(SplDoublyLinkedList, isEmpty)
        }
 
        spl_dllist_object_count_elements(getThis(), &count TSRMLS_CC);
-       RETURN_BOOL(count==0);
+       RETURN_BOOL(count == 0);
 }
 /* }}} */
 
-/* {{{ proto int SplDoublyLinkedList::setIteratorMode($flags) U
+/* {{{ proto int SplDoublyLinkedList::setIteratorMode($flags)
  Set the mode of iteration */
 SPL_METHOD(SplDoublyLinkedList, setIteratorMode)
 {
@@ -730,7 +712,7 @@ SPL_METHOD(SplDoublyLinkedList, setIteratorMode)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
 
        if (intern->flags & SPL_DLLIST_IT_FIX
                && (intern->flags & SPL_DLLIST_IT_LIFO) != (value & SPL_DLLIST_IT_LIFO)) {
@@ -744,7 +726,7 @@ SPL_METHOD(SplDoublyLinkedList, setIteratorMode)
 }
 /* }}} */
 
-/* {{{ proto int SplDoublyLinkedList::getIteratorMode() U
+/* {{{ proto int SplDoublyLinkedList::getIteratorMode()
  Return the mode of iteration */
 SPL_METHOD(SplDoublyLinkedList, getIteratorMode)
 {
@@ -754,13 +736,13 @@ SPL_METHOD(SplDoublyLinkedList, getIteratorMode)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
 
        RETURN_LONG(intern->flags);
 }
 /* }}} */
 
-/* {{{ proto bool SplDoublyLinkedList::offsetExists(mixed $index) U
+/* {{{ proto bool SplDoublyLinkedList::offsetExists(mixed $index)
  Returns whether the requested $index exists. */
 SPL_METHOD(SplDoublyLinkedList, offsetExists)
 {
@@ -772,17 +754,17 @@ SPL_METHOD(SplDoublyLinkedList, offsetExists)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
 
        RETURN_BOOL(index >= 0 && index < intern->llist->count);
 } /* }}} */
 
-/* {{{ proto mixed SplDoublyLinkedList::offsetGet(mixed $index) U
+/* {{{ proto mixed SplDoublyLinkedList::offsetGet(mixed $index) 
  Returns the value at the specified $index. */
 SPL_METHOD(SplDoublyLinkedList, offsetGet)
 {
-       zval                  *zindex, *value;
+       zval                  *zindex;
        long                   index;
        spl_dllist_object     *intern;
        spl_ptr_llist_element *element;
@@ -791,7 +773,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
 
        if (index < 0 || index >= intern->llist->count) {
@@ -802,15 +784,14 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet)
        element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);
 
        if (element != NULL) {
-               value = (zval *)element->data;
-               RETURN_ZVAL(value, 1, 0);
+               RETURN_ZVAL(&element->data, 1, 0);
        } else {
                zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
                return;
        }
 } /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::offsetSet(mixed $index, mixed $newval) U
+/* {{{ proto void SplDoublyLinkedList::offsetSet(mixed $index, mixed $newval)
  Sets the value at the specified $index to $newval. */
 SPL_METHOD(SplDoublyLinkedList, offsetSet)
 {
@@ -822,7 +803,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetSet)
        }
        SEPARATE_ARG_IF_REF(value);
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
 
        if (Z_TYPE_P(zindex) == IS_NULL) {
                /* $obj[] = ... */
@@ -835,7 +816,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetSet)
                index = spl_offset_convert_to_long(zindex TSRMLS_CC);
 
                if (index < 0 || index >= intern->llist->count) {
-                       zval_ptr_dtor(&value);
+                       zval_ptr_dtor(value);
                        zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
                        return;
                }
@@ -850,22 +831,22 @@ SPL_METHOD(SplDoublyLinkedList, offsetSet)
 
                        /* the element is replaced, delref the old one as in
                         * SplDoublyLinkedList::pop() */
-                       zval_ptr_dtor((zval **)&element->data);
-                       element->data = value;
+                       zval_ptr_dtor(&element->data);
+                       ZVAL_COPY_VALUE(&element->data, value);
 
                        /* new element, call ctor as in spl_ptr_llist_push */
                        if (intern->llist->ctor) {
                                intern->llist->ctor(element TSRMLS_CC);
                        }
                } else {
-                       zval_ptr_dtor(&value);
+                       zval_ptr_dtor(value);
                        zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid", 0 TSRMLS_CC);
                        return;
                }
        }
 } /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::offsetUnset(mixed $index) U
+/* {{{ proto void SplDoublyLinkedList::offsetUnset(mixed $index)
  Unsets the value at the specified $index. */
 SPL_METHOD(SplDoublyLinkedList, offsetUnset)
 {
@@ -879,7 +860,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
        llist  = intern->llist;
 
@@ -916,8 +897,8 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
                        llist->dtor(element TSRMLS_CC);
                }
 
-               zval_ptr_dtor((zval **)&element->data);
-               element->data = NULL;
+               zval_ptr_dtor(&element->data);
+               ZVAL_UNDEF(&element->data);
 
                SPL_LLIST_DELREF(element);
        } else {
@@ -933,7 +914,7 @@ static void spl_dllist_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        SPL_LLIST_CHECK_DELREF(iterator->traverse_pointer);
 
        zend_user_it_invalidate_current(iter TSRMLS_CC);
-       zval_ptr_dtor((zval**)&iterator->intern.it.data);
+       zval_ptr_dtor(iterator->intern.it.data);
 
        efree(iterator);
 }
@@ -965,21 +946,19 @@ static void spl_dllist_it_helper_move_forward(spl_ptr_llist_element **traverse_p
                        (*traverse_position_ptr)--;
 
                        if (flags & SPL_DLLIST_IT_DELETE) {
-                               zval *prev = (zval *)spl_ptr_llist_pop(llist TSRMLS_CC);
+                               zval prev;
+                               spl_ptr_llist_pop(llist, &prev TSRMLS_CC);
 
-                               if (prev) {
-                                       zval_ptr_dtor((zval **)&prev);
-                               }
+                               zval_ptr_dtor(&prev);
                        }
                } else {
                        *traverse_pointer_ptr = old->next;
 
                        if (flags & SPL_DLLIST_IT_DELETE) {
-                               zval *prev = (zval *)spl_ptr_llist_shift(llist TSRMLS_CC);
+                               zval prev;
+                               spl_ptr_llist_shift(llist, &prev TSRMLS_CC);
 
-                               if (prev) {
-                                       zval_ptr_dtor((zval **)&prev);
-                               }
+                               zval_ptr_dtor(&prev);
                        } else {
                                (*traverse_position_ptr)++;
                        }
@@ -1010,16 +989,16 @@ static int spl_dllist_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static void spl_dllist_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
+static zval *spl_dllist_it_get_current_data(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 {
        spl_dllist_it         *iterator = (spl_dllist_it *)iter;
        spl_ptr_llist_element *element  = iterator->traverse_pointer;
 
-       if (element == NULL || element->data == NULL) {
-               *data = NULL;
-       } else {
-               *data = (zval **)&element->data;
+       if (element == NULL || ZVAL_IS_UNDEF(&element->data)) {
+               return NULL;
        }
+
+       return &element->data;
 }
 /* }}} */
 
@@ -1042,11 +1021,11 @@ static void spl_dllist_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /*
 }
 /* }}} */
 
-/* {{{  proto int SplDoublyLinkedList::key() U
+/* {{{  proto int SplDoublyLinkedList::key()
    Return current array key */
 SPL_METHOD(SplDoublyLinkedList, key)
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1056,11 +1035,11 @@ SPL_METHOD(SplDoublyLinkedList, key)
 }
 /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::prev() U
+/* {{{ proto void SplDoublyLinkedList::prev()
    Move to next entry */
 SPL_METHOD(SplDoublyLinkedList, prev)
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1070,11 +1049,11 @@ SPL_METHOD(SplDoublyLinkedList, prev)
 }
 /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::next() U
+/* {{{ proto void SplDoublyLinkedList::next()
    Move to next entry */
 SPL_METHOD(SplDoublyLinkedList, next)
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1084,11 +1063,11 @@ SPL_METHOD(SplDoublyLinkedList, next)
 }
 /* }}} */
 
-/* {{{ proto bool SplDoublyLinkedList::valid() U
+/* {{{ proto bool SplDoublyLinkedList::valid()
    Check whether the datastructure contains more entries */
 SPL_METHOD(SplDoublyLinkedList, valid)
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1098,11 +1077,11 @@ SPL_METHOD(SplDoublyLinkedList, valid)
 }
 /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::rewind() U
+/* {{{ proto void SplDoublyLinkedList::rewind()
    Rewind the datastructure back to the start */
 SPL_METHOD(SplDoublyLinkedList, rewind)
 {
-       spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1112,33 +1091,33 @@ SPL_METHOD(SplDoublyLinkedList, rewind)
 }
 /* }}} */
 
-/* {{{ proto mixed|NULL SplDoublyLinkedList::current() U
+/* {{{ proto mixed|NULL SplDoublyLinkedList::current()
    Return current datastructure entry */
 SPL_METHOD(SplDoublyLinkedList, current)
 {
-       spl_dllist_object     *intern  = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object     *intern  = (spl_dllist_object*)Z_OBJ_P(getThis());
        spl_ptr_llist_element *element = intern->traverse_pointer;
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       if (element == NULL || element->data == NULL) {
+       if (element == NULL || ZVAL_IS_UNDEF(&element->data)) {
                RETURN_NULL();
        } else {
-               zval *data    = (zval *)element->data;
-               RETURN_ZVAL(data, 1, 0);
+               RETURN_ZVAL(&element->data, 1, 0);
        }
 }
 /* }}} */
+
 /* {{{ proto string SplDoublyLinkedList::serialize()
  Serializes storage */
 SPL_METHOD(SplDoublyLinkedList, serialize)
 {
-       spl_dllist_object     *intern   = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_dllist_object     *intern   = (spl_dllist_object*)Z_OBJ_P(getThis());
        smart_str              buf      = {0};
        spl_ptr_llist_element *current  = intern->llist->head, *next;
-       zval                   *flags;
+       zval                   flags;
        php_serialize_data_t   var_hash;
 
        if (zend_parse_parameters_none() == FAILURE) {
@@ -1148,8 +1127,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
        PHP_VAR_SERIALIZE_INIT(var_hash);
 
        /* flags */
-       MAKE_STD_ZVAL(flags);
-       ZVAL_LONG(flags, intern->flags);
+       ZVAL_LONG(&flags, intern->flags);
        php_var_serialize(&buf, &flags, &var_hash TSRMLS_CC);
        zval_ptr_dtor(&flags);
 
@@ -1158,7 +1136,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
                smart_str_appendc(&buf, ':');
                next = current->next;
 
-               php_var_serialize(&buf, (zval **)&current->data, &var_hash TSRMLS_CC);
+               php_var_serialize(&buf, &current->data, &var_hash TSRMLS_CC);
 
                current = next;
        }
@@ -1169,7 +1147,9 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
        PHP_VAR_SERIALIZE_DESTROY(var_hash);
 
        if (buf.c) {
-               RETURN_STRINGL(buf.c, buf.len, 0);
+               RETVAL_STRINGL(buf.c, buf.len);
+               smart_str_free(&buf);
+               return;
        } else {
                RETURN_NULL();
        }
@@ -1180,8 +1160,8 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
  Unserializes storage */
 SPL_METHOD(SplDoublyLinkedList, unserialize)
 {
-       spl_dllist_object     *intern   = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       zval                  *flags, *elem;
+       spl_dllist_object *intern = (spl_dllist_object*)Z_OBJ_P(getThis());
+       zval flags, elem;
        char *buf;
        int buf_len;
        const unsigned char *p, *s;
@@ -1200,24 +1180,27 @@ SPL_METHOD(SplDoublyLinkedList, unserialize)
        PHP_VAR_UNSERIALIZE_INIT(var_hash);
 
        /* flags */
-       ALLOC_INIT_ZVAL(flags);
-       if (!php_var_unserialize(&flags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(flags) != IS_LONG) {
+       if (!php_var_unserialize(&flags, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+               goto error;
+       }
+
+       if (Z_TYPE(flags) != IS_LONG) {
                zval_ptr_dtor(&flags);
                goto error;
        }
-       intern->flags = Z_LVAL_P(flags);
+
+       intern->flags = Z_LVAL(flags);
        zval_ptr_dtor(&flags);
 
        /* elements */
        while(*p == ':') {
                ++p;
-               ALLOC_INIT_ZVAL(elem);
                if (!php_var_unserialize(&elem, &p, s + buf_len, &var_hash TSRMLS_CC)) {
-                       zval_ptr_dtor(&elem);
                        goto error;
                }
 
-               spl_ptr_llist_push(intern->llist, elem TSRMLS_CC);
+               spl_ptr_llist_push(intern->llist, &elem TSRMLS_CC);
+               zval_ptr_dtor(&elem);
        }
 
        if (*p != '\0') {
@@ -1234,7 +1217,7 @@ error:
 
 } /* }}} */
 
-/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval) U
+/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval)
  Inserts a new entry before the specified $index consisting of $newval. */
 SPL_METHOD(SplDoublyLinkedList, add)
 {
@@ -1247,7 +1230,7 @@ SPL_METHOD(SplDoublyLinkedList, add)
                return;
        }
 
-       intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_dllist_object*)Z_OBJ_P(getThis());
        index  = spl_offset_convert_to_long(zindex TSRMLS_CC);
 
        if (index < 0 || index > intern->llist->count) {
@@ -1266,7 +1249,7 @@ SPL_METHOD(SplDoublyLinkedList, add)
                /* Get the element we want to insert before */
                element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);
 
-               elem->data = value;
+               ZVAL_COPY_VALUE(&elem->data, value);
                elem->rc   = 1;
                /* connect to the neighbours */
                elem->next = element;
@@ -1288,8 +1271,7 @@ SPL_METHOD(SplDoublyLinkedList, add)
        }
 } /* }}} */
 
-
-/* iterator handler table */
+/* {{{ iterator handler table */
 zend_object_iterator_funcs spl_dllist_it_funcs = {
        spl_dllist_it_dtor,
        spl_dllist_it_valid,
@@ -1297,12 +1279,12 @@ zend_object_iterator_funcs spl_dllist_it_funcs = {
        spl_dllist_it_get_current_key,
        spl_dllist_it_move_forward,
        spl_dllist_it_rewind
-};
+}; /* }}} */
 
 zend_object_iterator *spl_dllist_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
 {
        spl_dllist_it     *iterator;
-       spl_dllist_object *dllist_object = (spl_dllist_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_dllist_object *dllist_object = (spl_dllist_object*)Z_OBJ_P(object);
 
        if (by_ref) {
                zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
@@ -1398,9 +1380,11 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
        REGISTER_SPL_STD_CLASS_EX(SplDoublyLinkedList, spl_dllist_object_new, spl_funcs_SplDoublyLinkedList);
        memcpy(&spl_handler_SplDoublyLinkedList, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
 
-       spl_handler_SplDoublyLinkedList.clone_obj      = spl_dllist_object_clone;
+       spl_handler_SplDoublyLinkedList.clone_obj = spl_dllist_object_clone;
        spl_handler_SplDoublyLinkedList.count_elements = spl_dllist_object_count_elements;
        spl_handler_SplDoublyLinkedList.get_debug_info = spl_dllist_object_get_debug_info;
+       spl_handler_SplDoublyLinkedList.dtor_obj = zend_objects_destroy_object;
+       spl_handler_SplDoublyLinkedList.free_obj = spl_dllist_object_free_storage;
 
        REGISTER_SPL_CLASS_CONST_LONG(SplDoublyLinkedList, "IT_MODE_LIFO",  SPL_DLLIST_IT_LIFO);
        REGISTER_SPL_CLASS_CONST_LONG(SplDoublyLinkedList, "IT_MODE_FIFO",  0);
@@ -1423,6 +1407,7 @@ PHP_MINIT_FUNCTION(spl_dllist) /* {{{ */
        return SUCCESS;
 }
 /* }}} */
+
 /*
  * Local variables:
  * tab-width: 4
index dcd1582d60e67225f960553306d62fe9861bc6c5..3c35dc77c29231fcc76111fa602bbcf6475d3a70 100644 (file)
@@ -44,14 +44,14 @@ ZEND_GET_MODULE(spl_fixedarray)
 
 typedef struct _spl_fixedarray { /* {{{ */
        long size;
-       zval **elements;
+       zval *elements;
 } spl_fixedarray;
 /* }}} */
 
 typedef struct _spl_fixedarray_object { /* {{{ */
        zend_object            std;
-       spl_fixedarray         *array;
-       zval                  *retval;
+       spl_fixedarray        *array;
+       zval                   retval;
        zend_function         *fptr_offset_get;
        zend_function         *fptr_offset_set;
        zend_function         *fptr_offset_has;
@@ -79,7 +79,7 @@ static void spl_fixedarray_init(spl_fixedarray *array, long size TSRMLS_DC) /* {
 {
        if (size > 0) {
                array->size = 0; /* reset size in case ecalloc() fails */
-               array->elements = ecalloc(size, sizeof(zval *));
+               array->elements = ecalloc(size, sizeof(zval));
                array->size = size;
        } else {
                array->elements = NULL;
@@ -106,9 +106,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, long size TSRMLS_DC) /*
                long i;
 
                for (i = 0; i < array->size; i++) {
-                       if (array->elements[i]) {
-                               zval_ptr_dtor(&(array->elements[i]));
-                       }
+                       zval_ptr_dtor(&(array->elements[i]));
                }
 
                if (array->elements) {
@@ -116,17 +114,15 @@ static void spl_fixedarray_resize(spl_fixedarray *array, long size TSRMLS_DC) /*
                        array->elements = NULL;
                }
        } else if (size > array->size) {
-               array->elements = erealloc(array->elements, sizeof(zval *) * size);
-               memset(array->elements + array->size, '\0', sizeof(zval *) * (size - array->size));
+               array->elements = erealloc(array->elements, sizeof(zval) * size);
+               memset(array->elements + array->size, '\0', sizeof(zval) * (size - array->size));
        } else { /* size < array->size */
                long i;
 
                for (i = size; i < array->size; i++) {
-                       if (array->elements[i]) {
-                               zval_ptr_dtor(&(array->elements[i]));
-                       }
+                       zval_ptr_dtor(&(array->elements[i]));
                }
-               array->elements = erealloc(array->elements, sizeof(zval *) * size);
+               array->elements = erealloc(array->elements, sizeof(zval) * size);
        }
 
        array->size = size;
@@ -137,19 +133,14 @@ static void spl_fixedarray_copy(spl_fixedarray *to, spl_fixedarray *from TSRMLS_
 {
        int i;
        for (i = 0; i < from->size; i++) {
-               if (from->elements[i]) {
-                       Z_ADDREF_P(from->elements[i]);
-                       to->elements[i] = from->elements[i];
-               } else {
-                       to->elements[i] = NULL;
-               }
+               ZVAL_COPY(&to->elements[i], &from->elements[i]);
        }
 }
 /* }}} */
 
-static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{{ */
+static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval **table, int *n TSRMLS_DC) /* {{{{ */
 {
-       spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC);
+       spl_fixedarray_object *intern  = (spl_fixedarray_object*)Z_OBJ_P(obj);
        HashTable *ht = zend_std_get_properties(obj TSRMLS_CC);
 
        if (intern->array) {
@@ -166,7 +157,7 @@ static HashTable* spl_fixedarray_object_get_gc(zval *obj, zval ***table, int *n
 
 static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {{{{ */
 {
-       spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC);
+       spl_fixedarray_object *intern  = (spl_fixedarray_object*)Z_OBJ_P(obj);
        HashTable *ht = zend_std_get_properties(obj TSRMLS_CC);
        int  i = 0;
 
@@ -174,12 +165,12 @@ static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {
                int j = zend_hash_num_elements(ht);
 
                for (i = 0; i < intern->array->size; i++) {
-                       if (intern->array->elements[i]) {
-                               zend_hash_index_update(ht, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL);
-                               Z_ADDREF_P(intern->array->elements[i]);
+                       if (!ZVAL_IS_UNDEF(&intern->array->elements[i])) {
+                               zend_hash_index_update(ht, i, &intern->array->elements[i]);
+                               Z_ADDREF_P(&intern->array->elements[i]);
                        } else {
-                               zend_hash_index_update(ht, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL);
-                               Z_ADDREF_P(EG(uninitialized_zval_ptr));
+                               zend_hash_index_update(ht, i, &EG(uninitialized_zval));
+                               Z_ADDREF_P(&EG(uninitialized_zval));
                        }
                }
                if (j > intern->array->size) {
@@ -193,16 +184,14 @@ static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {
 }
 /* }}}} */
 
-static void spl_fixedarray_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void spl_fixedarray_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        spl_fixedarray_object *intern = (spl_fixedarray_object *)object;
        long i;
 
        if (intern->array) {
                for (i = 0; i < intern->array->size; i++) {
-                       if (intern->array->elements[i]) {
-                               zval_ptr_dtor(&(intern->array->elements[i]));
-                       }
+                       zval_ptr_dtor(&(intern->array->elements[i]));
                }
 
                if (intern->array->size > 0 && intern->array->elements) {
@@ -220,16 +209,13 @@ static void spl_fixedarray_object_free_storage(void *object TSRMLS_DC) /* {{{ */
 
 zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
 
-static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_type, spl_fixedarray_object **obj, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
+static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
 {
-       zend_object_value     retval;
        spl_fixedarray_object *intern;
        zend_class_entry     *parent = class_type;
        int                   inherited = 0;
 
        intern = ecalloc(1, sizeof(spl_fixedarray_object));
-       *obj = intern;
-       ALLOC_INIT_ZVAL(intern->retval);
 
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
@@ -238,7 +224,7 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty
        intern->flags = 0;
 
        if (orig && clone_orig) {
-               spl_fixedarray_object *other = (spl_fixedarray_object*)zend_object_store_get_object(orig TSRMLS_CC);
+               spl_fixedarray_object *other = (spl_fixedarray_object*)Z_OBJ_P(orig);
                intern->ce_get_iterator = other->ce_get_iterator;
                if (!other->array) {
                        /* leave a empty object, will be dtor later by CLONE handler */
@@ -252,7 +238,7 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty
 
        while (parent) {
                if (parent == spl_ce_SplFixedArray) {
-                       retval.handlers = &spl_handler_SplFixedArray;
+                       intern->std.handlers = &spl_handler_SplFixedArray;
                        class_type->get_iterator = spl_fixedarray_get_iterator;
                        break;
                }
@@ -261,17 +247,18 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty
                inherited = 1;
        }
 
-       retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_fixedarray_object_free_storage, NULL TSRMLS_CC);
+       zend_objects_store_put(&intern->std);
 
        if (!parent) { /* this must never happen */
                php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray");
        }
+
        if (!class_type->iterator_funcs.zf_current) {
-               zend_hash_find(&class_type->function_table, "rewind",  sizeof("rewind"),  (void **) &class_type->iterator_funcs.zf_rewind);
-               zend_hash_find(&class_type->function_table, "valid",   sizeof("valid"),   (void **) &class_type->iterator_funcs.zf_valid);
-               zend_hash_find(&class_type->function_table, "key",     sizeof("key"),     (void **) &class_type->iterator_funcs.zf_key);
-               zend_hash_find(&class_type->function_table, "current", sizeof("current"), (void **) &class_type->iterator_funcs.zf_current);
-               zend_hash_find(&class_type->function_table, "next",    sizeof("next"),    (void **) &class_type->iterator_funcs.zf_next);
+               class_type->iterator_funcs.zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
+               class_type->iterator_funcs.zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
+               class_type->iterator_funcs.zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
+               class_type->iterator_funcs.zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
+               class_type->iterator_funcs.zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
        }
        if (inherited) {
                if (class_type->iterator_funcs.zf_rewind->common.scope  != parent) { 
@@ -290,58 +277,53 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty
                        intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT;
                }
 
-               zend_hash_find(&class_type->function_table, "offsetget",    sizeof("offsetget"),    (void **) &intern->fptr_offset_get);
+               intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1);
                if (intern->fptr_offset_get->common.scope == parent) {
                        intern->fptr_offset_get = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetset",    sizeof("offsetset"),    (void **) &intern->fptr_offset_set);
+               intern->fptr_offset_set = zend_hash_str_find_ptr(&class_type->function_table, "offsetset", sizeof("offsetset") - 1);
                if (intern->fptr_offset_set->common.scope == parent) {
                        intern->fptr_offset_set = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetexists", sizeof("offsetexists"), (void **) &intern->fptr_offset_has);
+               intern->fptr_offset_has = zend_hash_str_find_ptr(&class_type->function_table, "offsetexists", sizeof("offsetexists") - 1);
                if (intern->fptr_offset_has->common.scope == parent) {
                        intern->fptr_offset_has = NULL;
                }
-               zend_hash_find(&class_type->function_table, "offsetunset",  sizeof("offsetunset"),  (void **) &intern->fptr_offset_del);
+               intern->fptr_offset_del = zend_hash_str_find_ptr(&class_type->function_table, "offsetunset", sizeof("offsetunset") - 1);
                if (intern->fptr_offset_del->common.scope == parent) {
                        intern->fptr_offset_del = NULL;
                }
-               zend_hash_find(&class_type->function_table, "count",        sizeof("count"),        (void **) &intern->fptr_count);
+               intern->fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1);
                if (intern->fptr_count->common.scope == parent) {
                        intern->fptr_count = NULL;
                }
        }
 
-       return retval;
+       return &intern->std;
 }
 /* }}} */
 
-static zend_object_value spl_fixedarray_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *spl_fixedarray_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       spl_fixedarray_object *tmp;
-       return spl_fixedarray_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC);
+       return spl_fixedarray_object_new_ex(class_type, NULL, 0 TSRMLS_CC);
 }
 /* }}} */
 
-static zend_object_value spl_fixedarray_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
+static zend_object *spl_fixedarray_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
 {
-       zend_object_value      new_obj_val;
-       zend_object           *old_object;
-       zend_object           *new_object;
-       zend_object_handle     handle = Z_OBJ_HANDLE_P(zobject);
-       spl_fixedarray_object  *intern;
+       zend_object *old_object;
+       zend_object *new_object;
 
-       old_object  = zend_objects_get_address(zobject TSRMLS_CC);
-       new_obj_val = spl_fixedarray_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC);
-       new_object  = &intern->std;
+       old_object  = Z_OBJ_P(zobject);
+       new_object = spl_fixedarray_object_new_ex(old_object->ce, zobject, 1 TSRMLS_CC);
 
-       zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
+       zend_objects_clone_members(new_object, old_object TSRMLS_CC);
 
-       return new_obj_val;
+       return new_object;
 }
 /* }}} */
 
-static inline zval **spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */
+static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */
 {
        long index;
 
@@ -361,7 +343,7 @@ static inline zval **spl_fixedarray_object_read_dimension_helper(spl_fixedarray_
        if (index < 0 || intern->array == NULL || index >= intern->array->size) {
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
                return NULL;
-       } else if(!intern->array->elements[index]) {
+       } else if (ZVAL_IS_UNDEF(&intern->array->elements[index])) {
                return NULL;
        } else {
                return &intern->array->elements[index];
@@ -372,33 +354,29 @@ static inline zval **spl_fixedarray_object_read_dimension_helper(spl_fixedarray_
 static zval *spl_fixedarray_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */
 {
        spl_fixedarray_object *intern;
-       zval **retval;
+       zval *retval;
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
 
        if (intern->fptr_offset_get) {
-               zval *rv;
+               zval tmp, rv;
                if (!offset) {
-                       ALLOC_INIT_ZVAL(offset);
+                       ZVAL_UNDEF(&tmp);
+                       offset = &tmp;
                } else {
                        SEPARATE_ARG_IF_REF(offset);
                }
-               zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", &rv, offset);
-               zval_ptr_dtor(&offset);
-               if (rv) {
+               zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", &rv, offset);
+               zval_ptr_dtor(offset);
+               if (!ZVAL_IS_UNDEF(&rv)) {
                        zval_ptr_dtor(&intern->retval);
-                       MAKE_STD_ZVAL(intern->retval);
-                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
-                       return intern->retval;
+                       ZVAL_ZVAL(&intern->retval, &rv, 0, 0);
+                       return &intern->retval;
                }
-               return EG(uninitialized_zval_ptr);
+               return &EG(uninitialized_zval);
        }
 
-       retval = spl_fixedarray_object_read_dimension_helper(intern, offset TSRMLS_CC);
-       if (retval) {
-               return *retval;
-       }
-       return NULL;
+       return spl_fixedarray_object_read_dimension_helper(intern, offset TSRMLS_CC);
 }
 /* }}} */
 
@@ -422,11 +400,11 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
                return;
        } else {
-               if (intern->array->elements[index]) {
+               if (!ZVAL_IS_UNDEF(&intern->array->elements[index])) {
                        zval_ptr_dtor(&(intern->array->elements[index]));
                }
                SEPARATE_ARG_IF_REF(value);
-               intern->array->elements[index] = value;
+               ZVAL_COPY_VALUE(&intern->array->elements[index], value);
        }
 }
 /* }}} */
@@ -435,18 +413,20 @@ static void spl_fixedarray_object_write_dimension(zval *object, zval *offset, zv
 {
        spl_fixedarray_object *intern;
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object *)Z_OBJ_P(object);
 
        if (intern->fptr_offset_set) {
+               zval tmp;
                if (!offset) {
-                       ALLOC_INIT_ZVAL(offset);
+                       ZVAL_UNDEF(&tmp);
+                       offset = &tmp;
                } else {
                        SEPARATE_ARG_IF_REF(offset);
                }
                SEPARATE_ARG_IF_REF(value);
-               zend_call_method_with_2_params(&object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value);
-               zval_ptr_dtor(&value);
-               zval_ptr_dtor(&offset);
+               zend_call_method_with_2_params(object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value);
+               zval_ptr_dtor(value);
+               zval_ptr_dtor(offset);
                return;
        }
 
@@ -468,10 +448,8 @@ static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_o
                zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
                return;
        } else {
-               if (intern->array->elements[index]) {
-                       zval_ptr_dtor(&(intern->array->elements[index]));
-               }
-               intern->array->elements[index] = NULL;
+               zval_ptr_dtor(&(intern->array->elements[index]));
+               ZVAL_UNDEF(&intern->array->elements[index]);
        }
 }
 /* }}} */
@@ -480,12 +458,12 @@ static void spl_fixedarray_object_unset_dimension(zval *object, zval *offset TSR
 {
        spl_fixedarray_object *intern;
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object *)Z_OBJ_P(object);
 
        if (intern->fptr_offset_del) {
                SEPARATE_ARG_IF_REF(offset);
-               zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset);
-               zval_ptr_dtor(&offset);
+               zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset);
+               zval_ptr_dtor(offset);
                return;
        }
 
@@ -508,10 +486,10 @@ static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_obje
        if (index < 0 || intern->array == NULL || index >= intern->array->size) {
                retval = 0;
        } else {
-               if (!intern->array->elements[index]) {
+               if (ZVAL_IS_UNDEF(&intern->array->elements[index])) {
                        retval = 0;
                } else if (check_empty) {
-                       if (zend_is_true(intern->array->elements[index] TSRMLS_CC)) {
+                       if (zend_is_true(&intern->array->elements[index] TSRMLS_CC)) {
                                retval = 1;
                        } else {
                                retval = 0;
@@ -529,18 +507,17 @@ static int spl_fixedarray_object_has_dimension(zval *object, zval *offset, int c
 {
        spl_fixedarray_object *intern;
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
 
        if (intern->fptr_offset_get) {
-               zval *rv;
+               zval rv;
                SEPARATE_ARG_IF_REF(offset);
-               zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_has, "offsetExists", &rv, offset);
-               zval_ptr_dtor(&offset);
-               if (rv) {
+               zend_call_method_with_1_params(object, intern->std.ce, &intern->fptr_offset_has, "offsetExists", &rv, offset);
+               zval_ptr_dtor(offset);
+               if (!ZVAL_IS_UNDEF(&rv)) {
                        zval_ptr_dtor(&intern->retval);
-                       MAKE_STD_ZVAL(intern->retval);
-                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
-                       return zend_is_true(intern->retval TSRMLS_CC);
+                       ZVAL_ZVAL(&intern->retval, &rv, 0, 0);
+                       return zend_is_true(&intern->retval TSRMLS_CC);
                }
                return 0;
        }
@@ -553,16 +530,15 @@ static int spl_fixedarray_object_count_elements(zval *object, long *count TSRMLS
 {
        spl_fixedarray_object *intern;
        
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
        if (intern->fptr_count) {
-               zval *rv;
-               zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv);
-               if (rv) {
+               zval rv;
+               zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+               if (!ZVAL_IS_UNDEF(&rv)) {
                        zval_ptr_dtor(&intern->retval);
-                       MAKE_STD_ZVAL(intern->retval);
-                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
-                       convert_to_long(intern->retval);
-                       *count = (long) Z_LVAL_P(intern->retval);
+                       ZVAL_ZVAL(&intern->retval, &rv, 0, 0);
+                       convert_to_long(&intern->retval);
+                       *count = (long) Z_LVAL(intern->retval);
                        return SUCCESS;
                }
        } else if (intern->array) {
@@ -592,7 +568,7 @@ SPL_METHOD(SplFixedArray, __construct)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
 
        if (intern->array) {
                /* called __construct() twice, bail out */
@@ -608,10 +584,10 @@ SPL_METHOD(SplFixedArray, __construct)
 */
 SPL_METHOD(SplFixedArray, __wakeup)
 {
-       spl_fixedarray_object *intern = (spl_fixedarray_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_fixedarray_object *intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        HashPosition ptr;
        HashTable *intern_ht = zend_std_get_properties(getThis() TSRMLS_CC);
-       zval **data;
+       zval *data;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -624,9 +600,9 @@ SPL_METHOD(SplFixedArray, __wakeup)
                intern->array = emalloc(sizeof(spl_fixedarray));
                spl_fixedarray_init(intern->array, size TSRMLS_CC);
 
-               for (zend_hash_internal_pointer_reset_ex(intern_ht, &ptr); zend_hash_get_current_data_ex(intern_ht, (void **) &data, &ptr) == SUCCESS; zend_hash_move_forward_ex(intern_ht, &ptr)) {
+               for (zend_hash_internal_pointer_reset_ex(intern_ht, &ptr); (data = zend_hash_get_current_data_ex(intern_ht, &ptr)) != NULL; zend_hash_move_forward_ex(intern_ht, &ptr)) {
                        Z_ADDREF_PP(data);
-                       intern->array->elements[index++] = *data;
+                       ZVAL_COPY_VALUE(&intern->array->elements[index++], data);
                }
 
                /* Remove the unserialised properties, since we now have the elements
@@ -647,7 +623,7 @@ SPL_METHOD(SplFixedArray, count)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
        if (intern->array) {
                RETURN_LONG(intern->array->size);
        }
@@ -665,18 +641,18 @@ SPL_METHOD(SplFixedArray, toArray)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
 
        array_init(return_value);
        if (intern->array) {
                int i = 0;
                for (; i < intern->array->size; i++) {
-                       if (intern->array->elements[i]) {
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, (void *)&intern->array->elements[i], sizeof(zval *), NULL);
-                               Z_ADDREF_P(intern->array->elements[i]);
+                       if (!ZVAL_IS_UNDEF(&intern->array->elements[i])) {
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array->elements[i]);
+                               Z_ADDREF_P(&intern->array->elements[i]);
                        } else {
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL);
-                               Z_ADDREF_P(EG(uninitialized_zval_ptr));
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), i, &EG(uninitialized_zval));
+                               Z_ADDREF_P(&EG(uninitialized_zval));
                        }
                }
        }
@@ -697,17 +673,17 @@ SPL_METHOD(SplFixedArray, fromArray)
                return;
        }
 
-       array = ecalloc(1, sizeof(*array));
+       array = ecalloc(1, sizeof(spl_fixedarray));
        num = zend_hash_num_elements(Z_ARRVAL_P(data));
        
        if (num > 0 && save_indexes) {
-               zval **element, *value;
-               char *str_index;
+               zval *element;
+               zend_string *str_index;
                ulong num_index, max_index = 0;
                long tmp;
 
                for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
-                       zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+                       (element = zend_hash_get_current_data(Z_ARRVAL_P(data))) != NULL;
                        zend_hash_move_forward(Z_ARRVAL_P(data))
                        ) {
                        if (zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0) != HASH_KEY_IS_LONG || (long)num_index < 0) {
@@ -730,32 +706,29 @@ SPL_METHOD(SplFixedArray, fromArray)
                spl_fixedarray_init(array, tmp TSRMLS_CC);
 
                for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
-                       zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+                       (element = zend_hash_get_current_data(Z_ARRVAL_P(data))) != NULL;
                        zend_hash_move_forward(Z_ARRVAL_P(data))
                        ) {
                        
                        zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0);
-                       value = *element;
 
-                       SEPARATE_ARG_IF_REF(value);
-                       array->elements[num_index] = value;
+                       SEPARATE_ARG_IF_REF(element);
+                       ZVAL_COPY_VALUE(&array->elements[num_index], element);
                }
 
        } else if (num > 0 && !save_indexes) {
-               zval **element, *value;
+               zval *element;
                long i = 0;
                
                spl_fixedarray_init(array, num TSRMLS_CC);
                
                for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
-                       zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
+                       (element = zend_hash_get_current_data(Z_ARRVAL_P(data))) != NULL;
                        zend_hash_move_forward(Z_ARRVAL_P(data))
                        ) {
                        
-                       value = *element;
-
-                       SEPARATE_ARG_IF_REF(value);
-                       array->elements[i] = value;
+                       SEPARATE_ARG_IF_REF(element);
+                       ZVAL_COPY_VALUE(&array->elements[i], element);
                        i++;
                }
        } else {
@@ -765,7 +738,7 @@ SPL_METHOD(SplFixedArray, fromArray)
        object_init_ex(return_value, spl_ce_SplFixedArray);
        Z_TYPE_P(return_value) = IS_OBJECT;
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(return_value TSRMLS_CC);
+       intern = (spl_fixedarray_object *)Z_OBJ_P(return_value);
        intern->array = array;
 }
 /* }}} */
@@ -781,7 +754,7 @@ SPL_METHOD(SplFixedArray, getSize)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
        if (intern->array) {
                RETURN_LONG(intern->array->size);
        }
@@ -806,7 +779,7 @@ SPL_METHOD(SplFixedArray, setSize)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(object);
        if (!intern->array) {
                intern->array = ecalloc(1, sizeof(spl_fixedarray));
        }
@@ -827,7 +800,7 @@ SPL_METHOD(SplFixedArray, offsetExists)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
 
        RETURN_BOOL(spl_fixedarray_object_has_dimension_helper(intern, zindex, 0 TSRMLS_CC));
 } /* }}} */
@@ -836,18 +809,18 @@ SPL_METHOD(SplFixedArray, offsetExists)
  Returns the value at the specified $index. */
 SPL_METHOD(SplFixedArray, offsetGet)
 {
-       zval                  *zindex, **value_pp;
+       zval *zindex, *value;
        spl_fixedarray_object  *intern;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
                return;
        }
 
-       intern    = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
-       value_pp  = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
+       value = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
 
-       if (value_pp) {
-               RETURN_ZVAL(*value_pp, 1, 0);
+       if (value) {
+               RETURN_ZVAL(value, 1, 0);
        }
        RETURN_NULL();
 } /* }}} */
@@ -863,7 +836,7 @@ SPL_METHOD(SplFixedArray, offsetSet)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        spl_fixedarray_object_write_dimension_helper(intern, zindex, value TSRMLS_CC);
 
 } /* }}} */
@@ -879,7 +852,7 @@ SPL_METHOD(SplFixedArray, offsetUnset)
                return;
        }
 
-       intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        spl_fixedarray_object_unset_dimension_helper(intern, zindex TSRMLS_CC);
 
 } /* }}} */
@@ -889,7 +862,7 @@ static void spl_fixedarray_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{
        spl_fixedarray_it  *iterator = (spl_fixedarray_it *)iter;
 
        zend_user_it_invalidate_current(iter TSRMLS_CC);
-       zval_ptr_dtor((zval**)&iterator->intern.it.data);
+       zval_ptr_dtor(iterator->intern.it.data);
 
        efree(iterator);
 }
@@ -925,32 +898,33 @@ static int spl_fixedarray_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{
 }
 /* }}} */
 
-static void spl_fixedarray_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
+static zval *spl_fixedarray_it_get_current_data(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 {
-       zval                  *zindex;
-       spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
+       zval zindex;
+       spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter;
        spl_fixedarray_object *intern   = iterator->object;
 
        if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_CURRENT) {
-               zend_user_it_get_current_data(iter, data TSRMLS_CC);
+               return zend_user_it_get_current_data(iter TSRMLS_CC);
        } else {
-               ALLOC_INIT_ZVAL(zindex);
-               ZVAL_LONG(zindex, iterator->object->current);
-
-               *data = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
+               zval *data;
 
-               if (*data == NULL) {
-                       *data = &EG(uninitialized_zval_ptr);
-               }
+               ZVAL_LONG(&zindex, iterator->object->current);
 
+               data = spl_fixedarray_object_read_dimension_helper(intern, &zindex TSRMLS_CC);
                zval_ptr_dtor(&zindex);
+
+               if (data == NULL) {
+                       data = &EG(uninitialized_zval);
+               }
+               return data;
        }
 }
 /* }}} */
 
 static void spl_fixedarray_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
 {
-       spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
+       spl_fixedarray_it  *iterator = (spl_fixedarray_it *)iter;
        spl_fixedarray_object *intern   = iterator->object;
 
        if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_KEY) {
@@ -975,11 +949,11 @@ static void spl_fixedarray_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
 }
 /* }}} */
 
-/* {{{  proto int SplFixedArray::key() U
+/* {{{  proto int SplFixedArray::key()
    Return current array key */
 SPL_METHOD(SplFixedArray, key)
 {
-       spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_fixedarray_object *intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -989,11 +963,11 @@ SPL_METHOD(SplFixedArray, key)
 }
 /* }}} */
 
-/* {{{ proto void SplFixedArray::next() U
+/* {{{ proto void SplFixedArray::next()
    Move to next entry */
 SPL_METHOD(SplFixedArray, next)
 {
-       spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_fixedarray_object *intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1003,11 +977,11 @@ SPL_METHOD(SplFixedArray, next)
 }
 /* }}} */
 
-/* {{{ proto bool SplFixedArray::valid() U
+/* {{{ proto bool SplFixedArray::valid()
    Check whether the datastructure contains more entries */
 SPL_METHOD(SplFixedArray, valid)
 {
-       spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_fixedarray_object *intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1017,11 +991,11 @@ SPL_METHOD(SplFixedArray, valid)
 }
 /* }}} */
 
-/* {{{ proto void SplFixedArray::rewind() U
+/* {{{ proto void SplFixedArray::rewind()
    Rewind the datastructure back to the start */
 SPL_METHOD(SplFixedArray, rewind)
 {
-       spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_fixedarray_object *intern = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1031,26 +1005,25 @@ SPL_METHOD(SplFixedArray, rewind)
 }
 /* }}} */
 
-/* {{{ proto mixed|NULL SplFixedArray::current() U
+/* {{{ proto mixed|NULL SplFixedArray::current()
    Return current datastructure entry */
 SPL_METHOD(SplFixedArray, current)
 {
-       zval                 *zindex, **value_pp;
-       spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       zval zindex, *value;
+       spl_fixedarray_object *intern  = (spl_fixedarray_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       ALLOC_INIT_ZVAL(zindex);
-       ZVAL_LONG(zindex, intern->current);
+       ZVAL_LONG(&zindex, intern->current);
 
-       value_pp  = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
+       value = spl_fixedarray_object_read_dimension_helper(intern, &zindex TSRMLS_CC);
 
        zval_ptr_dtor(&zindex);
 
-       if (value_pp) {
-               RETURN_ZVAL(*value_pp, 1, 0);
+       if (value) {
+               RETURN_ZVAL(value, 1, 0);
        }
        RETURN_NULL();
 }
@@ -1069,7 +1042,7 @@ zend_object_iterator_funcs spl_fixedarray_it_funcs = {
 zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
 {
        spl_fixedarray_it      *iterator;
-       spl_fixedarray_object  *fixedarray_object = (spl_fixedarray_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_fixedarray_object  *fixedarray_object = (spl_fixedarray_object*)Z_OBJ_P(object);
 
        if (by_ref) {
                zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
@@ -1078,12 +1051,12 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob
 
        Z_ADDREF_P(object);
 
-       iterator                     = emalloc(sizeof(spl_fixedarray_it));
-       iterator->intern.it.data     = (void*)object;
-       iterator->intern.it.funcs    = &spl_fixedarray_it_funcs;
-       iterator->intern.ce          = ce;
-       iterator->intern.value       = NULL;
-       iterator->object             = fixedarray_object;
+       iterator = emalloc(sizeof(spl_fixedarray_it));
+       iterator->intern.it.data object;
+       iterator->intern.it.funcs = &spl_fixedarray_it_funcs;
+       iterator->intern.ce = ce;
+       iterator->intern.value = NULL;
+       iterator->object = fixedarray_object;
 
        return (zend_object_iterator*)iterator;
 }
@@ -1149,6 +1122,8 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
        spl_handler_SplFixedArray.count_elements  = spl_fixedarray_object_count_elements;
        spl_handler_SplFixedArray.get_properties  = spl_fixedarray_object_get_properties;
        spl_handler_SplFixedArray.get_gc          = spl_fixedarray_object_get_gc;
+       spl_handler_SplFixedArray.dtor_obj        = zend_objects_destroy_object;
+       spl_handler_SplFixedArray.free_obj        = spl_fixedarray_object_free_storage;
 
        REGISTER_SPL_IMPLEMENTS(SplFixedArray, Iterator);
        REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess);
index 8ad6e0de3bb3ecbcc3cd2a7bb4948091820e69c6..1520bfb4016dfee0b4ab3b52156815316c1c2eff 100644 (file)
@@ -49,14 +49,13 @@ PHPAPI zend_class_entry  *spl_ce_SplMaxHeap;
 PHPAPI zend_class_entry  *spl_ce_SplMinHeap;
 PHPAPI zend_class_entry  *spl_ce_SplPriorityQueue;
 
-typedef void *spl_ptr_heap_element;
 
-typedef void (*spl_ptr_heap_dtor_func)(spl_ptr_heap_element TSRMLS_DC);
-typedef void (*spl_ptr_heap_ctor_func)(spl_ptr_heap_element TSRMLS_DC);
-typedef int  (*spl_ptr_heap_cmp_func)(spl_ptr_heap_element, spl_ptr_heap_element, void* TSRMLS_DC);
+typedef void (*spl_ptr_heap_dtor_func)(zval * TSRMLS_DC);
+typedef void (*spl_ptr_heap_ctor_func)(zval * TSRMLS_DC);
+typedef int  (*spl_ptr_heap_cmp_func)(zval *, zval *, zval * TSRMLS_DC);
 
 typedef struct _spl_ptr_heap {
-       spl_ptr_heap_element   *elements;
+       zval                    *elements;
        spl_ptr_heap_ctor_func  ctor;
        spl_ptr_heap_dtor_func  dtor;
        spl_ptr_heap_cmp_func   cmp;
@@ -71,7 +70,7 @@ typedef struct _spl_heap_it spl_heap_it;
 struct _spl_heap_object {
        zend_object         std;
        spl_ptr_heap       *heap;
-       zval               *retval;
+       zval                retval;
        int                 flags;
        zend_class_entry   *ce_get_iterator;
        zend_function      *fptr_cmp;
@@ -86,51 +85,50 @@ struct _spl_heap_it {
        spl_heap_object    *object;
 };
 
-/* {{{  spl_ptr_heap */
-static void spl_ptr_heap_zval_dtor(spl_ptr_heap_element elem TSRMLS_DC) { /* {{{ */
-       if (elem) {
-               zval_ptr_dtor((zval **)&elem);
+static void spl_ptr_heap_zval_dtor(zval *elem TSRMLS_DC) { /* {{{ */
+       if (!ZVAL_IS_UNDEF(elem)) {
+               zval_ptr_dtor(elem);
        }
 }
 /* }}} */
 
-static void spl_ptr_heap_zval_ctor(spl_ptr_heap_element elem TSRMLS_DC) { /* {{{ */
-       Z_ADDREF_P((zval *)elem);
+static void spl_ptr_heap_zval_ctor(zval *elem TSRMLS_DC) { /* {{{ */
+       Z_ADDREF_P(elem);
 }
 /* }}} */
 
 static int spl_ptr_heap_cmp_cb_helper(zval *object, spl_heap_object *heap_object, zval *a, zval *b, long *result TSRMLS_DC) { /* {{{ */
-               zval *result_p = NULL;
+       zval zresult;
 
-               zend_call_method_with_2_params(&object, heap_object->std.ce, &heap_object->fptr_cmp, "compare", &result_p, a, b);
+       zend_call_method_with_2_params(object, heap_object->std.ce, &heap_object->fptr_cmp, "compare", &zresult, a, b);
 
-               if (EG(exception)) {
-                       return FAILURE;
-               }
+       if (EG(exception)) {
+               return FAILURE;
+       }
 
-               convert_to_long(result_p);
-               *result = Z_LVAL_P(result_p);
+       convert_to_long(&zresult);
+       *result = Z_LVAL(zresult);
 
-               zval_ptr_dtor(&result_p);
+       zval_ptr_dtor(&zresult);
 
-               return SUCCESS;
+       return SUCCESS;
 }
 /* }}} */
 
-static zval **spl_pqueue_extract_helper(zval **value, int flags) /* {{{ */
+static zval *spl_pqueue_extract_helper(zval *value, int flags) /* {{{ */
 {
        if ((flags & SPL_PQUEUE_EXTR_BOTH) == SPL_PQUEUE_EXTR_BOTH) {
                return value;
        } else if ((flags & SPL_PQUEUE_EXTR_BOTH) > 0) {
 
                if ((flags & SPL_PQUEUE_EXTR_DATA) == SPL_PQUEUE_EXTR_DATA) {
-                       zval **data;
-                       if (zend_hash_find(Z_ARRVAL_PP(value), "data", sizeof("data"), (void **) &data) == SUCCESS) {
+                       zval *data;
+                       if ((data = zend_hash_str_find(Z_ARRVAL_P(value), "data", sizeof("data") - 1)) != NULL) {
                                return data;
                        }
                } else {
-                       zval **priority;
-                       if (zend_hash_find(Z_ARRVAL_PP(value), "priority", sizeof("priority"), (void **) &priority) == SUCCESS) {
+                       zval *priority;
+                       if ((priority = zend_hash_str_find(Z_ARRVAL_P(value), "priority", sizeof("priority") - 1)) != NULL) {
                                return priority;
                        }
                }
@@ -140,7 +138,7 @@ static zval **spl_pqueue_extract_helper(zval **value, int flags) /* {{{ */
 }
 /* }}} */
 
-static int spl_ptr_heap_zval_max_cmp(spl_ptr_heap_element a, spl_ptr_heap_element b, void* object TSRMLS_DC) { /* {{{ */
+static int spl_ptr_heap_zval_max_cmp(zval *a, zval *b, zval *object TSRMLS_DC) { /* {{{ */
        zval result;
 
        if (EG(exception)) {
@@ -148,10 +146,10 @@ static int spl_ptr_heap_zval_max_cmp(spl_ptr_heap_element a, spl_ptr_heap_elemen
        }
 
        if (object) {
-               spl_heap_object *heap_object = (spl_heap_object*)zend_object_store_get_object((zval *)object TSRMLS_CC);
+               spl_heap_object *heap_object = (spl_heap_object*)Z_OBJ_P(object);
                if (heap_object->fptr_cmp) {
                        long lval = 0;
-                       if (spl_ptr_heap_cmp_cb_helper((zval *)object, heap_object, (zval *)a, (zval *)b, &lval TSRMLS_CC) == FAILURE) {
+                       if (spl_ptr_heap_cmp_cb_helper(object, heap_object, a, b, &lval TSRMLS_CC) == FAILURE) {
                                /* exception or call failure */
                                return 0;
                        }
@@ -159,13 +157,12 @@ static int spl_ptr_heap_zval_max_cmp(spl_ptr_heap_element a, spl_ptr_heap_elemen
                }
        }
 
-       INIT_ZVAL(result);
-       compare_function(&result, (zval *)a, (zval *)b TSRMLS_CC);
+       compare_function(&result, a, b TSRMLS_CC);
        return Z_LVAL(result);
 }
 /* }}} */
 
-static int spl_ptr_heap_zval_min_cmp(spl_ptr_heap_element a, spl_ptr_heap_element b, void* object TSRMLS_DC) { /* {{{ */
+static int spl_ptr_heap_zval_min_cmp(zval *a, zval *b, zval* object TSRMLS_DC) { /* {{{ */
        zval result;
 
        if (EG(exception)) {
@@ -173,7 +170,7 @@ static int spl_ptr_heap_zval_min_cmp(spl_ptr_heap_element a, spl_ptr_heap_elemen
        }
 
        if (object) {
-               spl_heap_object *heap_object = (spl_heap_object*)zend_object_store_get_object((zval *)object TSRMLS_CC);
+               spl_heap_object *heap_object = (spl_heap_object*)Z_OBJ_P(object);
                if (heap_object->fptr_cmp) {
                        long lval = 0;
                        if (spl_ptr_heap_cmp_cb_helper((zval *)object, heap_object, (zval *)a, (zval *)b, &lval TSRMLS_CC) == FAILURE) {
@@ -184,30 +181,30 @@ static int spl_ptr_heap_zval_min_cmp(spl_ptr_heap_element a, spl_ptr_heap_elemen
                }
        }
 
-       INIT_ZVAL(result);
-       compare_function(&result, (zval *)b, (zval *)a TSRMLS_CC);
+       compare_function(&result, b, a TSRMLS_CC);
        return Z_LVAL(result);
 }
 /* }}} */
 
-static int spl_ptr_pqueue_zval_cmp(spl_ptr_heap_element a, spl_ptr_heap_element b, void* object TSRMLS_DC) { /* {{{ */
+static int spl_ptr_pqueue_zval_cmp(zval *a, zval *b, zval *object TSRMLS_DC) { /* {{{ */
        zval result;
-       zval **a_priority_pp = spl_pqueue_extract_helper((zval **)&a, SPL_PQUEUE_EXTR_PRIORITY);
-       zval **b_priority_pp = spl_pqueue_extract_helper((zval **)&b, SPL_PQUEUE_EXTR_PRIORITY);
+       zval *a_priority_p = spl_pqueue_extract_helper(a, SPL_PQUEUE_EXTR_PRIORITY);
+       zval *b_priority_p = spl_pqueue_extract_helper(b, SPL_PQUEUE_EXTR_PRIORITY);
 
-       if ((!a_priority_pp) || (!b_priority_pp)) {
+       if ((!a_priority_p) || (!b_priority_p)) {
                zend_error(E_RECOVERABLE_ERROR, "Unable to extract from the PriorityQueue node");
                return 0;
        }
+
        if (EG(exception)) {
                return 0;
        }
 
        if (object) {
-               spl_heap_object *heap_object = (spl_heap_object*)zend_object_store_get_object(object TSRMLS_CC);
+               spl_heap_object *heap_object = (spl_heap_object*)Z_OBJ_P(object);
                if (heap_object->fptr_cmp) {
                        long lval = 0;
-                       if (spl_ptr_heap_cmp_cb_helper((zval *)object, heap_object, *a_priority_pp, *b_priority_pp, &lval TSRMLS_CC) == FAILURE) {
+                       if (spl_ptr_heap_cmp_cb_helper((zval *)object, heap_object, a_priority_p, b_priority_p, &lval TSRMLS_CC) == FAILURE) {
                                /* exception or call failure */
                                return 0;
                        }
@@ -215,8 +212,7 @@ static int spl_ptr_pqueue_zval_cmp(spl_ptr_heap_element a, spl_ptr_heap_element
                }
        }
 
-       INIT_ZVAL(result);
-       compare_function(&result, *a_priority_pp, *b_priority_pp TSRMLS_CC);
+       compare_function(&result, a_priority_p, b_priority_p TSRMLS_CC);
        return Z_LVAL(result);
 }
 /* }}} */
@@ -228,7 +224,7 @@ static spl_ptr_heap *spl_ptr_heap_init(spl_ptr_heap_cmp_func cmp, spl_ptr_heap_c
        heap->dtor     = dtor;
        heap->ctor     = ctor;
        heap->cmp      = cmp;
-       heap->elements = safe_emalloc(sizeof(spl_ptr_heap_element), PTR_HEAP_BLOCK_SIZE, 0);
+       heap->elements = ecalloc(PTR_HEAP_BLOCK_SIZE, sizeof(zval));
        heap->max_size = PTR_HEAP_BLOCK_SIZE;
        heap->count    = 0;
        heap->flags    = 0;
@@ -237,19 +233,20 @@ static spl_ptr_heap *spl_ptr_heap_init(spl_ptr_heap_cmp_func cmp, spl_ptr_heap_c
 }
 /* }}} */
 
-static void spl_ptr_heap_insert(spl_ptr_heap *heap, spl_ptr_heap_element elem, void *cmp_userdata TSRMLS_DC) { /* {{{ */
+static void spl_ptr_heap_insert(spl_ptr_heap *heap, zval *elem, void *cmp_userdata TSRMLS_DC) { /* {{{ */
        int i;
 
        if (heap->count+1 > heap->max_size) {
                /* we need to allocate more memory */
-               heap->elements  = (void **) safe_erealloc(heap->elements, sizeof(spl_ptr_heap_element), (heap->max_size), (sizeof(spl_ptr_heap_element) * (heap->max_size)));
                heap->max_size *= 2;
+               heap->elements  = erealloc(heap->elements, heap->max_size * sizeof(zval));
+               memset(heap->elements + heap->max_size/2 * sizeof(zval), 0, heap->max_size/2 * sizeof(zval));
        }
 
        heap->ctor(elem TSRMLS_CC);
 
        /* sifting up */
-       for(i = heap->count++; i > 0 && heap->cmp(heap->elements[(i-1)/2], elem, cmp_userdata TSRMLS_CC) < 0; i = (i-1)/2) {
+       for(i = heap->count++; i > 0 && heap->cmp(&heap->elements[(i-1)/2], elem, cmp_userdata TSRMLS_CC) < 0; i = (i-1)/2) {
                heap->elements[i] = heap->elements[(i-1)/2];
        }
 
@@ -258,43 +255,41 @@ static void spl_ptr_heap_insert(spl_ptr_heap *heap, spl_ptr_heap_element elem, v
                heap->flags |= SPL_HEAP_CORRUPTED;
        }
 
-       heap->elements[i] = elem;
+       ZVAL_COPY_VALUE(&heap->elements[i], elem);
 
 }
 /* }}} */
 
-static spl_ptr_heap_element spl_ptr_heap_top(spl_ptr_heap *heap) { /* {{{ */
+static zval *spl_ptr_heap_top(spl_ptr_heap *heap) { /* {{{ */
        if (heap->count == 0) {
                return NULL;
        }
 
-       return heap->elements[0];
+       return ZVAL_IS_UNDEF(&heap->elements[0])? NULL : &heap->elements[0];
 }
 /* }}} */
 
-static spl_ptr_heap_element spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *cmp_userdata TSRMLS_DC) { /* {{{ */
+static zval *spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *cmp_userdata TSRMLS_DC) { /* {{{ */
        int i, j;
        const int limit = (heap->count-1)/2;
-       spl_ptr_heap_element top;
-       spl_ptr_heap_element bottom;
+       zval *top, *bottom;
 
        if (heap->count == 0) {
                return NULL;
        }
 
-       top    = heap->elements[0];
-       bottom = heap->elements[--heap->count];
+       top    = &heap->elements[0];
+       bottom = &heap->elements[--heap->count];
 
-       for( i = 0; i < limit; i = j)
-       {
+       for (i = 0; i < limit; i = j) {
                /* Find smaller child */
-               j = i*2+1;
-               if(j != heap->count && heap->cmp(heap->elements[j+1], heap->elements[j], cmp_userdata TSRMLS_CC) > 0) {
+               j = i * 2 + 1;
+               if(j != heap->count && heap->cmp(&heap->elements[j+1], &heap->elements[j], cmp_userdata TSRMLS_CC) > 0) {
                        j++; /* next child is bigger */
                }
 
                /* swap elements between two levels */
-               if(heap->cmp(bottom, heap->elements[j], cmp_userdata TSRMLS_CC) < 0) {
+               if(heap->cmp(bottom, &heap->elements[j], cmp_userdata TSRMLS_CC) < 0) {
                        heap->elements[i] = heap->elements[j];
                } else {
                        break;
@@ -306,9 +301,9 @@ static spl_ptr_heap_element spl_ptr_heap_delete_top(spl_ptr_heap *heap, void *cm
                heap->flags |= SPL_HEAP_CORRUPTED;
        }
 
-       heap->elements[i] = bottom;
+       ZVAL_COPY_VALUE(&heap->elements[i], bottom);
        heap->dtor(top TSRMLS_CC);
-       return top;
+       return ZVAL_IS_UNDEF(top)? NULL : top;
 }
 /* }}} */
 
@@ -324,11 +319,11 @@ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from TSRMLS_DC) { /* {{{ *
        heap->count    = from->count;
        heap->flags    = from->flags;
 
-       heap->elements = safe_emalloc(sizeof(spl_ptr_heap_element),from->max_size,0);
-       memcpy(heap->elements, from->elements, sizeof(spl_ptr_heap_element)*from->max_size);
+       heap->elements = safe_emalloc(sizeof(zval), from->max_size, 0);
+       memcpy(heap->elements, from->elements, sizeof(zval)*from->max_size);
 
        for (i=0; i < heap->count; ++i) {
-               heap->ctor(heap->elements[i] TSRMLS_CC);
+               heap->ctor(&heap->elements[i] TSRMLS_CC);
        }
 
        return heap;
@@ -339,7 +334,7 @@ static void spl_ptr_heap_destroy(spl_ptr_heap *heap TSRMLS_DC) { /* {{{ */
        int i;
 
        for (i=0; i < heap->count; ++i) {
-               heap->dtor(heap->elements[i] TSRMLS_CC);
+               heap->dtor(&heap->elements[i]);
        }
 
        efree(heap->elements);
@@ -355,7 +350,7 @@ static int spl_ptr_heap_count(spl_ptr_heap *heap) { /* {{{ */
 
 zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
 
-static void spl_heap_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void spl_heap_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        int i;
        spl_heap_object *intern = (spl_heap_object *)object;
@@ -363,8 +358,8 @@ static void spl_heap_object_free_storage(void *object TSRMLS_DC) /* {{{ */
        zend_object_std_dtor(&intern->std TSRMLS_CC);
 
        for (i = 0; i < intern->heap->count; ++i) {
-               if (intern->heap->elements[i]) {
-                       zval_ptr_dtor((zval **)&intern->heap->elements[i]);
+               if (!ZVAL_IS_UNDEF(&intern->heap->elements[i])) {
+                       zval_ptr_dtor(&intern->heap->elements[i]);
                }
        }
 
@@ -381,16 +376,13 @@ static void spl_heap_object_free_storage(void *object TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, spl_heap_object **obj, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
+static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
 {
-       zend_object_value  retval;
        spl_heap_object   *intern;
        zend_class_entry  *parent = class_type;
        int                inherited = 0;
 
        intern = ecalloc(1, sizeof(spl_heap_object));
-       *obj = intern;
-       ALLOC_INIT_ZVAL(intern->retval);
 
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
@@ -400,15 +392,15 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp
        intern->debug_info = NULL;
 
        if (orig) {
-               spl_heap_object *other = (spl_heap_object*)zend_object_store_get_object(orig TSRMLS_CC);
+               spl_heap_object *other = (spl_heap_object*)Z_OBJ_P(orig);
                intern->ce_get_iterator = other->ce_get_iterator;
 
                if (clone_orig) {
                        int i;
                        intern->heap = spl_ptr_heap_clone(other->heap TSRMLS_CC);
                        for (i = 0; i < intern->heap->count; ++i) {
-                               if (intern->heap->elements[i]) {
-                                       Z_ADDREF_P((zval *)intern->heap->elements[i]);
+                               if (!ZVAL_IS_UNDEF(&intern->heap->elements[i])) {
+                                       Z_ADDREF_P(&intern->heap->elements[i]);
                                }
                        }
                } else {
@@ -420,13 +412,13 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp
                intern->heap = spl_ptr_heap_init(spl_ptr_heap_zval_max_cmp, spl_ptr_heap_zval_ctor, spl_ptr_heap_zval_dtor);
        }
 
-       retval.handlers = &spl_handler_SplHeap;
+       intern->std.handlers = &spl_handler_SplHeap;
 
        while (parent) {
                if (parent == spl_ce_SplPriorityQueue) {
                        intern->heap->cmp = spl_ptr_pqueue_zval_cmp;
-                       intern->flags     = SPL_PQUEUE_EXTR_DATA;
-                       retval.handlers   = &spl_handler_SplPriorityQueue;
+                       intern->flags = SPL_PQUEUE_EXTR_DATA;
+                       intern->std.handlers = &spl_handler_SplPriorityQueue;
                        break;
                }
 
@@ -448,65 +440,59 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp
                inherited = 1;
        }
 
-       retval.handle   = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_heap_object_free_storage, NULL TSRMLS_CC);
+       zend_objects_store_put(&intern->std);
 
        if (!parent) { /* this must never happen */
                php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplHeap");
        }
 
        if (inherited) {
-               zend_hash_find(&class_type->function_table, "compare",    sizeof("compare"),    (void **) &intern->fptr_cmp);
+               intern->fptr_cmp = zend_hash_str_find_ptr(&class_type->function_table, "compare", sizeof("compare") - 1);
                if (intern->fptr_cmp->common.scope == parent) {
                        intern->fptr_cmp = NULL;
                }
-               zend_hash_find(&class_type->function_table, "count",        sizeof("count"),        (void **) &intern->fptr_count);
+               intern->fptr_count = zend_hash_str_find_ptr(&class_type->function_table, "count", sizeof("count") - 1);
                if (intern->fptr_count->common.scope == parent) {
                        intern->fptr_count = NULL;
                }
        }
 
-       return retval;
+       return &intern->std;
 }
 /* }}} */
 
-static zend_object_value spl_heap_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+static zend_object *spl_heap_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
 {
-       spl_heap_object *tmp;
-       return spl_heap_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC);
+       return spl_heap_object_new_ex(class_type, NULL, 0 TSRMLS_CC);
 }
 /* }}} */
 
-static zend_object_value spl_heap_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
+static zend_object *spl_heap_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
 {
-       zend_object_value   new_obj_val;
        zend_object        *old_object;
        zend_object        *new_object;
-       zend_object_handle  handle = Z_OBJ_HANDLE_P(zobject);
-       spl_heap_object    *intern;
 
-       old_object  = zend_objects_get_address(zobject TSRMLS_CC);
-       new_obj_val = spl_heap_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC);
-       new_object  = &intern->std;
+       old_object  = Z_OBJ_P(zobject);
+       new_object = spl_heap_object_new_ex(old_object->ce, zobject, 1 TSRMLS_CC);
 
-       zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
+       zend_objects_clone_members(new_object, old_object TSRMLS_CC);
 
-       return new_obj_val;
+       return new_object;
 }
 /* }}} */
 
 static int spl_heap_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
 {
-       spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(object);
 
        if (intern->fptr_count) {
-               zval *rv;
-               zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv);
-               if (rv) {
+               zval rv;
+               zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+               if (!ZVAL_IS_UNDEF(&rv)) {
                        zval_ptr_dtor(&intern->retval);
-                       MAKE_STD_ZVAL(intern->retval);
-                       ZVAL_ZVAL(intern->retval, rv, 1, 1);
-                       convert_to_long(intern->retval);
-                       *count = (long) Z_LVAL_P(intern->retval);
+                       ZVAL_ZVAL(&intern->retval, &rv, 0, 0);
+                       convert_to_long(&intern->retval);
+                       *count = (long) Z_LVAL(intern->retval);
                        return SUCCESS;
                }
                *count = 0;
@@ -520,8 +506,8 @@ static int spl_heap_object_count_elements(zval *object, long *count TSRMLS_DC) /
 /* }}} */
 
 static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp TSRMLS_DC) { /* {{{ */
-       spl_heap_object *intern  = (spl_heap_object*)zend_object_store_get_object(obj TSRMLS_CC);
-       zval *tmp, zrv, *heap_array;
+       spl_heap_object *intern  = (spl_heap_object*)Z_OBJ_P(obj);
+       zval tmp, heap_array;
        char *pnstr;
        int  pnlen;
        int  i;
@@ -538,29 +524,28 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zv
        }
 
        if (intern->debug_info->nApplyCount == 0) {
-               INIT_PZVAL(&zrv);
-               Z_ARRVAL(zrv) = intern->debug_info;
 
-               zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+               zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref);
 
                pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC);
-               add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags);
+               ZVAL_LONG(&tmp, intern->flags);
+               zend_hash_str_update(intern->debug_info, pnstr, pnlen, &tmp);
                efree(pnstr);
 
                pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC);
-               add_assoc_bool_ex(&zrv, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED);
+               ZVAL_BOOL(&tmp, intern->heap->flags&SPL_HEAP_CORRUPTED);
+               zend_hash_str_update(intern->debug_info, pnstr, pnlen, &tmp);
                efree(pnstr);
 
-               ALLOC_INIT_ZVAL(heap_array);
-               array_init(heap_array);
+               array_init(&heap_array);
 
                for (i = 0; i < intern->heap->count; ++i) {
-                       add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]);
-                       Z_ADDREF_P(intern->heap->elements[i]);
+                       add_index_zval(&heap_array, i, &intern->heap->elements[i]);
+                       Z_ADDREF_P(&intern->heap->elements[i]);
                }
 
                pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC);
-               add_assoc_zval_ex(&zrv, pnstr, pnlen+1, heap_array);
+               zend_hash_str_update(intern->debug_info, pnstr, pnlen, &heap_array);
                efree(pnstr);
        }
 
@@ -580,12 +565,12 @@ static HashTable* spl_pqueue_object_get_debug_info(zval *obj, int *is_temp TSRML
 }
 /* }}} */
 
-/* {{{ proto int SplHeap::count() U
+/* {{{ proto int SplHeap::count()
  Return the number of elements in the heap. */
 SPL_METHOD(SplHeap, count)
 {
        long count;
-       spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -596,21 +581,21 @@ SPL_METHOD(SplHeap, count)
 }
 /* }}} */
 
-/* {{{ proto int SplHeap::isEmpty() U
+/* {{{ proto int SplHeap::isEmpty()
  Return true if the heap is empty. */
 SPL_METHOD(SplHeap, isEmpty)
 {
-       spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       RETURN_BOOL(spl_ptr_heap_count(intern->heap)==0);
+       RETURN_BOOL(spl_ptr_heap_count(intern->heap) == 0);
 }
 /* }}} */
 
-/* {{{ proto bool SplHeap::insert(mixed $value) U
+/* {{{ proto bool SplHeap::insert(mixed $value)
           Push $value on the heap */
 SPL_METHOD(SplHeap, insert)
 {
@@ -621,7 +606,7 @@ SPL_METHOD(SplHeap, insert)
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
@@ -636,7 +621,7 @@ SPL_METHOD(SplHeap, insert)
 } 
 /* }}} */
 
-/* {{{ proto mixed SplHeap::extract() U
+/* {{{ proto mixed SplHeap::extract()
           extract the element out of the top of the heap */
 SPL_METHOD(SplHeap, extract)
 {
@@ -647,14 +632,14 @@ SPL_METHOD(SplHeap, extract)
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       value  = (zval *)spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
+       value = (zval *)spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
 
        if (!value) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't extract from an empty heap", 0 TSRMLS_CC);
@@ -665,18 +650,18 @@ SPL_METHOD(SplHeap, extract)
 } 
 /* }}} */
 
-/* {{{ proto bool SplPriorityQueue::insert(mixed $value, mixed $priority) U
+/* {{{ proto bool SplPriorityQueue::insert(mixed $value, mixed $priority)
           Push $value with the priority $priodiry on the priorityqueue */
 SPL_METHOD(SplPriorityQueue, insert)
 {
-       zval *data, *priority, *elem;
+       zval *data, *priority, elem;
        spl_heap_object *intern;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &data, &priority) == FAILURE) {
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
@@ -686,98 +671,93 @@ SPL_METHOD(SplPriorityQueue, insert)
        SEPARATE_ARG_IF_REF(data);
        SEPARATE_ARG_IF_REF(priority);
 
-       ALLOC_INIT_ZVAL(elem);
+       array_init(&elem);
+       add_assoc_zval_ex(&elem, "data", sizeof("data") - 1, data);
+       add_assoc_zval_ex(&elem, "priority", sizeof("priority") - 1, priority);
 
-       array_init(elem);
-       add_assoc_zval_ex(elem, "data",     sizeof("data"),     data);
-       add_assoc_zval_ex(elem, "priority", sizeof("priority"), priority);
-
-       spl_ptr_heap_insert(intern->heap, elem, getThis() TSRMLS_CC);
+       spl_ptr_heap_insert(intern->heap, &elem, getThis() TSRMLS_CC);
 
        RETURN_TRUE;
 } 
 /* }}} */
 
-/* {{{ proto mixed SplPriorityQueue::extract() U
+/* {{{ proto mixed SplPriorityQueue::extract()
           extract the element out of the top of the priority queue */
 SPL_METHOD(SplPriorityQueue, extract)
 {
-       zval *value, *value_out, **value_out_pp;
+       zval *value, *value_out;
        spl_heap_object *intern;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       value  = (zval *)spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
+       value spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
 
-       if (!value) {
+       if (!value || ZVAL_IS_UNDEF(value)) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't extract from an empty heap", 0 TSRMLS_CC);
                return;
        }
 
-       value_out_pp = spl_pqueue_extract_helper(&value, intern->flags);
+       value_out = spl_pqueue_extract_helper(value, intern->flags);
 
-
-       if (!value_out_pp) {
+       if (!value_out) {
                zend_error(E_RECOVERABLE_ERROR, "Unable to extract from the PriorityQueue node");
-               zval_ptr_dtor(&value);
+               zval_ptr_dtor(value);
                return;
        }
 
-       value_out = *value_out_pp;
-
        Z_ADDREF_P(value_out);
-       zval_ptr_dtor(&value);
+       zval_ptr_dtor(value);
 
        RETURN_ZVAL(value_out, 1, 1);
 } 
 /* }}} */
 
-/* {{{ proto mixed SplPriorityQueue::top() U
+/* {{{ proto mixed SplPriorityQueue::top()
           Peek at the top element of the priority queue */
 SPL_METHOD(SplPriorityQueue, top)
 {
-       zval *value, **value_out;
+       zval *value, *value_out;
        spl_heap_object *intern;
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       value  = (zval *)spl_ptr_heap_top(intern->heap);
+       value spl_ptr_heap_top(intern->heap);
 
        if (!value) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty heap", 0 TSRMLS_CC);
                return;
        }
 
-       value_out = spl_pqueue_extract_helper(&value, intern->flags);
+       value_out = spl_pqueue_extract_helper(value, intern->flags);
 
        if (!value_out) {
                zend_error(E_RECOVERABLE_ERROR, "Unable to extract from the PriorityQueue node");
                return;
        }
 
-       RETURN_ZVAL(*value_out, 1, 0);
+       RETURN_ZVAL(value_out, 1, 0);
 }
 /* }}} */
 
-/* {{{ proto int SplPriorityQueue::setIteratorMode($flags) U
+/* {{{ proto int SplPriorityQueue::setIteratorMode($flags)
  Set the flags of extraction*/
 SPL_METHOD(SplPriorityQueue, setExtractFlags)
 {
@@ -788,7 +768,7 @@ SPL_METHOD(SplPriorityQueue, setExtractFlags)
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        intern->flags = value & SPL_PQUEUE_EXTR_MASK;
 
@@ -796,7 +776,7 @@ SPL_METHOD(SplPriorityQueue, setExtractFlags)
 }
 /* }}} */
 
-/* {{{ proto int SplHeap::recoverFromCorruption() U
+/* {{{ proto int SplHeap::recoverFromCorruption()
  Recover from a corrupted state*/
 SPL_METHOD(SplHeap, recoverFromCorruption)
 {
@@ -806,7 +786,7 @@ SPL_METHOD(SplHeap, recoverFromCorruption)
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        intern->heap->flags = intern->heap->flags & ~SPL_HEAP_CORRUPTED;
 
@@ -814,7 +794,7 @@ SPL_METHOD(SplHeap, recoverFromCorruption)
 }
 /* }}} */
 
-/* {{{ proto bool SplPriorityQueue::compare(mixed $a, mixed $b) U
+/* {{{ proto bool SplPriorityQueue::compare(mixed $a, mixed $b)
           compare the priorities */
 SPL_METHOD(SplPriorityQueue, compare)
 {
@@ -828,7 +808,7 @@ SPL_METHOD(SplPriorityQueue, compare)
 } 
 /* }}} */
 
-/* {{{ proto mixed SplHeap::top() U
+/* {{{ proto mixed SplHeap::top()
           Peek at the top element of the heap */
 SPL_METHOD(SplHeap, top)
 {
@@ -839,14 +819,14 @@ SPL_METHOD(SplHeap, top)
                return;
        }
 
-       intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_heap_object*)Z_OBJ_P(getThis());
 
        if (intern->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       value  = (zval *)spl_ptr_heap_top(intern->heap);
+       value spl_ptr_heap_top(intern->heap);
 
        if (!value) {
                zend_throw_exception(spl_ce_RuntimeException, "Can't peek at an empty heap", 0 TSRMLS_CC);
@@ -857,7 +837,7 @@ SPL_METHOD(SplHeap, top)
 }
 /* }}} */
 
-/* {{{ proto bool SplMinHeap::compare(mixed $a, mixed $b) U
+/* {{{ proto bool SplMinHeap::compare(mixed $a, mixed $b)
           compare the values */
 SPL_METHOD(SplMinHeap, compare)
 {
@@ -871,7 +851,7 @@ SPL_METHOD(SplMinHeap, compare)
 } 
 /* }}} */
 
-/* {{{ proto bool SplMaxHeap::compare(mixed $a, mixed $b) U
+/* {{{ proto bool SplMaxHeap::compare(mixed $a, mixed $b)
           compare the values */
 SPL_METHOD(SplMaxHeap, compare)
 {
@@ -890,7 +870,7 @@ static void spl_heap_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
        spl_heap_it *iterator = (spl_heap_it *)iter;
 
        zend_user_it_invalidate_current(iter TSRMLS_CC);
-       zval_ptr_dtor((zval**)&iterator->intern.it.data);
+       zval_ptr_dtor(iterator->intern.it.data);
 
        efree(iterator);
 }
@@ -910,41 +890,42 @@ static int spl_heap_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static void spl_heap_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
+static zval *spl_heap_it_get_current_data(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 {
-       spl_heap_it  *iterator = (spl_heap_it *)iter;
-       zval        **element  = (zval **)&iterator->object->heap->elements[0];
+       spl_heap_it *iterator = (spl_heap_it *)iter;
+       zval *element = &iterator->object->heap->elements[0];
 
        if (iterator->object->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       if (iterator->object->heap->count == 0 || !*element) {
-               *data = NULL;
+       if (iterator->object->heap->count == 0 || ZVAL_IS_UNDEF(element)) {
+               return NULL;
        } else {
-               *data = element;
+               return element;
        }
 }
 /* }}} */
 
-static void spl_pqueue_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
+static zval *spl_pqueue_it_get_current_data(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 {
        spl_heap_it  *iterator = (spl_heap_it *)iter;
-       zval        **element  = (zval **)&iterator->object->heap->elements[0];
+       zval *element  = &iterator->object->heap->elements[0];
 
        if (iterator->object->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
                return;
        }
 
-       if (iterator->object->heap->count == 0 || !*element) {
-               *data = NULL;
+       if (iterator->object->heap->count == 0 || ZVAL_IS_UNDEF(element)) {
+               return NULL;
        } else {
-               *data = spl_pqueue_extract_helper(element, iterator->object->flags);
-               if (!*data) {
+               zval *data = spl_pqueue_extract_helper(element, iterator->object->flags);
+               if (!data) {
                        zend_error(E_RECOVERABLE_ERROR, "Unable to extract from the PriorityQueue node");
                }
+               return data;
        }
 }
 /* }}} */
@@ -959,9 +940,9 @@ static void spl_heap_it_get_current_key(zend_object_iterator *iter, zval *key TS
 
 static void spl_heap_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
 {
-       zval                 *object   = (zval*)((zend_user_iterator *)iter)->it.data;
-       spl_heap_it          *iterator = (spl_heap_it *)iter;
-       spl_ptr_heap_element elem;
+       zval *object = (zval*)((zend_user_iterator *)iter)->it.data;
+       spl_heap_it *iterator = (spl_heap_it *)iter;
+       zval *elem;
 
        if (iterator->object->heap->flags & SPL_HEAP_CORRUPTED) {
                zend_throw_exception(spl_ce_RuntimeException, "Heap is corrupted, heap properties are no longer ensured.", 0 TSRMLS_CC);
@@ -971,18 +952,18 @@ static void spl_heap_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{
        elem = spl_ptr_heap_delete_top(iterator->object->heap, object TSRMLS_CC);
 
        if (elem != NULL) {
-               zval_ptr_dtor((zval **)&elem);
+               zval_ptr_dtor(elem);
        }
 
        zend_user_it_invalidate_current(iter TSRMLS_CC);
 }
 /* }}} */
 
-/* {{{  proto int SplHeap::key() U
+/* {{{  proto int SplHeap::key()
    Return current array key */
 SPL_METHOD(SplHeap, key)
 {
-       spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -992,28 +973,28 @@ SPL_METHOD(SplHeap, key)
 }
 /* }}} */
 
-/* {{{ proto void SplHeap::next() U
+/* {{{ proto void SplHeap::next()
    Move to next entry */
 SPL_METHOD(SplHeap, next)
 {
-       spl_heap_object      *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       spl_ptr_heap_element  elem   = spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(getThis());
+       zval *elem = spl_ptr_heap_delete_top(intern->heap, getThis() TSRMLS_CC);
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
        if (elem != NULL) {
-               zval_ptr_dtor((zval **)&elem);
+               zval_ptr_dtor(elem);
        }
 }
 /* }}} */
 
-/* {{{ proto bool SplHeap::valid() U
+/* {{{ proto bool SplHeap::valid()
    Check whether the datastructure contains more entries */
 SPL_METHOD(SplHeap, valid)
 {
-       spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_heap_object *intern = (spl_heap_object*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1023,7 +1004,7 @@ SPL_METHOD(SplHeap, valid)
 }
 /* }}} */
 
-/* {{{ proto void SplHeap::rewind() U
+/* {{{ proto void SplHeap::rewind()
    Rewind the datastructure back to the start */
 SPL_METHOD(SplHeap, rewind)
 {
@@ -1034,18 +1015,18 @@ SPL_METHOD(SplHeap, rewind)
 }
 /* }}} */
 
-/* {{{ proto mixed|NULL SplHeap::current() U
+/* {{{ proto mixed|NULL SplHeap::current()
    Return current datastructure entry */
 SPL_METHOD(SplHeap, current)
 {
-       spl_heap_object *intern  = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       zval            *element = (zval *)intern->heap->elements[0];
+       spl_heap_object *intern  = (spl_heap_object*)Z_OBJ_P(getThis());
+       zval *element = &intern->heap->elements[0];
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       if (!intern->heap->count || !element) {
+       if (!intern->heap->count || ZVAL_IS_UNDEF(element)) {
                RETURN_NULL();
        } else {
                RETURN_ZVAL(element, 1, 0);
@@ -1053,28 +1034,28 @@ SPL_METHOD(SplHeap, current)
 }
 /* }}} */
 
-/* {{{ proto mixed|NULL SplPriorityQueue::current() U
+/* {{{ proto mixed|NULL SplPriorityQueue::current()
    Return current datastructure entry */
 SPL_METHOD(SplPriorityQueue, current)
 {
-       spl_heap_object  *intern  = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       zval            **element = (zval **)&intern->heap->elements[0];
+       spl_heap_object  *intern  = (spl_heap_object*)Z_OBJ_P(getThis());
+       zval *element = &intern->heap->elements[0];
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
-       if (!intern->heap->count || !*element) {
+       if (!intern->heap->count || ZVAL_IS_UNDEF(element)) {
                RETURN_NULL();
        } else {
-               zval **data = spl_pqueue_extract_helper(element, intern->flags);
+               zval *data = spl_pqueue_extract_helper(element, intern->flags);
 
                if (!data) {
                        zend_error(E_RECOVERABLE_ERROR, "Unable to extract from the PriorityQueue node");
                        RETURN_NULL();
                }
 
-               RETURN_ZVAL(*data, 1, 0);
+               RETURN_ZVAL(data, 1, 0);
        }
 }
 /* }}} */
@@ -1101,7 +1082,7 @@ zend_object_iterator_funcs spl_pqueue_it_funcs = {
 zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
 {
        spl_heap_it     *iterator;
-       spl_heap_object *heap_object = (spl_heap_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_heap_object *heap_object = (spl_heap_object*)Z_OBJ_P(object);
 
        if (by_ref) {
                zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
@@ -1125,7 +1106,7 @@ zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object,
 zend_object_iterator *spl_pqueue_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
 {
        spl_heap_it     *iterator;
-       spl_heap_object *heap_object = (spl_heap_object*)zend_object_store_get_object(object TSRMLS_CC);
+       spl_heap_object *heap_object = (spl_heap_object*)Z_OBJ_P(object);
 
        if (by_ref) {
                zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
@@ -1218,6 +1199,8 @@ PHP_MINIT_FUNCTION(spl_heap) /* {{{ */
        spl_handler_SplHeap.clone_obj      = spl_heap_object_clone;
        spl_handler_SplHeap.count_elements = spl_heap_object_count_elements;
        spl_handler_SplHeap.get_debug_info = spl_heap_object_get_debug_info;
+       spl_handler_SplHeap.dtor_obj = zend_objects_destroy_object;
+       spl_handler_SplHeap.free_obj = spl_heap_object_free_storage;
 
        REGISTER_SPL_IMPLEMENTS(SplHeap, Iterator);
        REGISTER_SPL_IMPLEMENTS(SplHeap, Countable);