]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorXinchen Hui <laruence@gmail.com>
Sat, 15 Feb 2014 15:21:09 +0000 (23:21 +0800)
committerXinchen Hui <laruence@gmail.com>
Sat, 15 Feb 2014 15:21:09 +0000 (23:21 +0800)
ext/spl/spl_directory.c
ext/spl/spl_directory.h
ext/spl/spl_observer.c

index 92457fa0f73bddbe902702dc9e1879d59c980fed..1233436ada111ad49efa6e89d59139f3c8ec14cb 100644 (file)
@@ -72,7 +72,7 @@ static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_D
        }
 } /* }}} */
 
-static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */
+static void spl_filesystem_object_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        spl_filesystem_object *intern = (spl_filesystem_object*)object;
 
@@ -1658,7 +1658,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
                iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
                /* ->current must be initialized; rewind doesn't set it and valid
                 * doesn't check whether it's set */
-               iterator->current = object;
+               iterator->current = *object;
        }
        zval_add_ref(object);
        
@@ -1697,7 +1697,7 @@ static zval *spl_filesystem_dir_it_current_data(zend_object_iterator *iter TSRML
 {
        spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
        
-       return iterator->current;
+       return &iterator->current;
 }
 /* }}} */
 
@@ -1743,11 +1743,12 @@ static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC)
        spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
 
        if (iterator->intern.data) {
-               zval *object =  iterator->intern.data;
+               zval *object = iterator->intern.data;
                zval_ptr_dtor(object);
        } else {
-               if (iterator->current) {
-                       zval_ptr_dtor(iterator->current);
+               if (!ZVAL_IS_UNDEF(&iterator->current)) {
+                       zval_ptr_dtor(&iterator->current);
+                       ZVAL_UNDEF(&iterator->current);
                }
        }
 }
@@ -1760,21 +1761,19 @@ static zval *spl_filesystem_tree_it_current_data(zend_object_iterator *iter TSRM
        spl_filesystem_object   *object   = spl_filesystem_iterator_to_object(iterator);
 
        if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_PATHNAME)) {
-               if (!iterator->current) {
-                       ALLOC_INIT_ZVAL(iterator->current);
+               if (ZVAL_IS_UNDEF(&iterator->current)) {
                        spl_filesystem_object_get_file_name(object TSRMLS_CC);
-                       ZVAL_STRINGL(iterator->current, object->file_name, object->file_name_len);
+                       ZVAL_STRINGL(&iterator->current, object->file_name, object->file_name_len);
                }
-               *data = &iterator->current;
+               return &iterator->current;
        } else if (SPL_FILE_DIR_CURRENT(object, SPL_FILE_DIR_CURRENT_AS_FILEINFO)) {
-               if (!iterator->current) {
-                       ALLOC_INIT_ZVAL(iterator->current);
+               if (ZVAL_IS_UNDEF(&iterator->current)) {
                        spl_filesystem_object_get_file_name(object TSRMLS_CC);
-                       spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, iterator->current TSRMLS_CC);
+                       spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, &iterator->current TSRMLS_CC);
                }
-               *data = &iterator->current;
+               return &iterator->current;
        } else {
-               *data = (zval**)&iterator->intern.data;
+               return (zval*)iterator->intern.data;
        }
 }
 /* }}} */
@@ -1807,9 +1806,9 @@ static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRML
                efree(object->file_name);
                object->file_name = NULL;
        }
-       if (iterator->current) {
-               zval_ptr_dtor(iterator->current);
-               iterator->current = NULL;
+       if (!ZVAL_IS_UNDEF(&iterator->current)) {
+               zval_ptr_dtor(&iterator->current);
+               ZVAL_UNDEF(&iterator->current);
        }
 }
 /* }}} */
@@ -1827,9 +1826,9 @@ static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC)
        do {
                spl_filesystem_dir_read(object TSRMLS_CC);
        } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
-       if (iterator->current) {
-               zval_ptr_dtor(iterator->current);
-               iterator->current = NULL;
+       if (!ZVAL_IS_UNDEF(&iterator->current)) {
+               zval_ptr_dtor(&iterator->current);
+               ZVAL_UNDEF(&iterator->current);
        }
 }
 /* }}} */
@@ -2047,7 +2046,7 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TS
 {
        char *buf;
        size_t line_len = 0;
-       long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;
+       long line_add = (intern->u.file.current_line || !ZVAL_IS_UNDEF(&intern->u.file.current_zval)) ? 1 : 0;
 
        spl_filesystem_file_free_line(intern TSRMLS_CC);
        
@@ -2091,8 +2090,7 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function
 {
        zend_fcall_info fci;
        zend_fcall_info_cache fcic;
-       zval z_fname;
-       zval * zresource_ptr = &intern->u.file.zresource, *retval;
+       zval *zresource_ptr = &intern->u.file.zresource, retval;
        int result;
        int num_args = pass_num_args + (arg2 ? 2 : 1);
 
@@ -2106,17 +2104,15 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function
 
        zend_get_parameters_array_ex(pass_num_args, params + (arg2 ? 2 : 1));
 
-       ZVAL_STRING(&z_fname, func_ptr->common.function_name);
-
        fci.size = sizeof(fci);
        fci.function_table = EG(function_table);
        fci.object_ptr = NULL;
-       fci.function_name = &z_fname;
-       fci.retval_ptr_ptr = &retval;
+       fci.retval = &retval;
        fci.param_count = num_args;
        fci.params = params;
        fci.no_separation = 1;
        fci.symbol_table = NULL;
+       ZVAL_STR(&fci.function_name, func_ptr->common.function_name);
 
        fcic.initialized = 1;
        fcic.function_handler = func_ptr;
@@ -2125,12 +2121,11 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function
        fcic.object_ptr = NULL;
 
        result = zend_call_function(&fci, &fcic TSRMLS_CC);
-       zval_ptr_dtor(&z_fname);
        
-       if (result == FAILURE) {
+       if (result == FAILURE || ZVAL_IS_UNDEF(&retval)) {
                RETVAL_FALSE;
        } else {
-               ZVAL_ZVAL(return_value, retval, 1, 1);
+               ZVAL_ZVAL(return_value, &retval, 0, 0);
        }
 
        efree(params);
@@ -2140,9 +2135,8 @@ static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function
 #define FileFunctionCall(func_name, pass_num_args, arg2) /* {{{ */ \
 { \
        zend_function *func_ptr; \
-       int ret; \
-       ret = zend_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \
-       if (ret != SUCCESS) { \
+       func_ptr = (zend_function *)zend_hash_str_find_ptr(EG(function_table), #func_name, sizeof(#func_name) - 1); \
+       if (func_ptr == NULL) { \
                zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Internal error, function '%s' not found. Please report", #func_name); \
                return; \
        } \
@@ -2161,18 +2155,18 @@ static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char deli
                size_t buf_len = intern->u.file.current_line_len;
                char *buf = estrndup(intern->u.file.current_line, buf_len);
 
-               if (intern->u.file.current_zval) {
+               if (!ZVAL_IS_UNDEF(&intern->u.file.current_zval)) {
                        zval_ptr_dtor(&intern->u.file.current_zval);
+                       ZVAL_UNDEF(&intern->u.file.current_zval);
                }
-               ALLOC_INIT_ZVAL(intern->u.file.current_zval);
 
-               php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
+               php_fgetcsv(intern->u.file.stream, delimiter, enclosure, escape, buf_len, buf, &intern->u.file.current_zval TSRMLS_CC);
                if (return_value) {
                        if (Z_TYPE_P(return_value) != IS_NULL) {
                                zval_dtor(return_value);
                                ZVAL_NULL(return_value);
                        }
-                       ZVAL_ZVAL(return_value, intern->u.file.current_zval, 1, 0);
+                       ZVAL_ZVAL(return_value, &intern->u.file.current_zval, 1, 0);
                }
        }
        return ret;
@@ -2181,7 +2175,7 @@ static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char deli
 
 static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
 {
-       zval *retval = NULL;
+       zval retval;
 
        /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */
        if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) {
@@ -2194,19 +2188,18 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje
                if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)) {
                        return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, intern->u.file.escape, NULL TSRMLS_CC);
                } else {
-                       zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
+                       zend_call_method_with_0_params(this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
                }
-               if (retval) {
-                       if (intern->u.file.current_line || intern->u.file.current_zval) {
+               if (!ZVAL_IS_UNDEF(&retval)) {
+                       if (intern->u.file.current_line || !ZVAL_IS_UNDEF(&intern->u.file.current_zval)) {
                                intern->u.file.current_line_num++;
                        }
                        spl_filesystem_file_free_line(intern TSRMLS_CC);
-                       if (Z_TYPE_P(retval) == IS_STRING) {
-                               intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
-                               intern->u.file.current_line_len = Z_STRLEN_P(retval);
+                       if (Z_TYPE(retval) == IS_STRING) {
+                               intern->u.file.current_line = estrndup(Z_STRVAL(retval), Z_STRLEN(retval));
+                               intern->u.file.current_line_len = Z_STRLEN(retval);
                        } else {
-                               MAKE_STD_ZVAL(intern->u.file.current_zval);
-                               ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0);
+                               ZVAL_ZVAL(&intern->u.file.current_zval, &retval, 1, 0);
                        }
                        zval_ptr_dtor(&retval);
                        return SUCCESS;
@@ -2222,27 +2215,27 @@ static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRML
 {
        if (intern->u.file.current_line) {
                return intern->u.file.current_line_len == 0;
-       } else if (intern->u.file.current_zval) {
-               switch(Z_TYPE_P(intern->u.file.current_zval)) {
-               case IS_STRING:
-                       return Z_STRLEN_P(intern->u.file.current_zval) == 0;
-               case IS_ARRAY:
-                       if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)
-                       && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) {
-                               uint idx = 0;
-                               zval *first;
-
-                               while (Z_ARRVAL_P(intern->u.file.current_zval)->arData[idx].xData == NULL) {
-                                       idx++;
+       } else if (!ZVAL_IS_UNDEF(&intern->u.file.current_zval)) {
+               switch(Z_TYPE(intern->u.file.current_zval)) {
+                       case IS_STRING:
+                               return Z_STRLEN(intern->u.file.current_zval) == 0;
+                       case IS_ARRAY:
+                               if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV)
+                                               && zend_hash_num_elements(Z_ARRVAL(intern->u.file.current_zval)) == 1) {
+                                       uint idx = 0;
+                                       zval *first;
+
+                                       while (ZVAL_IS_UNDEF(&Z_ARRVAL(intern->u.file.current_zval)->arData[idx].val)) {
+                                               idx++;
+                                       }
+                                       first = &Z_ARRVAL(intern->u.file.current_zval)->arData[idx].val;
+                                       return Z_TYPE_P(first) == IS_STRING && Z_STRLEN_P(first) == 0;
                                }
-                               first = Z_ARRVAL_P(intern->u.file.current_zval)->arData[idx].xData;
-                               return Z_TYPE_P(first) == IS_STRING && Z_STRLEN_P(first) == 0;
-                       }
-                       return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0;
-               case IS_NULL:
-                       return 1;
-               default:
-                       return 0;
+                               return zend_hash_num_elements(Z_ARRVAL(intern->u.file.current_zval)) == 0;
+                       case IS_NULL:
+                               return 1;
+                       default:
+                               return 0;
                }
        } else {
                return 1;
@@ -2365,7 +2358,7 @@ SPL_METHOD(SplTempFileObject, __construct)
        }
        intern->u.file.open_mode = "wb";
        intern->u.file.open_mode_len = 1;
-       intern->u.file.zcontext = NULL;
+       ZVAL_UNDEF(&intern->u.file.zcontext);
        
        if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) {
                intern->_path_len = 0;
@@ -2411,7 +2404,7 @@ SPL_METHOD(SplFileObject, valid)
        }
 
        if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) {
-               RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval);
+               RETURN_BOOL(intern->u.file.current_line || !ZVAL_IS_UNDEF(&intern->u.file.current_zval));
        } else {
                RETVAL_BOOL(!php_stream_eof(intern->u.file.stream));
        }
@@ -2430,7 +2423,7 @@ SPL_METHOD(SplFileObject, fgets)
        if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) {
                RETURN_FALSE;
        }
-       RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
+       RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
 } /* }}} */
 
 /* {{{ proto string SplFileObject::current()
@@ -2443,13 +2436,13 @@ SPL_METHOD(SplFileObject, current)
                return;
        }
 
-       if (!intern->u.file.current_line && !intern->u.file.current_zval) {
+       if (!intern->u.file.current_line && ZVAL_IS_UNDEF(&intern->u.file.current_zval)) {
                spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
        }
-       if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) {
-               RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
-       } else if (intern->u.file.current_zval) {
-               RETURN_ZVAL(intern->u.file.current_zval, 1, 0);
+       if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || ZVAL_IS_UNDEF(&intern->u.file.current_zval))) {
+               RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len);
+       } else if (!ZVAL_IS_UNDEF(&intern->u.file.current_zval)) {
+               RETURN_ZVAL(&intern->u.file.current_zval, 1, 0);
        }
        RETURN_FALSE;
 } /* }}} */
@@ -2779,7 +2772,7 @@ SPL_METHOD(SplFileObject, fgetc)
                buf[0] = result;
                buf[1] = '\0';
 
-               RETURN_STRINGL(buf, 1, 1);
+               RETURN_STRINGL(buf, 1);
        }
 } /* }}} */
 
@@ -2788,21 +2781,18 @@ SPL_METHOD(SplFileObject, fgetc)
 SPL_METHOD(SplFileObject, fgetss)
 {
        spl_filesystem_object *intern = (spl_filesystem_object*)Z_OBJ_P(getThis());
-       zval *arg2 = NULL;
-       MAKE_STD_ZVAL(arg2);
+       zval arg2;
 
        if (intern->u.file.max_line_len > 0) {
-               ZVAL_LONG(arg2, intern->u.file.max_line_len);
+               ZVAL_LONG(&arg2, intern->u.file.max_line_len);
        } else {
-               ZVAL_LONG(arg2, 1024);
+               ZVAL_LONG(&arg2, 1024);
        }
 
        spl_filesystem_file_free_line(intern TSRMLS_CC);
        intern->u.file.current_line_num++;
 
-       FileFunctionCall(fgetss, ZEND_NUM_ARGS(), arg2);
-
-       zval_ptr_dtor(&arg2);
+       FileFunctionCall(fgetss, ZEND_NUM_ARGS(), &arg2);
 } /* }}} */
 
 /* {{{ proto int SplFileObject::fpassthru()
index 133b6247f0fde95f6ca9569858df0afa96a813c8..b65133ff8c4419a24896ca8f81cfcdd33381d7c5 100644 (file)
@@ -55,7 +55,7 @@ typedef struct _spl_other_handler {
 /* define an overloaded iterator structure */
 typedef struct {
        zend_object_iterator  intern;
-       zval                  *current;
+       zval                  current;
        spl_filesystem_object *object;
 } spl_filesystem_iterator;
 
index 3882deb2294d515c3129b0a1fe621998f17191bc..92baee4b0c35296218544a5ca05d5d8d6677cf93 100644 (file)
@@ -90,11 +90,11 @@ typedef struct _spl_SplObjectStorage { /* {{{ */
 
 /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */
 typedef struct _spl_SplObjectStorageElement {
-       zvalobj;
-       zval* inf;
+       zval *obj;
+       zval  inf;
 } spl_SplObjectStorageElement; /* }}} */
 
-void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
+void spl_SplOjectStorage_free_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;
 
@@ -110,22 +110,13 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */
        efree(object);
 } /* }}} */
 
-static char *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this,  zval *obj, int *hash_len_ptr TSRMLS_DC) {
+static zend_string *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *this, zval *obj TSRMLS_DC) {
        if (intern->fptr_get_hash) {
-               zval *rv;
-               zend_call_method_with_1_params(&this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj);
-               if (rv) {
-                       if (Z_TYPE_P(rv) == IS_STRING) {
-                               int hash_len = Z_STRLEN_P(rv);
-                               char *hash = emalloc((hash_len+1)*sizeof(char));
-                               strncpy(hash, Z_STRVAL_P(rv), hash_len);
-                               hash[hash_len] = 0;
-
-                               zval_ptr_dtor(&rv);
-                               if (hash_len_ptr) {
-                                       *hash_len_ptr = hash_len;
-                               }
-                               return hash;
+               zval rv;
+               zend_call_method_with_1_params(this, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, obj);
+               if (!ZVAL_IS_UNDEF(&rv)) {
+                       if (Z_TYPE(rv) == IS_STRING) {
+                               return Z_STR(rv);
                        } else {
                                zend_throw_exception(spl_ce_RuntimeException, "Hash needs to be a string", 0 TSRMLS_CC);
 
@@ -136,6 +127,7 @@ static char *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *thi
                        return NULL;
                }
        } else {
+               /* !!! FIXME
                int hash_len = sizeof(zend_object_value);
 
 #if HAVE_PACKED_OBJECT_VALUE
@@ -162,75 +154,72 @@ static char *spl_object_storage_get_hash(spl_SplObjectStorage *intern, zval *thi
 
                return hash;
 #endif
+*/
+               return NULL;
        }
 }
 
-static void spl_object_storage_free_hash(spl_SplObjectStorage *intern, char *hash) {
+static void spl_object_storage_free_hash(spl_SplObjectStorage *intern, zend_string *hash) {
+       STR_RELEASE(hash);
+/*
        if (intern->fptr_get_hash) {
-               efree(hash);
        } else {
 #if HAVE_PACKED_OBJECT_VALUE
-               /* Nothing to do */
 #else
                efree(hash);
 #endif
        }
+*/
 }
 
-static void spl_object_storage_dtor(spl_SplObjectStorageElement *element) /* {{{ */
+static void spl_object_storage_dtor(zval *element) /* {{{ */
 {
-       zval_ptr_dtor(&element->obj);
-       zval_ptr_dtor(&element->inf);
+       spl_SplObjectStorageElement *el = Z_PTR_P(element);
+       zval_ptr_dtor(el->obj);
+       zval_ptr_dtor(&el->inf);
+       ZVAL_UNDEF(&el->inf);
 } /* }}} */
 
-spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern, char *hash, int hash_len TSRMLS_DC) /* {{{ */
+spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern, zend_string *hash TSRMLS_DC) /* {{{ */
 {
-       spl_SplObjectStorageElement *element;
-       if (zend_hash_find(&intern->storage, hash, hash_len, (void**)&element) == SUCCESS) {
-               return element;
-       } else {
-               return NULL;
-       }
+       return (spl_SplObjectStorageElement*)zend_hash_find_ptr(&intern->storage, hash);
 } /* }}} */
 
 void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *this, zval *obj, zval *inf TSRMLS_DC) /* {{{ */
 {
        spl_SplObjectStorageElement *pelement, element;
-       
-       int hash_len;
-       char *hash = spl_object_storage_get_hash(intern, this, obj, &hash_len TSRMLS_CC);
+       zend_string *hash = spl_object_storage_get_hash(intern, this, obj TSRMLS_CC);
+
        if (!hash) {
                return;
        }
 
-       pelement = spl_object_storage_get(intern, hash, hash_len TSRMLS_CC);
+       pelement = spl_object_storage_get(intern, hash TSRMLS_CC);
 
-       if (inf) {
-               Z_ADDREF_P(inf);
-       } else {
-               ALLOC_INIT_ZVAL(inf);
-       }
        if (pelement) {
                zval_ptr_dtor(&pelement->inf);
-               pelement->inf = inf;
+               if (inf) {
+                       ZVAL_ZVAL(&pelement->inf, inf, 1, 0);
+               }
                spl_object_storage_free_hash(intern, hash);
                return;
        }
+
        Z_ADDREF_P(obj);
        element.obj = obj;
-       element.inf = inf;
-       zend_hash_update(&intern->storage, hash, hash_len, &element, sizeof(spl_SplObjectStorageElement), NULL);
+       ZVAL_ZVAL(&element.inf, inf, 1, 0);
+       zend_hash_update_mem(&intern->storage, hash, &element, sizeof(spl_SplObjectStorageElement));
        spl_object_storage_free_hash(intern, hash);
 } /* }}} */
 
 int spl_object_storage_detach(spl_SplObjectStorage *intern, zval *this, zval *obj TSRMLS_DC) /* {{{ */
 {
-       int hash_len, ret = FAILURE;
-       char *hash = spl_object_storage_get_hash(intern, this, obj, &hash_len TSRMLS_CC);
+       int ret = FAILURE;
+       zend_string *hash = spl_object_storage_get_hash(intern, this, obj TSRMLS_CC);
        if (!hash) {
                return ret;
        }
-       ret = zend_hash_del(&intern->storage, hash, hash_len);
+       ret = zend_hash_del(&intern->storage, hash);
        spl_object_storage_free_hash(intern, hash);
        
        return ret;
@@ -241,8 +230,8 @@ void spl_object_storage_addall(spl_SplObjectStorage *intern, zval *this, spl_Spl
        spl_SplObjectStorageElement *element;
 
        zend_hash_internal_pointer_reset_ex(&other->storage, &pos);
-       while (zend_hash_get_current_data_ex(&other->storage, (void **)&element, &pos) == SUCCESS) {
-               spl_object_storage_attach(intern, this, element->obj, element->inf TSRMLS_CC);
+       while ((element = zend_hash_get_current_data_ptr_ex(&other->storage, &pos)) != NULL) {
+               spl_object_storage_attach(intern, this, element->obj, &element->inf TSRMLS_CC);
                zend_hash_move_forward_ex(&other->storage, &pos);
        }
 
@@ -250,34 +239,32 @@ void spl_object_storage_addall(spl_SplObjectStorage *intern, zval *this, spl_Spl
        intern->index = 0;
 } /* }}} */
 
-static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */
+static zend_object *spl_object_storage_new_ex(zend_class_entry *class_type, zval *orig TSRMLS_DC) /* {{{ */
 {
-       zend_object_value     retval;
        spl_SplObjectStorage *intern;
        zend_class_entry     *parent = class_type;
 
        intern = emalloc(sizeof(spl_SplObjectStorage));
        memset(intern, 0, sizeof(spl_SplObjectStorage));
        intern->pos = INVALID_IDX;
-       *obj = intern;
 
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
 
-       zend_hash_init(&intern->storage, 0, NULL, (void (*)(void *))spl_object_storage_dtor, 0);
+       zend_hash_init(&intern->storage, 0, NULL, spl_object_storage_dtor, 0);
 
-       retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC);
-       retval.handlers = &spl_handler_SplObjectStorage;
+       zend_objects_store_put(&intern->std TSRMLS_CC);
+       intern->std.handlers = &spl_handler_SplObjectStorage;
 
        if (orig) {
-               spl_SplObjectStorage *other = (spl_SplObjectStorage*)zend_object_store_get_object(orig TSRMLS_CC);
+               spl_SplObjectStorage *other = (spl_SplObjectStorage*)Z_OBJ_P(orig);
                spl_object_storage_addall(intern, orig, other TSRMLS_CC);
        }
 
        while (parent) {
                if (parent == spl_ce_SplObjectStorage) {
                        if (class_type != spl_ce_SplObjectStorage) {
-                               zend_hash_find(&class_type->function_table, "gethash",    sizeof("gethash"),    (void **) &intern->fptr_get_hash);
+                               intern->fptr_get_hash = zend_hash_str_find_ptr(&class_type->function_table, "gethash", sizeof("gethash") - 1);
                                if (intern->fptr_get_hash->common.scope == spl_ce_SplObjectStorage) {
                                        intern->fptr_get_hash = NULL;
                                }
@@ -288,36 +275,33 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type,
                parent = parent->parent;
        }
 
-       return retval;
+       return &intern->std;
 }
 /* }}} */
 
 /* {{{ spl_object_storage_clone */
-static zend_object_value spl_object_storage_clone(zval *zobject TSRMLS_DC)
+static zend_object *spl_object_storage_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_SplObjectStorage *intern;
 
-       old_object = zend_objects_get_address(zobject TSRMLS_CC);
-       new_obj_val = spl_object_storage_new_ex(old_object->ce, &intern, zobject TSRMLS_CC);
-       new_object = &intern->std;
+       old_object = Z_OBJ_P(zobject);
+       new_object = spl_object_storage_new_ex(old_object->ce, zobject 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 HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(obj);
        spl_SplObjectStorageElement *element;
        HashTable *props;
        HashPosition pos;
-       zval *tmp, *storage;
+       zval tmp, storage;
        char md5str[33];
        int name_len;
        char *zname;
@@ -325,7 +309,7 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
        *is_temp = 0;
 
        props = Z_OBJPROP_P(obj);
-       zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
+       zend_hash_str_del(props, "\x00gcdata", sizeof("\x00gcdata") - 1);
 
        if (intern->debug_info == NULL) {
                ALLOC_HASHTABLE(intern->debug_info);
@@ -333,27 +317,25 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
        }
 
        if (intern->debug_info->nApplyCount == 0) {
-               zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+               zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t)zval_add_ref);
 
-               MAKE_STD_ZVAL(storage);
-               array_init(storage);
+               array_init(&storage);
 
                zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
-               while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
+               while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &pos)) != NULL) {
                                php_spl_object_hash(element->obj, md5str TSRMLS_CC);
-                               MAKE_STD_ZVAL(tmp);
-                               array_init(tmp);
+                               array_init(&tmp);
                                /* Incrementing the refcount of obj and inf would confuse the garbage collector.
                                 * Prefer to null the destructor */
-                               Z_ARRVAL_P(tmp)->pDestructor = NULL;
-                               add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj);
-                               add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf);
-                               add_assoc_zval_ex(storage, md5str, 33, tmp);
+                               Z_ARRVAL_P(&tmp)->pDestructor = NULL;
+                               add_assoc_zval_ex(&tmp, "obj", sizeof("obj"), element->obj);
+                               add_assoc_zval_ex(&tmp, "inf", sizeof("inf"), &element->inf);
+                               add_assoc_zval_ex(&storage, md5str, 33, &tmp);
                                zend_hash_move_forward_ex(&intern->storage, &pos);
                }
 
                zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC);
-               zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL);
+               zend_symtable_str_update(intern->debug_info, zname, name_len, &storage);
                efree(zname);
        }
 
@@ -363,14 +345,13 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D
 
 /* overriden for garbage collection
  * This is very hacky */
-static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
+static HashTable *spl_object_storage_get_gc(zval *obj, zval **table, int *n TSRMLS_DC) /* {{{ */
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(obj);
        spl_SplObjectStorageElement *element;
        HashTable *props;
        HashPosition pos;
-       zval *gcdata_arr = NULL,
-                **gcdata_arr_pp;
+       zval *gcdata_arr, tmp;
 
        props = std_object_handlers.get_properties(obj TSRMLS_CC);
        
@@ -378,25 +359,24 @@ static HashTable *spl_object_storage_get_gc(zval *obj, zval ***table, int *n TSR
        *n = 0;
 
        /* clean \x00gcdata, as it may be out of date */
-       if (zend_hash_find(props, "\x00gcdata", sizeof("\x00gcdata"), (void**) &gcdata_arr_pp) == SUCCESS) {
-               gcdata_arr = *gcdata_arr_pp;
+       if ((gcdata_arr = zend_hash_str_find(props, "\x00gcdata", sizeof("\x00gcdata") - 1)) != NULL) {
                zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
        }
 
        if (gcdata_arr == NULL) {
-               MAKE_STD_ZVAL(gcdata_arr);
-               array_init(gcdata_arr);
+               array_init(&tmp);
                /* don't decrease refcount of members when destroying */
-               Z_ARRVAL_P(gcdata_arr)->pDestructor = NULL;
+               Z_ARRVAL_P(&tmp)->pDestructor = NULL;
 
                /* name starts with \x00 to make tampering in user-land more difficult */
-               zend_hash_add(props, "\x00gcdata", sizeof("\x00gcdata"), &gcdata_arr, sizeof(gcdata_arr), NULL);
+               zend_hash_str_add(props, "\x00gcdata", sizeof("\x00gcdata") - 1, &tmp);
+               gcdata_arr = &tmp;
        }
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
-       while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
+       while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &pos)) != NULL) {
                add_next_index_zval(gcdata_arr, element->obj);
-               add_next_index_zval(gcdata_arr, element->inf);
+               add_next_index_zval(gcdata_arr, &element->inf);
                zend_hash_move_forward_ex(&intern->storage, &pos);
        }
 
@@ -408,7 +388,7 @@ static int spl_object_storage_compare_info(spl_SplObjectStorageElement *e1, spl_
 {
        zval result;
 
-       if (compare_function(&result, e1->inf, e2->inf TSRMLS_CC) == FAILURE) {
+       if (compare_function(&result, &e1->inf, &e2->inf TSRMLS_CC) == FAILURE) {
                return 1;
        }
 
@@ -418,8 +398,8 @@ static int spl_object_storage_compare_info(spl_SplObjectStorageElement *e1, spl_
 
 static int spl_object_storage_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
 {
-       zend_object *zo1 = (zend_object *)zend_object_store_get_object(o1 TSRMLS_CC);
-       zend_object *zo2 = (zend_object *)zend_object_store_get_object(o2 TSRMLS_CC);
+       zend_object *zo1 = (zend_object *)Z_OBJ_P(o1);
+       zend_object *zo2 = (zend_object *)Z_OBJ_P(o2);
 
        if (zo1->ce != spl_ce_SplObjectStorage || zo2->ce != spl_ce_SplObjectStorage) {
                return 1;
@@ -430,22 +410,21 @@ static int spl_object_storage_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {
 /* }}} */
 
 /* {{{ spl_array_object_new */
-static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC)
+static zend_object *spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC)
 {
-       spl_SplObjectStorage *tmp;
-       return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
+       return spl_object_storage_new_ex(class_type, NULL TSRMLS_CC);
 }
 /* }}} */
 
 int spl_object_storage_contains(spl_SplObjectStorage *intern, zval *this, zval *obj TSRMLS_DC) /* {{{ */
 {
-       int hash_len, found;
-       char *hash = spl_object_storage_get_hash(intern, this, obj, &hash_len TSRMLS_CC);
+       int found;
+       zend_string *hash = spl_object_storage_get_hash(intern, this, obj TSRMLS_CC);
        if (!hash) {
                return 0;
        }
 
-       found = zend_hash_exists(&intern->storage, hash, hash_len);
+       found = zend_hash_exists(&intern->storage, hash);
        spl_object_storage_free_hash(intern, hash);
        return found;
 } /* }}} */
@@ -456,7 +435,7 @@ SPL_METHOD(SplObjectStorage, attach)
 {
        zval *obj, *inf = NULL;
 
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|z!", &obj, &inf) == FAILURE) {
                return;
@@ -469,7 +448,7 @@ SPL_METHOD(SplObjectStorage, attach)
 SPL_METHOD(SplObjectStorage, detach)
 {
        zval *obj;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
                return;
@@ -494,7 +473,7 @@ SPL_METHOD(SplObjectStorage, getHash)
        hash = emalloc(33);
        php_spl_object_hash(obj, hash TSRMLS_CC);
        
-       RETVAL_STRING(hash, 0);
+       RETVAL_STRING(hash);
 
 } /* }}} */
 
@@ -504,26 +483,25 @@ SPL_METHOD(SplObjectStorage, offsetGet)
 {
        zval *obj;
        spl_SplObjectStorageElement *element;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
-       char *hash;
-       int hash_len;
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
+       zend_string *hash;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
                return;
        }
 
-       hash = spl_object_storage_get_hash(intern, getThis(), obj, &hash_len TSRMLS_CC);
+       hash = spl_object_storage_get_hash(intern, getThis(), obj TSRMLS_CC);
        if (!hash) {
                return;
        }
 
-       element = spl_object_storage_get(intern, hash, hash_len TSRMLS_CC);
+       element = spl_object_storage_get(intern, hash TSRMLS_CC);
        spl_object_storage_free_hash(intern, hash);
 
        if (!element) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Object not found");
        } else {
-               RETURN_ZVAL(element->inf,1, 0);
+               RETURN_ZVAL(&element->inf, 1, 0);
        }
 } /* }}} */
 
@@ -532,16 +510,16 @@ SPL_METHOD(SplObjectStorage, offsetGet)
 SPL_METHOD(SplObjectStorage, addAll)
 {
        zval *obj;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        spl_SplObjectStorage *other;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &obj, spl_ce_SplObjectStorage) == FAILURE) {
                return;
        }
 
-       other = (spl_SplObjectStorage *)zend_object_store_get_object(obj TSRMLS_CC);
+       other = (spl_SplObjectStorage *)Z_OBJ_P(obj);
 
-       spl_object_storage_addall(intern, getThis(),  other TSRMLS_CC);
+       spl_object_storage_addall(intern, getThis(), other TSRMLS_CC);
 
        RETURN_LONG(zend_hash_num_elements(&intern->storage));
 } /* }}} */
@@ -551,7 +529,7 @@ SPL_METHOD(SplObjectStorage, addAll)
 SPL_METHOD(SplObjectStorage, removeAll)
 {
        zval *obj;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        spl_SplObjectStorage *other;
        spl_SplObjectStorageElement *element;
 
@@ -559,10 +537,10 @@ SPL_METHOD(SplObjectStorage, removeAll)
                return;
        }
 
-       other = (spl_SplObjectStorage *)zend_object_store_get_object(obj TSRMLS_CC);
+       other = (spl_SplObjectStorage *)Z_OBJ_P(obj);
 
        zend_hash_internal_pointer_reset(&other->storage);
-       while (zend_hash_get_current_data(&other->storage, (void **)&element) == SUCCESS) {
+       while ((element = zend_hash_get_current_data_ptr(&other->storage)) != NULL) {
                if (spl_object_storage_detach(intern, getThis(), element->obj TSRMLS_CC) == FAILURE) {
                        zend_hash_move_forward(&other->storage);
                }
@@ -579,7 +557,7 @@ SPL_METHOD(SplObjectStorage, removeAll)
 SPL_METHOD(SplObjectStorage, removeAllExcept)
 {
        zval *obj;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage *)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        spl_SplObjectStorage *other;
        spl_SplObjectStorageElement *element;
 
@@ -587,10 +565,10 @@ SPL_METHOD(SplObjectStorage, removeAllExcept)
                return;
        }
 
-       other = (spl_SplObjectStorage *)zend_object_store_get_object(obj TSRMLS_CC);
+       other = (spl_SplObjectStorage*)Z_OBJ_P(obj);
 
        zend_hash_internal_pointer_reset(&intern->storage);
-       while (zend_hash_get_current_data(&intern->storage, (void **)&element) == SUCCESS) {
+       while ((element = zend_hash_get_current_data_ptr(&intern->storage)) != NULL) {
                if (!spl_object_storage_contains(other, getThis(), element->obj TSRMLS_CC)) {
                        spl_object_storage_detach(intern, getThis(), element->obj TSRMLS_CC);
                }
@@ -609,7 +587,7 @@ SPL_METHOD(SplObjectStorage, removeAllExcept)
 SPL_METHOD(SplObjectStorage, contains)
 {
        zval *obj;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
                return;
@@ -621,7 +599,7 @@ SPL_METHOD(SplObjectStorage, contains)
  Determine number of objects in storage */
 SPL_METHOD(SplObjectStorage, count)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -634,7 +612,7 @@ SPL_METHOD(SplObjectStorage, count)
  Rewind to first position */
 SPL_METHOD(SplObjectStorage, rewind)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -648,7 +626,7 @@ SPL_METHOD(SplObjectStorage, rewind)
  Returns whether current position is valid */
 SPL_METHOD(SplObjectStorage, valid)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -661,7 +639,7 @@ SPL_METHOD(SplObjectStorage, valid)
  Returns current key */
 SPL_METHOD(SplObjectStorage, key)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -675,13 +653,13 @@ SPL_METHOD(SplObjectStorage, key)
 SPL_METHOD(SplObjectStorage, current)
 {
        spl_SplObjectStorageElement *element;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        
-       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
+       if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) {
                return;
        }
        RETVAL_ZVAL(element->obj, 1, 0);
@@ -692,16 +670,16 @@ SPL_METHOD(SplObjectStorage, current)
 SPL_METHOD(SplObjectStorage, getInfo)
 {
        spl_SplObjectStorageElement *element;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
        
-       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
+       if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) {
                return;
        }
-       RETVAL_ZVAL(element->inf, 1, 0);
+       RETVAL_ZVAL(&element->inf, 1, 0);
 } /* }}} */
 
 /* {{{ proto mixed SplObjectStorage::setInfo(mixed $inf)
@@ -709,26 +687,25 @@ SPL_METHOD(SplObjectStorage, getInfo)
 SPL_METHOD(SplObjectStorage, setInfo)
 {
        spl_SplObjectStorageElement *element;
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        zval *inf;
        
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &inf) == FAILURE) {
                return;
        }
 
-       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
+       if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) == NULL) {
                return;
        }
        zval_ptr_dtor(&element->inf);
-       element->inf = inf;
-       Z_ADDREF_P(inf);
+       ZVAL_ZVAL(&element->inf, inf, 1, 0);
 } /* }}} */
 
 /* {{{ proto void SplObjectStorage::next()
  Moves position forward */
 SPL_METHOD(SplObjectStorage, next)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -742,10 +719,10 @@ SPL_METHOD(SplObjectStorage, next)
  Serializes storage */
 SPL_METHOD(SplObjectStorage, serialize)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        spl_SplObjectStorageElement *element;
-       zval members, *pmembers, *flags;
+       zval members, flags;
        HashPosition      pos;
        php_serialize_data_t var_hash;
        smart_str buf = {0};
@@ -758,20 +735,19 @@ SPL_METHOD(SplObjectStorage, serialize)
        
        /* storage */
        smart_str_appendl(&buf, "x:", 2);
-       MAKE_STD_ZVAL(flags);
-       ZVAL_LONG(flags, zend_hash_num_elements(&intern->storage));
+       ZVAL_LONG(&flags, zend_hash_num_elements(&intern->storage));
        php_var_serialize(&buf, &flags, &var_hash TSRMLS_CC);
        zval_ptr_dtor(&flags);
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
 
-       while(zend_hash_has_more_elements_ex(&intern->storage, &pos) == SUCCESS) {
-               if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &pos) == FAILURE) {
+       while (zend_hash_has_more_elements_ex(&intern->storage, &pos) == SUCCESS) {
+               if ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &pos)) == NULL) {
                        smart_str_free(&buf);
                        PHP_VAR_SERIALIZE_DESTROY(var_hash);
                        RETURN_NULL();
                }
-               php_var_serialize(&buf, &element->obj, &var_hash TSRMLS_CC);
+               php_var_serialize(&buf, element->obj, &var_hash TSRMLS_CC);
                smart_str_appendc(&buf, ',');
                php_var_serialize(&buf, &element->inf, &var_hash TSRMLS_CC);
                smart_str_appendc(&buf, ';');
@@ -780,17 +756,18 @@ SPL_METHOD(SplObjectStorage, serialize)
 
        /* members */
        smart_str_appendl(&buf, "m:", 2);
-       INIT_PZVAL(&members);
-       Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC);
-       Z_TYPE(members) = IS_ARRAY;
-       pmembers = &members;
-       php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */
+       array_init(&members);
+       zend_hash_copy(Z_ARRVAL(members), zend_std_get_properties(getThis() TSRMLS_CC), (copy_ctor_func_t) zval_add_ref);
+       php_var_serialize(&buf, &members, &var_hash TSRMLS_CC); /* finishes the string */
+       zval_ptr_dtor(&members);
 
        /* done */
        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();
        }
@@ -801,13 +778,13 @@ SPL_METHOD(SplObjectStorage, serialize)
  Unserializes storage */
 SPL_METHOD(SplObjectStorage, unserialize)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        char *buf;
        int buf_len;
        const unsigned char *p, *s;
        php_unserialize_data_t var_hash;
-       zval *pentry, *pmembers, *pcount = NULL, *pinf;
+       zval entry, pmembers, pcount, inf;
        long count;
        
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) {
@@ -828,18 +805,20 @@ SPL_METHOD(SplObjectStorage, unserialize)
        }
        ++p;
 
-       ALLOC_INIT_ZVAL(pcount);
-       if (!php_var_unserialize(&pcount, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pcount) != IS_LONG) {
+       if (!php_var_unserialize(&pcount, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+               goto outexcept;
+       }
+       if (Z_TYPE(pcount) != IS_LONG) {
+               zval_ptr_dtor(&pcount);
                goto outexcept;
        }
 
        --p; /* for ';' */
-       count = Z_LVAL_P(pcount);
+       count = Z_LVAL(pcount);
                
-       while(count-- > 0) {
+       while (count-- > 0) {
                spl_SplObjectStorageElement *pelement;
-               char *hash;
-               int hash_len;
+               zend_string *hash;
                
                if (*p != ';') {
                        goto outexcept;
@@ -848,43 +827,40 @@ SPL_METHOD(SplObjectStorage, unserialize)
                if(*p != 'O' && *p != 'C' && *p != 'r') {
                        goto outexcept;
                }
-               ALLOC_INIT_ZVAL(pentry);
-               if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) {
-                       zval_ptr_dtor(&pentry);
+               if (!php_var_unserialize(&entry, &p, s + buf_len, &var_hash TSRMLS_CC)) {
                        goto outexcept;
                }
-               if(Z_TYPE_P(pentry) != IS_OBJECT) {
-                       zval_ptr_dtor(&pentry);
+               if (Z_TYPE(entry) != IS_OBJECT) {
+                       zval_ptr_dtor(&entry);
                        goto outexcept;
                }
-               ALLOC_INIT_ZVAL(pinf);
                if (*p == ',') { /* new version has inf */
                        ++p;
-                       if (!php_var_unserialize(&pinf, &p, s + buf_len, &var_hash TSRMLS_CC)) {
-                               zval_ptr_dtor(&pinf);
+                       if (!php_var_unserialize(&inf, &p, s + buf_len, &var_hash TSRMLS_CC)) {
+                               zval_ptr_dtor(&entry);
                                goto outexcept;
                        }
                }
 
-               hash = spl_object_storage_get_hash(intern, getThis(), pentry, &hash_len TSRMLS_CC);
+               hash = spl_object_storage_get_hash(intern, getThis(), &entry TSRMLS_CC);
                if (!hash) {
-                       zval_ptr_dtor(&pentry);
-                       zval_ptr_dtor(&pinf);
+                       zval_ptr_dtor(&entry);
+                       zval_ptr_dtor(&inf);
                        goto outexcept;
                }
-               pelement = spl_object_storage_get(intern, hash, hash_len TSRMLS_CC);
+               pelement = spl_object_storage_get(intern, hash TSRMLS_CC);
                spl_object_storage_free_hash(intern, hash);
-               if(pelement) {
-                       if(pelement->inf) {
+               if (pelement) {
+                       if (!ZVAL_IS_UNDEF(&pelement->inf)) {
                                var_push_dtor(&var_hash, &pelement->inf);
                        }
-                       if(pelement->obj) {
-                               var_push_dtor(&var_hash, &pelement->obj);
+                       if (pelement->obj) {
+                               var_push_dtor(&var_hash, pelement->obj);
                        }
                } 
-               spl_object_storage_attach(intern, getThis(), pentry, pinf TSRMLS_CC);
-               zval_ptr_dtor(&pentry);
-               zval_ptr_dtor(&pinf);
+               spl_object_storage_attach(intern, getThis(), &entry, &inf TSRMLS_CC);
+               zval_ptr_dtor(&entry);
+               zval_ptr_dtor(&inf);
        }
 
        if (*p != ';') {
@@ -898,9 +874,7 @@ SPL_METHOD(SplObjectStorage, unserialize)
        }
        ++p;
 
-       ALLOC_INIT_ZVAL(pmembers);
        if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) {
-               zval_ptr_dtor(&pmembers);
                goto outexcept;
        }
 
@@ -908,20 +882,13 @@ SPL_METHOD(SplObjectStorage, unserialize)
        if (!intern->std.properties) {
                rebuild_object_properties(&intern->std);
        }
-       zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers), (copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *));
+       zend_hash_copy(intern->std.properties, Z_ARRVAL(pmembers), (copy_ctor_func_t) zval_add_ref);
        zval_ptr_dtor(&pmembers);
 
-       /* done reading $serialized */
-       if (pcount) {
-               zval_ptr_dtor(&pcount);
-       }
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
        return;
 
 outexcept:
-       if (pcount) {
-               zval_ptr_dtor(&pcount);
-       }
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
        zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
        return;
@@ -1010,7 +977,7 @@ SPL_METHOD(MultipleIterator, __construct)
                return;
        }
 
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        intern->flags = flags;
        zend_restore_error_handling(&error_handling TSRMLS_CC);
 }
@@ -1020,7 +987,7 @@ SPL_METHOD(MultipleIterator, __construct)
    Return current flags */
 SPL_METHOD(MultipleIterator, getFlags)
 {
-       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1034,7 +1001,7 @@ SPL_METHOD(MultipleIterator, getFlags)
 SPL_METHOD(MultipleIterator, setFlags)
 {
        spl_SplObjectStorage *intern;
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags) == FAILURE) {
                return;
@@ -1053,7 +1020,7 @@ SPL_METHOD(MultipleIterator, attachIterator)
                return;
        }
 
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
 
        if (info != NULL) {
                spl_SplObjectStorageElement *element;
@@ -1065,8 +1032,8 @@ SPL_METHOD(MultipleIterator, attachIterator)
                }
 
                zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-               while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS) {
-                       is_identical_function(&compare_result, info, element->inf TSRMLS_CC);
+               while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL) {
+                       is_identical_function(&compare_result, info, &element->inf TSRMLS_CC);
                        if (Z_LVAL(compare_result)) {
                                zend_throw_exception(spl_ce_InvalidArgumentException, "Key duplication error", 0 TSRMLS_CC);
                                return;
@@ -1087,16 +1054,16 @@ SPL_METHOD(MultipleIterator, rewind)
        spl_SplObjectStorageElement *element;
        zval                        *it;
 
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
+       while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
                it = element->obj;
-               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_rewind, "rewind", NULL);
+               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_rewind, "rewind", NULL);
                zend_hash_move_forward_ex(&intern->storage, &intern->pos);
        }
 }
@@ -1110,16 +1077,16 @@ SPL_METHOD(MultipleIterator, next)
        spl_SplObjectStorageElement *element;
        zval                        *it;
 
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
        }
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
+       while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
                it = element->obj;
-               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_next, "next", NULL);
+               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_next, "next", NULL);
                zend_hash_move_forward_ex(&intern->storage, &intern->pos);
        }
 }
@@ -1131,10 +1098,10 @@ SPL_METHOD(MultipleIterator, valid)
 {
        spl_SplObjectStorage        *intern;
        spl_SplObjectStorageElement *element;
-       zval                        *it, *retval = NULL;
+       zval                        *it, retval;
        long                         expect, valid;
 
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1147,12 +1114,12 @@ SPL_METHOD(MultipleIterator, valid)
        expect = (intern->flags & MIT_NEED_ALL) ? 1 : 0;
 
        zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
+       while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
                it = element->obj;
-               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);
+               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);
 
-               if (retval) {
-                       valid = Z_LVAL_P(retval);
+               if (!ZVAL_IS_UNDEF(&retval)) {
+                       valid = Z_LVAL(retval);
                        zval_ptr_dtor(&retval);
                } else {
                        valid = 0;
@@ -1172,7 +1139,7 @@ SPL_METHOD(MultipleIterator, valid)
 static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_type, zval *return_value TSRMLS_DC) /* {{{ */
 {
        spl_SplObjectStorageElement *element;
-       zval                        *it, *retval = NULL;
+       zval                        *it, retval;
        int                          valid = 1, num_elements;
 
        num_elements = zend_hash_num_elements(&intern->storage);
@@ -1183,12 +1150,12 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
        array_init_size(return_value, num_elements);
        
        zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
-       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
+       while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
                it = element->obj;
-               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);
+               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);
 
-               if (retval) {
-                       valid = Z_LVAL_P(retval);
+               if (!ZVAL_IS_UNDEF(&retval)) {
+                       valid = Z_LVAL(retval);
                        zval_ptr_dtor(&retval);
                } else {
                        valid = 0;
@@ -1196,11 +1163,11 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
 
                if (valid) {
                        if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
-                               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_current, "current", &retval);
+                               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_current, "current", &retval);
                        } else {
-                               zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_key,     "key",     &retval);
+                               zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_key, "key", &retval);
                        }
-                       if (!retval) {
+                       if (ZVAL_IS_UNDEF(&retval)) {
                                zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0 TSRMLS_CC);
                                return;
                        }
@@ -1212,16 +1179,16 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
                        }
                        return;
                } else {
-                       ALLOC_INIT_ZVAL(retval);
+                       ZVAL_NULL(&retval);
                }
 
                if (intern->flags & MIT_KEYS_ASSOC) {
-                       switch (Z_TYPE_P(element->inf)) {
+                       switch (Z_TYPE(element->inf)) {
                                case IS_LONG:
-                                       add_index_zval(return_value, Z_LVAL_P(element->inf), retval);
+                                       add_index_zval(return_value, Z_LVAL(element->inf), &retval);
                                        break;
                                case IS_STRING:
-                                       add_assoc_zval_ex(return_value, Z_STRVAL_P(element->inf), Z_STRLEN_P(element->inf)+1U, retval);
+                                       add_assoc_zval_ex(return_value, Z_STRVAL(element->inf), Z_STRLEN(element->inf), &retval);
                                        break;
                                default:
                                        zval_ptr_dtor(&retval);
@@ -1229,7 +1196,7 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
                                        return;
                        }
                } else {
-                       add_next_index_zval(return_value, retval);
+                       add_next_index_zval(return_value, &retval);
                }
 
                zend_hash_move_forward_ex(&intern->storage, &intern->pos);
@@ -1242,7 +1209,7 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
 SPL_METHOD(MultipleIterator, current)
 {
        spl_SplObjectStorage        *intern;
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1257,7 +1224,7 @@ SPL_METHOD(MultipleIterator, current)
 SPL_METHOD(MultipleIterator, key)
 {
        spl_SplObjectStorage        *intern;
-       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
+       intern = (spl_SplObjectStorage*)Z_OBJ_P(getThis());
        
        if (zend_parse_parameters_none() == FAILURE) {
                return;
@@ -1314,6 +1281,8 @@ PHP_MINIT_FUNCTION(spl_observer)
        spl_handler_SplObjectStorage.compare_objects = spl_object_storage_compare_objects;
        spl_handler_SplObjectStorage.clone_obj       = spl_object_storage_clone;
        spl_handler_SplObjectStorage.get_gc          = spl_object_storage_get_gc;
+       spl_handler_SplObjectStorage.dtor_obj        = zend_objects_destroy_object;
+       spl_handler_SplObjectStorage.free_obj        = spl_SplOjectStorage_free_storage;
 
        REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable);
        REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator);