summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-09-10 02:51:23 +0300
committerDmitry Stogov <dmitry@zend.com>2015-09-10 02:51:23 +0300
commitc174e4cd73cd16ce0b52ab66a90e97c476a444fe (patch)
treee844a3d8bbc5c58960e5859eaf2d5495fc991983
parent2ea18cd43165f791a5b0170795a790d2c0198ec8 (diff)
downloadphp-git-c174e4cd73cd16ce0b52ab66a90e97c476a444fe.tar.gz
Change array sorting implementation to avoid two level callbacks system.
Simplify zval comparion API.
-rw-r--r--Zend/zend_operators.c65
-rw-r--r--Zend/zend_operators.h18
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h54
-rw-r--r--ext/intl/collator/collator_sort.c5
-rw-r--r--ext/standard/array.c763
-rw-r--r--ext/standard/php_array.h3
-rw-r--r--sapi/phpdbg/phpdbg_wait.c10
8 files changed, 654 insertions, 270 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 1ed54aa32b..426a85ffe8 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1662,92 +1662,88 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
}
/* }}} */
-ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */
{
zend_string *str1 = zval_get_string(op1);
zend_string *str2 = zval_get_string(op2);
+ int ret;
if (case_insensitive) {
- ZVAL_LONG(result, zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)));
+ ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
} else {
- ZVAL_LONG(result, zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)));
+ ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
}
zend_string_release(str1);
zend_string_release(str2);
- return SUCCESS;
+ return ret;
}
/* }}} */
-ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
if (Z_STR_P(op1) == Z_STR_P(op2)) {
- ZVAL_LONG(result, 0);
+ return 0;
} else {
- ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
+ return zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
}
} else {
zend_string *str1 = zval_get_string(op1);
zend_string *str2 = zval_get_string(op2);
-
- ZVAL_LONG(result, zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2)));
+ int ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
zend_string_release(str1);
zend_string_release(str2);
+ return ret;
}
- return SUCCESS;
}
/* }}} */
-ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
if (Z_STR_P(op1) == Z_STR_P(op2)) {
- ZVAL_LONG(result, 0);
+ return 0;
} else {
- ZVAL_LONG(result, zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
+ return zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
}
} else {
zend_string *str1 = zval_get_string(op1);
zend_string *str2 = zval_get_string(op2);
-
- ZVAL_LONG(result, zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1)));
+ int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
zend_string_release(str1);
zend_string_release(str2);
+ return ret;
}
- return SUCCESS;
}
/* }}} */
#if HAVE_STRCOLL
-ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */
{
zend_string *str1 = zval_get_string(op1);
zend_string *str2 = zval_get_string(op2);
-
- ZVAL_LONG(result, strcoll(ZSTR_VAL(str1), ZSTR_VAL(str2)));
+ int ret = strcoll(ZSTR_VAL(str1), ZSTR_VAL(str2));
zend_string_release(str1);
zend_string_release(str2);
- return SUCCESS;
+ return ret;
}
/* }}} */
#endif
-ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{ */
{
double d1, d2;
d1 = zval_get_double(op1);
d2 = zval_get_double(op2);
- ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(d1 - d2));
-
- return SUCCESS;
+ return ZEND_NORMALIZE_BOOL(d1 - d2);
}
/* }}} */
@@ -1763,7 +1759,7 @@ static inline void zend_free_obj_get_result(zval *op) /* {{{ */
}
/* }}} */
-static int ZEND_FASTCALL convert_compare_result_to_long(zval *result)
+static void ZEND_FASTCALL convert_compare_result_to_long(zval *result)
{
if (Z_TYPE_P(result) == IS_DOUBLE) {
ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
@@ -1829,7 +1825,7 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
ZVAL_LONG(result, 0);
return SUCCESS;
}
- ZVAL_LONG(result, zendi_smart_strcmp(op1, op2));
+ ZVAL_LONG(result, zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)));
return SUCCESS;
case TYPE_PAIR(IS_NULL, IS_STRING):
@@ -1962,15 +1958,6 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
}
/* }}} */
-ZEND_API int zval_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
-{
- int ret = compare_function(result, op1, op2);
-
- ZEND_ASSERT(Z_TYPE_P(result) == IS_LONG);
- return ret;
-}
-/* }}} */
-
static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
{
zval result;
@@ -2644,15 +2631,15 @@ ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval
}
/* }}} */
-ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2) /* {{{ */
+ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
{
int ret1, ret2;
int oflow1, oflow2;
zend_long lval1 = 0, lval2 = 0;
double dval1 = 0.0, dval2 = 0.0;
- if ((ret1 = is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
- (ret2 = is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
+ if ((ret1 = is_numeric_string_ex(s1->val, s1->len, &lval1, &dval1, 0, &oflow1)) &&
+ (ret2 = is_numeric_string_ex(s2->val, s2->len, &lval2, &dval2, 0, &oflow2))) {
#if ZEND_ULONG_MAX == 0xFFFFFFFF
if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
@@ -2689,7 +2676,7 @@ ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2) /* {{{ *
} else {
int strcmp_ret;
string_cmp:
- strcmp_ret = zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
+ strcmp_ret = zend_binary_strcmp(s1->val, s1->len, s2->val, s2->len);
return ZEND_NORMALIZE_BOOL(strcmp_ret);
}
}
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index f9a299bd01..7cb3ee1b8a 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -329,13 +329,13 @@ again:
}
ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2);
-ZEND_API int zval_compare_function(zval *result, zval *op1, zval *op2);
-ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2);
-ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive);
-ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2);
-ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2);
+
+ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2);
+ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend_bool case_insensitive);
+ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2);
+ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2);
#if HAVE_STRCOLL
-ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2);
+ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2);
#endif
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length);
@@ -355,7 +355,7 @@ ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1,
ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
-ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2);
+ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2);
ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2);
ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2);
ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2);
@@ -692,7 +692,7 @@ static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
}
} else {
- return zendi_smart_strcmp(op1, op2) == 0;
+ return zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0;
}
}
}
@@ -723,7 +723,7 @@ static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
}
} else {
- return zendi_smart_strcmp(op1, op2) == 0;
+ return zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0;
}
}
compare_function(&result, op1, op2);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 193ea32c62..faff4a1978 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -380,7 +380,7 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
FREE_OP1();
FREE_OP2();
@@ -448,7 +448,7 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
FREE_OP1();
FREE_OP2();
@@ -4832,7 +4832,7 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
FREE_OP2();
} else {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 2889de55f2..717b670176 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4635,7 +4635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
@@ -4703,7 +4703,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
@@ -5805,7 +5805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -8572,7 +8572,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
@@ -8640,7 +8640,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HAN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
@@ -9567,7 +9567,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -10377,7 +10377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op2);
@@ -10445,7 +10445,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
zval_ptr_dtor_nogc(free_op2);
@@ -11326,7 +11326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -29972,7 +29972,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
@@ -30040,7 +30040,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
@@ -31820,7 +31820,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -35168,7 +35168,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
@@ -35236,7 +35236,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
@@ -36849,7 +36849,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -37805,7 +37805,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op2);
@@ -37873,7 +37873,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
zval_ptr_dtor_nogc(free_op2);
@@ -39407,7 +39407,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op2);
} else {
@@ -40811,7 +40811,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HAN
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -40879,7 +40879,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -41635,7 +41635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -43151,7 +43151,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -43219,7 +43219,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HA
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
zval_ptr_dtor_nogc(free_op1);
@@ -43749,7 +43749,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
} else {
@@ -44288,7 +44288,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HA
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -44356,7 +44356,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVA
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) != 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) != 0);
}
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
@@ -44888,7 +44888,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
result = (memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
}
} else {
- result = (zendi_smart_strcmp(op1, op2) == 0);
+ result = (zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)) == 0);
}
zval_ptr_dtor_nogc(free_op2);
} else {
diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c
index ca4b7ea785..68e9ccf537 100644
--- a/ext/intl/collator/collator_sort.c
+++ b/ext/intl/collator/collator_sort.c
@@ -144,7 +144,6 @@ static int collator_regular_compare_function(zval *result, zval *op1, zval *op2)
*/
static int collator_numeric_compare_function(zval *result, zval *op1, zval *op2)
{
- int rc = SUCCESS;
zval num1, num2;
zval *num1_p = NULL;
zval *num2_p = NULL;
@@ -161,14 +160,14 @@ static int collator_numeric_compare_function(zval *result, zval *op1, zval *op2)
op2 = num2_p;
}
- rc = numeric_compare_function( result, op1, op2);
+ ZVAL_LONG(result, numeric_compare_function(op1, op2));
if( num1_p )
zval_ptr_dtor( num1_p );
if( num2_p )
zval_ptr_dtor( num2_p );
- return rc;
+ return SUCCESS;
}
/* }}} */
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 1067b37e75..b1ee800bc2 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -141,70 +141,561 @@ PHP_MSHUTDOWN_FUNCTION(array) /* {{{ */
}
/* }}} */
-static void php_set_compare_func(zend_long sort_type) /* {{{ */
+static int php_array_key_compare(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ zend_uchar t;
+ zend_long l1, l2;
+ double d;
+
+ if (f->key == NULL) {
+ if (s->key == NULL) {
+ return (zend_long)f->h > (zend_long)s->h ? 1 : -1;
+ } else {
+ l1 = (zend_long)f->h;
+ t = is_numeric_string(s->key->val, s->key->len, &l2, &d, 1);
+ if (t == IS_LONG) {
+ /* pass */
+ } else if (t == IS_DOUBLE) {
+ return ZEND_NORMALIZE_BOOL((double)l1 - d);
+ } else {
+ l2 = 0;
+ }
+ }
+ } else if (f->key) {
+ if (s->key) {
+ return zendi_smart_strcmp(f->key, s->key);
+ } else {
+ l2 = (zend_long)s->h;
+ t = is_numeric_string(f->key->val, f->key->len, &l1, &d, 1);
+ if (t == IS_LONG) {
+ /* pass */
+ } else if (t == IS_DOUBLE) {
+ return ZEND_NORMALIZE_BOOL(d - (double)l2);
+ } else {
+ l1 = 0;
+ }
+ }
+ }
+ return l1 > l2 ? 1 : (l1 < l2 ? -1 : 0);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare(b, a);
+}
+/* }}} */
+
+static int php_array_key_compare_numeric(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+
+ if (f->key == NULL && s->key == NULL) {
+ return (zend_long)f->h > (zend_long)s->h ? 1 : -1;
+ } else {
+ double d1, d2;
+ if (f->key) {
+ d1 = zend_strtod(f->key->val, NULL);
+ } else {
+ d1 = (double)(zend_long)f->h;
+ }
+ if (s->key) {
+ d2 = zend_strtod(s->key->val, NULL);
+ } else {
+ d2 = (double)(zend_long)s->h;
+ }
+ return ZEND_NORMALIZE_BOOL(d1 - d2);
+ }
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_numeric(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_numeric(b, a);
+}
+/* }}} */
+
+static int php_array_key_compare_string_case(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ char *s1, *s2;
+ size_t l1, l2;
+ char buf1[MAX_LENGTH_OF_LONG + 1];
+ char buf2[MAX_LENGTH_OF_LONG + 1];
+
+ if (f->key) {
+ s1 = f->key->val;
+ l1 = f->key->len;
+ } else {
+ s1 = zend_print_long_to_buf(buf1 + sizeof(buf1) - 1, f->h);
+ l1 = buf1 + sizeof(buf1) - 1 - s1;
+ }
+ if (s->key) {
+ s2 = s->key->val;
+ l2 = s->key->len;
+ } else {
+ s2 = zend_print_long_to_buf(buf2 + sizeof(buf2) - 1, s->h);
+ l2 = buf2 + sizeof(buf2) - 1 - s1;
+ }
+ return zend_binary_strcasecmp_l(s1, l1, s2, l2);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_string_case(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_case(b, a);
+}
+/* }}} */
+
+static int php_array_key_compare_string(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ char *s1, *s2;
+ size_t l1, l2;
+ char buf1[MAX_LENGTH_OF_LONG + 1];
+ char buf2[MAX_LENGTH_OF_LONG + 1];
+
+ if (f->key) {
+ s1 = f->key->val;
+ l1 = f->key->len;
+ } else {
+ s1 = zend_print_long_to_buf(buf1 + sizeof(buf1) - 1, f->h);
+ l1 = buf1 + sizeof(buf1) - 1 - s1;
+ }
+ if (s->key) {
+ s2 = s->key->val;
+ l2 = s->key->len;
+ } else {
+ s2 = zend_print_long_to_buf(buf2 + sizeof(buf2) - 1, s->h);
+ l2 = buf2 + sizeof(buf2) - 1 - s1;
+ }
+ return zend_binary_strcmp(s1, l1, s2, l2);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_string(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string(b, a);
+}
+/* }}} */
+
+static int php_array_key_compare_string_natural_general(const void *a, const void *b, int fold_case) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ char *s1, *s2;
+ size_t l1, l2;
+ char buf1[MAX_LENGTH_OF_LONG + 1];
+ char buf2[MAX_LENGTH_OF_LONG + 1];
+
+ if (f->key) {
+ s1 = f->key->val;
+ l1 = f->key->len;
+ } else {
+ s1 = zend_print_long_to_buf(buf1 + sizeof(buf1) - 1, f->h);
+ l1 = buf1 + sizeof(buf1) - 1 - s1;
+ }
+ if (s->key) {
+ s2 = s->key->val;
+ l2 = s->key->len;
+ } else {
+ s2 = zend_print_long_to_buf(buf2 + sizeof(buf2) - 1, s->h);
+ l2 = buf2 + sizeof(buf2) - 1 - s1;
+ }
+ return strnatcmp_ex(s1, l1, s2, l2, fold_case);
+}
+/* }}} */
+
+static int php_array_key_compare_string_natural_case(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_natural_general(a, b, 1);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_string_natural_case(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_natural_general(b, a, 1);
+}
+/* }}} */
+
+static int php_array_key_compare_string_natural(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_natural_general(a, b, 0);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_string_natural(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_natural_general(b, a, 0);
+}
+/* }}} */
+
+#if HAVE_STRCOLL
+static int php_array_key_compare_string_locale(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ char *s1, *s2;
+ char buf1[MAX_LENGTH_OF_LONG + 1];
+ char buf2[MAX_LENGTH_OF_LONG + 1];
+
+ if (f->key) {
+ s1 = f->key->val;
+ } else {
+ s1 = zend_print_long_to_buf(buf1 + sizeof(buf1) - 1, f->h);
+ }
+ if (s->key) {
+ s2 = s->key->val;
+ } else {
+ s2 = zend_print_long_to_buf(buf2 + sizeof(buf2) - 1, s->h);
+ }
+ return strcoll(s1, s2);
+}
+/* }}} */
+
+static int php_array_reverse_key_compare_string_locale(const void *a, const void *b) /* {{{ */
+{
+ return php_array_key_compare_string_locale(b, a);
+}
+/* }}} */
+#endif
+
+/* Numbers are always smaller than strings int this function as it
+ * anyway doesn't make much sense to compare two different data types.
+ * This keeps it consistent and simple.
+ *
+ * This is not correct any more, depends on what compare_func is set to.
+ */
+static int php_array_data_compare(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f;
+ Bucket *s;
+ zval result;
+ zval *first;
+ zval *second;
+
+ f = (Bucket *) a;
+ s = (Bucket *) b;
+
+ first = &f->val;
+ second = &s->val;
+
+ if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
+ second = Z_INDIRECT_P(second);
+ }
+ if (compare_function(&result, first, second) == FAILURE) {
+ return 0;
+ }
+
+ ZEND_ASSERT(Z_TYPE(result) == IS_LONG);
+ return Z_LVAL(result);
+}
+/* }}} */
+
+static int php_array_reverse_data_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_data_compare(a, b) * -1;
+}
+/* }}} */
+
+static int php_array_data_compare_numeric(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f;
+ Bucket *s;
+ zval *first;
+ zval *second;
+
+ f = (Bucket *) a;
+ s = (Bucket *) b;
+
+ first = &f->val;
+ second = &s->val;
+
+ if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
+ second = Z_INDIRECT_P(second);
+ }
+
+ return numeric_compare_function(first, second);
+}
+/* }}} */
+
+static int php_array_reverse_data_compare_numeric(const void *a, const void *b) /* {{{ */
+{
+ return php_array_data_compare_numeric(b, a);
+}
+/* }}} */
+
+static int php_array_data_compare_string_case(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f;
+ Bucket *s;
+ zval *first;
+ zval *second;
+
+ f = (Bucket *) a;
+ s = (Bucket *) b;
+
+ first = &f->val;
+ second = &s->val;
+
+ if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
+ second = Z_INDIRECT_P(second);
+ }
+
+ return string_case_compare_function(first, second);
+}
+/* }}} */
+
+static int php_array_reverse_data_compare_string_case(const void *a, const void *b) /* {{{ */
+{
+ return php_array_data_compare_string_case(b, a);
+}
+/* }}} */
+
+static int php_array_data_compare_string(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f;
+ Bucket *s;
+ zval *first;
+ zval *second;
+
+ f = (Bucket *) a;
+ s = (Bucket *) b;
+
+ first = &f->val;
+ second = &s->val;
+
+ if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
+ second = Z_INDIRECT_P(second);
+ }
+
+ return string_compare_function(first, second);
+}
+/* }}} */
+
+static int php_array_reverse_data_compare_string(const void *a, const void *b) /* {{{ */
+{
+ return php_array_data_compare_string(b, a);
+}
+/* }}} */
+
+static int php_array_natural_general_compare(const void *a, const void *b, int fold_case) /* {{{ */
+{
+ Bucket *f = (Bucket *) a;
+ Bucket *s = (Bucket *) b;
+ zend_string *str1 = zval_get_string(&f->val);
+ zend_string *str2 = zval_get_string(&s->val);
+
+ int result = strnatcmp_ex(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2), fold_case);
+
+ zend_string_release(str1);
+ zend_string_release(str2);
+ return result;
+}
+/* }}} */
+
+static int php_array_natural_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_natural_general_compare(a, b, 0);
+}
+/* }}} */
+
+static int php_array_reverse_natural_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_natural_general_compare(b, a, 0);
+}
+/* }}} */
+
+static int php_array_natural_case_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_natural_general_compare(a, b, 1);
+}
+/* }}} */
+
+static int php_array_reverse_natural_case_compare(const void *a, const void *b) /* {{{ */
+{
+ return php_array_natural_general_compare(b, a, 1);
+}
+/* }}} */
+
+#if HAVE_STRCOLL
+static int php_array_data_compare_string_locale(const void *a, const void *b) /* {{{ */
+{
+ Bucket *f;
+ Bucket *s;
+ zval *first;
+ zval *second;
+
+ f = (Bucket *) a;
+ s = (Bucket *) b;
+
+ first = &f->val;
+ second = &s->val;
+
+ if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
+ second = Z_INDIRECT_P(second);
+ }
+
+ return string_locale_compare_function(first, second);
+}
+/* }}} */
+
+static int php_array_reverse_data_compare_string_locale(const void *a, const void *b) /* {{{ */
+{
+ return php_array_data_compare_string_locale(b, a);
+}
+/* }}} */
+#endif
+
+static compare_func_t php_get_key_compare_func(zend_long sort_type, int reverse) /* {{{ */
{
switch (sort_type & ~PHP_SORT_FLAG_CASE) {
case PHP_SORT_NUMERIC:
- ARRAYG(compare_func) = numeric_compare_function;
+ if (reverse) {
+ return php_array_reverse_key_compare_numeric;
+ } else {
+ return php_array_key_compare_numeric;
+ }
break;
case PHP_SORT_STRING:
- ARRAYG(compare_func) = sort_type & PHP_SORT_FLAG_CASE ? string_case_compare_function : string_compare_function;
+ if (sort_type & PHP_SORT_FLAG_CASE) {
+ if (reverse) {
+ return php_array_reverse_key_compare_string_case;
+ } else {
+ return php_array_key_compare_string_case;
+ }
+ } else {
+ if (reverse) {
+ return php_array_reverse_key_compare_string;
+ } else {
+ return php_array_key_compare_string;
+ }
+ }
break;
case PHP_SORT_NATURAL:
- ARRAYG(compare_func) = sort_type & PHP_SORT_FLAG_CASE ? string_natural_case_compare_function : string_natural_compare_function;
+ if (sort_type & PHP_SORT_FLAG_CASE) {
+ if (reverse) {
+ return php_array_reverse_key_compare_string_natural_case;
+ } else {
+ return php_array_key_compare_string_natural_case;
+ }
+ } else {
+ if (reverse) {
+ return php_array_reverse_key_compare_string_natural;
+ } else {
+ return php_array_key_compare_string_natural;
+ }
+ }
break;
#if HAVE_STRCOLL
case PHP_SORT_LOCALE_STRING:
- ARRAYG(compare_func) = string_locale_compare_function;
+ if (reverse) {
+ return php_array_reverse_key_compare_string_locale;
+ } else {
+ return php_array_key_compare_string_locale;
+ }
break;
#endif
case PHP_SORT_REGULAR:
default:
- ARRAYG(compare_func) = zval_compare_function;
+ if (reverse) {
+ return php_array_reverse_key_compare;
+ } else {
+ return php_array_key_compare;
+ }
break;
}
+ return NULL;
}
/* }}} */
-static int php_array_key_compare(const void *a, const void *b) /* {{{ */
+static compare_func_t php_get_data_compare_func(zend_long sort_type, int reverse) /* {{{ */
{
- Bucket *f;
- Bucket *s;
- zval result;
- zval first;
- zval second;
+ switch (sort_type & ~PHP_SORT_FLAG_CASE) {
+ case PHP_SORT_NUMERIC:
+ if (reverse) {
+ return php_array_reverse_data_compare_numeric;
+ } else {
+ return php_array_data_compare_numeric;
+ }
+ break;
- f = (Bucket *) a;
- s = (Bucket *) b;
+ case PHP_SORT_STRING:
+ if (sort_type & PHP_SORT_FLAG_CASE) {
+ if (reverse) {
+ return php_array_reverse_data_compare_string_case;
+ } else {
+ return php_array_data_compare_string_case;
+ }
+ } else {
+ if (reverse) {
+ return php_array_reverse_data_compare_string;
+ } else {
+ return php_array_data_compare_string;
+ }
+ }
+ break;
- if (f->key == NULL) {
- ZVAL_LONG(&first, f->h);
- } else {
- ZVAL_STR(&first, f->key);
- }
+ case PHP_SORT_NATURAL:
+ if (sort_type & PHP_SORT_FLAG_CASE) {
+ if (reverse) {
+ return php_array_reverse_natural_case_compare;
+ } else {
+ return php_array_natural_case_compare;
+ }
+ } else {
+ if (reverse) {
+ return php_array_reverse_natural_compare;
+ } else {
+ return php_array_natural_compare;
+ }
+ }
+ break;
- if (s->key == NULL) {
- ZVAL_LONG(&second, s->h);
- } else {
- ZVAL_STR(&second, s->key);
- }
+#if HAVE_STRCOLL
+ case PHP_SORT_LOCALE_STRING:
+ if (reverse) {
+ return php_array_reverse_data_compare_string_locale;
+ } else {
+ return php_array_data_compare_string_locale;
+ }
+ break;
+#endif
- if (ARRAYG(compare_func)(&result, &first, &second) == FAILURE) {
- return 0;
+ case PHP_SORT_REGULAR:
+ default:
+ if (reverse) {
+ return php_array_reverse_data_compare;
+ } else {
+ return php_array_data_compare;
+ }
+ break;
}
-
- ZEND_ASSERT(Z_TYPE(result) == IS_LONG);
- return ZEND_NORMALIZE_BOOL(Z_LVAL(result));
-}
-/* }}} */
-
-static int php_array_reverse_key_compare(const void *a, const void *b) /* {{{ */
-{
- return php_array_key_compare(a, b) * -1;
+ return NULL;
}
/* }}} */
@@ -214,6 +705,7 @@ PHP_FUNCTION(krsort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
@@ -227,9 +719,9 @@ PHP_FUNCTION(krsort)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
#endif
- php_set_compare_func(sort_type);
+ cmp = php_get_key_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_reverse_key_compare, 0) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -242,6 +734,7 @@ PHP_FUNCTION(ksort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
#ifndef FAST_ZPP
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
@@ -255,9 +748,9 @@ PHP_FUNCTION(ksort)
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
#endif
- php_set_compare_func(sort_type);
+ cmp = php_get_key_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_key_compare, 0) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -359,74 +852,6 @@ PHP_FUNCTION(count)
}
/* }}} */
-/* Numbers are always smaller than strings int this function as it
- * anyway doesn't make much sense to compare two different data types.
- * This keeps it consistent and simple.
- *
- * This is not correct any more, depends on what compare_func is set to.
- */
-static int php_array_data_compare(const void *a, const void *b) /* {{{ */
-{
- Bucket *f;
- Bucket *s;
- zval result;
- zval *first;
- zval *second;
-
- f = (Bucket *) a;
- s = (Bucket *) b;
-
- first = &f->val;
- second = &s->val;
-
- if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
- first = Z_INDIRECT_P(first);
- }
- if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
- second = Z_INDIRECT_P(second);
- }
- if (ARRAYG(compare_func)(&result, first, second) == FAILURE) {
- return 0;
- }
-
- ZEND_ASSERT(Z_TYPE(result) == IS_LONG);
- return ZEND_NORMALIZE_BOOL(Z_LVAL(result));
-}
-/* }}} */
-
-static int php_array_reverse_data_compare(const void *a, const void *b) /* {{{ */
-{
- return php_array_data_compare(a, b) * -1;
-}
-/* }}} */
-
-static int php_array_natural_general_compare(const void *a, const void *b, int fold_case) /* {{{ */
-{
- Bucket *f = (Bucket *) a;
- Bucket *s = (Bucket *) b;
- zend_string *str1 = zval_get_string(&f->val);
- zend_string *str2 = zval_get_string(&s->val);
-
- int result = strnatcmp_ex(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2), fold_case);
-
- zend_string_release(str1);
- zend_string_release(str2);
- return result;
-}
-/* }}} */
-
-static int php_array_natural_compare(const void *a, const void *b) /* {{{ */
-{
- return php_array_natural_general_compare(a, b, 0);
-}
-/* }}} */
-
-static int php_array_natural_case_compare(const void *a, const void *b) /* {{{ */
-{
- return php_array_natural_general_compare(a, b, 1);
-}
-/* }}} */
-
static void php_natsort(INTERNAL_FUNCTION_PARAMETERS, int fold_case) /* {{{ */
{
zval *array;
@@ -471,14 +896,15 @@ PHP_FUNCTION(asort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
- php_set_compare_func(sort_type);
+ cmp = php_get_data_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_data_compare, 0) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -491,14 +917,15 @@ PHP_FUNCTION(arsort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
- php_set_compare_func(sort_type);
+ cmp = php_get_data_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_reverse_data_compare, 0) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 0) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -511,14 +938,15 @@ PHP_FUNCTION(sort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
- php_set_compare_func(sort_type);
+ cmp = php_get_data_compare_func(sort_type, 0);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_data_compare, 1) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 1) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -531,14 +959,15 @@ PHP_FUNCTION(rsort)
{
zval *array;
zend_long sort_type = PHP_SORT_REGULAR;
+ compare_func_t cmp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &array, &sort_type) == FAILURE) {
RETURN_FALSE;
}
- php_set_compare_func(sort_type);
+ cmp = php_get_data_compare_func(sort_type, 1);
- if (zend_hash_sort(Z_ARRVAL_P(array), php_array_reverse_data_compare, 1) == FAILURE) {
+ if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 1) == FAILURE) {
RETURN_FALSE;
}
RETURN_TRUE;
@@ -909,8 +1338,6 @@ PHP_FUNCTION(min)
return;
}
- php_set_compare_func(PHP_SORT_REGULAR);
-
/* mixed min ( array $values ) */
if (argc == 1) {
zval *result;
@@ -958,8 +1385,6 @@ PHP_FUNCTION(max)
return;
}
- php_set_compare_func(PHP_SORT_REGULAR);
-
/* mixed max ( array $values ) */
if (argc == 1) {
zval *result;
@@ -3274,12 +3699,13 @@ PHP_FUNCTION(array_unique)
struct bucketindex *arTmp, *cmpdata, *lastkept;
unsigned int i;
zend_long sort_type = PHP_SORT_STRING;
+ compare_func_t cmp;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|l", &array, &sort_type) == FAILURE) {
return;
}
- php_set_compare_func(sort_type);
+ cmp = php_get_data_compare_func(sort_type, 0);
if (Z_ARRVAL_P(array)->nNumOfElements <= 1) { /* nothing to do */
@@ -3305,11 +3731,11 @@ PHP_FUNCTION(array_unique)
}
ZVAL_UNDEF(&arTmp[i].b.val);
zend_sort((void *) arTmp, i, sizeof(struct bucketindex),
- php_array_data_compare, (swap_func_t)array_bucketindex_swap);
+ cmp, (swap_func_t)array_bucketindex_swap);
/* go through the sorted array and delete duplicates from the copy */
lastkept = arTmp;
for (cmpdata = arTmp + 1; Z_TYPE(cmpdata->b.val) != IS_UNDEF; cmpdata++) {
- if (php_array_data_compare(lastkept, cmpdata)) {
+ if (cmp(lastkept, cmpdata)) {
lastkept = cmpdata;
} else {
if (lastkept->i > cmpdata->i) {
@@ -3335,19 +3761,7 @@ PHP_FUNCTION(array_unique)
static int zval_compare(zval *first, zval *second) /* {{{ */
{
- zval result;
-
- if (UNEXPECTED(Z_TYPE_P(first) == IS_INDIRECT)) {
- first = Z_INDIRECT_P(first);
- }
- if (UNEXPECTED(Z_TYPE_P(second) == IS_INDIRECT)) {
- second = Z_INDIRECT_P(second);
- }
- if (string_compare_function(&result, first, second) == FAILURE) {
- return 0;
- }
-
- return ZEND_NORMALIZE_BOOL(Z_LVAL(result));
+ return string_compare_function(first, second);
}
/* }}} */
@@ -3356,13 +3770,6 @@ static int zval_user_compare(zval *a, zval *b) /* {{{ */
zval args[2];
zval retval;
- if (UNEXPECTED(Z_TYPE_P(a) == IS_INDIRECT)) {
- a = Z_INDIRECT_P(a);
- }
- if (UNEXPECTED(Z_TYPE_P(b) == IS_INDIRECT)) {
- b = Z_INDIRECT_P(b);
- }
-
ZVAL_COPY_VALUE(&args[0], a);
ZVAL_COPY_VALUE(&args[1], b);
@@ -3433,6 +3840,10 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
p = Z_ARRVAL(args[0])->arData + idx;
val = &p->val;
if (Z_TYPE_P(val) == IS_UNDEF) continue;
+ if (UNEXPECTED(Z_TYPE_P(val) == IS_INDIRECT)) {
+ val = Z_INDIRECT_P(val);
+ if (Z_TYPE_P(val) == IS_UNDEF) continue;
+ }
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
ZVAL_UNREF(val);
}
@@ -3456,7 +3867,7 @@ static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compa
} else {
ok = 1;
for (i = 1; i < argc; i++) {
- if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) == NULL ||
+ if ((data = zend_hash_find_ind(Z_ARRVAL(args[i]), p->key)) == NULL ||
(intersect_data_compare_func &&
intersect_data_compare_func(val, data) != 0)
) {
@@ -3494,13 +3905,13 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
int (*intersect_data_compare_func)(const void *, const void *);
if (behavior == INTERSECT_NORMAL) {
- intersect_key_compare_func = php_array_key_compare;
+ intersect_key_compare_func = php_array_key_compare_string;
if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL) {
/* array_intersect() */
req_args = 2;
param_spec = "+";
- intersect_data_compare_func = php_array_data_compare;
+ intersect_data_compare_func = php_array_data_compare_string;
} else if (data_compare_type == INTERSECT_COMP_DATA_USER) {
/* array_uintersect() */
req_args = 3;
@@ -3525,19 +3936,19 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
} else if (behavior & INTERSECT_ASSOC) { /* triggered also when INTERSECT_KEY */
/* INTERSECT_KEY is subset of INTERSECT_ASSOC. When having the former
* no comparison of the data is done (part of INTERSECT_ASSOC) */
- intersect_key_compare_func = php_array_key_compare;
+ intersect_key_compare_func = php_array_key_compare_string;
if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {
/* array_intersect_assoc() or array_intersect_key() */
req_args = 2;
param_spec = "+";
- intersect_key_compare_func = php_array_key_compare;
- intersect_data_compare_func = php_array_data_compare;
+ intersect_key_compare_func = php_array_key_compare_string;
+ intersect_data_compare_func = php_array_data_compare_string;
} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_INTERNAL) {
/* array_uintersect_assoc() */
req_args = 3;
param_spec = "+f";
- intersect_key_compare_func = php_array_key_compare;
+ intersect_key_compare_func = php_array_key_compare_string;
intersect_data_compare_func = php_array_user_compare;
fci_data = &fci1;
fci_data_cache = &fci1_cache;
@@ -3546,7 +3957,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
req_args = 3;
param_spec = "+f";
intersect_key_compare_func = php_array_user_key_compare;
- intersect_data_compare_func = php_array_data_compare;
+ intersect_data_compare_func = php_array_data_compare_string;
fci_key = &fci1;
fci_key_cache = &fci1_cache;
} else if (data_compare_type == INTERSECT_COMP_DATA_USER && key_compare_type == INTERSECT_COMP_KEY_USER) {
@@ -3583,7 +3994,6 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
/* for each argument, create and sort list with pointers to the hash buckets */
lists = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);
ptrs = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);
- php_set_compare_func(PHP_SORT_STRING);
if (behavior == INTERSECT_NORMAL && data_compare_type == INTERSECT_COMP_DATA_USER) {
BG(user_compare_fci) = *fci_data;
@@ -3853,6 +4263,10 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
p = Z_ARRVAL(args[0])->arData + idx;
val = &p->val;
if (Z_TYPE_P(val) == IS_UNDEF) continue;
+ if (UNEXPECTED(Z_TYPE_P(val) == IS_INDIRECT)) {
+ val = Z_INDIRECT_P(val);
+ if (Z_TYPE_P(val) == IS_UNDEF) continue;
+ }
if (Z_ISREF_P(val) && Z_REFCOUNT_P(val) == 1) {
ZVAL_UNREF(val);
}
@@ -3876,7 +4290,7 @@ static void php_array_diff_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_ty
} else {
ok = 1;
for (i = 1; i < argc; i++) {
- if ((data = zend_hash_find(Z_ARRVAL(args[i]), p->key)) != NULL &&
+ if ((data = zend_hash_find_ind(Z_ARRVAL(args[i]), p->key)) != NULL &&
(!diff_data_compare_func ||
diff_data_compare_func(val, data) == 0)
) {
@@ -3914,13 +4328,13 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
int (*diff_data_compare_func)(const void *, const void *);
if (behavior == DIFF_NORMAL) {
- diff_key_compare_func = php_array_key_compare;
+ diff_key_compare_func = php_array_key_compare_string;
if (data_compare_type == DIFF_COMP_DATA_INTERNAL) {
/* array_diff */
req_args = 2;
param_spec = "+";
- diff_data_compare_func = php_array_data_compare;
+ diff_data_compare_func = php_array_data_compare_string;
} else if (data_compare_type == DIFF_COMP_DATA_USER) {
/* array_udiff */
req_args = 3;
@@ -3950,13 +4364,13 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
/* array_diff_assoc() or array_diff_key() */
req_args = 2;
param_spec = "+";
- diff_key_compare_func = php_array_key_compare;
- diff_data_compare_func = php_array_data_compare;
+ diff_key_compare_func = php_array_key_compare_string;
+ diff_data_compare_func = php_array_data_compare_string;
} else if (data_compare_type == DIFF_COMP_DATA_USER && key_compare_type == DIFF_COMP_KEY_INTERNAL) {
/* array_udiff_assoc() */
req_args = 3;
param_spec = "+f";
- diff_key_compare_func = php_array_key_compare;
+ diff_key_compare_func = php_array_key_compare_string;
diff_data_compare_func = php_array_user_compare;
fci_data = &fci1;
fci_data_cache = &fci1_cache;
@@ -3965,7 +4379,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
req_args = 3;
param_spec = "+f";
diff_key_compare_func = php_array_user_key_compare;
- diff_data_compare_func = php_array_data_compare;
+ diff_data_compare_func = php_array_data_compare_string;
fci_key = &fci1;
fci_key_cache = &fci1_cache;
} else if (data_compare_type == DIFF_COMP_DATA_USER && key_compare_type == DIFF_COMP_KEY_USER) {
@@ -4002,7 +4416,6 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
/* for each argument, create and sort list with pointers to the hash buckets */
lists = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);
ptrs = (Bucket **)safe_emalloc(arr_argc, sizeof(Bucket *), 0);
- php_set_compare_func(PHP_SORT_STRING);
if (behavior == DIFF_NORMAL && data_compare_type == DIFF_COMP_DATA_USER) {
BG(user_compare_fci) = *fci_data;
@@ -4297,15 +4710,10 @@ PHPAPI int php_multisort_compare(const void *a, const void *b) /* {{{ */
Bucket *bb = *(Bucket **)b;
int r;
zend_long result;
- zval temp;
r = 0;
do {
-
- php_set_compare_func(ARRAYG(multisort_flags)[MULTISORT_TYPE][r]);
-
- ARRAYG(compare_func)(&temp, &ab[r].val, &bb[r].val);
- result = ARRAYG(multisort_flags)[MULTISORT_ORDER][r] * Z_LVAL(temp);
+ result = ARRAYG(multisort_func)[r](&ab[r], &bb[r]);
if (result != 0) {
return result > 0 ? 1 : -1;
}
@@ -4316,10 +4724,9 @@ PHPAPI int php_multisort_compare(const void *a, const void *b) /* {{{ */
}
/* }}} */
-#define MULTISORT_ABORT \
- for (k = 0; k < MULTISORT_LAST; k++) \
- efree(ARRAYG(multisort_flags)[k]); \
- efree(arrays); \
+#define MULTISORT_ABORT \
+ efree(ARRAYG(multisort_func)); \
+ efree(arrays); \
RETURN_FALSE;
static void array_bucket_p_sawp(void *p, void *q) /* {{{ */ {
@@ -4359,8 +4766,8 @@ PHP_FUNCTION(array_multisort)
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));
}
+ ARRAYG(multisort_func) = (compare_func_t*)ecalloc(argc, sizeof(compare_func_t));
/* Here we go through the input arguments and parse them. Each one can
* be either an array or a sort flag which follows an array. If not
@@ -4376,8 +4783,7 @@ PHP_FUNCTION(array_multisort)
/* We see the next array, so we update the sort flags of
* the previous array and reset the sort flags. */
if (i > 0) {
- ARRAYG(multisort_flags)[MULTISORT_ORDER][num_arrays - 1] = sort_order;
- ARRAYG(multisort_flags)[MULTISORT_TYPE][num_arrays - 1] = sort_type;
+ ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func(sort_type, sort_order != PHP_SORT_ASC);
sort_order = PHP_SORT_ASC;
sort_type = PHP_SORT_REGULAR;
}
@@ -4394,7 +4800,7 @@ PHP_FUNCTION(array_multisort)
/* 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_P(arg) == PHP_SORT_DESC ? -1 : 1;
+ sort_order = Z_LVAL_P(arg) == PHP_SORT_DESC ? PHP_SORT_DESC : PHP_SORT_ASC;
parse_state[MULTISORT_ORDER] = 0;
} else {
php_error_docref(NULL, E_WARNING, "Argument #%d is expected to be an array or sorting flag that has not already been specified", i + 1);
@@ -4432,8 +4838,7 @@ PHP_FUNCTION(array_multisort)
}
}
/* Take care of the last array sort flags. */
- ARRAYG(multisort_flags)[MULTISORT_ORDER][num_arrays - 1] = sort_order;
- ARRAYG(multisort_flags)[MULTISORT_TYPE][num_arrays - 1] = sort_type;
+ ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func(sort_type, sort_order != PHP_SORT_ASC);
/* Make sure the arrays are of the same size. */
array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
@@ -4446,9 +4851,7 @@ PHP_FUNCTION(array_multisort)
/* If all arrays are empty we don't need to do anything. */
if (array_size < 1) {
- for (k = 0; k < MULTISORT_LAST; k++) {
- efree(ARRAYG(multisort_flags)[k]);
- }
+ efree(ARRAYG(multisort_func));
efree(arrays);
RETURN_TRUE;
}
@@ -4509,9 +4912,7 @@ PHP_FUNCTION(array_multisort)
efree(indirect[i]);
}
efree(indirect);
- for (k = 0; k < MULTISORT_LAST; k++) {
- efree(ARRAYG(multisort_flags)[k]);
- }
+ efree(ARRAYG(multisort_func));
efree(arrays);
RETURN_TRUE;
}
diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h
index fb33341030..ba2490c98b 100644
--- a/ext/standard/php_array.h
+++ b/ext/standard/php_array.h
@@ -125,8 +125,7 @@ PHPAPI zend_long php_count_recursive(zval *array, zend_long mode);
#define ARRAY_FILTER_USE_KEY 2
ZEND_BEGIN_MODULE_GLOBALS(array)
- int *multisort_flags[2];
- int (*compare_func)(zval *result, zval *op1, zval *op2);
+ compare_func_t *multisort_func;
ZEND_END_MODULE_GLOBALS(array)
#define ARRAYG(v) ZEND_MODULE_GLOBALS_ACCESSOR(array, v)
diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c
index 856f6e2b3e..cee926f579 100644
--- a/sapi/phpdbg/phpdbg_wait.c
+++ b/sapi/phpdbg/phpdbg_wait.c
@@ -50,7 +50,7 @@ typedef struct {
static int phpdbg_array_data_compare(const void *a, const void *b) {
Bucket *f, *s;
- zval result;
+ int result;
zval *first, *second;
f = *((Bucket **) a);
@@ -59,13 +59,11 @@ static int phpdbg_array_data_compare(const void *a, const void *b) {
first = &f->val;
second = &s->val;
- if (string_compare_function(&result, first, second) == FAILURE) {
- return 0;
- }
+ result = string_compare_function(first, second);
- if (Z_LVAL(result) < 0) {
+ if (result < 0) {
return -1;
- } else if (Z_LVAL(result) > 0) {
+ } else if (result > 0) {
return 1;
}