summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-09-09 15:11:03 +0300
committerDmitry Stogov <dmitry@zend.com>2015-09-09 15:11:03 +0300
commit2ea18cd43165f791a5b0170795a790d2c0198ec8 (patch)
treebc7e409f1009e9a3c0ce9a28f86baec5ca0d59b1
parente0f390cb72b62ca359d6aad744cfa4e2a239d364 (diff)
downloadphp-git-2ea18cd43165f791a5b0170795a790d2c0198ec8.tar.gz
Better array_compare improvement
-rw-r--r--Zend/zend_operators.c26
-rw-r--r--ext/standard/array.c15
2 files changed, 24 insertions, 17 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 0e2cc91cf6..1ed54aa32b 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1763,6 +1763,15 @@ static inline void zend_free_obj_get_result(zval *op) /* {{{ */
}
/* }}} */
+static int 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)));
+ } else {
+ convert_to_long(result);
+ }
+}
+
ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
int ret;
@@ -1849,9 +1858,17 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
}
if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
- return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
+ ret = Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
+ if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
+ convert_compare_result_to_long(result);
+ }
+ return ret;
} else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
- return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
+ ret = Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
+ if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
+ convert_compare_result_to_long(result);
+ }
+ return ret;
}
if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
@@ -1947,7 +1964,10 @@ 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) /* {{{ */
{
- return compare_function(result, op1, op2);
+ int ret = compare_function(result, op1, op2);
+
+ ZEND_ASSERT(Z_TYPE_P(result) == IS_LONG);
+ return ret;
}
/* }}} */
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 1b1d1c148a..1067b37e75 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -83,8 +83,6 @@
#define INTERSECT_COMP_KEY_USER 1
#define DOUBLE_DRIFT_FIX 0.000000000000001
-
-static int regular_compare_function(zval *result, zval *a, zval *b);
/* }}} */
ZEND_DECLARE_MODULE_GLOBALS(array)
@@ -166,7 +164,7 @@ static void php_set_compare_func(zend_long sort_type) /* {{{ */
case PHP_SORT_REGULAR:
default:
- ARRAYG(compare_func) = regular_compare_function;
+ ARRAYG(compare_func) = zval_compare_function;
break;
}
}
@@ -3383,17 +3381,6 @@ static int zval_user_compare(zval *a, zval *b) /* {{{ */
}
/* }}} */
-static int regular_compare_function(zval *result, zval *a, zval *b) /* {{{ */ {
- int ret = zval_compare_function(result, a, b);
- if (ret == SUCCESS) {
- if (Z_TYPE_P(result) == IS_DOUBLE) {
- ZVAL_LONG(result, Z_DVAL_P(result) > 0? 1 : (Z_DVAL_P(result) < 0? -1 : 0));
- }
- }
- return ret;
-}
-/* }}} */
-
static void php_array_intersect_key(INTERNAL_FUNCTION_PARAMETERS, int data_compare_type) /* {{{ */
{
uint idx;