]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Mon, 10 Feb 2014 13:49:21 +0000 (17:49 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 10 Feb 2014 13:49:21 +0000 (17:49 +0400)
Zend/zend.h
Zend/zend_API.h
ext/standard/array.c
ext/standard/php_array.h
ext/standard/string.c

index fe80471c9d2e09536e0ea07ca262a3c4ced0212d..ac3758d4ea0d6cfd26252dc33ffbe764fe909e6c 100644 (file)
@@ -685,6 +685,11 @@ END_EXTERN_C()
                SEPARATE_ZVAL(zv);                                              \
        }
 
+#define SEPARATE_ZVAL_IF_REF(zv)                               \
+       if (Z_ISREF_P(zv)) {                                            \
+               SEPARATE_ZVAL(zv);                                              \
+       }
+
 #define SEPARATE_ZVAL_TO_MAKE_IS_REF(zv)               \
        if (!Z_ISREF_P(zv)) {                                           \
                zval ref;                                                               \
index 37c112cd9c5a18fa9ecc365f155555141c2c1156..0eadf7548b7d0f3b798b61f071ad3fc752b62d52 100644 (file)
@@ -673,30 +673,30 @@ END_EXTERN_C()
        {                                                                                                                                                               \
                char *_name = (name);                                                                                                           \
                                                                                                                                                                        \
-               ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name)+1, var, 1, 0);       \
+               ZEND_SET_SYMBOL_WITH_LENGTH(symtable, _name, strlen(_name), var, 1, 0);         \
        }
 
 #define ZEND_SET_SYMBOL_WITH_LENGTH(symtable, name, name_length, var, _refcount, _is_ref)                              \
        {                                                                                                                                                                                                       \
-               zval **orig_var;                                                                                                                                                                \
+               zval *orig_var;                                                                                                                                                                 \
                                                                                                                                                                                                                \
-               if (zend_hash_find(symtable, (name), (name_length), (void **) &orig_var)==SUCCESS                               \
-                       && Z_ISREF_PP(orig_var)) {                                                                                                                              \
-                       Z_SET_REFCOUNT_P(var, Z_REFCOUNT_PP(orig_var));                                                                                         \
-                       Z_SET_ISREF_P(var);                                                                                                                                                     \
+               if ((orig_var = zend_hash_str_find(symtable, (name), (name_length))) != NULL                                    \
+                       && Z_ISREF_P(orig_var)) {                                                                                                                                       \
+                       Z_SET_REFCOUNT_P(var, Z_REFCOUNT_P(orig_var));                                                                                          \
+                       /*???Z_SET_ISREF_P(var);*/                                                                                                                                      \
                                                                                                                                                                                                                \
                        if (_refcount) {                                                                                                                                                        \
                                Z_SET_REFCOUNT_P(var, Z_REFCOUNT_P(var) + _refcount - 1);                                                               \
                        }                                                                                                                                                                                       \
-                       zval_dtor(*orig_var);                                                                                                                                           \
-                       **orig_var = *(var);                                                                                                                                            \
-                       FREE_ZVAL(var);                                                                                                                                                         \
+                       zval_dtor(orig_var);                                                                                                                                            \
+                       ZVAL_COPY_VALUE(orig_var, var);                                                                                                                         \
+                       /*???FREE_ZVAL(var);*/                                                                                                                                          \
                } else {                                                                                                                                                                                \
-                       Z_SET_ISREF_TO_P(var, _is_ref);                                                                                                                         \
+                       /*???Z_SET_ISREF_TO_P(var, _is_ref);*/                                                                                                          \
                        if (_refcount) {                                                                                                                                                        \
                                Z_SET_REFCOUNT_P(var, _refcount);                                                                                                               \
                        }                                                                                                                                                                                       \
-                       zend_hash_update(symtable, (name), (name_length), &(var), sizeof(zval *), NULL);                        \
+                       zend_hash_str_update(symtable, (name), (name_length), var);                                                                     \
                }                                                                                                                                                                                               \
        }
 
index 9892bd49ae457cfdcf5d6d6a6cef9f34a6751ece..502d15ea3ac1f5dbefe09541adea8bedc62a6fe1 100644 (file)
@@ -184,22 +184,16 @@ static int php_array_key_compare(const void *a, const void *b TSRMLS_DC) /* {{{
        f = (Bucket *) a;
        s = (Bucket *) b;
 
-       if (f->nKeyLength == 0) {
-               Z_TYPE(first) = IS_LONG;
-               Z_LVAL(first) = f->h;
+       if (f->key == NULL) {
+               ZVAL_LONG(&first, f->h);
        } else {
-               Z_TYPE(first) = IS_STRING;
-               Z_STRVAL(first) = (char*)f->arKey;
-               Z_STRLEN(first) = f->nKeyLength - 1;
+               ZVAL_STR(&first, f->key);
        }
 
-       if (s->nKeyLength == 0) {
-               Z_TYPE(second) = IS_LONG;
-               Z_LVAL(second) = s->h;
+       if (s->key == 0) {
+               ZVAL_LONG(&second, s->h);
        } else {
-               Z_TYPE(second) = IS_STRING;
-               Z_STRVAL(second) = (char*)s->arKey;
-               Z_STRLEN(second) = s->nKeyLength - 1;
+               ZVAL_STR(&second, s->key);
        }
 
        if (ARRAYG(compare_func)(&result, &first, &second TSRMLS_CC) == FAILURE) {
@@ -277,7 +271,7 @@ PHP_FUNCTION(ksort)
 static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
 {
        long cnt = 0;
-       zval **element;
+       zval *element;
 
        if (Z_TYPE_P(array) == IS_ARRAY) {
                if (Z_ARRVAL_P(array)->nApplyCount > 1) {
@@ -290,11 +284,11 @@ static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */
                        HashPosition pos;
 
                        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
-                               zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **) &element, &pos) == SUCCESS;
+                               (element = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL;
                                zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)
                        ) {
                                Z_ARRVAL_P(array)->nApplyCount++;
-                               cnt += php_count_recursive(*element, COUNT_RECURSIVE TSRMLS_CC);
+                               cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC);
                                Z_ARRVAL_P(array)->nApplyCount--;
                        }
                }
@@ -324,7 +318,7 @@ PHP_FUNCTION(count)
                        break;
                case IS_OBJECT: {
 #ifdef HAVE_SPL
-                       zval *retval;
+                       zval retval;
 #endif
                        /* first, we check if the handler is defined */
                        if (Z_OBJ_HT_P(array)->count_elements) {
@@ -333,20 +327,17 @@ PHP_FUNCTION(count)
                                        return;
                                }
                        }
-//???
-#if 0
 #ifdef HAVE_SPL
                        /* if not and the object implements Countable we call its count() method */
                        if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) {
-                               zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval);
-                               if (retval) {
+                               zend_call_method_with_0_params(array, NULL, NULL, "count", &retval);
+                               if (Z_TYPE(retval) != IS_UNDEF) {
                                        convert_to_long_ex(&retval);
-                                       RETVAL_LONG(Z_LVAL_P(retval));
+                                       RETVAL_LONG(Z_LVAL(retval));
                                        zval_ptr_dtor(&retval);
                                }
                                return;
                        }
-#endif
 #endif
                }
                default:
@@ -373,8 +364,8 @@ static int php_array_data_compare(const void *a, const void *b TSRMLS_DC) /* {{{
        f = (Bucket *) a;
        s = (Bucket *) b;
 
-       first = (zval *) f->xData;
-       second = (zval *) s->xData;
+       first = &f->val;
+       second = &s->val;
 
        if (ARRAYG(compare_func)(&result, first, second TSRMLS_CC) == FAILURE) {
                return 0;
@@ -418,10 +409,10 @@ static int php_array_natural_general_compare(const void *a, const void *b, int f
        f = (Bucket *) a;
        s = (Bucket *) b;
 
-       fval = (zval *) f->xData;
-       sval = (zval *) s->xData;
-       first = *fval;
-       second = *sval;
+       fval = &f->val;
+       sval = &s->val;
+       ZVAL_COPY_VALUE(&first, fval);
+       ZVAL_COPY_VALUE(&second, sval);
 
        if (Z_TYPE_P(fval) != IS_STRING) {
                zval_copy_ctor(&first);
@@ -581,26 +572,26 @@ static int php_array_user_compare(const void *a, const void *b TSRMLS_DC) /* {{{
 {
        Bucket *f;
        Bucket *s;
-       zval **args[2];
-       zval *retval_ptr = NULL;
+       zval args[2];
+       zval retval;
 
        f = (Bucket *) a;
        s = (Bucket *) b;
 
-       args[0] = (zval **) &f->xData;
-       args[1] = (zval **) &s->xData;
+       ZVAL_COPY_VALUE(&args[0], &f->val);
+       ZVAL_COPY_VALUE(&args[1], &s->val);
 
        BG(user_compare_fci).param_count = 2;
        BG(user_compare_fci).params = args;
-       BG(user_compare_fci).retval_ptr_ptr = &retval_ptr;
+       BG(user_compare_fci).retval = &retval;
        BG(user_compare_fci).no_separation = 0;
-       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && retval_ptr) {
-               long retval;
+       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               long ret;
 
-               convert_to_long_ex(&retval_ptr);
-               retval = Z_LVAL_P(retval_ptr);
-               zval_ptr_dtor(&retval_ptr);
-               return retval < 0 ? -1 : retval > 0 ? 1 : 0;
+               convert_to_long_ex(&retval);
+               ret = Z_LVAL(retval);
+               zval_ptr_dtor(&retval);
+               return ret < 0 ? -1 : ret > 0 ? 1 : 0;
        } else {
                return 0;
        }
@@ -657,7 +648,7 @@ PHP_FUNCTION(usort)
         * comparison. The result of sorting in such case is undefined and the
         * function returns FALSE.
         */
-       Z_UNSET_ISREF_P(array);
+//???  Z_UNSET_ISREF_P(array);
        refcount = Z_REFCOUNT_P(array);
 
        if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_compare, 1 TSRMLS_CC) == FAILURE) {
@@ -672,7 +663,7 @@ PHP_FUNCTION(usort)
        }
        
        if (Z_REFCOUNT_P(array) > 1) {
-               Z_SET_ISREF_P(array);
+//???          Z_SET_ISREF_P(array);
        }
 
        PHP_ARRAY_CMP_FUNC_RESTORE();
@@ -700,7 +691,7 @@ PHP_FUNCTION(uasort)
         * comparison. The result of sorting in such case is undefined and the
         * function returns FALSE.
         */
-       Z_UNSET_ISREF_P(array);
+//???  Z_UNSET_ISREF_P(array);
        refcount = Z_REFCOUNT_P(array);
 
        if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_compare, 0 TSRMLS_CC) == FAILURE) {
@@ -715,7 +706,7 @@ PHP_FUNCTION(uasort)
        }
 
        if (Z_REFCOUNT_P(array) > 1) {
-               Z_SET_ISREF_P(array);
+//???          Z_SET_ISREF_P(array);
        }
 
        PHP_ARRAY_CMP_FUNC_RESTORE();
@@ -726,50 +717,41 @@ static int php_array_user_key_compare(const void *a, const void *b TSRMLS_DC) /*
 {
        Bucket *f;
        Bucket *s;
-       zval *key1, *key2;
-       zval **args[2];
-       zval *retval_ptr = NULL;
+       zval args[2];
+       zval retval;
        long result;
 
-       ALLOC_INIT_ZVAL(key1);
-       ALLOC_INIT_ZVAL(key2);
-       args[0] = &key1;
-       args[1] = &key2;
+       ZVAL_NULL(&args[0]);
+       ZVAL_NULL(&args[1]);
 
        f = (Bucket *) a;
        s = (Bucket *) b;
 
-       if (f->nKeyLength == 0) {
-               Z_LVAL_P(key1) = f->h;
-               Z_TYPE_P(key1) = IS_LONG;
+       if (f->key == NULL) {
+               ZVAL_LONG(&args[0], f->h);
        } else {
-               Z_STRVAL_P(key1) = estrndup(f->arKey, f->nKeyLength - 1);
-               Z_STRLEN_P(key1) = f->nKeyLength - 1;
-               Z_TYPE_P(key1) = IS_STRING;
+               ZVAL_STR(&args[0], STR_COPY(f->key));
        }
-       if (s->nKeyLength == 0) {
-               Z_LVAL_P(key2) = s->h;
-               Z_TYPE_P(key2) = IS_LONG;
+       if (s->key == NULL) {
+               ZVAL_LONG(&args[1], s->h);
        } else {
-               Z_STRVAL_P(key2) = estrndup(s->arKey, s->nKeyLength - 1);
-               Z_STRLEN_P(key2) = s->nKeyLength - 1;
-               Z_TYPE_P(key2) = IS_STRING;
+               ZVAL_STR(&args[1], STR_COPY(s->key));
        }
 
        BG(user_compare_fci).param_count = 2;
        BG(user_compare_fci).params = args;
-       BG(user_compare_fci).retval_ptr_ptr = &retval_ptr;
+       BG(user_compare_fci).retval = &retval;
        BG(user_compare_fci).no_separation = 0;
-       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && retval_ptr) {
-               convert_to_long_ex(&retval_ptr);
-               result = Z_LVAL_P(retval_ptr);
-               zval_ptr_dtor(&retval_ptr);
+       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               convert_to_long_ex(&retval);
+               result = Z_LVAL(retval);
+               zval_ptr_dtor(&retval);
        } else {
                result = 0;
        }
 
-       zval_ptr_dtor(&key1);
-       zval_ptr_dtor(&key2);
+       zval_ptr_dtor(&args[0]);
+       zval_ptr_dtor(&args[1]);
 
        return result;
 }
@@ -796,7 +778,7 @@ PHP_FUNCTION(uksort)
         * comparison. The result of sorting in such case is undefined and the
         * function returns FALSE.
         */
-       Z_UNSET_ISREF_P(array);
+//???  Z_UNSET_ISREF_P(array);
        refcount = Z_REFCOUNT_P(array);
 
        if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_key_compare, 0 TSRMLS_CC) == FAILURE) {
@@ -811,7 +793,7 @@ PHP_FUNCTION(uksort)
        }
 
        if (Z_REFCOUNT_P(array) > 1) {
-               Z_SET_ISREF_P(array);
+//???          Z_SET_ISREF_P(array);
        }
 
        PHP_ARRAY_CMP_FUNC_RESTORE();
@@ -823,7 +805,7 @@ PHP_FUNCTION(uksort)
 PHP_FUNCTION(end)
 {
        HashTable *array;
-       zval **entry;
+       zval *entry;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
                return;
@@ -832,11 +814,11 @@ PHP_FUNCTION(end)
        zend_hash_internal_pointer_end(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data(array)) == NULL) {
                        RETURN_FALSE;
                }
 
-               RETURN_ZVAL_FAST(*entry);
+               RETURN_ZVAL_FAST(entry);
        }
 }
 /* }}} */
@@ -846,7 +828,7 @@ PHP_FUNCTION(end)
 PHP_FUNCTION(prev)
 {
        HashTable *array;
-       zval **entry;
+       zval *entry;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
                return;
@@ -855,11 +837,11 @@ PHP_FUNCTION(prev)
        zend_hash_move_backwards(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data(array)) == NULL) {
                        RETURN_FALSE;
                }
 
-               RETURN_ZVAL_FAST(*entry);
+               RETURN_ZVAL_FAST(entry);
        }
 }
 /* }}} */
@@ -869,7 +851,7 @@ PHP_FUNCTION(prev)
 PHP_FUNCTION(next)
 {
        HashTable *array;
-       zval **entry;
+       zval *entry;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
                return;
@@ -878,11 +860,11 @@ PHP_FUNCTION(next)
        zend_hash_move_forward(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data(array)) == NULL) {
                        RETURN_FALSE;
                }
 
-               RETURN_ZVAL_FAST(*entry);
+               RETURN_ZVAL_FAST(entry);
        }
 }
 /* }}} */
@@ -892,7 +874,7 @@ PHP_FUNCTION(next)
 PHP_FUNCTION(reset)
 {
        HashTable *array;
-       zval **entry;
+       zval *entry;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
                return;
@@ -901,11 +883,11 @@ PHP_FUNCTION(reset)
        zend_hash_internal_pointer_reset(array);
 
        if (return_value_used) {
-               if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
+               if ((entry = zend_hash_get_current_data(array)) == NULL) {
                        RETURN_FALSE;
                }
 
-               RETURN_ZVAL_FAST(*entry);
+               RETURN_ZVAL_FAST(entry);
        }
 }
 /* }}} */
@@ -915,17 +897,17 @@ PHP_FUNCTION(reset)
 PHP_FUNCTION(current)
 {
        HashTable *array;
-       zval **entry;
+       zval *entry;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
                return;
        }
 
-       if (zend_hash_get_current_data(array, (void **) &entry) == FAILURE) {
+       if ((entry = zend_hash_get_current_data(array)) == NULL) {
                RETURN_FALSE;
        }
 
-       RETURN_ZVAL_FAST(*entry);
+       RETURN_ZVAL_FAST(entry);
 }
 /* }}} */
 
@@ -948,7 +930,7 @@ PHP_FUNCTION(key)
 PHP_FUNCTION(min)
 {
        int argc;
-       zval ***args = NULL;
+       zval *args = NULL;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
                return;
@@ -958,14 +940,14 @@ PHP_FUNCTION(min)
        
        /* mixed min ( array $values ) */
        if (argc == 1) {
-               zval **result;
+               zval *result;
                
-               if (Z_TYPE_PP(args[0]) != IS_ARRAY) {
+               if (Z_TYPE(args[0]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "When only one parameter is given, it must be an array");
                        RETVAL_NULL();
                } else {
-                       if (zend_hash_minmax(Z_ARRVAL_PP(args[0]), php_array_data_compare, 0, (void **) &result TSRMLS_CC) == SUCCESS) {
-                               RETVAL_ZVAL_FAST(*result);
+                       if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 0 TSRMLS_CC)) != NULL) {
+                               RETVAL_ZVAL_FAST(result);
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain at least one element");
                                RETVAL_FALSE;
@@ -973,19 +955,19 @@ PHP_FUNCTION(min)
                }
        } else {
                /* mixed min ( mixed $value1 , mixed $value2 [, mixed $value3... ] ) */
-               zval **min, result;
+               zval *min, result;
                int i;
 
-               min = args[0];
+               min = &args[0];
 
                for (i = 1; i < argc; i++) {
-                       is_smaller_function(&result, *args[i], *min TSRMLS_CC);
+                       is_smaller_function(&result, &args[i], min TSRMLS_CC);
                        if (Z_LVAL(result) == 1) {
-                               min = args[i];
+                               min = &args[i];
                        }
                }
 
-               RETVAL_ZVAL_FAST(*min);
+               RETVAL_ZVAL_FAST(min);
        }
 
        if (args) {
@@ -998,7 +980,7 @@ PHP_FUNCTION(min)
    Return the highest value in an array or a series of arguments */
 PHP_FUNCTION(max)
 {
-       zval ***args = NULL;
+       zval *args = NULL;
        int argc;
        
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
@@ -1009,14 +991,14 @@ PHP_FUNCTION(max)
        
        /* mixed max ( array $values ) */
        if (argc == 1) {
-               zval **result;
+               zval *result;
 
-               if (Z_TYPE_PP(args[0]) != IS_ARRAY) {
+               if (Z_TYPE(args[0]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "When only one parameter is given, it must be an array");
                        RETVAL_NULL();
                } else {
-                       if (zend_hash_minmax(Z_ARRVAL_PP(args[0]), php_array_data_compare, 1, (void **) &result TSRMLS_CC) == SUCCESS) {
-                               RETVAL_ZVAL_FAST(*result);
+                       if ((result = zend_hash_minmax(Z_ARRVAL(args[0]), php_array_data_compare, 1 TSRMLS_CC)) != NULL) {
+                               RETVAL_ZVAL_FAST(result);
                        } else {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array must contain at least one element");
                                RETVAL_FALSE;
@@ -1024,19 +1006,19 @@ PHP_FUNCTION(max)
                }
        } else {
                /* mixed max ( mixed $value1 , mixed $value2 [, mixed $value3... ] ) */
-               zval **max, result;
+               zval *max, result;
                int i;
 
-               max = args[0];
+               max = &args[0];
 
                for (i = 1; i < argc; i++) {
-                       is_smaller_or_equal_function(&result, *args[i], *max TSRMLS_CC);
+                       is_smaller_or_equal_function(&result, &args[i], max TSRMLS_CC);
                        if (Z_LVAL(result) == 0) {
-                               max = args[i];
+                               max = &args[i];
                        }
                }
 
-               RETVAL_ZVAL_FAST(*max);
+               RETVAL_ZVAL_FAST(max);
        }
        
        if (args) {
@@ -1047,36 +1029,37 @@ PHP_FUNCTION(max)
 
 static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive TSRMLS_DC) /* {{{ */
 {
-       zval **args[3],                 /* Arguments to userland function */
-                 *retval_ptr = NULL,           /* Return value - unused */
-                 *key=NULL;            /* Entry key */
+       zval args[3],           /* Arguments to userland function */
+                retval,                /* Return value - unused */
+                *zv;
 
        /* Set up known arguments */
-       args[1] = &key;
-       args[2] = &userdata;
+       ZVAL_UNDEF(&retval);
+       ZVAL_UNDEF(&args[1]);
        if (userdata) {
-               Z_ADDREF_P(userdata);
+               ZVAL_COPY(&args[2], userdata);
        }
 
-       BG(array_walk_fci).retval_ptr_ptr = &retval_ptr;
+       BG(array_walk_fci).retval = &retval;
        BG(array_walk_fci).param_count = userdata ? 3 : 2;
        BG(array_walk_fci).params = args;
        BG(array_walk_fci).no_separation = 0;
        
        /* Iterate through hash */
        zend_hash_internal_pointer_reset(target_hash);
-       while (!EG(exception) && zend_hash_get_current_data(target_hash, (void **)&args[0]) == SUCCESS) {
-               if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {
+       while (!EG(exception) && (zv = zend_hash_get_current_data(target_hash)) != NULL) {
+               ZVAL_COPY_VALUE(&args[0], zv);
+               if (recursive && Z_TYPE(args[0]) == IS_ARRAY) {
                        HashTable *thash;
                        zend_fcall_info orig_array_walk_fci;
                        zend_fcall_info_cache orig_array_walk_fci_cache;
 
-                       SEPARATE_ZVAL_IF_NOT_REF(args[0]);
-                       thash = Z_ARRVAL_PP(args[0]);
+                       SEPARATE_ZVAL_IF_NOT_REF(&args[0]);
+                       thash = Z_ARRVAL(args[0]);
                        if (thash->nApplyCount > 1) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
                                if (userdata) {
-                                       zval_ptr_dtor(&userdata);
+                                       zval_ptr_dtor(userdata);
                                }
                                return 0;
                        }
@@ -1094,32 +1077,29 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
                        BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
                } else {
                        /* Allocate space for key */
-                       MAKE_STD_ZVAL(key);
-                       zend_hash_get_current_key_zval(target_hash, key);
+                       zend_hash_get_current_key_zval(target_hash, &args[1]);
 
                        /* Call the userland function */
                        if (zend_call_function(&BG(array_walk_fci), &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) {
-                               if (retval_ptr) {
-                                       zval_ptr_dtor(&retval_ptr);
-                               }
+                               zval_ptr_dtor(&retval);
                        } else {
-                               if (key) {
-                                       zval_ptr_dtor(&key);
-                                       key = NULL;
+                               if (Z_TYPE(args[1]) != IS_UNDEF) {
+                                       zval_ptr_dtor(&args[1]);
+                                       ZVAL_UNDEF(&args[1]);
                                }
                                break;
                        }
                }
 
-               if (key) {
-                       zval_ptr_dtor(&key);
-                       key = NULL;
+               if (Z_TYPE(args[1]) != IS_UNDEF) {
+                       zval_ptr_dtor(&args[1]);
+                       ZVAL_UNDEF(&args[1]);
                }
                zend_hash_move_forward(target_hash);
        }
 
        if (userdata) {
-               zval_ptr_dtor(&userdata);
+               zval_ptr_dtor(userdata);
        }
        return 0;
 }
@@ -1183,7 +1163,7 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
 {
        zval *value,                            /* value to check for */
                 *array,                                /* array to check in */
-                **entry,                               /* pointer to array entry */
+                *entry,                                /* pointer to array entry */
                  res;                                  /* comparison result */
        HashPosition pos;                       /* hash iterator */
        zend_bool strict = 0;           /* strict comparison or not */
@@ -1198,8 +1178,8 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
        }
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&entry, &pos) == SUCCESS) {
-               is_equal_func(&res, value, *entry TSRMLS_CC);
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) {
+               is_equal_func(&res, value, entry TSRMLS_CC);
                if (Z_LVAL(res)) {
                        if (behavior == 0) {
                                RETURN_TRUE;
@@ -1269,9 +1249,7 @@ static int php_valid_var_name(char *var_name, int var_name_len) /* {{{ */
 
 PHPAPI int php_prefix_varname(zval *result, zval *prefix, char *var_name, int var_name_len, zend_bool add_underscore TSRMLS_DC) /* {{{ */
 {
-       Z_STRLEN_P(result) = Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0) + var_name_len;
-       Z_TYPE_P(result) = IS_STRING;
-       Z_STRVAL_P(result) = emalloc(Z_STRLEN_P(result) + 1);
+       ZVAL_STR(result, STR_ALLOC(Z_STRLEN_P(prefix) + (add_underscore ? 1 : 0) + var_name_len, 0));
        memcpy(Z_STRVAL_P(result), Z_STRVAL_P(prefix), Z_STRLEN_P(prefix));
 
        if (add_underscore) {
@@ -1290,10 +1268,9 @@ PHP_FUNCTION(extract)
 {
        zval *var_array, *prefix = NULL;
        long extract_type = EXTR_OVERWRITE;
-       zval **entry, *data;
-       char *var_name;
+       zval *entry, data;
+       zend_string *var_name;
        ulong num_key;
-       uint var_name_len;
        int var_exists, key_type, count = 0;
        int extract_refs = 0;
        HashPosition pos;
@@ -1335,17 +1312,16 @@ PHP_FUNCTION(extract)
        }
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), &pos)) != NULL) {
                zval final_name;
 
                ZVAL_NULL(&final_name);
 
-               key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &var_name_len, &num_key, 0, &pos);
+               key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &num_key, 0, &pos);
                var_exists = 0;
 
                if (key_type == HASH_KEY_IS_STRING) {
-                       var_name_len--;
-                       var_exists = zend_hash_exists(EG(active_symbol_table), var_name, var_name_len + 1);
+                       var_exists = zend_hash_exists(EG(active_symbol_table), var_name);
                } else if (key_type == HASH_KEY_IS_LONG && (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID)) {
                        zval num;
 
@@ -1365,69 +1341,66 @@ PHP_FUNCTION(extract)
 
                        case EXTR_OVERWRITE:
                                /* GLOBALS protection */
-                               if (var_exists && var_name_len == sizeof("GLOBALS")-1 && !strcmp(var_name, "GLOBALS")) {
+                               if (var_exists && var_name->len == sizeof("GLOBALS")-1 && !strcmp(var_name->val, "GLOBALS")) {
                                        break;
                                }
-                               if (var_exists && var_name_len == sizeof("this")-1  && !strcmp(var_name, "this") && EG(scope) && EG(scope)->name_length != 0) {
+                               if (var_exists && var_name->len == sizeof("this")-1  && !strcmp(var_name->val, "this") && EG(scope) && EG(scope)->name->len != 0) {
                                        break;
                                }
-                               ZVAL_STRINGL(&final_name, var_name, var_name_len, 1);
+                               ZVAL_STR(&final_name, STR_COPY(var_name));
                                break;
 
                        case EXTR_PREFIX_IF_EXISTS:
                                if (var_exists) {
-                                       php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC);
+                                       php_prefix_varname(&final_name, prefix, var_name->val, var_name->len, 1 TSRMLS_CC);
                                }
                                break;
 
                        case EXTR_PREFIX_SAME:
-                               if (!var_exists && var_name_len != 0) {
-                                       ZVAL_STRINGL(&final_name, var_name, var_name_len, 1);
+                               if (!var_exists && var_name->len != 0) {
+                                       ZVAL_STR(&final_name, STR_COPY(var_name));
                                }
                                /* break omitted intentionally */
 
                        case EXTR_PREFIX_ALL:
-                               if (Z_TYPE(final_name) == IS_NULL && var_name_len != 0) {
-                                       php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC);
+                               if (Z_TYPE(final_name) == IS_NULL && var_name->len != 0) {
+                                       php_prefix_varname(&final_name, prefix, var_name->val, var_name->len, 1 TSRMLS_CC);
                                }
                                break;
 
                        case EXTR_PREFIX_INVALID:
                                if (Z_TYPE(final_name) == IS_NULL) {
-                                       if (!php_valid_var_name(var_name, var_name_len)) {
-                                               php_prefix_varname(&final_name, prefix, var_name, var_name_len, 1 TSRMLS_CC);
+                                       if (!php_valid_var_name(var_name->val, var_name->len)) {
+                                               php_prefix_varname(&final_name, prefix, var_name->val, var_name->len, 1 TSRMLS_CC);
                                        } else {
-                                               ZVAL_STRINGL(&final_name, var_name, var_name_len, 1);
+                                               ZVAL_STR(&final_name, STR_COPY(var_name));
                                        }
                                }
                                break;
 
                        default:
                                if (!var_exists) {
-                                       ZVAL_STRINGL(&final_name, var_name, var_name_len, 1);
+                                       ZVAL_STR(&final_name, STR_COPY(var_name));
                                }
                                break;
                }
 
                if (Z_TYPE(final_name) != IS_NULL && php_valid_var_name(Z_STRVAL(final_name), Z_STRLEN(final_name))) {
                        if (extract_refs) {
-                               zval **orig_var;
+                               zval *orig_var;
 
                                SEPARATE_ZVAL_TO_MAKE_IS_REF(entry);
                                zval_add_ref(entry);
 
-                               if (zend_hash_find(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) &orig_var) == SUCCESS) {
+                               if ((orig_var = zend_hash_find(EG(active_symbol_table), Z_STR(final_name))) != NULL) {
                                        zval_ptr_dtor(orig_var);
-                                       *orig_var = *entry;
+                                       ZVAL_COPY_VALUE(orig_var, entry);
                                } else {
-                                       zend_hash_update(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, (void **) entry, sizeof(zval *), NULL);
+                                       zend_hash_update(EG(active_symbol_table), Z_STR(final_name), entry);
                                }
                        } else {
-                               MAKE_STD_ZVAL(data);
-                               *data = **entry;
-                               zval_copy_ctor(data);
-
-                               ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, data, 1, 0);
+                               ZVAL_DUP(&data, entry);
+                               ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), Z_STRVAL(final_name), Z_STRLEN(final_name) + 1, &data, 1, 0);
                        }
                        count++;
                }
@@ -1437,7 +1410,7 @@ PHP_FUNCTION(extract)
        }
 
        if (!extract_refs) {
-               zval_ptr_dtor(&var_array);
+               zval_ptr_dtor(var_array);
        }
 
        RETURN_LONG(count);
@@ -1446,15 +1419,12 @@ PHP_FUNCTION(extract)
 
 static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_value, zval *entry TSRMLS_DC) /* {{{ */
 {
-       zval **value_ptr, *value, *data;
+       zval *value_ptr, data;
 
        if (Z_TYPE_P(entry) == IS_STRING) {
-               if (zend_hash_find(eg_active_symbol_table, Z_STRVAL_P(entry), Z_STRLEN_P(entry) + 1, (void **)&value_ptr) != FAILURE) {
-                       value = *value_ptr;
-                       ALLOC_ZVAL(data);
-                       MAKE_COPY_ZVAL(&value, data);
-
-                       zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_P(entry), Z_STRLEN_P(entry) + 1, &data, sizeof(zval *), NULL);
+               if ((value_ptr = zend_hash_find(eg_active_symbol_table, Z_STR_P(entry))) != NULL) {
+                       ZVAL_DUP(&data, value_ptr);
+                       zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
                }
        }
        else if (Z_TYPE_P(entry) == IS_ARRAY) {
@@ -1468,10 +1438,8 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
                Z_ARRVAL_P(entry)->nApplyCount++;
 
                zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos);
-               while (zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), (void**)&value_ptr, &pos) == SUCCESS) {
-                       value = *value_ptr;
-
-                       php_compact_var(eg_active_symbol_table, return_value, value TSRMLS_CC);
+               while ((value_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) != NULL) {
+                       php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC);
                        zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos);
                }
                Z_ARRVAL_P(entry)->nApplyCount--;
@@ -1483,7 +1451,7 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
    Creates a hash containing variables and their values */
 PHP_FUNCTION(compact)
 {
-       zval ***args = NULL;    /* function arguments array */
+       zval *args = NULL;      /* function arguments array */
        int num_args, i;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
@@ -1497,14 +1465,14 @@ PHP_FUNCTION(compact)
        /* compact() is probably most used with a single array of var_names
           or multiple string names, rather than a combination of both.
           So quickly guess a minimum result size based on that */
-       if (ZEND_NUM_ARGS() == 1 && Z_TYPE_PP(args[0]) == IS_ARRAY) {
-               array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_PP(args[0])));
+       if (ZEND_NUM_ARGS() == 1 && Z_TYPE(args[0]) == IS_ARRAY) {
+               array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL(args[0])));
        } else {
                array_init_size(return_value, ZEND_NUM_ARGS());
        }
 
        for (i=0; i<ZEND_NUM_ARGS(); i++) {
-               php_compact_var(EG(active_symbol_table), return_value, *args[i] TSRMLS_CC);
+               php_compact_var(EG(active_symbol_table), return_value, &args[i] TSRMLS_CC);
        }
 
        if (args) {
@@ -1537,12 +1505,12 @@ PHP_FUNCTION(array_fill)
        }
 
        num--;
-       zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, &val, sizeof(zval *), NULL);
-       zval_add_ref(&val);
+       zend_hash_index_update(Z_ARRVAL_P(return_value), start_key, val);
+       zval_add_ref(val);
 
        while (num--) {
-               if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &val, sizeof(zval *), NULL) == SUCCESS) {
-                       zval_add_ref(&val);
+               if (zend_hash_next_index_insert(Z_ARRVAL_P(return_value), val) != NULL) {
+                       zval_add_ref(val);
                } else {
                        zval_dtor(return_value);
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to the array as the next element is already occupied");
@@ -1556,7 +1524,7 @@ PHP_FUNCTION(array_fill)
    Create an array using the elements of the first parameter as keys each initialized to val */
 PHP_FUNCTION(array_fill_keys)
 {
-       zval *keys, *val, **entry;
+       zval *keys, *val, *entry;
        HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az", &keys, &val) == FAILURE) {
@@ -1567,25 +1535,24 @@ PHP_FUNCTION(array_fill_keys)
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(keys)));
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), &pos)) != NULL) {
 
-               if (Z_TYPE_PP(entry) == IS_LONG) {
-                       zval_add_ref(&val);
-                       zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &val, sizeof(zval *), NULL);
+               if (Z_TYPE_P(entry) == IS_LONG) {
+                       zval_add_ref(val);
+                       zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
                } else {
-                       zval key, *key_ptr = *entry;
+                       zval key, *key_ptr = entry;
 
-                       if (Z_TYPE_PP(entry) != IS_STRING) {
-                               key = **entry;
-                               zval_copy_ctor(&key);
+                       if (Z_TYPE_P(entry) != IS_STRING) {
+                               ZVAL_DUP(&key, entry);
                                convert_to_string(&key);
                                key_ptr = &key;
                        }
 
-                       zval_add_ref(&val);
-                       zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL_P(key_ptr), Z_STRLEN_P(key_ptr) + 1, &val, sizeof(zval *), NULL);
+                       zval_add_ref(val);
+                       zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(key_ptr), val);
 
-                       if (key_ptr != *entry) {
+                       if (key_ptr != entry) {
                                zval_dtor(&key);
                        }
                }
@@ -1614,7 +1581,7 @@ PHP_FUNCTION(range)
                        is_step_double = 1;
                }
 
-               convert_to_double_ex(&zstep);
+               convert_to_double_ex(zstep);
                step = Z_DVAL_P(zstep);
 
                /* We only want positive step values. */
@@ -1765,7 +1732,7 @@ static void php_array_data_shuffle(zval *array TSRMLS_DC) /* {{{ */
        if (hash->nNumUsed != hash->nNumOfElements) {
                for (j = 0, idx = 0; idx < hash->nNumUsed; idx++) {
                        p = hash->arData + idx;
-                       if (!p->xData) continue;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
                        if (j != idx) {
                                hash->arData[j] = *p;
                        }
@@ -1788,12 +1755,11 @@ static void php_array_data_shuffle(zval *array TSRMLS_DC) /* {{{ */
 
        for (j = 0; j < n_elems; j++) {
                p = hash->arData + j;
-               if (p->nKeyLength && !IS_INTERNED(p->arKey)) {
-                       pefree((char*)p->arKey, hash->flags & HASH_FLAG_PERSISTENT);
+               if (p->key && !IS_INTERNED(p->key)) {
+                       pefree((char*)p->key, hash->flags & HASH_FLAG_PERSISTENT);
                }
                p->h = j;
-               p->nKeyLength = 0;
-               p->arKey = NULL;
+               p->key = NULL;
        }
        hash->nNextFreeElement = n_elems;
        if (!(hash->flags & HASH_FLAG_PACKED)) {
@@ -1819,7 +1785,7 @@ PHP_FUNCTION(shuffle)
 }
 /* }}} */
 
-PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval ***list, int list_count, HashTable **removed) /* {{{ */
+PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval *list, int list_count, HashTable *removed) /* {{{ */
 {
        HashTable       *out_hash = NULL;       /* Output hashtable */
        int                      num_in,                        /* Number of entries in the input hashtable */
@@ -1858,17 +1824,17 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval **
        /* Start at the beginning of the input hash and copy entries to output hash until offset is reached */
        for (pos = 0, idx = 0; pos < offset && idx < in_hash->nNumUsed; idx++) {
                p = in_hash->arData + idx;
-               if (!p->xData) continue;
+               if (Z_TYPE(p->val) == IS_UNDEF) continue;
                pos++;
                /* Get entry and increase reference count */
-               entry = (zval *)p->xData;
+               entry = &p->val;
                Z_ADDREF_P(entry);
 
                /* Update output hash depending on key type */
-               if (p->nKeyLength == 0) {
-                       zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
+               if (p->key == NULL) {
+                       zend_hash_next_index_insert(out_hash, entry);
                } else {
-                       zend_hash_quick_update(out_hash, p->arKey, p->nKeyLength, p->h, &entry, sizeof(zval *), NULL);
+                       zend_hash_update(out_hash, p->key, entry);
                }
        }
 
@@ -1876,14 +1842,14 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval **
        if (removed != NULL) {
                for ( ; pos < offset + length && idx < in_hash->nNumUsed; idx++) {
                        p = in_hash->arData + idx;
-                       if (!p->xData) continue;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
                        pos++;
-                       entry = (zval *)p->xData;
+                       entry = &p->val;
                        Z_ADDREF_P(entry);
-                       if (p->nKeyLength == 0) {
-                               zend_hash_next_index_insert(*removed, &entry, sizeof(zval *), NULL);
+                       if (p->key == NULL) {
+                               zend_hash_next_index_insert(removed, entry);
                        } else {
-                               zend_hash_quick_update(*removed, p->arKey, p->nKeyLength, p->h, &entry, sizeof(zval *), NULL);
+                               zend_hash_update(removed, p->key, entry);
                        }
                }
        } else { /* otherwise just skip those entries */
@@ -1894,22 +1860,22 @@ PHPAPI HashTable* php_splice(HashTable *in_hash, int offset, int length, zval **
        if (list != NULL) {
                /* ..for each one, create a new zval, copy entry into it and copy it into the output hash */
                for (i = 0; i < list_count; i++) {
-                       entry = *list[i];
+                       entry = &list[i];
                        Z_ADDREF_P(entry);
-                       zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
+                       zend_hash_next_index_insert(out_hash, entry);
                }
        }
 
        /* Copy the remaining input hash entries to the output hash */
        for ( ; idx < in_hash->nNumUsed ; idx++) {
                p = in_hash->arData + idx;
-               if (!p->xData) continue;
-               entry = (zval *)p->xData;
+               if (Z_TYPE(p->val) == IS_UNDEF) continue;
+               entry = &p->val;
                Z_ADDREF_P(entry);
-               if (p->nKeyLength == 0) {
-                       zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);
+               if (p->key == NULL) {
+                       zend_hash_next_index_insert(out_hash, entry);
                } else {
-                       zend_hash_quick_update(out_hash, p->arKey, p->nKeyLength, p->h, &entry, sizeof(zval *), NULL);
+                       zend_hash_update(out_hash, p->key, entry);
                }
        }
 
@@ -1938,7 +1904,7 @@ PHP_FUNCTION(array_push)
                new_var = *args[i];
                Z_ADDREF_P(new_var);
 
-               if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var, sizeof(zval *), NULL) == FAILURE) {
+               if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), new_var) == NULL) {
                        Z_DELREF_P(new_var);
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to the array as the next element is already occupied");
                        efree(args);
@@ -1956,9 +1922,8 @@ PHP_FUNCTION(array_push)
 static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
 {
        zval *stack,    /* Input stack */
-                **val;         /* Value to be popped */
-       char *key = NULL;
-       uint key_len = 0;
+                *val;          /* Value to be popped */
+       zend_string *key = NULL;
        ulong index;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &stack) == FAILURE) {
@@ -1975,15 +1940,17 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
        } else {
                zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack));
        }
-       zend_hash_get_current_data(Z_ARRVAL_P(stack), (void **)&val);
-       RETVAL_ZVAL_FAST(*val);
+       val = zend_hash_get_current_data(Z_ARRVAL_P(stack));
+       RETVAL_ZVAL_FAST(val);
 
        /* Delete the first or last value */
-       zend_hash_get_current_key_ex(Z_ARRVAL_P(stack), &key, &key_len, &index, 0, NULL);
-       if (key && Z_ARRVAL_P(stack) == &EG(symbol_table)) {
-               zend_delete_global_variable(key, key_len - 1 TSRMLS_CC);
+       zend_hash_get_current_key_ex(Z_ARRVAL_P(stack), &key, &index, 0, NULL);
+       if (key && Z_ARRVAL_P(stack) == &EG(symbol_table).ht) {
+               zend_delete_global_variable(key TSRMLS_CC);
+       } else if (key) {
+               zend_hash_del(Z_ARRVAL_P(stack), key);
        } else {
-               zend_hash_del_key_or_index(Z_ARRVAL_P(stack), key, key_len, index, (key) ? HASH_DEL_KEY : HASH_DEL_INDEX);
+               zend_hash_index_del(Z_ARRVAL_P(stack), index);
        }
 
        /* If we did a shift... re-index like it did before */
@@ -1995,8 +1962,8 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
 
                for (idx = 0; idx < Z_ARRVAL_P(stack)->nNumUsed; idx++) {
                        p = Z_ARRVAL_P(stack)->arData + idx;
-                       if (!p->xData) continue;
-                       if (p->nKeyLength == 0) {
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
+                       if (p->key == NULL) {
                                if (p->h != k) {
                                        p->h = k++;
                                        should_rehash = 1;
@@ -2013,7 +1980,7 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
                                zend_hash_rehash(Z_ARRVAL_P(stack));
                        }
                }
-       } else if (!key_len && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) {
+       } else if (!key && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) {
                Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
        }
 
@@ -2041,7 +2008,7 @@ PHP_FUNCTION(array_shift)
    Pushes elements onto the beginning of the array */
 PHP_FUNCTION(array_unshift)
 {
-       zval ***args,                   /* Function arguments array */
+       zval   *args,                   /* Function arguments array */
                   *stack;                      /* Input stack */
        HashTable *new_hash;    /* New hashtable for the stack */
        HashTable  old_hash;
@@ -2055,8 +2022,8 @@ PHP_FUNCTION(array_unshift)
         * hashtable and replace it with new one */
        new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[0], argc, NULL);
        old_hash = *Z_ARRVAL_P(stack);
-       if (Z_ARRVAL_P(stack) == &EG(symbol_table)) {
-               zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
+       if (Z_ARRVAL_P(stack) == &EG(symbol_table).ht) {
+               zend_reset_all_cv(&EG(symbol_table).ht TSRMLS_CC);
        }
        *Z_ARRVAL_P(stack) = *new_hash;
        FREE_HASHTABLE(new_hash);
@@ -2074,9 +2041,9 @@ PHP_FUNCTION(array_splice)
 {
        zval *array,                            /* Input array */
                 *repl_array = NULL,    /* Replacement array */
-                ***repl = NULL;                /* Replacement elements */
+                *repl = NULL;                  /* Replacement elements */
        HashTable *new_hash = NULL,     /* Output array's hash */
-                **rem_hash = NULL;     /* Removed elements' hash */
+                 *rem_hash = NULL;     /* Removed elements' hash */
        HashTable  old_hash;
        uint    idx;
        Bucket *p;                                      /* Bucket used for traversing hash */
@@ -2102,11 +2069,11 @@ PHP_FUNCTION(array_splice)
 
                /* Create the array of replacement elements */
                repl_num = zend_hash_num_elements(Z_ARRVAL_P(repl_array));
-               repl = (zval ***)safe_emalloc(repl_num, sizeof(zval **), 0);
+               repl = (zval *)safe_emalloc(repl_num, sizeof(zval), 0);
                for (idx = 0, i = 0; idx < Z_ARRVAL_P(repl_array)->nNumUsed; idx++) {
                        p = Z_ARRVAL_P(repl_array)->arData + idx;
-                       if (!p->xData) continue;
-                       repl[i++] = (zval **)&p->xData;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
+                       ZVAL_COPY_VALUE(&repl[i++], &p->val);
                }
        }
 
@@ -2131,7 +2098,7 @@ PHP_FUNCTION(array_splice)
 
                /* Initialize return value */
                array_init_size(return_value, size > 0 ? size : 0);
-               rem_hash = &Z_ARRVAL_P(return_value);
+               rem_hash = Z_ARRVAL_P(return_value);
        }
 
        /* Perform splice */
@@ -2139,8 +2106,8 @@ PHP_FUNCTION(array_splice)
 
        /* Replace input array's hashtable with the new one */
        old_hash = *Z_ARRVAL_P(array);
-       if (Z_ARRVAL_P(array) == &EG(symbol_table)) {
-               zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
+       if (Z_ARRVAL_P(array) == &EG(symbol_table).ht) {
+               zend_reset_all_cv(&EG(symbol_table).ht TSRMLS_CC);
        }
        *Z_ARRVAL_P(array) = *new_hash;
        FREE_HASHTABLE(new_hash);
@@ -2158,19 +2125,18 @@ PHP_FUNCTION(array_splice)
 PHP_FUNCTION(array_slice)
 {
        zval     *input,                /* Input array */
-                       **z_length = NULL, /* How many elements to get */ 
-                       **entry;                /* An array entry */
+                        *z_length = NULL, /* How many elements to get */ 
+                        *entry;                /* An array entry */
        long     offset,                /* Offset to get elements from */
                         length = 0;    
        zend_bool preserve_keys = 0; /* Whether to preserve keys while copying to the new array or not */
        int              num_in,                /* Number of elements in the input array */
                         pos;                   /* Current position in the array */
-       char *string_key;
-       uint string_key_len;
+       zend_string *string_key;
        ulong num_key;
        HashPosition hpos;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|Zb", &input, &offset, &z_length, &preserve_keys) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|zb", &input, &offset, &z_length, &preserve_keys) == FAILURE) {
                return;
        }
 
@@ -2178,11 +2144,11 @@ PHP_FUNCTION(array_slice)
        num_in = zend_hash_num_elements(Z_ARRVAL_P(input));
 
        /* We want all entries from offset to the end if length is not passed or is null */
-       if (ZEND_NUM_ARGS() < 3 || Z_TYPE_PP(z_length) == IS_NULL) {
+       if (ZEND_NUM_ARGS() < 3 || Z_TYPE_P(z_length) == IS_NULL) {
                length = num_in;
        } else {
                convert_to_long_ex(z_length);
-               length = Z_LVAL_PP(z_length);
+               length = Z_LVAL_P(z_length);
        }
 
        /* Clamp the offset.. */
@@ -2210,26 +2176,26 @@ PHP_FUNCTION(array_slice)
        /* Start at the beginning and go until we hit offset */
        pos = 0;
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &hpos);
-       while (pos < offset && zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &hpos) == SUCCESS) {
+       while (pos < offset && (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &hpos)) != NULL) {
                pos++;
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &hpos);
        }
 
        /* Copy elements from input array to the one that's returned */
-       while (pos < offset + length && zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &hpos) == SUCCESS) {
+       while (pos < offset + length && (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &hpos)) != NULL) {
 
                zval_add_ref(entry);
 
-               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &hpos)) {
+               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &hpos)) {
                        case HASH_KEY_IS_STRING:
-                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, entry, sizeof(zval *), NULL);
+                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry);
                                break;
 
                        case HASH_KEY_IS_LONG:
                                if (preserve_keys) {
-                                       zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(zval *), NULL);
+                                       zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
                                } else {
-                                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry, sizeof(zval *), NULL);
+                                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry);
                                }
                                break;
                }
@@ -2241,47 +2207,45 @@ PHP_FUNCTION(array_slice)
 
 PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC) /* {{{ */
 {
-       zval **src_entry, **dest_entry;
-       char *string_key;
-       uint string_key_len;
+       zval *src_entry, *dest_entry;
+       zend_string *string_key;
        ulong num_key;
        HashPosition pos;
 
        zend_hash_internal_pointer_reset_ex(src, &pos);
-       while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) {
-               switch (zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos)) {
+       while ((src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL) {
+               switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_STRING:
-                               if (recursive && zend_hash_find(dest, string_key, string_key_len, (void **)&dest_entry) == SUCCESS) {
-                                       HashTable *thash = Z_TYPE_PP(dest_entry) == IS_ARRAY ? Z_ARRVAL_PP(dest_entry) : NULL;
-                                       zval *src_zval;
+                               if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) {
+                                       HashTable *thash = Z_TYPE_P(dest_entry) == IS_ARRAY ? Z_ARRVAL_P(dest_entry) : NULL;
+                                       zval src_zval;
                                        zval *tmp = NULL;
 
-                                       if ((thash && thash->nApplyCount > 1) || (*src_entry == *dest_entry && Z_ISREF_PP(dest_entry) && (Z_REFCOUNT_PP(dest_entry) % 2))) {
+                                       if ((thash && thash->nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
                                                return 0;
                                        }
                                        SEPARATE_ZVAL(dest_entry);
 
-                                       if (Z_TYPE_PP(dest_entry) == IS_NULL) {
+                                       if (Z_TYPE_P(dest_entry) == IS_NULL) {
                                                convert_to_array_ex(dest_entry);
-                                               add_next_index_null(*dest_entry);
+                                               add_next_index_null(dest_entry);
                                        } else {
                                                convert_to_array_ex(dest_entry);
                                        }
-                                       if (Z_TYPE_PP(src_entry) == IS_OBJECT) {
-                                               ALLOC_ZVAL(src_zval);
-                                               INIT_PZVAL_COPY(src_zval, *src_entry);
-                                               zval_copy_ctor(src_zval);
-                                               convert_to_array(src_zval);
-                                               tmp = src_zval;
+                                       if (Z_TYPE_P(src_entry) == IS_OBJECT) {
+                                               ZVAL_DUP(&src_zval, src_entry);
+                                               zval_copy_ctor(&src_zval);
+                                               convert_to_array(&src_zval);
+                                               tmp = &src_zval;
                                        } else {
-                                               src_zval = *src_entry;
+                                               ZVAL_COPY_VALUE(&src_zval, src_entry);
                                        }
-                                       if (Z_TYPE_P(src_zval) == IS_ARRAY) {
+                                       if (Z_TYPE(src_zval) == IS_ARRAY) {
                                                if (thash) {
                                                        thash->nApplyCount++;
                                                }
-                                               if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) {
+                                               if (!php_array_merge(Z_ARRVAL_P(dest_entry), Z_ARRVAL(src_zval), recursive TSRMLS_CC)) {
                                                        if (thash) {
                                                                thash->nApplyCount--;
                                                        }
@@ -2291,21 +2255,21 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
                                                        thash->nApplyCount--;
                                                }
                                        } else {
-                                               Z_ADDREF_PP(src_entry);
-                                               zend_hash_next_index_insert(Z_ARRVAL_PP(dest_entry), &src_zval, sizeof(zval *), NULL);
+                                               Z_ADDREF_P(src_entry);
+                                               zend_hash_next_index_insert(Z_ARRVAL_P(dest_entry), &src_zval);
                                        }
                                        if (tmp) {
-                                               zval_ptr_dtor(&tmp);
+                                               zval_ptr_dtor(tmp);
                                        }
                                } else {
-                                       Z_ADDREF_PP(src_entry);
-                                       zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
+                                       Z_ADDREF_P(src_entry);
+                                       zend_hash_update(dest, string_key, src_entry);
                                }
                                break;
 
                        case HASH_KEY_IS_LONG:
-                               Z_ADDREF_PP(src_entry);
-                               zend_hash_next_index_insert(dest, src_entry, sizeof(zval *), NULL);
+                               Z_ADDREF_P(src_entry);
+                               zend_hash_next_index_insert(dest, src_entry);
                                break;
                }
                zend_hash_move_forward_ex(src, &pos);
@@ -2316,57 +2280,56 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
 
 PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC) /* {{{ */
 {
-       zval **src_entry, **dest_entry;
-       char *string_key;
-       uint string_key_len;
+       zval *src_entry, *dest_entry;
+       zend_string *string_key;
        ulong num_key;
        HashPosition pos;
 
        for (zend_hash_internal_pointer_reset_ex(src, &pos);
-            zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS;
+            (src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL;
             zend_hash_move_forward_ex(src, &pos)) {
-               switch (zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos)) {
+               switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_STRING:
-                               if (Z_TYPE_PP(src_entry) != IS_ARRAY ||
-                                       zend_hash_find(dest, string_key, string_key_len, (void **)&dest_entry) == FAILURE ||
-                                       Z_TYPE_PP(dest_entry) != IS_ARRAY) {
+                               if (Z_TYPE_P(src_entry) != IS_ARRAY ||
+                                       (dest_entry = zend_hash_find(dest, string_key)) == NULL ||
+                                       Z_TYPE_P(dest_entry) != IS_ARRAY) {
 
-                                       Z_ADDREF_PP(src_entry);
-                                       zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
+                                       Z_ADDREF_P(src_entry);
+                                       zend_hash_update(dest, string_key, src_entry);
 
                                        continue;
                                }
                                break;
 
                        case HASH_KEY_IS_LONG:
-                               if (Z_TYPE_PP(src_entry) != IS_ARRAY ||
-                                       zend_hash_index_find(dest, num_key, (void **)&dest_entry) == FAILURE ||
-                                       Z_TYPE_PP(dest_entry) != IS_ARRAY) {
+                               if (Z_TYPE_P(src_entry) != IS_ARRAY ||
+                                       (dest_entry = zend_hash_index_find(dest, num_key)) == NULL ||
+                                       Z_TYPE_P(dest_entry) != IS_ARRAY) {
 
-                                       Z_ADDREF_PP(src_entry);
-                                       zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL);
+                                       Z_ADDREF_P(src_entry);
+                                       zend_hash_index_update(dest, num_key, src_entry);
 
                                        continue;
                                }
                                break;
                }
 
-               if (Z_ARRVAL_PP(dest_entry)->nApplyCount > 1 || Z_ARRVAL_PP(src_entry)->nApplyCount > 1 || (*src_entry == *dest_entry && Z_ISREF_PP(dest_entry) && (Z_REFCOUNT_PP(dest_entry) % 2))) {
+               if (Z_ARRVAL_P(dest_entry)->nApplyCount > 1 || Z_ARRVAL_P(src_entry)->nApplyCount > 1 || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
                        return 0;
                }
                SEPARATE_ZVAL(dest_entry);
-               Z_ARRVAL_PP(dest_entry)->nApplyCount++;
-               Z_ARRVAL_PP(src_entry)->nApplyCount++;
+               Z_ARRVAL_P(dest_entry)->nApplyCount++;
+               Z_ARRVAL_P(src_entry)->nApplyCount++;
                
 
-               if (!php_array_replace_recursive(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry) TSRMLS_CC)) {
-                       Z_ARRVAL_PP(dest_entry)->nApplyCount--;
-                       Z_ARRVAL_PP(src_entry)->nApplyCount--;
+               if (!php_array_replace_recursive(Z_ARRVAL_P(dest_entry), Z_ARRVAL_P(src_entry) TSRMLS_CC)) {
+                       Z_ARRVAL_P(dest_entry)->nApplyCount--;
+                       Z_ARRVAL_P(src_entry)->nApplyCount--;
                        return 0;
                }
-               Z_ARRVAL_PP(dest_entry)->nApplyCount--;
-               Z_ARRVAL_PP(src_entry)->nApplyCount--;
+               Z_ARRVAL_P(dest_entry)->nApplyCount--;
+               Z_ARRVAL_P(src_entry)->nApplyCount--;
        }
 
        return 1;
@@ -2375,7 +2338,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC
 
 static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive, int replace) /* {{{ */
 {
-       zval ***args = NULL;
+       zval *args = NULL;
        int argc, i, init_size = 0;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &argc) == FAILURE) {
@@ -2383,12 +2346,12 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int
        }
 
        for (i = 0; i < argc; i++) {
-               if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
+               if (Z_TYPE(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
                        efree(args);
                        RETURN_NULL();
                } else {
-                       int num = zend_hash_num_elements(Z_ARRVAL_PP(args[i]));
+                       int num = zend_hash_num_elements(Z_ARRVAL(args[i]));
 
                        if (num > init_size) {
                                init_size = num;
@@ -2400,11 +2363,11 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int
 
        for (i = 0; i < argc; i++) {
                if (!replace) {
-                       php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive TSRMLS_CC);
+                       php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL(args[i]), recursive TSRMLS_CC);
                } else if (recursive && i > 0) { /* First array will be copied directly instead */
-                       php_array_replace_recursive(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]) TSRMLS_CC);
+                       php_array_replace_recursive(Z_ARRVAL_P(return_value), Z_ARRVAL(args[i]) TSRMLS_CC);
                } else {
-                       zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *), 1);
+                       zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL(args[i]), zval_add_ref, 1);
                }
        }
 
@@ -2450,9 +2413,9 @@ PHP_FUNCTION(array_keys)
 {
        zval *input,                            /* Input array */
             *search_value = NULL,      /* Value to search for */
-            **entry,                           /* An entry in the input array */
+            *entry,                            /* An entry in the input array */
               res,                                     /* Result of comparison */
-             *new_val;                         /* New value */
+              new_val;                         /* New value */
        int    add_key;                         /* Flag to indicate whether a key should be added */
        zend_bool strict = 0;           /* do strict comparison */
        HashPosition pos;
@@ -2476,16 +2439,15 @@ PHP_FUNCTION(array_keys)
 
        /* Go through input array and add keys to the return array */
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) {
                if (search_value != NULL) {
-                       is_equal_func(&res, search_value, *entry TSRMLS_CC);
+                       is_equal_func(&res, search_value, entry TSRMLS_CC);
                        add_key = zval_is_true(&res);
                }
 
                if (add_key) {
-                       MAKE_STD_ZVAL(new_val);
-                       zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), new_val, &pos);
-                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
+                       zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), &new_val, &pos);
+                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val);
                }
 
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
@@ -2498,7 +2460,7 @@ PHP_FUNCTION(array_keys)
 PHP_FUNCTION(array_values)
 {
        zval     *input,                /* Input array */
-                       **entry;                /* An entry in the input array */
+                        *entry;                /* An entry in the input array */
        HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) {
@@ -2510,9 +2472,9 @@ PHP_FUNCTION(array_values)
 
        /* Go through input array and add values to the return array */
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) {
                zval_add_ref(entry);
-               zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry, sizeof(zval *), NULL);
+               zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry);
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
        }
 }
@@ -2522,9 +2484,9 @@ PHP_FUNCTION(array_values)
    Return the value as key and the frequency of that value in input as value */
 PHP_FUNCTION(array_count_values)
 {
-       zval    *input,                 /* Input array */
-                       **entry,                /* An entry in the input array */
-                       **tmp;
+       zval    *input,         /* Input array */
+                       *entry,         /* An entry in the input array */
+                       *tmp;
        HashTable *myht;
        HashPosition pos;
 
@@ -2538,24 +2500,22 @@ PHP_FUNCTION(array_count_values)
        /* Go through input array and add values to the return array */
        myht = Z_ARRVAL_P(input);
        zend_hash_internal_pointer_reset_ex(myht, &pos);
-       while (zend_hash_get_current_data_ex(myht, (void **)&entry, &pos) == SUCCESS) {
-               if (Z_TYPE_PP(entry) == IS_LONG) {
-                       if (zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), (void **)&tmp) == FAILURE) {
-                               zval *data;
-                               MAKE_STD_ZVAL(data);
-                               ZVAL_LONG(data, 1);
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);
+       while ((entry = zend_hash_get_current_data_ex(myht, &pos)) != NULL) {
+               if (Z_TYPE_P(entry) == IS_LONG) {
+                       if ((tmp = zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_P(entry))) == NULL) {
+                               zval data;
+                               ZVAL_LONG(&data, 1);
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data);
                        } else {
-                               Z_LVAL_PP(tmp)++;
+                               Z_LVAL_P(tmp)++;
                        }
-               } else if (Z_TYPE_PP(entry) == IS_STRING) {
-                       if (zend_symtable_find(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, (void**)&tmp) == FAILURE) {
-                               zval *data;
-                               MAKE_STD_ZVAL(data);
-                               ZVAL_LONG(data, 1);
-                               zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL);
+               } else if (Z_TYPE_P(entry) == IS_STRING) {
+                       if ((tmp = zend_symtable_find(Z_ARRVAL_P(return_value), Z_STR_P(entry))) == NULL) {
+                               zval data;
+                               ZVAL_LONG(&data, 1);
+                               zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
                        } else {
-                               Z_LVAL_PP(tmp)++;
+                               Z_LVAL_P(tmp)++;
                        }
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!");
@@ -2570,9 +2530,9 @@ PHP_FUNCTION(array_count_values)
  * Specialized conversion rules for array_column() function
  */
 static inline
-zend_bool array_column_param_helper(zval **param,
+zend_bool array_column_param_helper(zval *param,
                                     const char *name TSRMLS_DC) {
-       switch (Z_TYPE_PP(param)) {
+       switch (Z_TYPE_P(param)) {
                case IS_DOUBLE:
                        convert_to_long_ex(param);
                        /* fallthrough */
@@ -2596,11 +2556,11 @@ zend_bool array_column_param_helper(zval **param,
    value_key and optionally indexed by the index_key */
 PHP_FUNCTION(array_column)
 {
-       zval **zcolumn = NULL, **zkey = NULL, **data;
+       zval *zcolumn = NULL, *zkey = NULL, *data;
        HashTable *arr_hash;
        HashPosition pointer;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hZ!|Z!", &arr_hash, &zcolumn, &zkey) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hz!|z!", &arr_hash, &zcolumn, &zkey) == FAILURE) {
                return;
        }
 
@@ -2611,50 +2571,52 @@ PHP_FUNCTION(array_column)
 
        array_init(return_value);
        for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
-                       zend_hash_get_current_data_ex(arr_hash, (void**)&data, &pointer) == SUCCESS;
+                       (data = zend_hash_get_current_data_ex(arr_hash, &pointer)) != NULL;
                        zend_hash_move_forward_ex(arr_hash, &pointer)) {
-               zval **zcolval, **zkeyval = NULL;
+               zval *zcolval, *zkeyval = NULL;
                HashTable *ht;
 
-               if (Z_TYPE_PP(data) != IS_ARRAY) {
+               if (Z_TYPE_P(data) != IS_ARRAY) {
                        /* Skip elemens which are not sub-arrays */
                        continue;
                }
-               ht = Z_ARRVAL_PP(data);
+               ht = Z_ARRVAL_P(data);
 
                if (!zcolumn) {
                        /* NULL column ID means use entire subarray as data */
                        zcolval = data;
 
                        /* Otherwise, skip if the value doesn't exist in our subarray */
-               } else if ((Z_TYPE_PP(zcolumn) == IS_STRING) &&
-                   (zend_hash_find(ht, Z_STRVAL_PP(zcolumn), Z_STRLEN_PP(zcolumn) + 1, (void**)&zcolval) == FAILURE)) {
+               } else if ((Z_TYPE_P(zcolumn) == IS_STRING) &&
+                   ((zcolval = zend_hash_find(ht, Z_STR_P(zcolumn))) == NULL)) {
                        continue;
-               } else if ((Z_TYPE_PP(zcolumn) == IS_LONG) &&
-                   (zend_hash_index_find(ht, Z_LVAL_PP(zcolumn), (void**)&zcolval) == FAILURE)) {
+               } else if ((Z_TYPE_P(zcolumn) == IS_LONG) &&
+                   ((zcolval = zend_hash_index_find(ht, Z_LVAL_P(zcolumn))) == NULL)) {
                        continue;
                }
 
                /* Failure will leave zkeyval alone which will land us on the final else block below
                 * which is to append the value as next_index
                 */
-               if (zkey && (Z_TYPE_PP(zkey) == IS_STRING)) {
-                       zend_hash_find(ht, Z_STRVAL_PP(zkey), Z_STRLEN_PP(zkey) + 1, (void**)&zkeyval);
-               } else if (zkey && (Z_TYPE_PP(zkey) == IS_LONG)) {
-                       zend_hash_index_find(ht, Z_LVAL_PP(zkey), (void**)&zkeyval);
-               }
-
-               Z_ADDREF_PP(zcolval);
-               if (zkeyval && Z_TYPE_PP(zkeyval) == IS_STRING) {
-                       add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval);
-               } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_LONG) {
-                       add_index_zval(return_value, Z_LVAL_PP(zkeyval), *zcolval);
-               } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_OBJECT) {
+               if (zkey && (Z_TYPE_P(zkey) == IS_STRING)) {
+                       zkeyval = zend_hash_find(ht, Z_STR_P(zkey));
+               } else if (zkey && (Z_TYPE_P(zkey) == IS_LONG)) {
+                       zkeyval = zend_hash_index_find(ht, Z_LVAL_P(zkey));
+               }
+
+               Z_ADDREF_P(zcolval);
+               if (zkeyval && Z_TYPE_P(zkeyval) == IS_STRING) {
+//???
+                       add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval);
+               } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_LONG) {
+                       add_index_zval(return_value, Z_LVAL_P(zkeyval), zcolval);
+               } else if (zkeyval && Z_TYPE_P(zkeyval) == IS_OBJECT) {
                        SEPARATE_ZVAL(zkeyval);
-                       convert_to_string(*zkeyval);
-                       add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval);
+                       convert_to_string(zkeyval);
+//???
+                       add_assoc_zval(return_value, Z_STRVAL_P(zkeyval), zcolval);
                } else {
-                       add_next_index_zval(return_value, *zcolval);
+                       add_next_index_zval(return_value, zcolval);
                }
        }
 }
@@ -2665,9 +2627,8 @@ PHP_FUNCTION(array_column)
 PHP_FUNCTION(array_reverse)
 {
        zval     *input,                                /* Input array */
-                       **entry;                                /* An entry in the input array */
-       char     *string_key;
-       uint      string_key_len;
+                        *entry;                                /* An entry in the input array */
+       zend_string *string_key;
        ulong     num_key;
        zend_bool preserve_keys = 0;    /* whether to preserve keys */
        HashPosition pos;
@@ -2680,19 +2641,19 @@ PHP_FUNCTION(array_reverse)
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input)));
 
        zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(input), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) {
                zval_add_ref(entry);
 
-               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &pos)) {
+               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_STRING:
-                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, entry, sizeof(zval *), NULL);
+                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry);
                                break;
 
                        case HASH_KEY_IS_LONG:
                                if (preserve_keys) {
-                                       zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(zval *), NULL);
+                                       zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
                                } else {
-                                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry, sizeof(zval *), NULL);
+                                       zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry);
                                }
                                break;
                }
@@ -2708,7 +2669,7 @@ PHP_FUNCTION(array_pad)
 {
        zval  *input;           /* Input array */
        zval  *pad_value;       /* Padding value obviously */
-       zval ***pads;           /* Array to pass to splice */
+       zval  *pads;            /* Array to pass to splice */
        HashTable *new_hash;/* Return value from splice */
        HashTable  old_hash;
        long pad_size;          /* Size to pad to */
@@ -2747,9 +2708,9 @@ PHP_FUNCTION(array_pad)
                zval_dtor(return_value);
                RETURN_FALSE;
        }
-       pads = (zval ***)safe_emalloc(num_pads, sizeof(zval **), 0);
+       pads = (zval *)safe_emalloc(num_pads, sizeof(zval), 0);
        for (i = 0; i < num_pads; i++) {
-               pads[i] = &pad_value;
+               ZVAL_COPY_VALUE(&pads[i], pad_value);
        }
 
        /* Pad on the right or on the left */
@@ -2761,8 +2722,8 @@ PHP_FUNCTION(array_pad)
 
        /* Copy the result hash into return value */
        old_hash = *Z_ARRVAL_P(return_value);
-       if (Z_ARRVAL_P(return_value) == &EG(symbol_table)) {
-               zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
+       if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {
+               zend_reset_all_cv(&EG(symbol_table).ht TSRMLS_CC);
        }
        *Z_ARRVAL_P(return_value) = *new_hash;
        FREE_HASHTABLE(new_hash);
@@ -2777,7 +2738,7 @@ PHP_FUNCTION(array_pad)
    Return array with key <-> value flipped */
 PHP_FUNCTION(array_flip)
 {
-       zval *array, **entry, *data;
+       zval *array, *entry, data;
        HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
@@ -2787,14 +2748,13 @@ PHP_FUNCTION(array_flip)
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array)));
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&entry, &pos) == SUCCESS) {
-               MAKE_STD_ZVAL(data);
-               zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), data, &pos);
-
-               if (Z_TYPE_PP(entry) == IS_LONG) {
-                       zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);
-               } else if (Z_TYPE_PP(entry) == IS_STRING) {
-                       zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL);
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) {
+               zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), &data, &pos);
+
+               if (Z_TYPE_P(entry) == IS_LONG) {
+                       zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data);
+               } else if (Z_TYPE_P(entry) == IS_STRING) {
+                       zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
                } else {
                        zval_ptr_dtor(&data); /* will free also zval structure */
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only flip STRING and INTEGER values!");
@@ -2809,10 +2769,9 @@ PHP_FUNCTION(array_flip)
    Retuns an array with all string keys lowercased [or uppercased] */
 PHP_FUNCTION(array_change_key_case)
 {
-       zval *array, **entry;
-       char *string_key;
-       char *new_key;
-       uint str_key_len;
+       zval *array, *entry;
+       zend_string *string_key;
+       zend_string *new_key;
        ulong num_key;
        long change_to_upper=0;
        HashPosition pos;
@@ -2824,22 +2783,22 @@ PHP_FUNCTION(array_change_key_case)
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array)));
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) {
                zval_add_ref(entry);
 
-               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &str_key_len, &num_key, 0, &pos)) {
+               switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos)) {
                        case HASH_KEY_IS_LONG:
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry, sizeof(entry), NULL);
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
                                break;
                        case HASH_KEY_IS_STRING:
-                               new_key = estrndup(string_key, str_key_len - 1);
+                               new_key = STR_DUP(string_key, 0);
                                if (change_to_upper) {
-                                       php_strtoupper(new_key, str_key_len - 1);
+                                       php_strtoupper(new_key->val, new_key->len);
                                } else {
-                                       php_strtolower(new_key, str_key_len - 1);
+                                       php_strtolower(new_key->val, new_key->len);
                                }
-                               zend_hash_update(Z_ARRVAL_P(return_value), new_key, str_key_len, entry, sizeof(entry), NULL);
-                               efree(new_key);
+                               zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry);
+                               STR_FREE(new_key);
                                break;
                }
 
@@ -2852,7 +2811,7 @@ PHP_FUNCTION(array_change_key_case)
    Removes duplicate values from array */
 PHP_FUNCTION(array_unique)
 {
-       zval *array, *tmp;
+       zval *array;
        uint idx;
        Bucket *p;
        struct bucketindex {
@@ -2870,7 +2829,7 @@ PHP_FUNCTION(array_unique)
        php_set_compare_func(sort_type TSRMLS_CC);
 
        array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array)));
-       zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_P(array), (copy_ctor_func_t) zval_add_ref, (void *)&tmp, sizeof(zval*));
+       zend_hash_copy(Z_ARRVAL_P(return_value), Z_ARRVAL_P(array), zval_add_ref);
 
        if (Z_ARRVAL_P(array)->nNumOfElements <= 1) {   /* nothing to do */
                return;
@@ -2884,17 +2843,17 @@ PHP_FUNCTION(array_unique)
        }
        for (i = 0, idx = 0; idx < Z_ARRVAL_P(array)->nNumUsed; idx++) {
                p = Z_ARRVAL_P(array)->arData + idx;
-               if (!p->xData) continue;
+               if (Z_TYPE(p->val) == IS_UNDEF) continue;
                arTmp[i].b = *p;
                arTmp[i].i = i;
                i++;
        }
-       arTmp[i].b.xData = NULL;
+       ZVAL_UNDEF(&arTmp[i].b.val);
        zend_qsort((void *) arTmp, i, sizeof(struct bucketindex), php_array_data_compare TSRMLS_CC);
 
        /* go through the sorted array and delete duplicates from the copy */
        lastkept = arTmp;
-       for (cmpdata = arTmp + 1; cmpdata->b.xData; cmpdata++) {
+       for (cmpdata = arTmp + 1; Z_TYPE(cmpdata->b.val) != IS_UNDEF; cmpdata++) {
                if (php_array_data_compare(lastkept, cmpdata TSRMLS_CC)) {
                        lastkept = cmpdata;
                } else {
@@ -2904,13 +2863,13 @@ PHP_FUNCTION(array_unique)
                        } else {
                                p = &cmpdata->b;
                        }
-                       if (p->nKeyLength == 0) {
+                       if (p->key == NULL) {
                                zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);
                        } else {
-                               if (Z_ARRVAL_P(return_value) == &EG(symbol_table)) {
-                                       zend_delete_global_variable(p->arKey, p->nKeyLength - 1 TSRMLS_CC);
+                               if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {
+                                       zend_delete_global_variable(p->key TSRMLS_CC);
                                } else {
-                                       zend_hash_quick_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h);
+                                       zend_hash_del(Z_ARRVAL_P(return_value), p->key);
                                }
                        }
                }
@@ -2919,14 +2878,14 @@ PHP_FUNCTION(array_unique)
 }
 /* }}} */
 
-static int zval_compare(zval **a, zval **b TSRMLS_DC) /* {{{ */
+static int zval_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */
 {
        zval result;
        zval *first;
        zval *second;
 
-       first = *((zval **) a);
-       second = *((zval **) b);
+       first = a;
+       second = b;
 
        if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) {
                return 0;
@@ -2954,26 +2913,26 @@ static int zval_compare(zval **a, zval **b TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-static int zval_user_compare(zval **a, zval **b TSRMLS_DC) /* {{{ */
+static int zval_user_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */
 {
-       zval **args[2];
-       zval *retval_ptr = NULL;
+       zval args[2];
+       zval retval;
 
-       args[0] = (zval **) a;
-       args[1] = (zval **) b;
+       ZVAL_COPY_VALUE(&args[0], a);
+       ZVAL_COPY_VALUE(&args[1], b);
 
        BG(user_compare_fci).param_count = 2;
        BG(user_compare_fci).params = args;
-       BG(user_compare_fci).retval_ptr_ptr = &retval_ptr;
+       BG(user_compare_fci).retval = &retval;
        BG(user_compare_fci).no_separation = 0;
 
-       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && retval_ptr) {
-               long retval;
+       if (zend_call_function(&BG(user_compare_fci), &BG(user_compare_fci_cache) TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+               long ret;
 
-               convert_to_long_ex(&retval_ptr);
-               retval = Z_LVAL_P(retval_ptr);
-               zval_ptr_dtor(&retval_ptr);
-               return retval < 0 ? -1 : retval > 0 ? 1 : 0;;
+               convert_to_long_ex(&retval);
+               ret = Z_LVAL(retval);
+               zval_ptr_dtor(&retval);
+               return ret < 0 ? -1 : ret > 0 ? 1 : 0;;
        } else {
                return 0;
        }
@@ -2985,10 +2944,10 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
     uint idx;
        Bucket *p;
        int argc, i;
-       zval ***args;
-       int (*intersect_data_compare_func)(zval **, zval ** TSRMLS_DC) = NULL;
+       zval *args;
+       int (*intersect_data_compare_func)(zval *, zval * TSRMLS_DC) = NULL;
        zend_bool ok;
-       zval **data;
+       zval *data;
        int req_args;
        char *param_spec;
 
@@ -3020,7 +2979,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
        }
 
        for (i = 0; i < argc; i++) {
-               if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
+               if (Z_TYPE(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
                        RETVAL_NULL();
                        goto out;
@@ -3029,38 +2988,38 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
 
        array_init(return_value);
 
-       for (idx = 0; idx < Z_ARRVAL_PP(args[0])->nNumUsed; idx++) {
-               p = Z_ARRVAL_PP(args[0])->arData + idx;
-               if (!p->xData) continue;
-               if (p->nKeyLength == 0) {
+       for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) {
+               p = Z_ARRVAL(args[0])->arData + idx;
+               if (Z_TYPE(p->val) == IS_UNDEF) continue;
+               if (p->key == NULL) {
                        ok = 1;
                        for (i = 1; i < argc; i++) {
-                               if (zend_hash_index_find(Z_ARRVAL_PP(args[i]), p->h, (void**)&data) == FAILURE ||
+                               if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) == NULL ||
                                        (intersect_data_compare_func &&
-                                       intersect_data_compare_func((zval**)&p->xData, data TSRMLS_CC) != 0)
+                                       intersect_data_compare_func(&p->val, data TSRMLS_CC) != 0)
                                ) {
                                        ok = 0;
                                        break;
                                }
                        }
                        if (ok) {
-                               Z_ADDREF_P((zval*)p->xData);
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->xData, sizeof(zval*), NULL);
+                               Z_ADDREF(p->val);
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val);
                        }
                } else {
                        ok = 1;
                        for (i = 1; i < argc; i++) {
-                               if (zend_hash_quick_find(Z_ARRVAL_PP(args[i]), p->arKey, p->nKeyLength, p->h, (void**)&data) == FAILURE ||
+                               if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) == NULL ||
                                        (intersect_data_compare_func &&
-                                       intersect_data_compare_func((zval**)&p->xData, data TSRMLS_CC) != 0)
+                                       intersect_data_compare_func(&p->val, data TSRMLS_CC) != 0)
                                ) {
                                        ok = 0;
                                        break;
                                }
                        }
                        if (ok) {
-                               Z_ADDREF_P((zval*)p->xData);
-                               zend_hash_quick_update(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h, &p->xData, sizeof(zval*), NULL);
+                               Z_ADDREF(p->val);
+                               zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val);
                        }
                }
        }
@@ -3071,7 +3030,7 @@ out:
 
 static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) /* {{{ */
 {
-       zval ***args = NULL;
+       zval *args = NULL;
        HashTable *hash;
        int arr_argc, i, c = 0;
        uint idx;
@@ -3188,12 +3147,12 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
        }
 
        for (i = 0; i < arr_argc; i++) {
-               if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
+               if (Z_TYPE(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
                        arr_argc = i; /* only free up to i - 1 */
                        goto out;
                }
-               hash = Z_ARRVAL_PP(args[i]);
+               hash = Z_ARRVAL(args[i]);
                list = (Bucket *) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket), hash->flags & HASH_FLAG_PERSISTENT);
                if (!list) {
                        PHP_ARRAY_CMP_FUNC_RESTORE();
@@ -3207,10 +3166,10 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
                ptrs[i] = list;
                for (idx = 0; idx < hash->nNumUsed; idx++) {
                        p = hash->arData + idx;
-                       if (!p->xData) continue;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
                        *list++ = *p;
                }
-               list->xData = NULL;
+               ZVAL_UNDEF(&list->val);
                if (behavior == INTERSECT_NORMAL) {
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket), intersect_data_compare_func TSRMLS_CC);
                } else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */
@@ -3219,19 +3178,17 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
        }
 
        /* copy the argument array */
-       RETVAL_ZVAL(*args[0], 1, 0);
-       if (return_value->value.ht == &EG(symbol_table)) {
-               HashTable *ht;
-               zval *tmp;
+       RETVAL_ZVAL(&args[0], 1, 0);
+       if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {         
+               HashTable *old_ht = Z_ARRVAL_P(return_value);
 
-               ALLOC_HASHTABLE(ht);
-               zend_hash_init(ht, zend_hash_num_elements(return_value->value.ht), NULL, ZVAL_PTR_DTOR, 0);
-               zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-               return_value->value.ht = ht;
+               ZVAL_NEW_ARR(return_value);
+               zend_hash_init(Z_ARRVAL_P(return_value), zend_hash_num_elements(old_ht), NULL, ZVAL_PTR_DTOR, 0);
+               zend_hash_copy(Z_ARRVAL_P(return_value), old_ht, zval_add_ref);
        }
 
        /* go through the lists and look for common values */
-       while (ptrs[0]->xData) {
+       while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {
                if ((behavior & INTERSECT_ASSOC) /* triggered also when INTERSECT_KEY */
                        &&
                        key_compare_type == INTERSECT_COMP_KEY_USER) {
@@ -3242,14 +3199,14 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
 
                for (i = 1; i < arr_argc; i++) {
                        if (behavior & INTERSECT_NORMAL) {
-                               while (ptrs[i]->xData && (0 < (c = intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
+                               while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
                                        ptrs[i]++;
                                }
                        } else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */
-                               while (ptrs[i]->xData && (0 < (c = intersect_key_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
+                               while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = intersect_key_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
                                        ptrs[i]++;
                                }
-                               if ((!c && ptrs[i]->xData) && (behavior == INTERSECT_ASSOC)) { /* only when INTERSECT_ASSOC */
+                               if ((!c && Z_TYPE(ptrs[i]->val) != IS_UNDEF) && (behavior == INTERSECT_ASSOC)) { /* only when INTERSECT_ASSOC */
                                        /* this means that ptrs[i] is not NULL so we can compare
                                         * and "c==0" is from last operation
                                         * in this branch of code we enter only when INTERSECT_ASSOC
@@ -3271,19 +3228,19 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
                                        }
                                }
                        }
-                       if (!ptrs[i]->xData) {
+                       if (Z_TYPE(ptrs[i]->val) == IS_UNDEF) {
                                /* delete any values corresponding to remains of ptrs[0] */
                                /* and exit because they do not present in at least one of */
                                /* the other arguments */
                                for (;;) {
                                        p = ptrs[0]++;
-                                       if (!p->xData) {
+                                       if (Z_TYPE(p->val) == IS_UNDEF) {
                                                goto out;
                                        }
-                                       if (p->nKeyLength == 0) {
+                                       if (p->key == NULL) {
                                                zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);
                                        } else {
-                                               zend_hash_quick_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h);
+                                               zend_hash_del(Z_ARRVAL_P(return_value), p->key);
                                        }
                                }
                        }
@@ -3296,12 +3253,12 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
                        /* with value < value of ptrs[i] */
                        for (;;) {
                                p = ptrs[0];
-                               if (p->nKeyLength == 0) {
+                               if (p->key == NULL) {
                                        zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);
                                } else {
-                                       zend_hash_quick_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h);
+                                       zend_hash_del(Z_ARRVAL_P(return_value), p->key);
                                }
-                               if (!(++ptrs[0])->xData) {
+                               if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {
                                        goto out;
                                }
                                if (behavior == INTERSECT_NORMAL) {
@@ -3317,7 +3274,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
                        /* ptrs[0] is present in all the arguments */
                        /* Skip all entries with same value as ptrs[0] */
                        for (;;) {
-                               if (!(++ptrs[0])->xData) {
+                               if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {
                                        goto out;
                                }
                                if (behavior == INTERSECT_NORMAL) {
@@ -3333,7 +3290,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
        }
 out:
        for (i = 0; i < arr_argc; i++) {
-               hash = Z_ARRVAL_PP(args[i]);
+               hash = Z_ARRVAL(args[i]);
                pefree(lists[i], hash->flags & HASH_FLAG_PERSISTENT);
        }
 
@@ -3414,10 +3371,10 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
     uint idx;
        Bucket *p;
        int argc, i;
-       zval ***args;
-       int (*diff_data_compare_func)(zval **, zval ** TSRMLS_DC) = NULL;
+       zval *args;
+       int (*diff_data_compare_func)(zval *, zval * TSRMLS_DC) = NULL;
        zend_bool ok;
-       zval **data;
+       zval *data;
 
        /* Get the argument count */
        argc = ZEND_NUM_ARGS();
@@ -3444,7 +3401,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
        }
 
        for (i = 0; i < argc; i++) {
-               if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
+               if (Z_TYPE(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
                        RETVAL_NULL();
                        goto out;
@@ -3453,38 +3410,38 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
 
        array_init(return_value);
 
-       for (idx = 0; idx < Z_ARRVAL_PP(args[0])->nNumUsed; idx++) {
-               p = Z_ARRVAL_PP(args[0])->arData + idx;
-               if (!p->xData) continue;
-               if (p->nKeyLength == 0) {
+       for (idx = 0; idx < Z_ARRVAL(args[0])->nNumUsed; idx++) {
+               p = Z_ARRVAL(args[0])->arData + idx;
+               if (Z_TYPE(p->val) == IS_UNDEF) continue;
+               if (p->key == NULL) {
                        ok = 1;
                        for (i = 1; i < argc; i++) {
-                               if (zend_hash_index_find(Z_ARRVAL_PP(args[i]), p->h, (void**)&data) == SUCCESS &&
+                               if ((data = zend_hash_index_find(Z_ARRVAL(args[i]), p->h)) != NULL &&
                                        (!diff_data_compare_func ||
-                                       diff_data_compare_func((zval**)&p->xData, data TSRMLS_CC) == 0)
+                                       diff_data_compare_func(&p->val, data TSRMLS_CC) == 0)
                                ) {
                                        ok = 0;
                                        break;
                                }
                        }
                        if (ok) {
-                               Z_ADDREF_P((zval*)p->xData);
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->xData, sizeof(zval*), NULL);
+                               Z_ADDREF(p->val);
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), p->h, &p->val);
                        }
                } else {
                        ok = 1;
                        for (i = 1; i < argc; i++) {
-                               if (zend_hash_quick_find(Z_ARRVAL_PP(args[i]), p->arKey, p->nKeyLength, p->h, (void**)&data) == SUCCESS &&
+                               if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) != NULL &&
                                        (!diff_data_compare_func ||
-                                       diff_data_compare_func((zval**)&p->xData, data TSRMLS_CC) == 0)
+                                       diff_data_compare_func(&p->val, data TSRMLS_CC) == 0)
                                ) {
                                        ok = 0;
                                        break;
                                }
                        }
                        if (ok) {
-                               Z_ADDREF_P((zval*)p->xData);
-                               zend_hash_quick_update(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h, &p->xData, sizeof(zval*), NULL);
+                               Z_ADDREF(p->val);
+                               zend_hash_update(Z_ARRVAL_P(return_value), p->key, &p->val);
                        }
                }
        }
@@ -3495,7 +3452,7 @@ out:
 
 static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) /* {{{ */
 {
-       zval ***args = NULL;
+       zval *args = NULL;
        HashTable *hash;
        int arr_argc, i, c;
        uint idx;
@@ -3611,12 +3568,12 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
        }
 
        for (i = 0; i < arr_argc; i++) {
-               if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
+               if (Z_TYPE(args[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1);
                        arr_argc = i; /* only free up to i - 1 */
                        goto out;
                }
-               hash = Z_ARRVAL_PP(args[i]);
+               hash = Z_ARRVAL(args[i]);
                list = (Bucket *) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket), hash->flags & HASH_FLAG_PERSISTENT);
                if (!list) {
                        PHP_ARRAY_CMP_FUNC_RESTORE();
@@ -3630,10 +3587,10 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
                ptrs[i] = list;
                for (idx = 0; idx < hash->nNumUsed; idx++) {
                        p = hash->arData + idx;
-                       if (!p->xData) continue;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
                        *list++ = *p;
                }
-               list->xData = NULL;
+               ZVAL_UNDEF(&list->val);
                if (behavior == DIFF_NORMAL) {
                        zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket), diff_data_compare_func TSRMLS_CC);
                } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */
@@ -3642,19 +3599,17 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
        }
 
        /* copy the argument array */
-       RETVAL_ZVAL(*args[0], 1, 0);
-       if (return_value->value.ht == &EG(symbol_table)) {
-               HashTable *ht;
-               zval *tmp;
+       RETVAL_ZVAL(&args[0], 1, 0);
+       if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {
+               HashTable *old_ht = Z_ARRVAL_P(return_value);
 
-               ALLOC_HASHTABLE(ht);
-               zend_hash_init(ht, zend_hash_num_elements(return_value->value.ht), NULL, ZVAL_PTR_DTOR, 0);
-               zend_hash_copy(ht, return_value->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-               return_value->value.ht = ht;
+               ZVAL_NEW_ARR(return_value);
+               zend_hash_init(Z_ARRVAL_P(return_value), zend_hash_num_elements(old_ht), NULL, ZVAL_PTR_DTOR, 0);
+               zend_hash_copy(Z_ARRVAL_P(return_value), old_ht, zval_add_ref);
        }
 
        /* go through the lists and look for values of ptr[0] that are not in the others */
-       while (ptrs[0]->xData) {
+       while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {
                if ((behavior & DIFF_ASSOC) /* triggered also when DIFF_KEY */
                        &&
                        key_compare_type == DIFF_COMP_KEY_USER
@@ -3666,24 +3621,24 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
                for (i = 1; i < arr_argc; i++) {
                        Bucket *ptr = ptrs[i];
                        if (behavior == DIFF_NORMAL) {
-                               while (ptrs[i]->xData && (0 < (c = diff_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
+                               while (Z_TYPE(ptrs[i]->val) != IS_UNDEF && (0 < (c = diff_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC)))) {
                                        ptrs[i]++;
                                }
                        } else if (behavior & DIFF_ASSOC) { /* triggered also when DIFF_KEY */
-                               while (ptr->xData && (0 != (c = diff_key_compare_func(ptrs[0], ptr TSRMLS_CC)))) {
+                               while (Z_TYPE(ptr->val) != IS_UNDEF && (0 != (c = diff_key_compare_func(ptrs[0], ptr TSRMLS_CC)))) {
                                        ptr++;
                                }
                        }
                        if (!c) {
                                if (behavior == DIFF_NORMAL) {
-                                       if (ptrs[i]->xData) {
+                                       if (Z_TYPE(ptrs[i]->val) != IS_UNDEF) {
                                                ptrs[i]++;
                                        }
                                        break;
                                } else if (behavior == DIFF_ASSOC) {  /* only when DIFF_ASSOC */
                                        /* In this branch is execute only when DIFF_ASSOC. If behavior == DIFF_KEY
                                         * data comparison is not needed - skipped. */
-                                       if (ptr->xData) {
+                                       if (Z_TYPE(ptr->val) != IS_UNDEF) {
                                                if (data_compare_type == DIFF_COMP_DATA_USER) {
                                                        BG(user_compare_fci) = *fci_data;
                                                        BG(user_compare_fci_cache) = *fci_data_cache;
@@ -3715,12 +3670,12 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
                        /* delete all entries with value as ptrs[0] */
                        for (;;) {
                                p = ptrs[0];
-                               if (p->nKeyLength == 0) {
+                               if (p->key == NULL) {
                                        zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);
                                } else {
-                                       zend_hash_quick_del(Z_ARRVAL_P(return_value), p->arKey, p->nKeyLength, p->h);
+                                       zend_hash_del(Z_ARRVAL_P(return_value), p->key);
                                }
-                               if (!(++ptrs[0])->xData) {
+                               if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {
                                        goto out;
                                }
                                if (behavior == DIFF_NORMAL) {
@@ -3736,7 +3691,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
                        /* ptrs[0] in none of the other arguments */
                        /* skip all entries with value as ptrs[0] */
                        for (;;) {
-                               if (!(++ptrs[0])->xData) {
+                               if (Z_TYPE((++ptrs[0])->val) == IS_UNDEF) {
                                        goto out;
                                }
                                if (behavior == DIFF_NORMAL) {
@@ -3752,7 +3707,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
        }
 out:
        for (i = 0; i < arr_argc; i++) {
-               hash = Z_ARRVAL_PP(args[i]);
+               hash = Z_ARRVAL(args[i]);
                pefree(lists[i], hash->flags & HASH_FLAG_PERSISTENT);
        }
 
@@ -3844,13 +3799,13 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC) /* {{{
        do {
                php_set_compare_func(ARRAYG(multisort_flags)[MULTISORT_TYPE][r] TSRMLS_CC);
 
-               ARRAYG(compare_func)(&temp, (zval *)ab[r].xData, (zval *)bb[r].xData TSRMLS_CC);
+               ARRAYG(compare_func)(&temp, &ab[r].val, &bb[r].val TSRMLS_CC);
                result = ARRAYG(multisort_flags)[MULTISORT_ORDER][r] * Z_LVAL(temp);
                if (result != 0) {
                        return result;
                }
                r++;
-       } while (ab[r].xData != NULL);
+       } while (Z_TYPE(ab[r].val) != IS_UNDEF);
 
        return result;
 }
@@ -3867,8 +3822,8 @@ PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC) /* {{{
    Sort multiple arrays at once similar to how ORDER BY clause works in SQL */
 PHP_FUNCTION(array_multisort)
 {
-       zval***                 args;
-       zval***                 arrays;
+       zval*                   args;
+       zval**                  arrays;
        Bucket**                indirect;
        uint            idx;
        Bucket*                 p;
@@ -3886,7 +3841,7 @@ PHP_FUNCTION(array_multisort)
        }
 
        /* Allocate space for storing pointers to input arrays and sort flags. */
-       arrays = (zval ***)ecalloc(argc, sizeof(zval **));
+       arrays = (zval **)ecalloc(argc, sizeof(zval *));
        for (i = 0; i < MULTISORT_LAST; i++) {
                parse_state[i] = 0;
                ARRAYG(multisort_flags)[i] = (int *)ecalloc(argc, sizeof(int));
@@ -3898,7 +3853,7 @@ PHP_FUNCTION(array_multisort)
         * accordingly. There can't be two sort flags of the same type after an
         * array, and the very first argument has to be an array. */
        for (i = 0; i < argc; i++) {
-               if (Z_TYPE_PP(args[i]) == IS_ARRAY) {
+               if (Z_TYPE(args[i]) == IS_ARRAY) {
                        /* We see the next array, so we update the sort flags of
                         * the previous array and reset the sort flags. */
                        if (i > 0) {
@@ -3907,20 +3862,20 @@ PHP_FUNCTION(array_multisort)
                                sort_order = PHP_SORT_ASC;
                                sort_type = PHP_SORT_REGULAR;
                        }
-                       arrays[num_arrays++] = args[i];
+                       arrays[num_arrays++] = &args[i];
 
                        /* Next one may be an array or a list of sort flags. */
                        for (k = 0; k < MULTISORT_LAST; k++) {
                                parse_state[k] = 1;
                        }
-               } else if (Z_TYPE_PP(args[i]) == IS_LONG) {
-                       switch (Z_LVAL_PP(args[i]) & ~PHP_SORT_FLAG_CASE) {
+               } else if (Z_TYPE(args[i]) == IS_LONG) {
+                       switch (Z_LVAL(args[i]) & ~PHP_SORT_FLAG_CASE) {
                                case PHP_SORT_ASC:
                                case PHP_SORT_DESC:
                                        /* flag allowed here */
                                        if (parse_state[MULTISORT_ORDER] == 1) {
                                                /* Save the flag and make sure then next arg is not the current flag. */
-                                               sort_order = Z_LVAL_PP(args[i]) == PHP_SORT_DESC ? -1 : 1;
+                                               sort_order = Z_LVAL(args[i]) == PHP_SORT_DESC ? -1 : 1;
                                                parse_state[MULTISORT_ORDER] = 0;
                                        } else {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
@@ -3938,7 +3893,7 @@ PHP_FUNCTION(array_multisort)
                                        /* flag allowed here */
                                        if (parse_state[MULTISORT_TYPE] == 1) {
                                                /* Save the flag and make sure then next arg is not the current flag. */
-                                               sort_type = Z_LVAL_PP(args[i]);
+                                               sort_type = Z_LVAL(args[i]);
                                                parse_state[MULTISORT_TYPE] = 0;
                                        } else {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
@@ -3962,9 +3917,9 @@ PHP_FUNCTION(array_multisort)
        ARRAYG(multisort_flags)[MULTISORT_TYPE][num_arrays - 1] = sort_type;
 
        /* Make sure the arrays are of the same size. */
-       array_size = zend_hash_num_elements(Z_ARRVAL_PP(arrays[0]));
+       array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
        for (i = 0; i < num_arrays; i++) {
-               if (zend_hash_num_elements(Z_ARRVAL_PP(arrays[i])) != array_size) {
+               if (zend_hash_num_elements(Z_ARRVAL_P(arrays[i])) != array_size) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array sizes are inconsistent");
                        MULTISORT_ABORT;
                }
@@ -3990,15 +3945,15 @@ PHP_FUNCTION(array_multisort)
        }
        for (i = 0; i < num_arrays; i++) {
                k = 0;
-               for (idx = 0; idx < Z_ARRVAL_PP(arrays[i])->nNumUsed; idx++) {
-                       p = Z_ARRVAL_PP(arrays[i])->arData + idx;
-                       if (!p->xData) continue;
+               for (idx = 0; idx < Z_ARRVAL_P(arrays[i])->nNumUsed; idx++) {
+                       p = Z_ARRVAL_P(arrays[i])->arData + idx;
+                       if (Z_TYPE(p->val) == IS_UNDEF) continue;
                        indirect[k][i] = *p;
                        k++;
                }
        }
        for (k = 0; k < array_size; k++) {
-               indirect[k][num_arrays].xData = NULL;
+               ZVAL_UNDEF(&indirect[k][num_arrays].val);
        }
 
        /* Do the actual sort magic - bada-bim, bada-boom. */
@@ -4007,13 +3962,13 @@ PHP_FUNCTION(array_multisort)
        /* Restructure the arrays based on sorted indirect - this is mostly taken from zend_hash_sort() function. */
        HANDLE_BLOCK_INTERRUPTIONS();
        for (i = 0; i < num_arrays; i++) {
-               hash = Z_ARRVAL_PP(arrays[i]);
+               hash = Z_ARRVAL_P(arrays[i]);
                hash->nNumUsed = array_size;
                hash->nInternalPointer = 0;
 
                for (n = 0, k = 0; k < array_size; k++) {
                        hash->arData[k] = indirect[k][i];
-                       if (hash->arData[k].nKeyLength == 0)
+                       if (hash->arData[k].key == NULL)
                                hash->arData[k].h = n++;
 
                }
@@ -4045,8 +4000,7 @@ PHP_FUNCTION(array_rand)
        zval *input;
        long randval, num_req = 1;
        int num_avail, key_type;
-       char *string_key;
-       uint string_key_len;
+       zend_string *string_key;
        ulong num_key;
        HashPosition pos;
 
@@ -4070,7 +4024,7 @@ PHP_FUNCTION(array_rand)
 
        /* We can't use zend_hash_index_find() because the array may have string keys or gaps. */
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-       while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
+       while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
 
                randval = php_rand(TSRMLS_C);
 
@@ -4078,14 +4032,14 @@ PHP_FUNCTION(array_rand)
                        /* If we are returning a single result, just do it. */
                        if (Z_TYPE_P(return_value) != IS_ARRAY) {
                                if (key_type == HASH_KEY_IS_STRING) {
-                                       RETURN_STRINGL(string_key, string_key_len - 1, 1);
+                                       RETURN_STR(STR_COPY(string_key));
                                } else {
                                        RETURN_LONG(num_key);
                                }
                        } else {
                                /* Append the result to the return value. */
                                if (key_type == HASH_KEY_IS_STRING) {
-                                       add_next_index_stringl(return_value, string_key, string_key_len - 1, 1);
+                                       add_next_index_str(return_value, string_key);
                                } else {
                                        add_next_index_long(return_value, num_key);
                                }
@@ -4103,7 +4057,7 @@ PHP_FUNCTION(array_rand)
 PHP_FUNCTION(array_sum)
 {
        zval *input,
-                **entry,
+                *entry,
                 entry_n;
        HashPosition pos;
 
@@ -4114,14 +4068,13 @@ PHP_FUNCTION(array_sum)
        ZVAL_LONG(return_value, 0);
 
        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-               zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS;
+               (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL;
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos)
        ) {
-               if (Z_TYPE_PP(entry) == IS_ARRAY || Z_TYPE_PP(entry) == IS_OBJECT) {
+               if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) {
                        continue;
                }
-               entry_n = **entry;
-               zval_copy_ctor(&entry_n);
+               ZVAL_DUP(&entry_n, entry);
                convert_scalar_to_number(&entry_n TSRMLS_CC);
                fast_add_function(return_value, return_value, &entry_n TSRMLS_CC);
        }
@@ -4133,7 +4086,7 @@ PHP_FUNCTION(array_sum)
 PHP_FUNCTION(array_product)
 {
        zval *input,
-                **entry,
+                *entry,
                 entry_n;
        HashPosition pos;
        double dval;
@@ -4148,14 +4101,13 @@ PHP_FUNCTION(array_product)
        }
 
        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-               zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void **)&entry, &pos) == SUCCESS;
+               (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL;
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos)
        ) {
-               if (Z_TYPE_PP(entry) == IS_ARRAY || Z_TYPE_PP(entry) == IS_OBJECT) {
+               if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) {
                        continue;
                }
-               entry_n = **entry;
-               zval_copy_ctor(&entry_n);
+               ZVAL_DUP(&entry_n, entry);
                convert_scalar_to_number(&entry_n TSRMLS_CC);
 
                if (Z_TYPE(entry_n) == IS_LONG && Z_TYPE_P(return_value) == IS_LONG) {
@@ -4177,10 +4129,10 @@ PHP_FUNCTION(array_product)
 PHP_FUNCTION(array_reduce)
 {
        zval *input;
-       zval **args[2];
-       zval **operand;
-       zval *result = NULL;
-       zval *retval;
+       zval args[2];
+       zval *operand;
+       zval result;
+       zval retval;
        zend_fcall_info fci;
        zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
        zval *initial = NULL;
@@ -4191,12 +4143,11 @@ PHP_FUNCTION(array_reduce)
                return;
        }
 
+
        if (ZEND_NUM_ARGS() > 2) {
-               ALLOC_ZVAL(result);
-               MAKE_COPY_ZVAL(&initial, result);
+               ZVAL_DUP(&result, initial);
        } else {
-               MAKE_STD_ZVAL(result);
-               ZVAL_NULL(result);
+               ZVAL_NULL(&result);
        }
 
        /* (zval **)input points to an element of argument stack
@@ -4205,38 +4156,29 @@ PHP_FUNCTION(array_reduce)
        htbl = Z_ARRVAL_P(input);
 
        if (zend_hash_num_elements(htbl) == 0) {
-               if (result) {
-                       RETVAL_ZVAL(result, 1, 1);
-               }
-               return;
+               RETURN_ZVAL(&result, 1, 1);
        }
 
-       fci.retval_ptr_ptr = &retval;
+       fci.retval = &retval;
        fci.param_count = 2;
        fci.no_separation = 0;
 
        zend_hash_internal_pointer_reset_ex(htbl, &pos);
-       while (zend_hash_get_current_data_ex(htbl, (void **)&operand, &pos) == SUCCESS) {
-
-               if (result) {
-                       args[0] = &result;
-                       args[1] = operand;
-                       fci.params = args;
-
-                       if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) {
-                               zval_ptr_dtor(&result);
-                               result = retval;
-                       } else {
-                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback");
-                               return;
-                       }
+       while ((operand = zend_hash_get_current_data_ex(htbl, &pos)) != NULL) {
+               ZVAL_COPY_VALUE(&args[0], &result);
+               ZVAL_COPY_VALUE(&args[1], operand);
+               fci.params = args;
+
+               if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+                       zval_ptr_dtor(&result);
+                       ZVAL_COPY_VALUE(&result, &retval);
                } else {
-                       result = *operand;
-                       zval_add_ref(&result);
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback");
+                       return;
                }
                zend_hash_move_forward_ex(htbl, &pos);
        }
-       RETVAL_ZVAL(result, 1, 1);
+       RETVAL_ZVAL(&result, 1, 1);
 }
 /* }}} */
 
@@ -4245,16 +4187,15 @@ PHP_FUNCTION(array_reduce)
 PHP_FUNCTION(array_filter)
 {
        zval *array;
-       zval **operand;
-       zval **args[2];
-       zval *retval = NULL;
-    zval *key = NULL;
+       zval *operand;
+       zval args[2];
+       zval retval;
+//???    zval *key = NULL;
        zend_bool have_callback = 0;
        long use_type = 0;
-       char *string_key;
+       zend_string *string_key;
        zend_fcall_info fci = empty_fcall_info;
        zend_fcall_info_cache fci_cache = empty_fcall_info_cache;
-       uint string_key_len;
        ulong num_key;
        HashPosition pos;
 
@@ -4270,52 +4211,50 @@ PHP_FUNCTION(array_filter)
        if (ZEND_NUM_ARGS() > 1) {
                have_callback = 1;
                fci.no_separation = 0;
-               fci.retval_ptr_ptr = &retval;
+               fci.retval = &retval;
 
                if (use_type == ARRAY_FILTER_USE_BOTH) {
                        fci.param_count = 2;
-                       args[1] = &key;
+//???                  args[1] = &key;
                } else {
                        fci.param_count = 1;
                        if (use_type == ARRAY_FILTER_USE_KEY) {
-                               args[0] = &key;
+//???                          args[0] = &key;
                        }
                }
        }
 
        for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
-               zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&operand, &pos) == SUCCESS;
+               (operand = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL;
                zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos)
        ) {
-               int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &string_key_len, &num_key, 0, &pos);
+               int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos);
 
                if (have_callback) {
                        if (use_type) {
-                               MAKE_STD_ZVAL(key);
                                /* Set up the key */
                                switch (key_type) {
                                        case HASH_KEY_IS_LONG:
-                                               Z_TYPE_P(key) = IS_LONG;
-                                               Z_LVAL_P(key) = num_key;
+                                               ZVAL_LONG(&args[0], num_key);
                                                break;
 
                                        case HASH_KEY_IS_STRING:
-                                               ZVAL_STRINGL(key, string_key, string_key_len - 1, 1);
+                                               ZVAL_STR(&args[0], STR_COPY(string_key));
                                                break;
                                }
                        }
 
                        if (use_type != ARRAY_FILTER_USE_KEY) {
-                               args[0] = operand;
+                               ZVAL_COPY_VALUE(&args[0], operand);
                        }
                        fci.params = args;
 
-                       if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && retval) {
-                               int retval_true = zend_is_true(retval TSRMLS_CC);
+                       if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
+                               int retval_true = zend_is_true(&retval TSRMLS_CC);
 
                                zval_ptr_dtor(&retval);
                                if (use_type) {
-                                       zval_ptr_dtor(&key);
+                                       zval_ptr_dtor(&args[0]);
                                }
                                if (!retval_true) {
                                        continue;
@@ -4324,18 +4263,18 @@ PHP_FUNCTION(array_filter)
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the filter callback");
                                return;
                        }
-               } else if (!zend_is_true(*operand TSRMLS_CC)) {
+               } else if (!zend_is_true(operand TSRMLS_CC)) {
                        continue;
                }
 
                zval_add_ref(operand);
                switch (key_type) {
                        case HASH_KEY_IS_STRING:
-                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len, operand, sizeof(zval *), NULL);
+                               zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand);
                                break;
 
                        case HASH_KEY_IS_LONG:
-                               zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand, sizeof(zval *), NULL);
+                               zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand);
                                break;
                }
        }
@@ -4346,10 +4285,10 @@ PHP_FUNCTION(array_filter)
    Applies the callback to the elements in given arrays. */
 PHP_FUNCTION(array_map)
 {
-       zval ***arrays = NULL;
+       zval *arrays = NULL;
        int n_arrays = 0;
-       zval ***params;
-       zval *result, *null;
+       zval *params;
+       zval result;
        HashPosition *array_pos;
        zval **args;
        zend_fcall_info fci = empty_fcall_info;
@@ -4368,7 +4307,7 @@ PHP_FUNCTION(array_map)
        array_pos = (HashPosition *)safe_emalloc(n_arrays, sizeof(HashPosition), 0);
 
        for (i = 0; i < n_arrays; i++) {
-               if (Z_TYPE_PP(arrays[i]) != IS_ARRAY) {
+               if (Z_TYPE(arrays[i]) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d should be an array", i + 2);
                        efree(arrays);
                        efree(args);
@@ -4376,13 +4315,13 @@ PHP_FUNCTION(array_map)
                        efree(array_pos);
                        return;
                }
-               SEPARATE_ZVAL_IF_NOT_REF(arrays[i]);
-               args[i] = *arrays[i];
-               array_len[i] = zend_hash_num_elements(Z_ARRVAL_PP(arrays[i]));
+               SEPARATE_ZVAL_IF_NOT_REF(&arrays[i]);
+               args[i] = &arrays[i];
+               array_len[i] = zend_hash_num_elements(Z_ARRVAL(arrays[i]));
                if (array_len[i] > maxlen) {
                        maxlen = array_len[i];
                }
-               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(arrays[i]), &array_pos[i]);
+               zend_hash_internal_pointer_reset_ex(Z_ARRVAL(arrays[i]), &array_pos[i]);
        }
 
        efree(arrays);
@@ -4397,76 +4336,73 @@ PHP_FUNCTION(array_map)
        }
 
        array_init_size(return_value, maxlen);
-       params = (zval ***)safe_emalloc(n_arrays, sizeof(zval **), 0);
-       MAKE_STD_ZVAL(null);
-       ZVAL_NULL(null);
+       params = (zval *)safe_emalloc(n_arrays, sizeof(zval), 0);
 
        /* We iterate through all the arrays at once. */
        for (k = 0; k < maxlen; k++) {
-               uint str_key_len;
                ulong num_key;
-               char *str_key;
+               zend_string *str_key;
                int key_type = 0;
 
                /* If no callback, the result will be an array, consisting of current
                 * entries from all arrays. */
                if (!ZEND_FCI_INITIALIZED(fci)) {
-                       MAKE_STD_ZVAL(result);
-                       array_init_size(result, n_arrays);
+                       array_init_size(&result, n_arrays);
                }
 
                for (i = 0; i < n_arrays; i++) {
                        /* If this array still has elements, add the current one to the
                         * parameter list, otherwise use null value. */
                        if (k < array_len[i]) {
-                               zend_hash_get_current_data_ex(Z_ARRVAL_P(args[i]), (void **)&params[i], &array_pos[i]);
+                               zval *zv = zend_hash_get_current_data_ex(Z_ARRVAL_P(args[i]), &array_pos[i]);
+
+                               ZVAL_COPY_VALUE(&params[i], zv);
 
                                /* It is safe to store only last value of key type, because
                                 * this loop will run just once if there is only 1 array. */
                                if (n_arrays == 1) {
-                                       key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(args[0]), &str_key, &str_key_len, &num_key, 0, &array_pos[i]);
+                                       key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(args[0]), &str_key, &num_key, 0, &array_pos[i]);
                                }
                                zend_hash_move_forward_ex(Z_ARRVAL_P(args[i]), &array_pos[i]);
                        } else {
-                               params[i] = &null;
+                               ZVAL_NULL(&params[i]);
                        }
 
                        if (!ZEND_FCI_INITIALIZED(fci)) {
-                               zval_add_ref(params[i]);
-                               add_next_index_zval(result, *params[i]);
+                               zval_add_ref(&params[i]);
+                               add_next_index_zval(&result, &params[i]);
                        }
                }
 
                if (ZEND_FCI_INITIALIZED(fci)) {
-                       fci.retval_ptr_ptr = &result;
+                       fci.retval = &result;
                        fci.param_count = n_arrays;
                        fci.params = params;
                        fci.no_separation = 0;
 
-                       if (zend_call_function(&fci, &fci_cache TSRMLS_CC) != SUCCESS || !result) {
+                       if (zend_call_function(&fci, &fci_cache TSRMLS_CC) != SUCCESS || Z_TYPE(result) == IS_UNDEF) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the map callback");
                                efree(array_len);
                                efree(args);
                                efree(array_pos);
                                zval_dtor(return_value);
-                               zval_ptr_dtor(&null);
                                efree(params);
                                RETURN_NULL();
                        }
                }
 
                if (n_arrays > 1) {
-                       add_next_index_zval(return_value, result);
+                       add_next_index_zval(return_value, &result);
                } else {
                        if (key_type == HASH_KEY_IS_STRING) {
-                               add_assoc_zval_ex(return_value, str_key, str_key_len, result);
+//???
+                               add_assoc_zval_ex(return_value, str_key->val, str_key->len, &result);
                        } else {
-                               add_index_zval(return_value, num_key, result);
+                               add_index_zval(return_value, num_key, &result);
                        }
                }
        }
 
-       zval_ptr_dtor(&null);
        efree(params);
        efree(array_len);
        efree(array_pos);
@@ -4487,7 +4423,7 @@ PHP_FUNCTION(array_key_exists)
 
        switch (Z_TYPE_P(key)) {
                case IS_STRING:
-                       if (zend_symtable_exists(array, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1)) {
+                       if (zend_symtable_exists(array, Z_STR_P(key))) {
                                RETURN_TRUE;
                        }
                        RETURN_FALSE;
@@ -4497,7 +4433,7 @@ PHP_FUNCTION(array_key_exists)
                        }
                        RETURN_FALSE;
                case IS_NULL:
-                       if (zend_hash_exists(array, "", 1)) {
+                       if (zend_hash_exists(array, STR_EMPTY_ALLOC())) {
                                RETURN_TRUE;
                        }
                        RETURN_FALSE;
@@ -4515,13 +4451,12 @@ PHP_FUNCTION(array_chunk)
 {
        int argc = ZEND_NUM_ARGS(), key_type, num_in;
        long size, current = 0;
-       char *str_key;
-       uint str_key_len;
+       zend_string *str_key;
        ulong num_key;
        zend_bool preserve_keys = 0;
        zval *input = NULL;
-       zval *chunk = NULL;
-       zval **entry;
+       zval chunk;
+       zval *entry;
        HashPosition pos;
 
        if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) {
@@ -4541,44 +4476,45 @@ PHP_FUNCTION(array_chunk)
 
        array_init_size(return_value, ((num_in - 1) / size) + 1);
 
+       ZVAL_UNDEF(&chunk);
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(input), (void**)&entry, &pos) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) {
                /* If new chunk, create and initialize it. */
-               if (!chunk) {
-                       MAKE_STD_ZVAL(chunk);
-                       array_init_size(chunk, size);
+               if (Z_TYPE(chunk) == IS_UNDEF) {
+                       array_init_size(&chunk, size);
                }
 
                /* Add entry to the chunk, preserving keys if necessary. */
                zval_add_ref(entry);
 
                if (preserve_keys) {
-                       key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &str_key_len, &num_key, 0, &pos);
+                       key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &num_key, 0, &pos);
                        switch (key_type) {
                                case HASH_KEY_IS_STRING:
-                                       add_assoc_zval_ex(chunk, str_key, str_key_len, *entry);
+//???
+                                       add_assoc_zval_ex(&chunk, str_key->val, str_key->len, entry);
                                        break;
                                default:
-                                       add_index_zval(chunk, num_key, *entry);
+                                       add_index_zval(&chunk, num_key, entry);
                                        break;
                        }
                } else {
-                       add_next_index_zval(chunk, *entry);
+                       add_next_index_zval(&chunk, entry);
                }
 
                /* If reached the chunk size, add it to the result array, and reset the
                 * pointer. */
                if (!(++current % size)) {
-                       add_next_index_zval(return_value, chunk);
-                       chunk = NULL;
+                       add_next_index_zval(return_value, &chunk);
+                       ZVAL_UNDEF(&chunk);
                }
 
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
        }
 
        /* Add the final chunk if there is one. */
-       if (chunk) {
-               add_next_index_zval(return_value, chunk);
+       if (Z_TYPE(chunk) != IS_UNDEF) {
+               add_next_index_zval(return_value, &chunk);
        }
 }
 /* }}} */
@@ -4589,7 +4525,7 @@ PHP_FUNCTION(array_combine)
 {
        zval *values, *keys;
        HashPosition pos_values, pos_keys;
-       zval **entry_keys, **entry_values;
+       zval *entry_keys, *entry_values;
        int num_keys, num_values;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa", &keys, &values) == FAILURE) {
@@ -4612,26 +4548,26 @@ PHP_FUNCTION(array_combine)
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos_keys);
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), (void **)&entry_keys, &pos_keys) == SUCCESS &&
-               zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&entry_values, &pos_values) == SUCCESS
+       while ((entry_keys = zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), &pos_keys)) != NULL &&
+               (entry_values = zend_hash_get_current_data_ex(Z_ARRVAL_P(values), &pos_values)) != NULL
        ) {
-               if (Z_TYPE_PP(entry_keys) == IS_LONG) {
+               if (Z_TYPE_P(entry_keys) == IS_LONG) {
                        zval_add_ref(entry_values);
-                       add_index_zval(return_value, Z_LVAL_PP(entry_keys), *entry_values);
+                       add_index_zval(return_value, Z_LVAL_P(entry_keys), entry_values);
                } else {
-                       zval key, *key_ptr = *entry_keys;
+                       zval key, *key_ptr = entry_keys;
 
-                       if (Z_TYPE_PP(entry_keys) != IS_STRING) {
-                               key = **entry_keys;
-                               zval_copy_ctor(&key);
+                       if (Z_TYPE_P(entry_keys) != IS_STRING) {
+                               ZVAL_DUP(&key, entry_keys);
                                convert_to_string(&key);
                                key_ptr = &key;
                        }
 
                        zval_add_ref(entry_values);
-                       add_assoc_zval_ex(return_value, Z_STRVAL_P(key_ptr), Z_STRLEN_P(key_ptr) + 1, *entry_values);
+//???
+                       add_assoc_zval_ex(return_value, Z_STRVAL_P(key_ptr), Z_STRLEN_P(key_ptr), entry_values);
 
-                       if (key_ptr != *entry_keys) {
+                       if (key_ptr != entry_keys) {
                                zval_dtor(&key);
                        }
                }
index c4389dd92a5ae7cea74e35ba4a7d47bbe2df8e45..0a869e899b952c2d9ee863ad4e040892688a5a44 100644 (file)
@@ -103,7 +103,7 @@ PHP_FUNCTION(array_key_exists);
 PHP_FUNCTION(array_chunk);
 PHP_FUNCTION(array_combine);
 
-PHPAPI HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **);
+PHPAPI HashTable* php_splice(HashTable *, int, int, zval *, int, HashTable *);
 PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);
 PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC);
 PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
index b47319be310b34b77142aa013cf8684cc4c95a65..891bad30858e3331e6629454661f65cd8355896b 100644 (file)
@@ -251,7 +251,8 @@ PHP_FUNCTION(bin2hex)
                RETURN_FALSE;
        }
 
-       RETURN_STRINGL(result, newlen, 0);
+//???  RETURN_STRINGL(result, newlen, 0);
+       RETURN_STRINGL(result, newlen);
 }
 /* }}} */
 
@@ -279,7 +280,8 @@ PHP_FUNCTION(hex2bin)
                RETURN_FALSE;
        }
 
-       RETURN_STRINGL(result, newlen, 0);
+//???  RETURN_STRINGL(result, newlen, 0);
+       RETURN_STRINGL(result, newlen);
 }
 /* }}} */
 
@@ -706,7 +708,7 @@ PHP_FUNCTION(nl_langinfo)
        if (value == NULL) {
                RETURN_FALSE;
        } else {
-               RETURN_STRING(value, 1);
+               RETURN_STRING(value);
        }
 }
 #endif
@@ -818,7 +820,7 @@ PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_v
        }
 
        if (return_value) {
-               RETVAL_STRINGL(c, len, 1);
+               RETVAL_STRINGL(c, len);
        } else {
                return estrndup(c, len);
        }
@@ -918,7 +920,8 @@ PHP_FUNCTION(wordwrap)
                        }
                }
 
-               RETURN_STRINGL(newtext, textlen, 0);
+//???          RETURN_STRINGL(newtext, textlen, 0);
+               RETURN_STRINGL(newtext, textlen);
        } else {
                /* Multiple character line break or forced cut */
                if (linelength > 0) {
@@ -1001,7 +1004,8 @@ PHP_FUNCTION(wordwrap)
                /* free unused memory */
                newtext = erealloc(newtext, newtextlen+1);
 
-               RETURN_STRINGL(newtext, newtextlen, 0);
+//???          RETURN_STRINGL(newtext, newtextlen, 0);
+               RETURN_STRINGL(newtext, newtextlen);
        }
 }
 /* }}} */
@@ -1015,7 +1019,7 @@ PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit)
        endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);
 
        p1 = Z_STRVAL_P(str);
-       p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
+       p2 = (char*)php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
 
        if (p2 == NULL) {
                add_next_index_stringl(return_value, p1, Z_STRLEN_P(str), 1);
@@ -1023,7 +1027,7 @@ PHPAPI void php_explode(zval *delim, zval *str, zval *return_value, long limit)
                do {
                        add_next_index_stringl(return_value, p1, p2 - p1, 1);
                        p1 = p2 + Z_STRLEN_P(delim);
-               } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
+               } while ((p2 = (char*)php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL &&
                                 --limit > 1);
 
                if (p1 <= endp)
@@ -1042,7 +1046,7 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu
        endp = Z_STRVAL_P(str) + Z_STRLEN_P(str);
 
        p1 = Z_STRVAL_P(str);
-       p2 = php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
+       p2 = (char*)php_memnstr(Z_STRVAL_P(str), Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp);
 
        if (p2 == NULL) {
                /*
@@ -1061,7 +1065,7 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu
                                positions = erealloc(positions, allocated*sizeof(char *));
                        }
                        positions[found++] = p1 = p2 + Z_STRLEN_P(delim);
-               } while ((p2 = php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);
+               } while ((p2 = (char*)php_memnstr(p1, Z_STRVAL_P(delim), Z_STRLEN_P(delim), endp)) != NULL);
 
                to_return = limit + found;
                /* limit is at least -1 therefore no need of bounds checking : i will be always less than found */
@@ -1104,8 +1108,10 @@ PHP_FUNCTION(explode)
                return;
        }
 
-       ZVAL_STRINGL(&zstr, str, str_len, 0);
-       ZVAL_STRINGL(&zdelim, delim, delim_len, 0);
+//???  ZVAL_STRINGL(&zstr, str, str_len, 0);
+//???  ZVAL_STRINGL(&zdelim, delim, delim_len, 0);
+       ZVAL_STRINGL(&zstr, str, str_len);
+       ZVAL_STRINGL(&zdelim, delim, delim_len);
        if (limit > 1) {
                php_explode(&zdelim, &zstr, return_value, limit);
        } else if (limit < 0) {
@@ -1124,7 +1130,7 @@ PHP_FUNCTION(explode)
  */
 PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
 {
-       zval         **tmp;
+       zval          *tmp;
        HashPosition   pos;
        smart_str      implstr = {0};
        int            numelems, i = 0;
@@ -1139,21 +1145,21 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
 
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos);
 
-       while (zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **) &tmp, &pos) == SUCCESS) {
-               switch ((*tmp)->type) {
+       while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), &pos)) != NULL) {
+               switch (Z_TYPE_P(tmp)) {
                        case IS_STRING:
-                               smart_str_appendl(&implstr, Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp));
+                               smart_str_appendl(&implstr, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));
                                break;
 
                        case IS_LONG: {
                                char stmp[MAX_LENGTH_OF_LONG + 1];
-                               str_len = slprintf(stmp, sizeof(stmp), "%ld", Z_LVAL_PP(tmp));
+                               str_len = slprintf(stmp, sizeof(stmp), "%ld", Z_LVAL_P(tmp));
                                smart_str_appendl(&implstr, stmp, str_len);
                        }
                                break;
 
                        case IS_BOOL:
-                               if (Z_LVAL_PP(tmp) == 1) {
+                               if (Z_LVAL_P(tmp) == 1) {
                                        smart_str_appendl(&implstr, "1", sizeof("1")-1);
                                }
                                break;
@@ -1163,7 +1169,7 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
 
                        case IS_DOUBLE: {
                                char *stmp;
-                               str_len = spprintf(&stmp, 0, "%.*G", (int) EG(precision), Z_DVAL_PP(tmp));
+                               str_len = spprintf(&stmp, 0, "%.*G", (int) EG(precision), Z_DVAL_P(tmp));
                                smart_str_appendl(&implstr, stmp, str_len);
                                efree(stmp);
                        }
@@ -1172,7 +1178,7 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
                        case IS_OBJECT: {
                                int copy;
                                zval expr;
-                               zend_make_printable_zval(*tmp, &expr, &copy);
+                               zend_make_printable_zval(tmp, &expr, &copy);
                                smart_str_appendl(&implstr, Z_STRVAL(expr), Z_STRLEN(expr));
                                if (copy) {
                                        zval_dtor(&expr);
@@ -1181,9 +1187,7 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
                                break;
 
                        default:
-                               tmp_val = **tmp;
-                               zval_copy_ctor(&tmp_val);
-                               convert_to_string(&tmp_val);
+                               ZVAL_DUP(&tmp_val, tmp);
                                smart_str_appendl(&implstr, Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
                                zval_dtor(&tmp_val);
                                break;
@@ -1198,7 +1202,8 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
        smart_str_0(&implstr);
 
        if (implstr.len) {
-               RETURN_STRINGL(implstr.c, implstr.len, 0);
+//???          RETURN_STRINGL(implstr.c, implstr.len, 0);
+               RETURN_STRINGL(implstr.c, implstr.len);
        } else {
                smart_str_free(&implstr);
                RETURN_EMPTY_STRING();
@@ -1210,33 +1215,32 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC)
    Joins array elements placing glue string between items and return one string */
 PHP_FUNCTION(implode)
 {
-       zval **arg1 = NULL, **arg2 = NULL, *delim, *arr;
+       zval *arg1 = NULL, *arg2 = NULL, *delim, *arr, tmp;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|Z", &arg1, &arg2) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|z", &arg1, &arg2) == FAILURE) {
                return;
        }
 
        if (arg2 == NULL) {
-               if (Z_TYPE_PP(arg1) != IS_ARRAY) {
+               if (Z_TYPE_P(arg1) != IS_ARRAY) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument must be an array");
                        return;
                }
 
-               MAKE_STD_ZVAL(delim);
-#define _IMPL_EMPTY ""
-               ZVAL_STRINGL(delim, _IMPL_EMPTY, sizeof(_IMPL_EMPTY) - 1, 0);
+               ZVAL_STR(&tmp, STR_EMPTY_ALLOC());
+               delim = &tmp;
 
                SEPARATE_ZVAL(arg1);
-               arr = *arg1;
+               arr = arg1;
        } else {
-               if (Z_TYPE_PP(arg1) == IS_ARRAY) {
-                       arr = *arg1;
+               if (Z_TYPE_P(arg1) == IS_ARRAY) {
+                       arr = arg1;
                        convert_to_string_ex(arg2);
-                       delim = *arg2;
-               } else if (Z_TYPE_PP(arg2) == IS_ARRAY) {
-                       arr = *arg2;
+                       delim = arg2;
+               } else if (Z_TYPE_P(arg2) == IS_ARRAY) {
+                       arr = arg2;
                        convert_to_string_ex(arg1);
-                       delim = *arg1;
+                       delim = arg1;
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments passed");
                        return;
@@ -1244,10 +1248,6 @@ PHP_FUNCTION(implode)
        }
 
        php_implode(delim, arr, return_value TSRMLS_CC);
-
-       if (arg2 == NULL) {
-               FREE_ZVAL(delim);
-       }
 }
 /* }}} */
 
@@ -1259,8 +1259,6 @@ PHP_FUNCTION(strtok)
 {
        char *str, *tok = NULL;
        int str_len, tok_len = 0;
-       zval *zv;
-
        char *token;
        char *token_end;
        char *p;
@@ -1275,14 +1273,9 @@ PHP_FUNCTION(strtok)
                tok = str;
                tok_len = str_len;
        } else {
-               if (BG(strtok_zval)) {
-                       zval_ptr_dtor(&BG(strtok_zval));
-               }
-               MAKE_STD_ZVAL(zv);
-               ZVAL_STRINGL(zv, str, str_len, 1);
-
-               BG(strtok_zval) = zv;
-               BG(strtok_last) = BG(strtok_string) = Z_STRVAL_P(zv);
+               zval_ptr_dtor(&BG(strtok_zval));
+               ZVAL_STRINGL(&BG(strtok_zval), str, str_len);
+               BG(strtok_last) = BG(strtok_string) = Z_STRVAL(BG(strtok_zval));
                BG(strtok_len) = str_len;
        }
 
@@ -1320,7 +1313,7 @@ PHP_FUNCTION(strtok)
 
        if (p - BG(strtok_last)) {
 return_token:
-               RETVAL_STRINGL(BG(strtok_last) + skipped, (p - BG(strtok_last)) - skipped, 1);
+               RETVAL_STRINGL(BG(strtok_last) + skipped, (p - BG(strtok_last)) - skipped);
                BG(strtok_last) = p + 1;
        } else {
                RETVAL_FALSE;
@@ -1367,7 +1360,8 @@ PHP_FUNCTION(strtoupper)
 
        arg = estrndup(arg, arglen);
        php_strtoupper(arg, arglen);
-       RETURN_STRINGL(arg, arglen, 0);
+//???  RETURN_STRINGL(arg, arglen, 0);
+       RETURN_STRINGL(arg, arglen);
 }
 /* }}} */
 
@@ -1401,7 +1395,8 @@ PHP_FUNCTION(strtolower)
 
        str = estrndup(str, arglen);
        php_strtolower(str, arglen);
-       RETURN_STRINGL(str, arglen, 0);
+//???  RETURN_STRINGL(str, arglen, 0);
+       RETURN_STRINGL(str, arglen);
 }
 /* }}} */
 
@@ -1504,7 +1499,8 @@ PHP_FUNCTION(basename)
        }
 
        php_basename(string, string_len, suffix, suffix_len, &ret, &ret_len TSRMLS_CC);
-       RETURN_STRINGL(ret, (int)ret_len, 0);
+//???  RETURN_STRINGL(ret, (int)ret_len, 0);
+       RETURN_STRINGL(ret, (int)ret_len);
 }
 /* }}} */
 
@@ -1532,7 +1528,8 @@ PHP_FUNCTION(dirname)
        ret = estrndup(str, str_len);
        ret_len = php_dirname(ret, str_len);
 
-       RETURN_STRINGL(ret, ret_len, 0);
+//???  RETURN_STRINGL(ret, ret_len, 0);
+       RETURN_STRINGL(ret, ret_len);
 }
 /* }}} */
 
@@ -1540,7 +1537,7 @@ PHP_FUNCTION(dirname)
    Returns information about a certain string */
 PHP_FUNCTION(pathinfo)
 {
-       zval *tmp;
+       zval tmp;
        char *path, *ret = NULL;
        int path_len, have_basename;
        size_t ret_len;
@@ -1552,14 +1549,13 @@ PHP_FUNCTION(pathinfo)
 
        have_basename = ((opt & PHP_PATHINFO_BASENAME) == PHP_PATHINFO_BASENAME);
 
-       MAKE_STD_ZVAL(tmp);
-       array_init(tmp);
+       array_init(&tmp);
 
        if ((opt & PHP_PATHINFO_DIRNAME) == PHP_PATHINFO_DIRNAME) {
                ret = estrndup(path, path_len);
                php_dirname(ret, path_len);
                if (*ret) {
-                       add_assoc_string(tmp, "dirname", ret, 1);
+                       add_assoc_string(&tmp, "dirname", ret, 1);
                }
                efree(ret);
                ret = NULL;
@@ -1567,7 +1563,7 @@ PHP_FUNCTION(pathinfo)
 
        if (have_basename) {
                php_basename(path, path_len, NULL, 0, &ret, &ret_len TSRMLS_CC);
-               add_assoc_stringl(tmp, "basename", ret, ret_len, 0);
+               add_assoc_stringl(&tmp, "basename", ret, ret_len, 0);
        }
 
        if ((opt & PHP_PATHINFO_EXTENSION) == PHP_PATHINFO_EXTENSION) {
@@ -1582,7 +1578,7 @@ PHP_FUNCTION(pathinfo)
 
                if (p) {
                        idx = p - ret;
-                       add_assoc_stringl(tmp, "extension", ret + idx + 1, ret_len - idx - 1, 1);
+                       add_assoc_stringl(&tmp, "extension", ret + idx + 1, ret_len - idx - 1, 1);
                }
        }
 
@@ -1598,7 +1594,7 @@ PHP_FUNCTION(pathinfo)
                p = zend_memrchr(ret, '.', ret_len);
 
                idx = p ? (p - ret) : ret_len;
-               add_assoc_stringl(tmp, "filename", ret, idx, 1);
+               add_assoc_stringl(&tmp, "filename", ret, idx, 1);
        }
 
        if (!have_basename && ret) {
@@ -1606,11 +1602,11 @@ PHP_FUNCTION(pathinfo)
        }
 
        if (opt == PHP_PATHINFO_ALL) {
-               RETURN_ZVAL(tmp, 0, 1);
+               RETURN_ZVAL(&tmp, 0, 1);
        } else {
-               zval **element;
-               if (zend_hash_get_current_data(Z_ARRVAL_P(tmp), (void **) &element) == SUCCESS) {
-                       RETVAL_ZVAL(*element, 1, 0);
+               zval *element;
+               if ((element = zend_hash_get_current_data(Z_ARRVAL(tmp))) != NULL) {
+                       RETVAL_ZVAL(element, 1, 0);
                } else {
                        ZVAL_EMPTY_STRING(return_value);
                }
@@ -1626,7 +1622,7 @@ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len)
 {
        php_strtolower(s, s_len);
        php_strtolower(t, t_len);
-       return php_memnstr(s, t, t_len, s + s_len);
+       return (char*)php_memnstr(s, t, t_len, s + s_len);
 }
 /* }}} */
 
@@ -1744,9 +1740,9 @@ PHP_FUNCTION(stristr)
        if (found) {
                found_offset = found - haystack_dup;
                if (part) {
-                       RETVAL_STRINGL(haystack, found_offset, 1);
+                       RETVAL_STRINGL(haystack, found_offset);
                } else {
-                       RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset, 1);
+                       RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset);
                }
        } else {
                RETVAL_FALSE;
@@ -1778,22 +1774,22 @@ PHP_FUNCTION(strstr)
                        RETURN_FALSE;
                }
 
-               found = php_memnstr(haystack, Z_STRVAL_P(needle), Z_STRLEN_P(needle), haystack + haystack_len);
+               found = (char*)php_memnstr(haystack, Z_STRVAL_P(needle), Z_STRLEN_P(needle), haystack + haystack_len);
        } else {
                if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {
                        RETURN_FALSE;
                }
                needle_char[1] = 0;
 
-               found = php_memnstr(haystack, needle_char,      1, haystack + haystack_len);
+               found = (char*)php_memnstr(haystack, needle_char,       1, haystack + haystack_len);
        }
 
        if (found) {
                found_offset = found - haystack;
                if (part) {
-                       RETURN_STRINGL(haystack, found_offset, 1);
+                       RETURN_STRINGL(haystack, found_offset);
                } else {
-                       RETURN_STRINGL(found, haystack_len - found_offset, 1);
+                       RETURN_STRINGL(found, haystack_len - found_offset);
                }
        }
        RETURN_FALSE;
@@ -1830,7 +1826,7 @@ PHP_FUNCTION(strpos)
                        RETURN_FALSE;
                }
 
-               found = php_memnstr(haystack + offset,
+               found = (char*)php_memnstr(haystack + offset,
                                        Z_STRVAL_P(needle),
                                        Z_STRLEN_P(needle),
                                        haystack + haystack_len);
@@ -1840,7 +1836,7 @@ PHP_FUNCTION(strpos)
                }
                needle_char[1] = 0;
 
-               found = php_memnstr(haystack + offset,
+               found = (char*)php_memnstr(haystack + offset,
                                                        needle_char,
                                                        1,
                                    haystack + haystack_len);
@@ -1890,7 +1886,7 @@ PHP_FUNCTION(stripos)
 
                needle_dup = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle));
                php_strtolower(needle_dup, Z_STRLEN_P(needle));
-               found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len);
+               found = (char*)php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len);
        } else {
                if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) {
                        efree(haystack_dup);
@@ -1898,7 +1894,7 @@ PHP_FUNCTION(stripos)
                }
                needle_char[0] = tolower(needle_char[0]);
                needle_char[1] = '\0';
-               found = php_memnstr(haystack_dup + offset,
+               found = (char*)php_memnstr(haystack_dup + offset,
                                                        needle_char,
                                                        sizeof(needle_char) - 1,
                                                        haystack_dup + haystack_len);
@@ -2121,7 +2117,7 @@ PHP_FUNCTION(strrchr)
 
        if (found) {
                found_offset = found - haystack;
-               RETURN_STRINGL(found, haystack_len - found_offset, 1);
+               RETURN_STRINGL(found, haystack_len - found_offset);
        } else {
                RETURN_FALSE;
        }
@@ -2208,7 +2204,8 @@ PHP_FUNCTION(chunk_split)
                memcpy(result, str, str_len);
                memcpy(result + str_len, end, endlen);
                result[result_len] = '\0';
-               RETURN_STRINGL(result, result_len, 0);
+//???          RETURN_STRINGL(result, result_len, 0);
+               RETURN_STRINGL(result, result_len);
        }
 
        if (!str_len) {
@@ -2218,7 +2215,8 @@ PHP_FUNCTION(chunk_split)
        result = php_chunk_split(str, str_len, end, endlen, chunklen, &result_len);
 
        if (result) {
-               RETURN_STRINGL(result, result_len, 0);
+//???          RETURN_STRINGL(result, result_len, 0);
+               RETURN_STRINGL(result, result_len);
        } else {
                RETURN_FALSE;
        }
@@ -2286,7 +2284,7 @@ PHP_FUNCTION(substr)
                l = str_len - f;
        }
 
-       RETURN_STRINGL(str + f, l, 1);
+       RETURN_STRINGL(str + f, l);
 }
 /* }}} */
 
@@ -2294,10 +2292,10 @@ PHP_FUNCTION(substr)
    Replaces part of a string with another string */
 PHP_FUNCTION(substr_replace)
 {
-       zval **str;
-       zval **from;
-       zval **len = NULL;
-       zval **repl;
+       zval *str;
+       zval *from;
+       zval *len = NULL;
+       zval *repl;
        char *result;
        int result_len;
        int l = 0;
@@ -2305,165 +2303,159 @@ PHP_FUNCTION(substr_replace)
        int argc = ZEND_NUM_ARGS();
 
        HashPosition pos_str, pos_from, pos_repl, pos_len;
-       zval **tmp_str = NULL, **tmp_from = NULL, **tmp_repl = NULL, **tmp_len= NULL;
+       zval *tmp_str = NULL, *tmp_from = NULL, *tmp_repl = NULL, *tmp_len= NULL;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &str, &repl, &from, &len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z", &str, &repl, &from, &len) == FAILURE) {
                return;
        }
 
-       if (Z_TYPE_PP(str) != IS_ARRAY) {
-               if (Z_ISREF_PP(str)) {
-                       SEPARATE_ZVAL(str);
-               }
+       if (Z_TYPE_P(str) != IS_ARRAY) {
+               SEPARATE_ZVAL_IF_REF(str);
                convert_to_string_ex(str);
        }
-       if (Z_TYPE_PP(repl) != IS_ARRAY) {
-               if (Z_ISREF_PP(repl)) {
-                       SEPARATE_ZVAL(repl);
-               }
+       if (Z_TYPE_P(repl) != IS_ARRAY) {
+               SEPARATE_ZVAL_IF_REF(repl);
                convert_to_string_ex(repl);
        }
-       if (Z_TYPE_PP(from) != IS_ARRAY) {
-               if (Z_ISREF_PP(from)) {
-                       SEPARATE_ZVAL(from);
-               }
+       if (Z_TYPE_P(from) != IS_ARRAY) {
+               SEPARATE_ZVAL_IF_REF(from);
                convert_to_long_ex(from);
        }
 
        if (argc > 3) {
                SEPARATE_ZVAL(len);
-               if (Z_TYPE_PP(len) != IS_ARRAY) {
+               if (Z_TYPE_P(len) != IS_ARRAY) {
                        convert_to_long_ex(len);
-                       l = Z_LVAL_PP(len);
+                       l = Z_LVAL_P(len);
                }
        } else {
-               if (Z_TYPE_PP(str) != IS_ARRAY) {
-                       l = Z_STRLEN_PP(str);
+               if (Z_TYPE_P(str) != IS_ARRAY) {
+                       l = Z_STRLEN_P(str);
                }
        }
 
-       if (Z_TYPE_PP(str) == IS_STRING) {
+       if (Z_TYPE_P(str) == IS_STRING) {
                if (
-                       (argc == 3 && Z_TYPE_PP(from) == IS_ARRAY) ||
-                       (argc == 4 && Z_TYPE_PP(from) != Z_TYPE_PP(len))
+                       (argc == 3 && Z_TYPE_P(from) == IS_ARRAY) ||
+                       (argc == 4 && Z_TYPE_P(from) != Z_TYPE_P(len))
                ) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should be of same type - numerical or array ");
-                       RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
+                       RETURN_STR(STR_COPY(Z_STR_P(str)));
                }
-               if (argc == 4 && Z_TYPE_PP(from) == IS_ARRAY) {
-                       if (zend_hash_num_elements(Z_ARRVAL_PP(from)) != zend_hash_num_elements(Z_ARRVAL_PP(len))) {
+               if (argc == 4 && Z_TYPE_P(from) == IS_ARRAY) {
+                       if (zend_hash_num_elements(Z_ARRVAL_P(from)) != zend_hash_num_elements(Z_ARRVAL_P(len))) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "'from' and 'len' should have the same number of elements");
-                               RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
+                               RETURN_STR(STR_COPY(Z_STR_P(str)));
                        }
                }
        }
 
-       if (Z_TYPE_PP(str) != IS_ARRAY) {
-               if (Z_TYPE_PP(from) != IS_ARRAY) {
+       if (Z_TYPE_P(str) != IS_ARRAY) {
+               if (Z_TYPE_P(from) != IS_ARRAY) {
                        int repl_len = 0;
 
-                       f = Z_LVAL_PP(from);
+                       f = Z_LVAL_P(from);
 
                        /* if "from" position is negative, count start position from the end
                         * of the string
                         */
                        if (f < 0) {
-                               f = Z_STRLEN_PP(str) + f;
+                               f = Z_STRLEN_P(str) + f;
                                if (f < 0) {
                                        f = 0;
                                }
-                       } else if (f > Z_STRLEN_PP(str)) {
-                               f = Z_STRLEN_PP(str);
+                       } else if (f > Z_STRLEN_P(str)) {
+                               f = Z_STRLEN_P(str);
                        }
                        /* if "length" position is negative, set it to the length
                         * needed to stop that many chars from the end of the string
                         */
                        if (l < 0) {
-                               l = (Z_STRLEN_PP(str) - f) + l;
+                               l = (Z_STRLEN_P(str) - f) + l;
                                if (l < 0) {
                                        l = 0;
                                }
                        }
 
-                       if (f > Z_STRLEN_PP(str) || (f < 0 && -f > Z_STRLEN_PP(str))) {
+                       if (f > Z_STRLEN_P(str) || (f < 0 && -f > Z_STRLEN_P(str))) {
                                RETURN_FALSE;
-                       } else if (l > Z_STRLEN_PP(str) || (l < 0 && -l > Z_STRLEN_PP(str))) {
-                               l = Z_STRLEN_PP(str);
+                       } else if (l > Z_STRLEN_P(str) || (l < 0 && -l > Z_STRLEN_P(str))) {
+                               l = Z_STRLEN_P(str);
                        }
 
-                       if ((f + l) > Z_STRLEN_PP(str)) {
-                               l = Z_STRLEN_PP(str) - f;
+                       if ((f + l) > Z_STRLEN_P(str)) {
+                               l = Z_STRLEN_P(str) - f;
                        }
-                       if (Z_TYPE_PP(repl) == IS_ARRAY) {
-                               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(repl), &pos_repl);
-                               if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(repl), (void **) &tmp_repl, &pos_repl)) {
+                       if (Z_TYPE_P(repl) == IS_ARRAY) {
+                               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(repl), &pos_repl);
+                               if (NULL != (tmp_repl = zend_hash_get_current_data_ex(Z_ARRVAL_P(repl), &pos_repl))) {
                                        convert_to_string_ex(tmp_repl);
-                                       repl_len = Z_STRLEN_PP(tmp_repl);
+                                       repl_len = Z_STRLEN_P(tmp_repl);
                                }
                        } else {
-                               repl_len = Z_STRLEN_PP(repl);
+                               repl_len = Z_STRLEN_P(repl);
                        }
-                       result_len = Z_STRLEN_PP(str) - l + repl_len;
+                       result_len = Z_STRLEN_P(str) - l + repl_len;
                        result = emalloc(result_len + 1);
 
-                       memcpy(result, Z_STRVAL_PP(str), f);
+                       memcpy(result, Z_STRVAL_P(str), f);
                        if (repl_len) {
-                               memcpy((result + f), (Z_TYPE_PP(repl) == IS_ARRAY ? Z_STRVAL_PP(tmp_repl) : Z_STRVAL_PP(repl)), repl_len);
+                               memcpy((result + f), (Z_TYPE_P(repl) == IS_ARRAY ? Z_STRVAL_P(tmp_repl) : Z_STRVAL_P(repl)), repl_len);
                        }
-                       memcpy((result + f + repl_len), Z_STRVAL_PP(str) + f + l, Z_STRLEN_PP(str) - f - l);
+                       memcpy((result + f + repl_len), Z_STRVAL_P(str) + f + l, Z_STRLEN_P(str) - f - l);
                        result[result_len] = '\0';
-                       RETURN_STRINGL(result, result_len, 0);
+//???                  RETURN_STRINGL(result, result_len, 0);
+                       RETURN_STRINGL(result, result_len);
                } else {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Functionality of 'from' and 'len' as arrays is not implemented");
-                       RETURN_STRINGL(Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1);
+                       RETURN_STR(STR_COPY(Z_STR_P(str)));
                }
        } else { /* str is array of strings */
-               char *str_index = NULL;
-               uint str_index_len;
+               zend_string *str_index = NULL;
                ulong num_index;
 
                array_init(return_value);
 
-               if (Z_TYPE_PP(from) == IS_ARRAY) {
-                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(from), &pos_from);
+               if (Z_TYPE_P(from) == IS_ARRAY) {
+                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(from), &pos_from);
                }
 
-               if (argc > 3 && Z_TYPE_PP(len) == IS_ARRAY) {
-                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(len), &pos_len);
+               if (argc > 3 && Z_TYPE_P(len) == IS_ARRAY) {
+                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(len), &pos_len);
                }
 
-               if (Z_TYPE_PP(repl) == IS_ARRAY) {
-                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(repl), &pos_repl);
+               if (Z_TYPE_P(repl) == IS_ARRAY) {
+                       zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(repl), &pos_repl);
                }
 
-               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(str), &pos_str);
-               while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(str), (void **) &tmp_str, &pos_str) == SUCCESS) {
+               zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(str), &pos_str);
+               while ((tmp_str = zend_hash_get_current_data_ex(Z_ARRVAL_P(str), &pos_str)) != NULL) {
                        zval *orig_str;
                        zval dummy;
                        ulong refcount;
-                       int was_ref;
+//???                  int was_ref;
 
-                       if(Z_TYPE_PP(tmp_str) != IS_STRING) {
-                               dummy = **tmp_str;
+                       if(Z_TYPE_P(tmp_str) != IS_STRING) {
+                               ZVAL_DUP(&dummy, tmp_str);
+                               convert_to_string(&dummy);
                                orig_str = &dummy;
-                               zval_copy_ctor(orig_str);
-                               convert_to_string(orig_str);
                        } else {
-                               orig_str = *tmp_str;
+                               orig_str = tmp_str;
                        }
-                       was_ref = Z_ISREF_P(orig_str);
-                       Z_UNSET_ISREF_P(orig_str);
+//???                  was_ref = Z_ISREF_P(orig_str);
+//???                  Z_UNSET_ISREF_P(orig_str);
                        refcount = Z_REFCOUNT_P(orig_str);
 
-                       if (Z_TYPE_PP(from) == IS_ARRAY) {
-                               if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(from), (void **) &tmp_from, &pos_from)) {
-                                       if(Z_TYPE_PP(tmp_from) != IS_LONG) {
-                                               zval dummy = **tmp_from;
-                                               zval_copy_ctor(&dummy);
+                       if (Z_TYPE_P(from) == IS_ARRAY) {
+                               if (NULL != (tmp_from = zend_hash_get_current_data_ex(Z_ARRVAL_P(from), &pos_from))) {
+                                       if(Z_TYPE_P(tmp_from) != IS_LONG) {
+                                               zval dummy;
+                                               
+                                               ZVAL_DUP(&dummy, tmp_from);
                                                convert_to_long(&dummy);
                                                f = Z_LVAL(dummy);
                                        } else {
-                                               f = Z_LVAL_PP(tmp_from);
+                                               f = Z_LVAL_P(tmp_from);
                                        }
 
                                        if (f < 0) {
@@ -2474,12 +2466,12 @@ PHP_FUNCTION(substr_replace)
                                        } else if (f > Z_STRLEN_P(orig_str)) {
                                                f = Z_STRLEN_P(orig_str);
                                        }
-                                       zend_hash_move_forward_ex(Z_ARRVAL_PP(from), &pos_from);
+                                       zend_hash_move_forward_ex(Z_ARRVAL_P(from), &pos_from);
                                } else {
                                        f = 0;
                                }
                        } else {
-                               f = Z_LVAL_PP(from);
+                               f = Z_LVAL_P(from);
                                if (f < 0) {
                                        f = Z_STRLEN_P(orig_str) + f;
                                        if (f < 0) {
@@ -2490,22 +2482,23 @@ PHP_FUNCTION(substr_replace)
                                }
                        }
 
-                       if (argc > 3 && Z_TYPE_PP(len) == IS_ARRAY) {
-                               if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(len), (void **) &tmp_len, &pos_len)) {
-                                       if(Z_TYPE_PP(tmp_len) != IS_LONG) {
-                                               zval dummy = **tmp_len;
-                                               zval_copy_ctor(&dummy);
+                       if (argc > 3 && Z_TYPE_P(len) == IS_ARRAY) {
+                               if (NULL != (tmp_len = zend_hash_get_current_data_ex(Z_ARRVAL_P(len), &pos_len))) {
+                                       if(Z_TYPE_P(tmp_len) != IS_LONG) {
+                                               zval dummy;
+                                               
+                                               ZVAL_DUP(&dummy, tmp_len);
                                                convert_to_long(&dummy);
                                                l = Z_LVAL(dummy);
                                        } else {
-                                               l = Z_LVAL_PP(tmp_len);
+                                               l = Z_LVAL_P(tmp_len);
                                        }
-                                       zend_hash_move_forward_ex(Z_ARRVAL_PP(len), &pos_len);
+                                       zend_hash_move_forward_ex(Z_ARRVAL_P(len), &pos_len);
                                } else {
                                        l = Z_STRLEN_P(orig_str);
                                }
                        } else if (argc > 3) {
-                               l = Z_LVAL_PP(len);
+                               l = Z_LVAL_P(len);
                        } else {
                                l = Z_STRLEN_P(orig_str);
                        }
@@ -2523,35 +2516,34 @@ PHP_FUNCTION(substr_replace)
 
                        result_len = Z_STRLEN_P(orig_str) - l;
 
-                       if (Z_TYPE_PP(repl) == IS_ARRAY) {
-                               if (SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(repl), (void **) &tmp_repl, &pos_repl)) {
+                       if (Z_TYPE_P(repl) == IS_ARRAY) {
+                               if (NULL != (tmp_repl = zend_hash_get_current_data_ex(Z_ARRVAL_P(repl), &pos_repl))) {
                                        zval *repl_str;
                                        zval zrepl;
-                                       if(Z_TYPE_PP(tmp_repl) != IS_STRING) {
-                                               zrepl = **tmp_repl;
+                                       if(Z_TYPE_P(tmp_repl) != IS_STRING) {
+                                               ZVAL_DUP(&zrepl, tmp_repl);
+                                               convert_to_string(&zrepl);
                                                repl_str = &zrepl;
-                                               zval_copy_ctor(repl_str);
-                                               convert_to_string(repl_str);
                                        } else {
-                                               repl_str = *tmp_repl;
+                                               repl_str = tmp_repl;
                                        }
 
                                        if(Z_REFCOUNT_P(orig_str) != refcount) {
                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument was modified while replacing");
-                                               if(Z_TYPE_PP(tmp_repl) != IS_STRING) {
+                                               if(Z_TYPE_P(tmp_repl) != IS_STRING) {
                                                        zval_dtor(repl_str);
                                                }
                                                break;
                                        }
 
                                        result_len += Z_STRLEN_P(repl_str);
-                                       zend_hash_move_forward_ex(Z_ARRVAL_PP(repl), &pos_repl);
+                                       zend_hash_move_forward_ex(Z_ARRVAL_P(repl), &pos_repl);
                                        result = emalloc(result_len + 1);
 
                                        memcpy(result, Z_STRVAL_P(orig_str), f);
                                        memcpy((result + f), Z_STRVAL_P(repl_str), Z_STRLEN_P(repl_str));
                                        memcpy((result + f + Z_STRLEN_P(repl_str)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);
-                                       if(Z_TYPE_PP(tmp_repl) != IS_STRING) {
+                                       if(Z_TYPE_P(tmp_repl) != IS_STRING) {
                                                zval_dtor(repl_str);
                                        }
                                } else {
@@ -2561,29 +2553,30 @@ PHP_FUNCTION(substr_replace)
                                        memcpy((result + f), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);
                                }
                        } else {
-                               result_len += Z_STRLEN_PP(repl);
+                               result_len += Z_STRLEN_P(repl);
 
                                result = emalloc(result_len + 1);
 
                                memcpy(result, Z_STRVAL_P(orig_str), f);
-                               memcpy((result + f), Z_STRVAL_PP(repl), Z_STRLEN_PP(repl));
-                               memcpy((result + f + Z_STRLEN_PP(repl)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);
+                               memcpy((result + f), Z_STRVAL_P(repl), Z_STRLEN_P(repl));
+                               memcpy((result + f + Z_STRLEN_P(repl)), Z_STRVAL_P(orig_str) + f + l, Z_STRLEN_P(orig_str) - f - l);
                        }
 
                        result[result_len] = '\0';
 
-                       if (zend_hash_get_current_key_ex(Z_ARRVAL_PP(str), &str_index, &str_index_len, &num_index, 0, &pos_str) == HASH_KEY_IS_STRING) {
-                               add_assoc_stringl_ex(return_value, str_index, str_index_len, result, result_len, 0);
+                       if (zend_hash_get_current_key_ex(Z_ARRVAL_P(str), &str_index, &num_index, 0, &pos_str) == HASH_KEY_IS_STRING) {
+//???
+                               add_assoc_stringl_ex(return_value, str_index->val, str_index->len, result, result_len, 0);
                        } else {
                                add_index_stringl(return_value, num_index, result, result_len, 0);
                        }
 
-                       if(Z_TYPE_PP(tmp_str) != IS_STRING) {
+                       if(Z_TYPE_P(tmp_str) != IS_STRING) {
                                zval_dtor(orig_str);
                        } else {
-                               Z_SET_ISREF_TO_P(orig_str, was_ref);
+//???                          Z_SET_ISREF_TO_P(orig_str, was_ref);
                        }
-                       zend_hash_move_forward_ex(Z_ARRVAL_PP(str), &pos_str);
+                       zend_hash_move_forward_ex(Z_ARRVAL_P(str), &pos_str);
                } /*while*/
        } /* if */
 }
@@ -2633,7 +2626,8 @@ PHP_FUNCTION(quotemeta)
        }
        *q = 0;
 
-       RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0);
+//???  RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0);
+       RETURN_STRINGL(erealloc(str, q - str + 1), q - str);
 }
 /* }}} */
 
@@ -2670,7 +2664,7 @@ PHP_FUNCTION(chr)
        temp[0] = (char)c;
        temp[1] = '\0';
 
-       RETURN_STRINGL(temp, 1, 1);
+       RETURN_STRINGL(temp, 1);
 }
 /* }}} */
 
@@ -2699,7 +2693,7 @@ PHP_FUNCTION(ucfirst)
                RETURN_EMPTY_STRING();
        }
 
-       ZVAL_STRINGL(return_value, str, str_len, 1);
+       ZVAL_STRINGL(return_value, str, str_len);
        php_ucfirst(Z_STRVAL_P(return_value));
 }
 /* }}} */
@@ -2729,7 +2723,7 @@ PHP_FUNCTION(lcfirst)
                RETURN_EMPTY_STRING();
        }
 
-       ZVAL_STRINGL(return_value, str, str_len, 1);
+       ZVAL_STRINGL(return_value, str, str_len);
        php_lcfirst(Z_STRVAL_P(return_value));
 }
 /* }}} */
@@ -2750,7 +2744,7 @@ PHP_FUNCTION(ucwords)
                RETURN_EMPTY_STRING();
        }
 
-       ZVAL_STRINGL(return_value, str, str_len, 1);
+       ZVAL_STRINGL(return_value, str, str_len);
        r = Z_STRVAL_P(return_value);
 
        *r = toupper((unsigned char) *r);
@@ -2889,7 +2883,7 @@ static int php_strtr_compare_hash_suffix(const void *a, const void *b TSRMLS_DC,
 /* {{{ php_strtr_free_strp */
 static void php_strtr_free_strp(void *strp)
 {
-       STR_FREE(*(char**)strp);
+//???  STR_FREE(*(char**)strp);
 }
 /* }}} */
 /* {{{ php_strtr_array_prepare_repls */
@@ -2897,7 +2891,7 @@ static PATNREPL *php_strtr_array_prepare_repls(int slen, HashTable *pats, zend_l
 {
        PATNREPL                *patterns;
        HashPosition    hpos;
-       zval                    **entry;
+       zval                    *entry;
        int                             num_pats = zend_hash_num_elements(pats),
                                        i;
 
@@ -2906,50 +2900,42 @@ static PATNREPL *php_strtr_array_prepare_repls(int slen, HashTable *pats, zend_l
        zend_llist_init(*allocs, sizeof(void*), &php_strtr_free_strp, 0);
 
        for (i = 0, zend_hash_internal_pointer_reset_ex(pats, &hpos);
-                       zend_hash_get_current_data_ex(pats, (void **)&entry, &hpos) == SUCCESS;
+                       (entry = zend_hash_get_current_data_ex(pats, &hpos)) != NULL;
                        zend_hash_move_forward_ex(pats, &hpos)) {
-               char    *string_key;
-               uint    string_key_len;
+               zend_string     *string_key;
                ulong   num_key;
-               zval    *tzv = NULL;
+               zval    tzv;
 
-               switch (zend_hash_get_current_key_ex(pats, &string_key, &string_key_len, &num_key, 0, &hpos)) {
+               switch (zend_hash_get_current_key_ex(pats, &string_key, &num_key, 0, &hpos)) {
                case HASH_KEY_IS_LONG:
-                       string_key_len = 1 + zend_spprintf(&string_key, 0, "%ld", (long)num_key);
+//???                  string_key_len = 1 + zend_spprintf(&string_key, 0, "%ld", (long)num_key);
                        zend_llist_add_element(*allocs, &string_key);
                        /* break missing intentionally */
 
                case HASH_KEY_IS_STRING:
-                       string_key_len--; /* exclude final '\0' */
-                       if (string_key_len == 0) { /* empty string given as pattern */
+                       if (string_key->len == 0) { /* empty string given as pattern */
                                efree(patterns);
                                zend_llist_destroy(*allocs);
                                efree(*allocs);
                                *allocs = NULL;
                                return NULL;
                        }
-                       if (string_key_len > slen) { /* this pattern can never match */
+                       if (string_key->len > slen) { /* this pattern can never match */
                                continue;
                        }
 
-                       if (Z_TYPE_PP(entry) != IS_STRING) {
-                               tzv = *entry;
-                               zval_addref_p(tzv);
-                               SEPARATE_ZVAL(&tzv);
-                               convert_to_string(tzv);
+                       if (Z_TYPE_P(entry) != IS_STRING) {
+                               ZVAL_DUP(&tzv, entry);
+                               convert_to_string(&tzv);
                                entry = &tzv;
-                               zend_llist_add_element(*allocs, &Z_STRVAL_PP(entry));
+                               zend_llist_add_element(*allocs, &Z_STRVAL_P(entry));
                        }
 
-                       S(&patterns[i].pat) = string_key;
-                       L(&patterns[i].pat) = string_key_len;
-                       S(&patterns[i].repl) = Z_STRVAL_PP(entry);
-                       L(&patterns[i].repl) = Z_STRLEN_PP(entry);
+                       S(&patterns[i].pat) = string_key->val;
+                       L(&patterns[i].pat) = string_key->len;
+                       S(&patterns[i].repl) = Z_STRVAL_P(entry);
+                       L(&patterns[i].repl) = Z_STRLEN_P(entry);
                        i++;
-
-                       if (tzv) {
-                               efree(tzv);
-                       }
                }
        }
 
@@ -3085,7 +3071,8 @@ end_outer_loop: ;
 
        if (result.c != NULL) {
                smart_str_0(&result);
-               RETVAL_STRINGL(result.c, result.len, 0);
+//???          RETVAL_STRINGL(result.c, result.len, 0);
+               RETVAL_STRINGL(result.c, result.len);
        } else {
                RETURN_EMPTY_STRING();
        }
@@ -3121,16 +3108,16 @@ static void php_strtr_array(zval *return_value, char *str, int slen, HashTable *
    Translates characters in str using given translation tables */
 PHP_FUNCTION(strtr)
 {
-       zval **from;
+       zval *from;
        char *str, *to = NULL;
        int str_len, to_len = 0;
        int ac = ZEND_NUM_ARGS();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|s", &str, &str_len, &from, &to, &to_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|s", &str, &str_len, &from, &to, &to_len) == FAILURE) {
                return;
        }
 
-       if (ac == 2 && Z_TYPE_PP(from) != IS_ARRAY) {
+       if (ac == 2 && Z_TYPE_P(from) != IS_ARRAY) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "The second argument is not an array");
                RETURN_FALSE;
        }
@@ -3141,17 +3128,17 @@ PHP_FUNCTION(strtr)
        }
 
        if (ac == 2) {
-               php_strtr_array(return_value, str, str_len, HASH_OF(*from));
+               php_strtr_array(return_value, str, str_len, HASH_OF(from));
        } else {
                convert_to_string_ex(from);
 
-               ZVAL_STRINGL(return_value, str, str_len, 1);
+               ZVAL_STRINGL(return_value, str, str_len);
 
                php_strtr(Z_STRVAL_P(return_value),
                                  Z_STRLEN_P(return_value),
-                                 Z_STRVAL_PP(from),
+                                 Z_STRVAL_P(from),
                                  to,
-                                 MIN(Z_STRLEN_PP(from),
+                                 MIN(Z_STRLEN_P(from),
                                  to_len));
        }
 }
@@ -3180,7 +3167,8 @@ PHP_FUNCTION(strrev)
 
        *p = '\0';
 
-       RETVAL_STRINGL(n, str_len, 0);
+//???  RETVAL_STRINGL(n, str_len, 0);
+       RETVAL_STRINGL(n, str_len);
 }
 /* }}} */
 
@@ -3235,12 +3223,12 @@ static int php_similar_char(const char *txt1, int len1, const char *txt2, int le
 PHP_FUNCTION(similar_text)
 {
        char *t1, *t2;
-       zval **percent = NULL;
+       zval *percent = NULL;
        int ac = ZEND_NUM_ARGS();
        int sim;
        int t1_len, t2_len;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|Z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|z", &t1, &t1_len, &t2, &t2_len, &percent) == FAILURE) {
                return;
        }
 
@@ -3250,7 +3238,7 @@ PHP_FUNCTION(similar_text)
 
        if (t1_len + t2_len == 0) {
                if (ac > 2) {
-                       Z_DVAL_PP(percent) = 0;
+                       Z_DVAL_P(percent) = 0;
                }
 
                RETURN_LONG(0);
@@ -3259,7 +3247,7 @@ PHP_FUNCTION(similar_text)
        sim = php_similar_char(t1, t1_len, t2, t2_len);
 
        if (ac > 2) {
-               Z_DVAL_PP(percent) = sim * 200.0 / (t1_len + t2_len);
+               Z_DVAL_P(percent) = sim * 200.0 / (t1_len + t2_len);
        }
 
        RETURN_LONG(sim);
@@ -3325,11 +3313,11 @@ PHP_FUNCTION(addcslashes)
        }
 
        if (what_len == 0) {
-               RETURN_STRINGL(str, str_len, 1);
+               RETURN_STRINGL(str, str_len);
        }
 
-       Z_STRVAL_P(return_value) = php_addcslashes(str, str_len, &Z_STRLEN_P(return_value), 0, what, what_len TSRMLS_CC);
-       RETURN_STRINGL(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), 0);
+//???  Z_STRVAL_P(return_value) = php_addcslashes(str, str_len, &Z_STRLEN_P(return_value), 0, what, what_len TSRMLS_CC);
+//???  RETURN_STRINGL(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), 0);
 }
 /* }}} */
 
@@ -3348,10 +3336,14 @@ PHP_FUNCTION(addslashes)
                RETURN_EMPTY_STRING();
        }
 
+//???  RETURN_STRING(php_addslashes(str,
+//???                               str_len,
+//???                               &Z_STRLEN_P(return_value), 0
+//???                               TSRMLS_CC), 0);
        RETURN_STRING(php_addslashes(str,
                                     str_len,
                                     &Z_STRLEN_P(return_value), 0
-                                    TSRMLS_CC), 0);
+                                    TSRMLS_CC));
 }
 /* }}} */
 
@@ -3366,7 +3358,7 @@ PHP_FUNCTION(stripcslashes)
                return;
        }
 
-       ZVAL_STRINGL(return_value, str, str_len, 1);
+       ZVAL_STRINGL(return_value, str, str_len);
        php_stripcslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value));
 }
 /* }}} */
@@ -3382,7 +3374,7 @@ PHP_FUNCTION(stripslashes)
                return;
        }
 
-       ZVAL_STRINGL(return_value, str, str_len, 1);
+       ZVAL_STRINGL(return_value, str, str_len);
        php_stripslashes(Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value) TSRMLS_CC);
 }
 /* }}} */
@@ -3516,7 +3508,7 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s
                *new_length = newlen;
        }
        if (should_free) {
-               STR_FREE((char*)str);
+//???          STR_FREE((char*)str);
        }
        return new_str;
 }
@@ -3566,7 +3558,7 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f
        *target = 0;
        *new_length = target - new_str;
        if (should_free) {
-               STR_FREE(str);
+//???          STR_FREE(str);
        }
        new_str = (char *) erealloc(new_str, *new_length + 1);
        return new_str;
@@ -3602,13 +3594,12 @@ PHPAPI int php_char_to_str_ex(char *str, uint len, char from, char *to, int to_l
        }
 
        if (char_count == 0 && case_sensitivity) {
-               ZVAL_STRINGL(result, str, len, 1);
+               ZVAL_STRINGL(result, str, len);
                return 0;
        }
 
-       Z_STRLEN_P(result) = len + (char_count * (to_len - 1));
-       Z_STRVAL_P(result) = target = safe_emalloc(char_count, to_len, len + 1);
-       Z_TYPE_P(result) = IS_STRING;
+       ZVAL_STR(result, STR_ALLOC(len + (char_count * (to_len - 1)), 0));
+       target = Z_STRVAL_P(result); //??? = target = safe_emalloc(char_count, to_len, len + 1);
 
        if (case_sensitivity) {
                char *p = str, *e = p + len, *s = str;
@@ -3674,7 +3665,7 @@ PHPAPI char *php_str_to_str_ex(char *haystack, int length,
 
                        if (case_sensitivity) {
                                end = new_str + length;
-                               for (p = new_str; (r = php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
+                               for (p = new_str; (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
                                        memcpy(r, str, str_len);
                                        if (replace_count) {
                                                (*replace_count)++;
@@ -3686,7 +3677,7 @@ PHPAPI char *php_str_to_str_ex(char *haystack, int length,
                                php_strtolower(haystack_dup, length);
                                php_strtolower(needle_dup, needle_len);
                                end = haystack_dup + length;
-                               for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) {
+                               for (p = haystack_dup; (r = (char*)php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) {
                                        memcpy(new_str + (r - haystack_dup), str, str_len);
                                        if (replace_count) {
                                                (*replace_count)++;
@@ -3719,7 +3710,7 @@ PHPAPI char *php_str_to_str_ex(char *haystack, int length,
                                }
                                endp = o + length;
 
-                               while ((o = php_memnstr(o, n, needle_len, endp))) {
+                               while ((o = (char*)php_memnstr(o, n, needle_len, endp))) {
                                        o += needle_len;
                                        count++;
                                }
@@ -3745,7 +3736,7 @@ PHPAPI char *php_str_to_str_ex(char *haystack, int length,
 
                        if (case_sensitivity) {
                                end = haystack + length;
-                               for (p = haystack; (r = php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
+                               for (p = haystack; (r = (char*)php_memnstr(p, needle, needle_len, end)); p = r + needle_len) {
                                        memcpy(e, p, r - p);
                                        e += r - p;
                                        memcpy(e, str, str_len);
@@ -3762,7 +3753,7 @@ PHPAPI char *php_str_to_str_ex(char *haystack, int length,
                        } else {
                                end = haystack_dup + length;
 
-                               for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) {
+                               for (p = haystack_dup; (r = (char*)php_memnstr(p, needle_dup, needle_len, end)); p = r + needle_len) {
                                        memcpy(e, haystack + (p - haystack_dup), r - p);
                                        e += r - p;
                                        memcpy(e, str, str_len);
@@ -3840,26 +3831,26 @@ PHPAPI char *php_str_to_str(char *haystack, int length,
 
 /* {{{ php_str_replace_in_subject
  */
-static void php_str_replace_in_subject(zval *search, zval *replace, zval **subject, zval *result, int case_sensitivity, int *replace_count)
+static void php_str_replace_in_subject(zval *search, zval *replace, zval *subject, zval *result, int case_sensitivity, int *replace_count)
 {
-       zval            **search_entry,
-                               **replace_entry = NULL,
-                                 temp_result;
+       zval            *search_entry,
+                               *replace_entry = NULL,
+                                temp_result;
        char            *replace_value = NULL;
        int                      replace_len = 0;
 
        /* Make sure we're dealing with strings. */
        convert_to_string_ex(subject);
        Z_TYPE_P(result) = IS_STRING;
-       if (Z_STRLEN_PP(subject) == 0) {
-               ZVAL_STRINGL(result, "", 0, 1);
+       if (Z_STRLEN_P(subject) == 0) {
+               ZVAL_EMPTY_STRING(result);
                return;
        }
 
        /* If search is an array */
        if (Z_TYPE_P(search) == IS_ARRAY) {
                /* Duplicate subject string for repeated replacement */
-               MAKE_COPY_ZVAL(subject, result);
+               ZVAL_DUP(result, subject);
 
                zend_hash_internal_pointer_reset(Z_ARRVAL_P(search));
 
@@ -3872,11 +3863,11 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
                }
 
                /* For each entry in the search array, get the entry */
-               while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) {
+               while ((search_entry = zend_hash_get_current_data(Z_ARRVAL_P(search))) != NULL) {
                        /* Make sure we're dealing with strings. */
                        SEPARATE_ZVAL(search_entry);
-                       convert_to_string(*search_entry);
-                       if (Z_STRLEN_PP(search_entry) == 0) {
+                       convert_to_string(search_entry);
+                       if (Z_STRLEN_P(search_entry) == 0) {
                                zend_hash_move_forward(Z_ARRVAL_P(search));
                                if (Z_TYPE_P(replace) == IS_ARRAY) {
                                        zend_hash_move_forward(Z_ARRVAL_P(replace));
@@ -3887,13 +3878,13 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
                        /* If replace is an array. */
                        if (Z_TYPE_P(replace) == IS_ARRAY) {
                                /* Get current entry */
-                               if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) {
+                               if ((replace_entry = zend_hash_get_current_data(Z_ARRVAL_P(replace))) != NULL) {
                                        /* Make sure we're dealing with strings. */
                                        convert_to_string_ex(replace_entry);
 
                                        /* Set replacement value to the one we got from array */
-                                       replace_value = Z_STRVAL_PP(replace_entry);
-                                       replace_len = Z_STRLEN_PP(replace_entry);
+                                       replace_value = Z_STRVAL_P(replace_entry);
+                                       replace_len = Z_STRLEN_P(replace_entry);
 
                                        zend_hash_move_forward(Z_ARRVAL_P(replace));
                                } else {
@@ -3903,24 +3894,23 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
                                }
                        }
 
-                       if (Z_STRLEN_PP(search_entry) == 1) {
+                       if (Z_STRLEN_P(search_entry) == 1) {
                                php_char_to_str_ex(Z_STRVAL_P(result),
                                                                Z_STRLEN_P(result),
-                                                               Z_STRVAL_PP(search_entry)[0],
+                                                               Z_STRVAL_P(search_entry)[0],
                                                                replace_value,
                                                                replace_len,
                                                                &temp_result,
                                                                case_sensitivity,
                                                                replace_count);
-                       } else if (Z_STRLEN_PP(search_entry) > 1) {
-                               Z_STRVAL(temp_result) = php_str_to_str_ex(Z_STRVAL_P(result), Z_STRLEN_P(result),
-                                                                                                                  Z_STRVAL_PP(search_entry), Z_STRLEN_PP(search_entry),
-                                                                                                                  replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);
+                       } else if (Z_STRLEN_P(search_entry) > 1) {
+//???                          Z_STRVAL(temp_result) = php_str_to_str_ex(Z_STRVAL_P(result), Z_STRLEN_P(result),
+//???                                                                                                             Z_STRVAL_P(search_entry), Z_STRLEN_P(search_entry),
+//???                                                                                                             replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);
                        }
 
-           str_efree(Z_STRVAL_P(result));
-                       Z_STRVAL_P(result) = Z_STRVAL(temp_result);
-                       Z_STRLEN_P(result) = Z_STRLEN(temp_result);
+                       STR_FREE(Z_STR_P(result));
+                       Z_STR_P(result) = Z_STR(temp_result);
 
                        if (Z_STRLEN_P(result) == 0) {
                                return;
@@ -3930,8 +3920,8 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
                }
        } else {
                if (Z_STRLEN_P(search) == 1) {
-                       php_char_to_str_ex(Z_STRVAL_PP(subject),
-                                                       Z_STRLEN_PP(subject),
+                       php_char_to_str_ex(Z_STRVAL_P(subject),
+                                                       Z_STRLEN_P(subject),
                                                        Z_STRVAL_P(search)[0],
                                                        Z_STRVAL_P(replace),
                                                        Z_STRLEN_P(replace),
@@ -3939,11 +3929,11 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
                                                        case_sensitivity,
                                                        replace_count);
                } else if (Z_STRLEN_P(search) > 1) {
-                       Z_STRVAL_P(result) = php_str_to_str_ex(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject),
-                                                                                                       Z_STRVAL_P(search), Z_STRLEN_P(search),
-                                                                                                       Z_STRVAL_P(replace), Z_STRLEN_P(replace), &Z_STRLEN_P(result), case_sensitivity, replace_count);
+//???                  Z_STRVAL_P(result) = php_str_to_str_ex(Z_STRVAL_P(subject), Z_STRLEN_P(subject),
+//???                                                                                                  Z_STRVAL_P(search), Z_STRLEN_P(search),
+//???                                                                                                  Z_STRVAL_P(replace), Z_STRLEN_P(replace), &Z_STRLEN_P(result), case_sensitivity, replace_count);
                } else {
-                       MAKE_COPY_ZVAL(subject, result);
+                       ZVAL_DUP(result, subject);
                }
        }
 }
@@ -3953,15 +3943,14 @@ static void php_str_replace_in_subject(zval *search, zval *replace, zval **subje
  */
 static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity)
 {
-       zval **subject, **search, **replace, **subject_entry, **zcount = NULL;
-       zval *result;
-       char *string_key;
-       uint string_key_len;
+       zval *subject, *search, *replace, *subject_entry, *zcount = NULL;
+       zval result;
+       zend_string *string_key;
        ulong num_key;
        int count = 0;
        int argc = ZEND_NUM_ARGS();
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZZ|Z", &search, &replace, &subject, &zcount) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz|z", &search, &replace, &subject, &zcount) == FAILURE) {
                return;
        }
 
@@ -3970,50 +3959,49 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit
        SEPARATE_ZVAL(subject);
 
        /* Make sure we're dealing with strings and do the replacement. */
-       if (Z_TYPE_PP(search) != IS_ARRAY) {
+       if (Z_TYPE_P(search) != IS_ARRAY) {
                convert_to_string_ex(search);
                convert_to_string_ex(replace);
-       } else if (Z_TYPE_PP(replace) != IS_ARRAY) {
+       } else if (Z_TYPE_P(replace) != IS_ARRAY) {
                convert_to_string_ex(replace);
        }
 
        /* if subject is an array */
-       if (Z_TYPE_PP(subject) == IS_ARRAY) {
+       if (Z_TYPE_P(subject) == IS_ARRAY) {
                array_init(return_value);
-               zend_hash_internal_pointer_reset(Z_ARRVAL_PP(subject));
+               zend_hash_internal_pointer_reset(Z_ARRVAL_P(subject));
 
                /* For each subject entry, convert it to string, then perform replacement
                   and add the result to the return_value array. */
-               while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) {
-                       if (Z_TYPE_PP(subject_entry) != IS_ARRAY && Z_TYPE_PP(subject_entry) != IS_OBJECT) {
-                               MAKE_STD_ZVAL(result);
+               while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) {
+                       if (Z_TYPE_P(subject_entry) != IS_ARRAY && Z_TYPE_P(subject_entry) != IS_OBJECT) {
                                SEPARATE_ZVAL(subject_entry);
-                               php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity, (argc > 3) ? &count : NULL);
+                               php_str_replace_in_subject(search, replace, subject_entry, &result, case_sensitivity, (argc > 3) ? &count : NULL);
                        } else {
-                               ALLOC_ZVAL(result);
-                               Z_ADDREF_P(*subject_entry);
-                               COPY_PZVAL_TO_ZVAL(*result, *subject_entry);
+                               Z_ADDREF_P(subject_entry);
+                               COPY_PZVAL_TO_ZVAL(result, subject_entry);
                        }
                        /* Add to return array */
-                       switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key,
-                                                                                               &string_key_len, &num_key, 0, NULL)) {
+                       switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(subject), &string_key,
+                                                                                               &num_key, 0, NULL)) {
                                case HASH_KEY_IS_STRING:
-                                       add_assoc_zval_ex(return_value, string_key, string_key_len, result);
+//???
+                                       add_assoc_zval_ex(return_value, string_key->val, string_key->len, &result);
                                        break;
 
                                case HASH_KEY_IS_LONG:
-                                       add_index_zval(return_value, num_key, result);
+                                       add_index_zval(return_value, num_key, &result);
                                        break;
                        }
 
-                       zend_hash_move_forward(Z_ARRVAL_PP(subject));
+                       zend_hash_move_forward(Z_ARRVAL_P(subject));
                }
        } else {        /* if subject is not an array */
-               php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL);
+               php_str_replace_in_subject(search, replace, subject, return_value, case_sensitivity, (argc > 3) ? &count : NULL);
        }
        if (argc > 3) {
-               zval_dtor(*zcount);
-               ZVAL_LONG(*zcount, count);
+               zval_dtor(zcount);
+               ZVAL_LONG(zcount, count);
        }
 }
 /* }}} */
@@ -4200,9 +4188,8 @@ static void php_hebrev(INTERNAL_FUNCTION_PARAMETERS, int convert_newlines)
                php_char_to_str(broken_str, str_len,'\n', "<br />\n", 7, return_value);
                efree(broken_str);
        } else {
-               Z_STRVAL_P(return_value) = broken_str;
-               Z_STRLEN_P(return_value) = str_len;
-               Z_TYPE_P(return_value) = IS_STRING;
+//???          RETURN_STRINGL(broken_str, str_len, 0);
+               RETURN_STRINGL(broken_str, str_len);
        }
 }
 /* }}} */
@@ -4261,7 +4248,7 @@ PHP_FUNCTION(nl2br)
        }
 
        if (repl_cnt == 0) {
-               RETURN_STRINGL(str, str_len, 1);
+               RETURN_STRINGL(str, str_len);
        }
 
        {
@@ -4299,7 +4286,8 @@ PHP_FUNCTION(nl2br)
 
        *target = '\0';
 
-       RETURN_STRINGL(tmp, new_length, 0);
+//???  RETURN_STRINGL(tmp, new_length, 0);
+       RETURN_STRINGL(tmp, new_length);
 }
 /* }}} */
 
@@ -4309,26 +4297,27 @@ PHP_FUNCTION(strip_tags)
 {
        char *buf;
        char *str;
-       zval **allow=NULL;
+       zval *allow=NULL;
        char *allowed_tags=NULL;
        int allowed_tags_len=0;
        int str_len;
        size_t retval_len;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Z", &str, &str_len, &allow) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &str, &str_len, &allow) == FAILURE) {
                return;
        }
 
        /* To maintain a certain BC, we allow anything for the second parameter and return original string */
        if (allow != NULL) {
                convert_to_string_ex(allow);
-               allowed_tags = Z_STRVAL_PP(allow);
-               allowed_tags_len = Z_STRLEN_PP(allow);
+               allowed_tags = Z_STRVAL_P(allow);
+               allowed_tags_len = Z_STRLEN_P(allow);
        }
 
        buf = estrndup(str, str_len);
        retval_len = php_strip_tags_ex(buf, str_len, NULL, allowed_tags, allowed_tags_len, 0);
-       RETURN_STRINGL(buf, retval_len, 0);
+//???  RETURN_STRINGL(buf, retval_len, 0);
+       RETURN_STRINGL(buf, retval_len);
 }
 /* }}} */
 
@@ -4336,19 +4325,19 @@ PHP_FUNCTION(strip_tags)
    Set locale information */
 PHP_FUNCTION(setlocale)
 {
-       zval ***args = NULL;
-       zval **pcategory, **plocale;
+       zval *args = NULL;
+       zval *pcategory, *plocale;
        int num_args, cat, i = 0;
        char *loc, *retval;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z+", &pcategory, &args, &num_args) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z+", &pcategory, &args, &num_args) == FAILURE) {
                return;
        }
 
 #ifdef HAVE_SETLOCALE
-       if (Z_TYPE_PP(pcategory) == IS_LONG) {
+       if (Z_TYPE_P(pcategory) == IS_LONG) {
                convert_to_long_ex(pcategory);
-               cat = Z_LVAL_PP(pcategory);
+               cat = Z_LVAL_P(pcategory);
        } else {
                /* FIXME: The following behaviour should be removed. */
                char *category;
@@ -4356,7 +4345,7 @@ PHP_FUNCTION(setlocale)
                php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "Passing locale category name as string is deprecated. Use the LC_* -constants instead");
 
                convert_to_string_ex(pcategory);
-               category = Z_STRVAL_PP(pcategory);
+               category = Z_STRVAL_P(pcategory);
 
                if (!strcasecmp("LC_ALL", category)) {
                        cat = LC_ALL;
@@ -4384,27 +4373,27 @@ PHP_FUNCTION(setlocale)
                }
        }
 
-       if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
-               zend_hash_internal_pointer_reset(Z_ARRVAL_PP(args[0]));
+       if (Z_TYPE(args[0]) == IS_ARRAY) {
+               zend_hash_internal_pointer_reset(Z_ARRVAL(args[0]));
        }
 
        while (1) {
-               if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
-                       if (!zend_hash_num_elements(Z_ARRVAL_PP(args[0]))) {
+               if (Z_TYPE(args[0]) == IS_ARRAY) {
+                       if (!zend_hash_num_elements(Z_ARRVAL(args[0]))) {
                                break;
                        }
-                       zend_hash_get_current_data(Z_ARRVAL_PP(args[0]), (void **)&plocale);
+                       plocale = zend_hash_get_current_data(Z_ARRVAL(args[0]));
                } else {
-                       plocale = args[i];
+                       plocale = &args[i];
                }
 
                convert_to_string_ex(plocale);
 
-               if (!strcmp ("0", Z_STRVAL_PP(plocale))) {
+               if (!strcmp ("0", Z_STRVAL_P(plocale))) {
                        loc = NULL;
                } else {
-                       loc = Z_STRVAL_PP(plocale);
-                       if (Z_STRLEN_PP(plocale) >= 255) {
+                       loc = Z_STRVAL_P(plocale);
+                       if (Z_STRLEN_P(plocale) >= 255) {
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Specified locale name is too long");
                                break;
                        }
@@ -4415,18 +4404,18 @@ PHP_FUNCTION(setlocale)
                if (retval) {
                        /* Remember if locale was changed */
                        if (loc) {
-                               STR_FREE(BG(locale_string));
+//???                          STR_FREE(BG(locale_string));
                                BG(locale_string) = estrdup(retval);
                        }
 
                        if (args) {
                                efree(args);
                        }
-                       RETURN_STRING(retval, 1);
+                       RETURN_STRING(retval);
                }
 
-               if (Z_TYPE_PP(args[0]) == IS_ARRAY) {
-                       if (zend_hash_move_forward(Z_ARRVAL_PP(args[0])) == FAILURE) break;
+               if (Z_TYPE(args[0]) == IS_ARRAY) {
+                       if (zend_hash_move_forward(Z_ARRVAL(args[0])) == FAILURE) break;
                } else {
                        if (++i >= num_args) break;
                }
@@ -4461,7 +4450,7 @@ PHP_FUNCTION(parse_str)
                if (!EG(active_symbol_table)) {
                        zend_rebuild_symbol_table(TSRMLS_C);
                }
-               Z_ARRVAL(tmp) = EG(active_symbol_table);
+//???          Z_ARRVAL(tmp) = EG(active_symbol_table);
                sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
        } else  {
                zval ret;
@@ -4584,12 +4573,12 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, int len, int *stateptr, char *allow,
        rp = rbuf;
        br = 0;
        if (allow) {
-               if (IS_INTERNED(allow)) {
-                       allow_free = allow = zend_str_tolower_dup(allow, allow_len);
-               } else {
+//???          if (IS_INTERNED(allow)) {
+//???                  allow_free = allow = zend_str_tolower_dup(allow, allow_len);
+//???          } else {
                        allow_free = NULL;
                        php_strtolower(allow, allow_len);
-               }
+//???          }
                tbuf = emalloc(PHP_TAG_BUF_SIZE + 1);
                tp = tbuf;
        } else {
@@ -4910,7 +4899,8 @@ PHP_FUNCTION(str_repeat)
 
        result[result_len] = '\0';
 
-       RETURN_STRINGL(result, result_len, 0);
+//???  RETURN_STRINGL(result, result_len, 0);
+       RETURN_STRINGL(result, result_len);
 }
 /* }}} */
 
@@ -4977,7 +4967,7 @@ PHP_FUNCTION(count_chars)
        }
 
        if (mymode >= 3 && mymode <= 4) {
-               RETURN_STRINGL(retstr, retlen, 1);
+               RETURN_STRINGL(retstr, retlen);
        }
 }
 /* }}} */
@@ -5054,7 +5044,7 @@ PHP_FUNCTION(strnatcmp)
    Returns numeric formatting information based on the current locale */
 PHP_FUNCTION(localeconv)
 {
-       zval *grouping, *mon_grouping;
+       zval grouping, mon_grouping;
        int len, i;
 
        /* We don't need no stinkin' parameters... */
@@ -5062,12 +5052,9 @@ PHP_FUNCTION(localeconv)
                return;
        }
 
-       MAKE_STD_ZVAL(grouping);
-       MAKE_STD_ZVAL(mon_grouping);
-
        array_init(return_value);
-       array_init(grouping);
-       array_init(mon_grouping);
+       array_init(&grouping);
+       array_init(&mon_grouping);
 
 #ifdef HAVE_LOCALECONV
        {
@@ -5079,14 +5066,14 @@ PHP_FUNCTION(localeconv)
                len = strlen(currlocdata.grouping);
 
                for (i = 0; i < len; i++) {
-                       add_index_long(grouping, i, currlocdata.grouping[i]);
+                       add_index_long(&grouping, i, currlocdata.grouping[i]);
                }
 
                /* Grab the monetary grouping data out of the array */
                len = strlen(currlocdata.mon_grouping);
 
                for (i = 0; i < len; i++) {
-                       add_index_long(mon_grouping, i, currlocdata.mon_grouping[i]);
+                       add_index_long(&mon_grouping, i, currlocdata.mon_grouping[i]);
                }
 
                add_assoc_string(return_value, "decimal_point",     currlocdata.decimal_point,     1);
@@ -5110,8 +5097,8 @@ PHP_FUNCTION(localeconv)
        /* Ok, it doesn't look like we have locale info floating around, so I guess it
           wouldn't hurt to just go ahead and return the POSIX locale information?  */
 
-       add_index_long(grouping, 0, -1);
-       add_index_long(mon_grouping, 0, -1);
+       add_index_long(&grouping, 0, -1);
+       add_index_long(&mon_grouping, 0, -1);
 
        add_assoc_string(return_value, "decimal_point",     "\x2E", 1);
        add_assoc_string(return_value, "thousands_sep",     "",     1);
@@ -5131,8 +5118,8 @@ PHP_FUNCTION(localeconv)
        add_assoc_long(  return_value, "n_sign_posn",       CHAR_MAX );
 #endif
 
-       zend_hash_update(Z_ARRVAL_P(return_value), "grouping", 9, &grouping, sizeof(zval *), NULL);
-       zend_hash_update(Z_ARRVAL_P(return_value), "mon_grouping", 13, &mon_grouping, sizeof(zval *), NULL);
+       zend_hash_str_update(Z_ARRVAL_P(return_value), "grouping", sizeof("grouping")-1, &grouping);
+       zend_hash_str_update(Z_ARRVAL_P(return_value), "mon_grouping", sizeof("mon_grouping")-1, &mon_grouping);
 }
 /* }}} */
 
@@ -5199,7 +5186,7 @@ PHP_FUNCTION(substr_count)
                        p++;
                }
        } else {
-               while ((p = php_memnstr(p, needle, needle_len, endp))) {
+               while ((p = (char*)php_memnstr(p, needle, needle_len, endp))) {
                        p += needle_len;
                        count++;
                }
@@ -5235,7 +5222,7 @@ PHP_FUNCTION(str_pad)
        /* If resulting string turns out to be shorter than input string,
           we simply copy the input and return. */
        if (pad_length <= 0 || (pad_length - input_len) <= 0) {
-               RETURN_STRINGL(input, input_len, 1);
+               RETURN_STRINGL(input, input_len);
        }
 
        if (pad_str_len == 0) {
@@ -5287,7 +5274,8 @@ PHP_FUNCTION(str_pad)
 
        result[result_len] = '\0';
 
-       RETURN_STRINGL(result, result_len, 0);
+//???  RETURN_STRINGL(result, result_len, 0);
+       RETURN_STRINGL(result, result_len);
 }
 /* }}} */
 
@@ -5330,7 +5318,7 @@ PHP_FUNCTION(str_rot13)
                return;
        }
 
-       RETVAL_STRINGL(arg, arglen, 1);
+       RETVAL_STRINGL(arg, arglen);
 
        php_strtr(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), rot13_from, rot13_to, 52);
 }
@@ -5373,7 +5361,7 @@ PHP_FUNCTION(str_shuffle)
                return;
        }
 
-       RETVAL_STRINGL(arg, arglen, 1);
+       RETVAL_STRINGL(arg, arglen);
        if (Z_STRLEN_P(return_value) > 1) {
                php_string_shuffle(Z_STRVAL_P(return_value), (long) Z_STRLEN_P(return_value) TSRMLS_CC);
        }
@@ -5503,7 +5491,8 @@ PHP_FUNCTION(money_format)
        }
        str[str_len] = 0;
 
-       RETURN_STRINGL(erealloc(str, str_len + 1), str_len, 0);
+//???  RETURN_STRINGL(erealloc(str, str_len + 1), str_len, 0);
+       RETURN_STRINGL(erealloc(str, str_len + 1), str_len);
 }
 /* }}} */
 #endif
@@ -5568,7 +5557,7 @@ PHP_FUNCTION(strpbrk)
        for (haystack_ptr = haystack; haystack_ptr < (haystack + haystack_len); ++haystack_ptr) {
                for (cl_ptr = char_list; cl_ptr < (char_list + char_list_len); ++cl_ptr) {
                        if (*cl_ptr == *haystack_ptr) {
-                               RETURN_STRINGL(haystack_ptr, (haystack + haystack_len - haystack_ptr), 1);
+                               RETURN_STRINGL(haystack_ptr, (haystack + haystack_len - haystack_ptr));
                        }
                }
        }