]> granicus.if.org Git - php/commitdiff
Make array_walk(_recursive) use params API with FCI cache and mark them
authorAndrei Zmievski <andrei@php.net>
Thu, 20 Jul 2006 23:21:32 +0000 (23:21 +0000)
committerAndrei Zmievski <andrei@php.net>
Thu, 20 Jul 2006 23:21:32 +0000 (23:21 +0000)
with U.

ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/basic_functions.h
unicode-progress.txt

index bb2f46f6f8bd8c02cbeb1e0abc8db3b33b08429e..72f8b30c83488212b207f856f032ec0cdb8636e1 100644 (file)
@@ -1025,13 +1025,12 @@ 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,                  /* Return value - unused */
-                 *key=NULL;                            /* Entry key */
+                 *retval_ptr,          /* Return value - unused */
+                 *key=NULL;            /* Entry key */
        zstr string_key;
        uint   string_key_len;
        ulong  num_key;
        HashPosition pos;
-       zend_fcall_info_cache array_walk_fci_cache = empty_fcall_info_cache;
 
        /* Set up known arguments */
        args[1] = &key;
@@ -1039,10 +1038,17 @@ static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive
 
        zend_hash_internal_pointer_reset_ex(target_hash, &pos);
 
+       BG(array_walk_fci).retval_ptr_ptr = &retval_ptr;
+       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 */
        while (!EG(exception) && zend_hash_get_current_data_ex(target_hash, (void **)&args[0], &pos) == SUCCESS) {
                if (recursive && Z_TYPE_PP(args[0]) == IS_ARRAY) {
                        HashTable *thash;
+                       zend_fcall_info orig_array_walk_fci;
+                       zend_fcall_info_cache orig_array_walk_fci_cache;
 
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(args[0]);
                        thash = HASH_OF(*(args[0]));
@@ -1050,10 +1056,17 @@ static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive
                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
                                return 0;
                        }
+
+                       /* backup the fcall info and cache */
+                       orig_array_walk_fci = BG(array_walk_fci);
+                       orig_array_walk_fci_cache = BG(array_walk_fci_cache);
+
                        php_array_walk(thash, userdata, recursive TSRMLS_CC);
-               } else {
-                       zend_fcall_info fci;
 
+                       /* restore the fcall info and cache */
+                       BG(array_walk_fci) = orig_array_walk_fci;
+                       BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
+               } else {
                        /* Allocate space for key */
                        MAKE_STD_ZVAL(key);
 
@@ -1071,29 +1084,14 @@ static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive
                                        break;
                        }
 
-                       fci.size = sizeof(fci);
-                       fci.function_table = EG(function_table);
-                       fci.function_name = *BG(array_walk_func_name);
-                       fci.symbol_table = NULL;
-                       fci.object_pp = NULL;
-                       fci.retval_ptr_ptr = &retval_ptr;
-                       fci.param_count = userdata ? 3 : 2;
-                       fci.params = args;
-                       fci.no_separation = 0;
-
                        /* Call the userland function */
-                       if (zend_call_function(&fci, &array_walk_fci_cache TSRMLS_CC) == SUCCESS) {
+                       if (zend_call_function(&BG(array_walk_fci), &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) {
                                if (retval_ptr) {
                                        zval_ptr_dtor(&retval_ptr);
                                }
                        } else {
                                zval func_name;
 
-                               if (zend_is_callable(*BG(array_walk_func_name), 0, &func_name)) {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R()", Z_TYPE(func_name), Z_UNIVAL(func_name));
-                               } else {
-                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %R() - function does not exist", Z_TYPE(func_name), Z_UNIVAL(func_name));
-                               }
                                if (key) {
                                        zval_ptr_dtor(&key);
                                        key = NULL;
@@ -1113,75 +1111,54 @@ static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive
        return 0;
 }
 
-/* {{{ proto bool array_walk(array input, string funcname [, mixed userdata])
+/* {{{ proto bool array_walk(array input, mixed callback [, mixed userdata]) U
    Apply a user function to every member of an array */
 PHP_FUNCTION(array_walk)
 {
-       int     argc;
-       zval **array,
-                **userdata = NULL,
-                **old_walk_func_name;
-       HashTable *target_hash;
-
-       argc = ZEND_NUM_ARGS();
-       old_walk_func_name = BG(array_walk_func_name);
-       if (argc < 2 || argc > 3 ||
-               zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) {
-               BG(array_walk_func_name) = old_walk_func_name;
-               WRONG_PARAM_COUNT;
-       }
-       target_hash = HASH_OF(*array);
-       if (!target_hash) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");
-               BG(array_walk_func_name) = old_walk_func_name;
-               RETURN_FALSE;
-       }
-       if (Z_TYPE_PP(BG(array_walk_func_name)) != IS_ARRAY && 
-               Z_TYPE_PP(BG(array_walk_func_name)) != IS_STRING &&
-               Z_TYPE_PP(BG(array_walk_func_name)) != IS_UNICODE) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong syntax for function name");
-               BG(array_walk_func_name) = old_walk_func_name;
-               RETURN_FALSE;
+       zval *array,
+                **userdata = NULL;
+       zend_fcall_info orig_array_walk_fci;
+       zend_fcall_info_cache orig_array_walk_fci_cache;
+
+       orig_array_walk_fci = BG(array_walk_fci);
+       orig_array_walk_fci_cache = BG(array_walk_fci_cache);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_DC, "af|Z", &array,
+                                                         &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
+               BG(array_walk_fci) = orig_array_walk_fci;
+               BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
+               return;
        }
-       php_array_walk(target_hash, userdata, 0 TSRMLS_CC);
-       BG(array_walk_func_name) = old_walk_func_name;
+
+       php_array_walk(HASH_OF(array), userdata, 0 TSRMLS_CC);
+       BG(array_walk_fci) = orig_array_walk_fci;
+       BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
        RETURN_TRUE;
 }
 /* }}} */
 
-/* {{{ proto bool array_walk_recursive(array input, string funcname [, mixed userdata])
+/* {{{ proto bool array_walk_recursive(array input, mixed callback [, mixed userdata]) U
    Apply a user function recursively to every member of an array */
 PHP_FUNCTION(array_walk_recursive)
 {
-       int     argc;
-       zval **array,
-                **userdata = NULL,
-                **old_walk_func_name;
-       HashTable *target_hash;
-
-       argc = ZEND_NUM_ARGS();
-       old_walk_func_name = BG(array_walk_func_name);
-
-       if (argc < 2 || argc > 3 ||
-               zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) {
-               BG(array_walk_func_name) = old_walk_func_name;
-               WRONG_PARAM_COUNT;
-       }
-       target_hash = HASH_OF(*array);
-       if (!target_hash) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");
-               BG(array_walk_func_name) = old_walk_func_name;
-               RETURN_FALSE;
-       }
-       if (Z_TYPE_PP(BG(array_walk_func_name)) != IS_ARRAY &&
-           Z_TYPE_PP(BG(array_walk_func_name)) != IS_STRING &&
-           Z_TYPE_PP(BG(array_walk_func_name)) != IS_UNICODE) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Wrong syntax for function name");
-               BG(array_walk_func_name) = old_walk_func_name;
-               RETURN_FALSE;
+       zval *array,
+                **userdata = NULL;
+       zend_fcall_info orig_array_walk_fci;
+       zend_fcall_info_cache orig_array_walk_fci_cache;
+
+       orig_array_walk_fci = BG(array_walk_fci);
+       orig_array_walk_fci_cache = BG(array_walk_fci_cache);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_DC, "af|Z", &array,
+                                                         &BG(array_walk_fci), &BG(array_walk_fci_cache), &userdata) == FAILURE) {
+               BG(array_walk_fci) = orig_array_walk_fci;
+               BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
+               return;
        }
-       php_array_walk(target_hash, userdata, 1 TSRMLS_CC);
-       BG(array_walk_func_name) = old_walk_func_name;
+
+       php_array_walk(HASH_OF(array), userdata, 1 TSRMLS_CC);
+       BG(array_walk_fci) = orig_array_walk_fci;
+       BG(array_walk_fci_cache) = orig_array_walk_fci_cache;
        RETURN_TRUE;
 }
 /* }}} */
@@ -3332,6 +3309,7 @@ PHP_FUNCTION(array_uintersect_uassoc)
 /* }}} */
 
 
+/* {{{ php_array_diff */
 static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type)
 {
        zval ***args = NULL;
@@ -3634,6 +3612,7 @@ out:
        efree(lists);
        efree(args);
 }
+/* }}} */
 
 
 /* {{{ proto array array_diff_key(array arr1, array arr2 [, array ...]) U
index 7ec5d9ac5ec205a84a1da0ccd96ecbd4141f6cc3..fa0f8e23732566ebfe95ed096a76180e90e3bdb4 100644 (file)
@@ -3863,8 +3863,6 @@ static void basic_globals_ctor(php_basic_globals *basic_globals_p TSRMLS_DC)
        BG(left) = -1;
        BG(user_tick_functions) = NULL;
        BG(user_filter_map) = NULL;
-       BG(user_compare_fci) = empty_fcall_info;
-       BG(user_compare_fci_cache) = empty_fcall_info_cache;
        zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1);
        BG(sm_allowed_env_vars) = NULL;
 
@@ -4083,7 +4081,10 @@ PHP_RINIT_FUNCTION(basic)
        BG(strtok_zval) = NULL;
        BG(locale_string) = NULL;
        BG(user_compare_func_name) = NULL;
-       BG(array_walk_func_name) = NULL;
+       BG(array_walk_fci) = empty_fcall_info;
+       BG(array_walk_fci_cache) = empty_fcall_info_cache;
+       BG(user_compare_fci) = empty_fcall_info;
+       BG(user_compare_fci_cache) = empty_fcall_info_cache;
        BG(page_uid) = -1;
        BG(page_gid) = -1;
        BG(page_inode) = -1;
index 190c4b5aee6a6d472ee538c6d607528b33841191..418e25d93ba12580125932bca0f9b26187b78103 100644 (file)
@@ -164,7 +164,8 @@ typedef struct _php_basic_globals {
        char strtok_table[256];
        ulong strtok_len;
        char str_ebuf[40];
-       zval **array_walk_func_name;
+       zend_fcall_info array_walk_fci;
+       zend_fcall_info_cache array_walk_fci_cache;
        zval **user_compare_func_name;
        zend_fcall_info user_compare_fci;
        zend_fcall_info_cache user_compare_fci_cache;
index 996eac71548073e4404115910654e0d934ed4794..f5fa28105ade6b8c5fae4a0d6e91e1890fb9caa7 100644 (file)
@@ -11,7 +11,8 @@ ext/standard
     directly in code point order
 
     array_intersect(), array_uintersect()
-    array_intersect_assoc(), array_uintersect_assoc(), array_intersect_uassoc(), array_uintersect_uassoc()
+    array_intersect_assoc(), array_uintersect_assoc()
+    array_intersect_uassoc(), array_uintersect_uassoc()
     array_intersect_key(), array_intersect_ukey()
         Should work with minor cleanups provided that underlying comparison
         functions are fixed, FCI cache, test
@@ -19,12 +20,6 @@ ext/standard
     array_multisort()
         Add SORT_LOCALE_STRING, test
 
-    array_walk()
-        Params API, is_callable check, FCI cache, test
-
-    array_walk_recursive()
-        Params API, is_callable check, FCI cache, test
-
     extract()
         Params API, fix php_valid_var_name(), test
 
@@ -62,6 +57,8 @@ ext/standard
     array_sum()
     array_values()
     array_unique()
+    array_walk()
+    array_walk_recursive()
     compact()
     count()
     in_array()