cvs: php-src /ext/standard array.c basic_functions.c basic_functions.h

From: Date: Wed, 15 Jun 2005 20:51:37 +0000
Subject: cvs: php-src /ext/standard array.c basic_functions.c basic_functions.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-32300@lists.php.net to get a copy of this message
andrei Wed Jun 15 16:51:37 2005 EDT Modified files: /php-src/ext/standard basic_functions.c basic_functions.h array.c Log: Fix FCI cache for array_walk and user array compare functions. Bug #33286. (Patch from m.bretz@metropolis-ag.de)

http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.719&r2=1.720&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.719 php-src/ext/standard/basic_functions.c:1.720 --- php-src/ext/standard/basic_functions.c:1.719 Tue Jun 14 17:32:27 2005 +++ php-src/ext/standard/basic_functions.c Wed Jun 15 16:51:31 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.719 2005/06/14 21:32:27 derick Exp $ */ +/* $Id: basic_functions.c,v 1.720 2005/06/15 20:51:31 andrei Exp $ */ #include "php.h" #include "php_streams.h" @@ -955,7 +955,6 @@ BG(user_tick_functions) = NULL; BG(user_filter_map) = NULL; BG(user_compare_fci_cache) = empty_fcall_info_cache; - /*BG(array_walk_fci_cache) = empty_fcall_info_cache;*/ zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1); BG(sm_allowed_env_vars) = NULL; http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.h?r1=1.137&r2=1.138&ty=u Index: php-src/ext/standard/basic_functions.h diff -u php-src/ext/standard/basic_functions.h:1.137 php-src/ext/standard/basic_functions.h:1.138 --- php-src/ext/standard/basic_functions.h:1.137 Sun Apr 10 12:25:11 2005 +++ php-src/ext/standard/basic_functions.h Wed Jun 15 16:51:33 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.137 2005/04/10 16:25:11 iliaa Exp $ */ +/* $Id: basic_functions.h,v 1.138 2005/06/15 20:51:33 andrei Exp $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -160,7 +160,6 @@ ulong strtok_len; char str_ebuf[40]; zval **array_walk_func_name; - zend_fcall_info_cache array_walk_fci_cache; zval **user_compare_func_name; zend_fcall_info_cache user_compare_fci_cache; zend_llist *user_tick_functions; http://cvs.php.net/diff.php/php-src/ext/standard/array.c?r1=1.300&r2=1.301&ty=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.300 php-src/ext/standard/array.c:1.301 --- php-src/ext/standard/array.c:1.300 Wed Jun 8 15:54:24 2005 +++ php-src/ext/standard/array.c Wed Jun 15 16:51:33 2005 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.300 2005/06/08 19:54:24 dmitry Exp $ */ +/* $Id: array.c,v 1.301 2005/06/15 20:51:33 andrei Exp $ */ #include "php.h" #include "php_ini.h" @@ -610,43 +610,66 @@ } } -/* check is comparison function is valid */ +/* check if comparison function is valid */ #define PHP_ARRAY_CMP_FUNC_CHECK(func_name) \ if (!zend_is_callable(*func_name, 0, NULL)) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid comparison function."); \ + BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ BG(user_compare_func_name) = old_compare_func; \ RETURN_FALSE; \ } \ + /* clear FCI cache otherwise : for example the same or other array with + (partly) the same key values has been sorted with uasort() or + other sorting function the comparison is cached, however the the name + of the function for comparison is not respected. see bug #28739 AND #33295 + + following defines will assist in backup / restore values. + */ + +#define PHP_ARRAY_CMP_FUNC_VARS \ + zval **old_compare_func; \ + zend_fcall_info_cache old_user_compare_fci_cache; \ + +#define PHP_ARRAY_CMP_FUNC_BACKUP() \ + old_compare_func = BG(user_compare_func_name); \ + old_user_compare_fci_cache = BG(user_compare_fci_cache); \ + BG(user_compare_fci_cache) = empty_fcall_info_cache; \ + +#define PHP_ARRAY_CMP_FUNC_RESTORE() \ + BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ + BG(user_compare_func_name) = old_compare_func; \ + + /* {{{ proto bool usort(array array_arg, string cmp_function) Sort an array by values using a user-defined comparison function */ PHP_FUNCTION(usort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); - BG(user_compare_fci_cache) = empty_fcall_info_cache; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); 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(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 1 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_TRUE; } /* }}} */ @@ -656,29 +679,30 @@ PHP_FUNCTION(uasort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); - BG(user_compare_fci_cache) = empty_fcall_info_cache; if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); 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(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 0 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_TRUE; } /* }}} */ @@ -735,28 +759,33 @@ PHP_FUNCTION(uksort) { zval **array; - zval **old_compare_func; HashTable *target_hash; + PHP_ARRAY_CMP_FUNC_VARS; + + + PHP_ARRAY_CMP_FUNC_BACKUP(); - old_compare_func = BG(user_compare_func_name); if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &array, &BG(user_compare_func_name)) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); 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(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_FALSE; } PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name)) if (zend_hash_sort(target_hash, zend_qsort, array_user_key_compare, 0 TSRMLS_CC) == FAILURE) { - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_FALSE; } - BG(user_compare_func_name) = old_compare_func; + + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_TRUE; } /* }}} */ @@ -1030,6 +1059,7 @@ 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; @@ -1073,7 +1103,7 @@ fci.no_separation = 0; /* Call the userland function */ - if (zend_call_function(&fci, &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) { + if (zend_call_function(&fci, &array_walk_fci_cache TSRMLS_CC) == SUCCESS) { if (retval_ptr) { zval_ptr_dtor(&retval_ptr); } @@ -1115,7 +1145,6 @@ HashTable *target_hash; argc = ZEND_NUM_ARGS(); - BG(array_walk_fci_cache) = empty_fcall_info_cache; 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) { @@ -1152,7 +1181,6 @@ argc = ZEND_NUM_ARGS(); old_walk_func_name = BG(array_walk_func_name); - BG(array_walk_fci_cache) = empty_fcall_info_cache; if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &array, &BG(array_walk_func_name), &userdata) == FAILURE) { @@ -2830,7 +2858,8 @@ Bucket ***lists, **list, ***ptrs, *p; char *callback_name; - zval **old_compare_func; + PHP_ARRAY_CMP_FUNC_VARS; + int (*intersect_key_compare_func)(const void *, const void * TSRMLS_DC); int (*intersect_data_compare_func)(const void *, const void * TSRMLS_DC); @@ -2844,13 +2873,7 @@ WRONG_PARAM_COUNT; } - old_compare_func = BG(user_compare_func_name); - /* clear FCI cache otherwise : for example the same or other array with - (partly) the same key values has been sorted with uasort() or - other sorting function the comparison is cached, however the the name - of the function for comparison is not respected. see bug #28739 - */ - BG(user_compare_fci_cache) = empty_fcall_info_cache; + PHP_ARRAY_CMP_FUNC_BACKUP(); if (behavior == INTERSECT_NORMAL) { intersect_key_compare_func = array_key_compare; @@ -3121,7 +3144,8 @@ pefree(lists[i], hash->persistent); } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + efree(ptrs); efree(lists); @@ -3210,7 +3234,8 @@ Bucket ***lists, **list, ***ptrs, *p; char *callback_name; - zval **old_compare_func; + PHP_ARRAY_CMP_FUNC_VARS; + int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC); int (*diff_data_compare_func)(const void *, const void * TSRMLS_DC); @@ -3224,13 +3249,7 @@ WRONG_PARAM_COUNT; } - old_compare_func = BG(user_compare_func_name); - /* clear FCI cache otherwise : for example the same or other array with - (partly) the same key values has been sorted with uasort() or - other sorting function the comparison is cached, however the the name - of the function for comparison is not respected. see bug #28739 - */ - BG(user_compare_fci_cache) = empty_fcall_info_cache; + PHP_ARRAY_CMP_FUNC_BACKUP(); if (behavior == DIFF_NORMAL) { diff_key_compare_func = array_key_compare; @@ -3499,7 +3518,8 @@ pefree(lists[i], hash->persistent); } - BG(user_compare_func_name) = old_compare_func; + PHP_ARRAY_CMP_FUNC_RESTORE(); + efree(ptrs); efree(lists);
« previous php.cvs (#32300) next »