summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--UPGRADING.INTERNALS5
-rw-r--r--Zend/zend_closures.c7
-rw-r--r--Zend/zend_iterators.c1
-rw-r--r--Zend/zend_object_handlers.c41
-rw-r--r--Zend/zend_object_handlers.h14
-rw-r--r--Zend/zend_operators.c191
-rw-r--r--Zend/zend_operators.h14
-rw-r--r--Zend/zend_vm_def.h35
-rw-r--r--Zend/zend_vm_execute.h50
-rw-r--r--ext/com_dotnet/com_handlers.c6
-rw-r--r--ext/com_dotnet/com_saproxy.c8
-rw-r--r--ext/date/php_date.c16
-rw-r--r--ext/ffi/ffi.c10
-rw-r--r--ext/gmp/gmp.c12
-rw-r--r--ext/intl/breakiterator/breakiterator_class.cpp7
-rw-r--r--ext/intl/timezone/timezone_class.cpp5
-rw-r--r--ext/opcache/Optimizer/sccp.c5
-rw-r--r--ext/pdo/pdo_dbh.c2
-rw-r--r--ext/pdo/pdo_stmt.c4
-rw-r--r--ext/simplexml/simplexml.c4
-rw-r--r--ext/spl/spl_array.c4
-rw-r--r--ext/spl/spl_heap.c12
-rw-r--r--ext/spl/spl_observer.c18
-rw-r--r--ext/standard/array.c8
24 files changed, 221 insertions, 258 deletions
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index 83c8c5a523..f893e06694 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -10,6 +10,7 @@ PHP 8.0 INTERNALS UPGRADE NOTES
g. zend_free_op type and should_free argument of zend_get_zval_ptr()
h. zend_value_error()
i. get_closure() object handler
+ j. compare_objects() and compare() object handlers
2. Build system changes
a. Abstract
@@ -76,6 +77,10 @@ PHP 8.0 INTERNALS UPGRADE NOTES
`check_only`. If it is true, the handler is called to check whether the
object is callable; in this case the handler should not throw an exception.
+ j. compare_objects() handler was removed. Extensions should use compare() object
+ handler instead and check if both arguments are objects and have the same
+ compare hanldler, using ZEND_COMPARE_OBJECTS_FALLBACK() macro.
+
========================
2. Build system changes
========================
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 68e698b626..4ed0b16b62 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -355,9 +355,10 @@ static ZEND_COLD zend_function *zend_closure_get_constructor(zend_object *object
}
/* }}} */
-static int zend_closure_compare_objects(zval *o1, zval *o2) /* {{{ */
+static int zend_closure_compare(zval *o1, zval *o2) /* {{{ */
{
- return (Z_OBJ_P(o1) != Z_OBJ_P(o2));
+ ZEND_COMPARE_OBJECTS_FALLBACK(o1, o2);
+ return Z_OBJ_P(o1) != Z_OBJ_P(o2);
}
/* }}} */
@@ -639,7 +640,7 @@ void zend_register_closure_ce(void) /* {{{ */
closure_handlers.get_property_ptr_ptr = zend_closure_get_property_ptr_ptr;
closure_handlers.has_property = zend_closure_has_property;
closure_handlers.unset_property = zend_closure_unset_property;
- closure_handlers.compare_objects = zend_closure_compare_objects;
+ closure_handlers.compare = zend_closure_compare;
closure_handlers.clone_obj = zend_closure_clone;
closure_handlers.get_debug_info = zend_closure_get_debug_info;
closure_handlers.get_closure = zend_closure_get_closure;
diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c
index f09ff22763..c0bb418f3a 100644
--- a/Zend/zend_iterators.c
+++ b/Zend/zend_iterators.c
@@ -44,7 +44,6 @@ static const zend_object_handlers iterator_object_handlers = {
NULL, /* method get */
NULL, /* get ctor */
NULL, /* get class name */
- NULL, /* compare */
NULL, /* cast */
NULL, /* count */
NULL, /* get_debug_info */
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 8a1898c227..8c5ddf454a 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1546,6 +1546,33 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
{
zend_object *zobj1, *zobj2;
+ if (Z_TYPE_P(o1) != Z_TYPE_P(o2)) {
+ /* Object and non-object */
+ zval casted;
+ if (Z_TYPE_P(o1) == IS_OBJECT) {
+ ZEND_ASSERT(Z_TYPE_P(o2) != IS_OBJECT);
+ if (Z_OBJ_HT_P(o1)->cast_object) {
+ if (Z_OBJ_HT_P(o1)->cast_object(Z_OBJ_P(o1), &casted, ((Z_TYPE_P(o2) == IS_FALSE || Z_TYPE_P(o2) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(o2))) == FAILURE) {
+ return 1;
+ }
+ int ret = zend_compare(&casted, o2);
+ zval_ptr_dtor(&casted);
+ return ret;
+ }
+ } else {
+ ZEND_ASSERT(Z_TYPE_P(o2) == IS_OBJECT);
+ if (Z_OBJ_HT_P(o2)->cast_object) {
+ if (Z_OBJ_HT_P(o2)->cast_object(Z_OBJ_P(o2), &casted, ((Z_TYPE_P(o1) == IS_FALSE || Z_TYPE_P(o1) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(o1))) == FAILURE) {
+ return -1;
+ }
+ int ret = zend_compare(o1, &casted);
+ zval_ptr_dtor(&casted);
+ return ret;
+ }
+ }
+ return 1;
+ }
+
zobj1 = Z_OBJ_P(o1);
zobj2 = Z_OBJ_P(o2);
@@ -1582,15 +1609,12 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
if (Z_TYPE_P(p1) != IS_UNDEF) {
if (Z_TYPE_P(p2) != IS_UNDEF) {
- zval result;
+ int ret;
- if (compare_function(&result, p1, p2)==FAILURE) {
- Z_UNPROTECT_RECURSION_P(o1);
- return 1;
- }
- if (Z_LVAL(result) != 0) {
+ ret = zend_compare(p1, p2);
+ if (ret != 0) {
Z_UNPROTECT_RECURSION_P(o1);
- return Z_LVAL(result);
+ return ret;
}
} else {
Z_UNPROTECT_RECURSION_P(o1);
@@ -1850,13 +1874,12 @@ ZEND_API const zend_object_handlers std_object_handlers = {
zend_std_get_method, /* get_method */
zend_std_get_constructor, /* get_constructor */
zend_std_get_class_name, /* get_class_name */
- zend_std_compare_objects, /* compare_objects */
zend_std_cast_object_tostring, /* cast_object */
NULL, /* count_elements */
zend_std_get_debug_info, /* get_debug_info */
zend_std_get_closure, /* get_closure */
zend_std_get_gc, /* get_gc */
NULL, /* do_operation */
- NULL, /* compare */
+ zend_std_compare_objects, /* compare */
NULL, /* get_properties_for */
};
diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h
index d8d7aca86c..713669f297 100644
--- a/Zend/zend_object_handlers.h
+++ b/Zend/zend_object_handlers.h
@@ -124,7 +124,6 @@ typedef zend_object* (*zend_object_clone_obj_t)(zend_object *object);
typedef zend_string *(*zend_object_get_class_name_t)(const zend_object *object);
typedef int (*zend_object_compare_t)(zval *object1, zval *object2);
-typedef int (*zend_object_compare_zvals_t)(zval *result, zval *op1, zval *op2);
/* Cast an object to some other type.
* readobj and retval must point to distinct zvals.
@@ -161,14 +160,13 @@ struct _zend_object_handlers {
zend_object_get_method_t get_method; /* required */
zend_object_get_constructor_t get_constructor; /* required */
zend_object_get_class_name_t get_class_name; /* required */
- zend_object_compare_t compare_objects; /* optional */
zend_object_cast_t cast_object; /* optional */
zend_object_count_elements_t count_elements; /* optional */
zend_object_get_debug_info_t get_debug_info; /* optional */
zend_object_get_closure_t get_closure; /* optional */
zend_object_get_gc_t get_gc; /* required */
zend_object_do_operation_t do_operation; /* optional */
- zend_object_compare_zvals_t compare; /* optional */
+ zend_object_compare_t compare; /* required */
zend_object_get_properties_for_t get_properties_for; /* optional */
};
@@ -241,6 +239,16 @@ ZEND_API HashTable *zend_get_properties_for(zval *obj, zend_prop_purpose purpose
} \
} while (0)
+/* Fallback to default comparison implementation if the arguments aren't both objects
+ * and have the same compare() handler. You'll likely want to use this unless you
+ * explicitly wish to support comparisons between objects and non-objects. */
+#define ZEND_COMPARE_OBJECTS_FALLBACK(op1, op2) \
+ if (Z_TYPE_P(op1) != IS_OBJECT || \
+ Z_TYPE_P(op2) != IS_OBJECT || \
+ Z_OBJ_HT_P(op1)->compare != Z_OBJ_HT_P(op2)->compare) { \
+ return zend_std_compare_objects(op1, op2); \
+ }
+
END_EXTERN_C()
#endif
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 7b4db44de8..6f939c0401 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1977,97 +1977,69 @@ ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{
}
/* }}} */
-static zend_always_inline void zend_free_obj_get_result(zval *op) /* {{{ */
-{
- ZEND_ASSERT(!Z_REFCOUNTED_P(op) || Z_REFCOUNT_P(op) != 0);
- zval_ptr_dtor(op);
-}
-/* }}} */
-
-static void ZEND_FASTCALL convert_compare_result_to_long(zval *result) /* {{{ */
+ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
- if (Z_TYPE_P(result) == IS_DOUBLE) {
- ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
- } else {
- convert_to_long(result);
- }
+ ZVAL_LONG(result, zend_compare(op1, op2));
+ return SUCCESS;
}
/* }}} */
-ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
+ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
{
- int ret;
int converted = 0;
- zval op1_copy, op2_copy, tmp_free;
+ zval op1_copy, op2_copy;
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
case TYPE_PAIR(IS_LONG, IS_LONG):
- ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
- return SUCCESS;
+ return Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0);
case TYPE_PAIR(IS_DOUBLE, IS_LONG):
- Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
- ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
- return SUCCESS;
+ return ZEND_NORMALIZE_BOOL(Z_DVAL_P(op1) - (double)Z_LVAL_P(op2));
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
- Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
- ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
- return SUCCESS;
+ return ZEND_NORMALIZE_BOOL((double)Z_LVAL_P(op1) - Z_DVAL_P(op2));
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
- ZVAL_LONG(result, 0);
+ return 0;
} else {
- Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
- ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
+ return ZEND_NORMALIZE_BOOL(Z_DVAL_P(op1) - Z_DVAL_P(op2));
}
- return SUCCESS;
case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
- ZVAL_LONG(result, zend_compare_arrays(op1, op2));
- return SUCCESS;
+ return zend_compare_arrays(op1, op2);
case TYPE_PAIR(IS_NULL, IS_NULL):
case TYPE_PAIR(IS_NULL, IS_FALSE):
case TYPE_PAIR(IS_FALSE, IS_NULL):
case TYPE_PAIR(IS_FALSE, IS_FALSE):
case TYPE_PAIR(IS_TRUE, IS_TRUE):
- ZVAL_LONG(result, 0);
- return SUCCESS;
+ return 0;
case TYPE_PAIR(IS_NULL, IS_TRUE):
- ZVAL_LONG(result, -1);
- return SUCCESS;
+ return -1;
case TYPE_PAIR(IS_TRUE, IS_NULL):
- ZVAL_LONG(result, 1);
- return SUCCESS;
+ return 1;
case TYPE_PAIR(IS_STRING, IS_STRING):
if (Z_STR_P(op1) == Z_STR_P(op2)) {
- ZVAL_LONG(result, 0);
- return SUCCESS;
+ return 0;
}
- ZVAL_LONG(result, zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)));
- return SUCCESS;
+ return zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2));
case TYPE_PAIR(IS_NULL, IS_STRING):
- ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
- return SUCCESS;
+ return Z_STRLEN_P(op2) == 0 ? 0 : -1;
case TYPE_PAIR(IS_STRING, IS_NULL):
- ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
- return SUCCESS;
+ return Z_STRLEN_P(op1) == 0 ? 0 : 1;
case TYPE_PAIR(IS_OBJECT, IS_NULL):
- ZVAL_LONG(result, 1);
- return SUCCESS;
+ return 1;
case TYPE_PAIR(IS_NULL, IS_OBJECT):
- ZVAL_LONG(result, -1);
- return SUCCESS;
+ return -1;
default:
if (Z_ISREF_P(op1)) {
@@ -2078,97 +2050,41 @@ ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
continue;
}
- if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
- 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)) {
- 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
+ && Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
+ return 0;
+ } else if (Z_TYPE_P(op1) == IS_OBJECT) {
+ return Z_OBJ_HANDLER_P(op1, compare)(op1, op2);
+ } else if (Z_TYPE_P(op2) == IS_OBJECT) {
+ return Z_OBJ_HANDLER_P(op2, compare)(op1, op2);
}
- if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
- if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
- /* object handles are identical, apparently this is the same object */
- ZVAL_LONG(result, 0);
- return SUCCESS;
- }
- if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
- ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2));
- return SUCCESS;
- }
- }
- if (Z_TYPE_P(op1) == IS_OBJECT) {
- if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
- ZVAL_UNDEF(&tmp_free);
- if (Z_OBJ_HT_P(op1)->cast_object(Z_OBJ_P(op1), &tmp_free, ((Z_TYPE_P(op2) == IS_FALSE || Z_TYPE_P(op2) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op2))) == FAILURE) {
- ZVAL_LONG(result, 1);
- zend_free_obj_get_result(&tmp_free);
- return SUCCESS;
- }
- ret = compare_function(result, &tmp_free, op2);
- zend_free_obj_get_result(&tmp_free);
- return ret;
- }
- }
- if (Z_TYPE_P(op2) == IS_OBJECT) {
- if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
- ZVAL_UNDEF(&tmp_free);
- if (Z_OBJ_HT_P(op2)->cast_object(Z_OBJ_P(op2), &tmp_free, ((Z_TYPE_P(op1) == IS_FALSE || Z_TYPE_P(op1) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op1))) == FAILURE) {
- ZVAL_LONG(result, -1);
- zend_free_obj_get_result(&tmp_free);
- return SUCCESS;
- }
- ret = compare_function(result, op1, &tmp_free);
- zend_free_obj_get_result(&tmp_free);
- return ret;
- } else if (Z_TYPE_P(op1) == IS_OBJECT) {
- ZVAL_LONG(result, 1);
- return SUCCESS;
- }
- }
if (!converted) {
if (Z_TYPE_P(op1) < IS_TRUE) {
- ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
- return SUCCESS;
+ return zval_is_true(op2) ? -1 : 0;
} else if (Z_TYPE_P(op1) == IS_TRUE) {
- ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
- return SUCCESS;
+ return zval_is_true(op2) ? 0 : 1;
} else if (Z_TYPE_P(op2) < IS_TRUE) {
- ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
- return SUCCESS;
+ return zval_is_true(op1) ? 1 : 0;
} else if (Z_TYPE_P(op2) == IS_TRUE) {
- ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
- return SUCCESS;
+ return zval_is_true(op1) ? 0 : -1;
} else {
- op1 = zendi_convert_scalar_to_number(op1, &op1_copy, result, 1);
- op2 = zendi_convert_scalar_to_number(op2, &op2_copy, result, 1);
+ op1 = _zendi_convert_scalar_to_number(op1, &op1_copy);
+ op2 = _zendi_convert_scalar_to_number(op2, &op2_copy);
if (EG(exception)) {
- if (result != op1) {
- ZVAL_UNDEF(result);
- }
- return FAILURE;
+ return 1; /* to stop comparison of arrays */
}
converted = 1;
}
} else if (Z_TYPE_P(op1)==IS_ARRAY) {
- ZVAL_LONG(result, 1);
- return SUCCESS;
+ return 1;
} else if (Z_TYPE_P(op2)==IS_ARRAY) {
- ZVAL_LONG(result, -1);
- return SUCCESS;
+ return -1;
} else {
ZEND_ASSERT(0);
zend_throw_error(NULL, "Unsupported operand types");
- if (result != op1) {
- ZVAL_UNDEF(result);
- }
- return FAILURE;
+ return 1;
}
}
}
@@ -2233,40 +2149,28 @@ ZEND_API int ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zv
ZEND_API int ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
- if (compare_function(result, op1, op2) == FAILURE) {
- return FAILURE;
- }
- ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
+ ZVAL_BOOL(result, zend_compare(op1, op2) == 0);
return SUCCESS;
}
/* }}} */
ZEND_API int ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
- if (compare_function(result, op1, op2) == FAILURE) {
- return FAILURE;
- }
- ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
+ ZVAL_BOOL(result, (zend_compare(op1, op2) != 0));
return SUCCESS;
}
/* }}} */
ZEND_API int ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
- if (compare_function(result, op1, op2) == FAILURE) {
- return FAILURE;
- }
- ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
+ ZVAL_BOOL(result, (zend_compare(op1, op2) < 0));
return SUCCESS;
}
/* }}} */
ZEND_API int ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
{
- if (compare_function(result, op1, op2) == FAILURE) {
- return FAILURE;
- }
- ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
+ ZVAL_BOOL(result, (zend_compare(op1, op2) <= 0));
return SUCCESS;
}
/* }}} */
@@ -2910,12 +2814,7 @@ string_cmp:
static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
{
- zval result;
-
- if (compare_function(&result, z1, z2)==FAILURE) {
- return 1;
- }
- return Z_LVAL(result);
+ return zend_compare(z1, z2);
}
/* }}} */
@@ -2937,10 +2836,10 @@ ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2) /* {{{ */
return 0;
}
- if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
+ if (Z_OBJ_HT_P(o1)->compare == NULL) {
return 1;
} else {
- return Z_OBJ_HT_P(o1)->compare_objects(o1, o2);
+ return Z_OBJ_HT_P(o1)->compare(o1, o2);
}
}
/* }}} */
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index e225e5eace..860d71b1d5 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -396,6 +396,8 @@ again:
return result;
}
+ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2);
+
ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2);
ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2);
@@ -850,7 +852,6 @@ static zend_always_inline int zend_fast_equal_strings(zend_string *s1, zend_stri
static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
{
- zval result;
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) == Z_LVAL_P(op2);
@@ -868,28 +869,23 @@ static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
return zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
}
}
- compare_function(&result, op1, op2);
- return Z_LVAL(result) == 0;
+ return zend_compare(op1, op2) == 0;
}
static zend_always_inline int fast_equal_check_long(zval *op1, zval *op2)
{
- zval result;
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) == Z_LVAL_P(op2);
}
- compare_function(&result, op1, op2);
- return Z_LVAL(result) == 0;
+ return zend_compare(op1, op2) == 0;
}
static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
{
- zval result;
if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
return zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2));
}
- compare_function(&result, op1, op2);
- return Z_LVAL(result) == 0;
+ return zend_compare(op1, op2) == 0;
}
static zend_always_inline zend_bool fast_is_identical_function(zval *op1, zval *op2)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 4d60feabd1..9680f4553a 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -478,6 +478,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CON
ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -487,7 +488,7 @@ ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -495,9 +496,10 @@ ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
+ if (ret == 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -572,6 +574,7 @@ ZEND_VM_C_LABEL(is_equal_double):
ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -581,7 +584,7 @@ ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -589,9 +592,10 @@ ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) != 0) {
+ if (ret != 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -666,6 +670,7 @@ ZEND_VM_C_LABEL(is_not_equal_double):
ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -675,7 +680,7 @@ ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -683,9 +688,10 @@ ZEND_VM_HELPER(zend_is_smaller_helper, ANY, ANY, zval *op_1, zval *op_2)
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) < 0) {
+ if (ret < 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -745,6 +751,7 @@ ZEND_VM_C_LABEL(is_smaller_double):
ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -754,7 +761,7 @@ ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -762,9 +769,10 @@ ZEND_VM_HELPER(zend_is_smaller_or_equal_helper, ANY, ANY, zval *op_1, zval *op_2
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) <= 0) {
+ if (ret <= 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -5252,6 +5260,7 @@ ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
ZEND_VM_HELPER(zend_case_helper, ANY, ANY, zval *op_1, zval *op_2)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -5261,14 +5270,15 @@ ZEND_VM_HELPER(zend_case_helper, ANY, ANY, zval *op_1, zval *op_2)
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (OP2_TYPE & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
+ if (ret == 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -8498,13 +8508,12 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM
result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
} else {
zend_string *key;
- zval key_tmp, result_tmp, *val;
+ zval key_tmp, *val;
result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
result = val;
break;
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 2b29fb63bb..07bc67cfd6 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -578,6 +578,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_shift_right_
static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -587,7 +588,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -595,9 +596,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
+ if (ret == 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -610,6 +612,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_equal_hel
static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -619,7 +622,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -627,9 +630,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) != 0) {
+ if (ret != 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -642,6 +646,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_not_equal
static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -651,7 +656,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_h
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -659,9 +664,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_h
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) < 0) {
+ if (ret < 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -674,6 +680,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_h
static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_or_equal_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -683,7 +690,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_o
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_1);
}
@@ -691,9 +698,10 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_is_smaller_o
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) <= 0) {
+ if (ret <= 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -2101,6 +2109,7 @@ send_array:
static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_case_helper_SPEC(zval *op_1, zval *op_2 ZEND_OPCODE_HANDLER_ARGS_DC)
{
+ int ret;
USE_OPLINE
SAVE_OPLINE();
@@ -2110,14 +2119,15 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_case_helper_
if (UNEXPECTED(Z_TYPE_INFO_P(op_2) == IS_UNDEF)) {
op_2 = ZVAL_UNDEFINED_OP2();
}
- compare_function(EX_VAR(opline->result.var), op_1, op_2);
+ ret = zend_compare(op_1, op_2);
if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
zval_ptr_dtor_nogc(op_2);
}
if (UNEXPECTED(EG(exception))) {
+ ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
}
- if (Z_LVAL_P(EX_VAR(opline->result.var)) == 0) {
+ if (ret == 0) {
ZEND_VM_SMART_BRANCH_TRUE();
ZVAL_TRUE(EX_VAR(opline->result.var));
ZEND_VM_NEXT_OPCODE();
@@ -6591,13 +6601,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CON
result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
} else {
zend_string *key;
- zval key_tmp, result_tmp, *val;
+ zval key_tmp, *val;
result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
result = val;
break;
}
@@ -18889,13 +18898,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLE
result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
} else {
zend_string *key;
- zval key_tmp, result_tmp, *val;
+ zval key_tmp, *val;
result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
result = val;
break;
}
@@ -24143,13 +24151,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLE
result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
} else {
zend_string *key;
- zval key_tmp, result_tmp, *val;
+ zval key_tmp, *val;
result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
result = val;
break;
}
@@ -41935,13 +41942,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER
result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1);
} else {
zend_string *key;
- zval key_tmp, result_tmp, *val;
+ zval key_tmp, *val;
result = NULL;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
result = val;
break;
}
diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c
index 788db3768c..c9b7d898ed 100644
--- a/ext/com_dotnet/com_handlers.c
+++ b/ext/com_dotnet/com_handlers.c
@@ -422,6 +422,8 @@ static int com_objects_compare(zval *object1, zval *object2)
* So, we have this declaration here to fix it */
STDAPI VarCmp(LPVARIANT pvarLeft, LPVARIANT pvarRight, LCID lcid, DWORD flags);
+ ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
+
obja = CDNO_FETCH(object1);
objb = CDNO_FETCH(object2);
@@ -538,12 +540,14 @@ zend_object_handlers php_com_object_handlers = {
com_method_get,
com_constructor_get,
com_class_name_get,
- com_objects_compare,
com_object_cast,
com_object_count,
NULL, /* get_debug_info */
NULL, /* get_closure */
zend_std_get_gc, /* get_gc */
+ NULL, /* do_operation */
+ com_objects_compare, /* compare */
+ NULL, /* get_properties_for */
};
void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable)
diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c
index 106cde856e..9ddcea3d9a 100644
--- a/ext/com_dotnet/com_saproxy.c
+++ b/ext/com_dotnet/com_saproxy.c
@@ -319,6 +319,7 @@ static zend_string* saproxy_class_name_get(const zend_object *object)
static int saproxy_objects_compare(zval *object1, zval *object2)
{
+ ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
return -1;
}
@@ -395,9 +396,14 @@ zend_object_handlers php_com_saproxy_handlers = {
saproxy_method_get,
saproxy_constructor_get,
saproxy_class_name_get,
- saproxy_objects_compare,
saproxy_object_cast,
saproxy_count_elements
+ NULL, /* get_debug_info */
+ NULL, /* get_closure */
+ NULL, /* get_gc */
+ NULL, /* do_operation */
+ saproxy_objects_compare, /* compare */
+ NULL, /* get_properties_for */
};
int php_com_saproxy_create(zend_object *com_object, zval *proxy_out, zval *index)
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index c1fc3f9076..32f515bfe4 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -1769,7 +1769,7 @@ static void date_register_classes(void) /* {{{ */
date_object_handlers_date.offset = XtOffsetOf(php_date_obj, std);
date_object_handlers_date.free_obj = date_object_free_storage_date;
date_object_handlers_date.clone_obj = date_object_clone_date;
- date_object_handlers_date.compare_objects = date_object_compare_date;
+ date_object_handlers_date.compare = date_object_compare_date;
date_object_handlers_date.get_properties_for = date_object_get_properties_for;
date_object_handlers_date.get_gc = date_object_get_gc;
zend_class_implements(date_ce_date, 1, date_ce_interface);
@@ -1779,7 +1779,7 @@ static void date_register_classes(void) /* {{{ */
date_ce_immutable = zend_register_internal_class_ex(&ce_immutable, NULL);
memcpy(&date_object_handlers_immutable, &std_object_handlers, sizeof(zend_object_handlers));
date_object_handlers_immutable.clone_obj = date_object_clone_date;
- date_object_handlers_immutable.compare_objects = date_object_compare_date;
+ date_object_handlers_immutable.compare = date_object_compare_date;
date_object_handlers_immutable.get_properties_for = date_object_get_properties_for;
date_object_handlers_immutable.get_gc = date_object_get_gc;
zend_class_implements(date_ce_immutable, 1, date_ce_interface);
@@ -1826,7 +1826,7 @@ static void date_register_classes(void) /* {{{ */
date_object_handlers_interval.get_properties = date_object_get_properties_interval;
date_object_handlers_interval.get_property_ptr_ptr = date_interval_get_property_ptr_ptr;
date_object_handlers_interval.get_gc = date_object_get_gc_interval;
- date_object_handlers_interval.compare_objects = date_interval_compare_objects;
+ date_object_handlers_interval.compare = date_interval_compare_objects;
INIT_CLASS_ENTRY(ce_period, "DatePeriod", date_funcs_period);
ce_period.create_object = date_object_new_period;
@@ -1890,8 +1890,13 @@ static void date_clone_immutable(zval *object, zval *new_object) /* {{{ */
static int date_object_compare_date(zval *d1, zval *d2) /* {{{ */
{
- php_date_obj *o1 = Z_PHPDATE_P(d1);
- php_date_obj *o2 = Z_PHPDATE_P(d2);
+ php_date_obj *o1;
+ php_date_obj *o2;
+
+ ZEND_COMPARE_OBJECTS_FALLBACK(d1, d2);
+
+ o1 = Z_PHPDATE_P(d1);
+ o2 = Z_PHPDATE_P(d2);
if (!o1->time || !o2->time) {
php_error_docref(NULL, E_WARNING, "Trying to compare an incomplete DateTime or DateTimeImmutable object");
@@ -3808,6 +3813,7 @@ static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *forma
} /* }}} */
static int date_interval_compare_objects(zval *o1, zval *o2) {
+ ZEND_COMPARE_OBJECTS_FALLBACK(o1, o2);
/* There is no well defined way to compare intervals like P1M and P30D, which may compare
* smaller, equal or greater depending on the point in time at which the interval starts. As
* such, we treat DateInterval objects are non-comparable and emit a warning. */
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
index c64675c650..0da267a7bb 100644
--- a/ext/ffi/ffi.c
+++ b/ext/ffi/ffi.c
@@ -4737,7 +4737,7 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_handlers.has_dimension = zend_fake_has_dimension;
zend_ffi_handlers.unset_dimension = zend_fake_unset_dimension;
zend_ffi_handlers.get_method = zend_ffi_get_func;
- zend_ffi_handlers.compare_objects = NULL;
+ zend_ffi_handlers.compare = NULL;
zend_ffi_handlers.cast_object = NULL;
zend_ffi_handlers.get_debug_info = NULL;
zend_ffi_handlers.get_closure = NULL;
@@ -4768,7 +4768,7 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_cdata_handlers.get_method = zend_fake_get_method;
zend_ffi_cdata_handlers.get_class_name = zend_ffi_cdata_get_class_name;
zend_ffi_cdata_handlers.do_operation = zend_ffi_cdata_do_operation;
- zend_ffi_cdata_handlers.compare_objects = zend_ffi_cdata_compare_objects;
+ zend_ffi_cdata_handlers.compare = zend_ffi_cdata_compare_objects;
zend_ffi_cdata_handlers.cast_object = zend_ffi_cdata_cast_object;
zend_ffi_cdata_handlers.count_elements = zend_ffi_cdata_count_elements;
zend_ffi_cdata_handlers.get_debug_info = zend_ffi_cdata_get_debug_info;
@@ -4791,7 +4791,7 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_cdata_value_handlers.unset_dimension = zend_fake_unset_dimension;
zend_ffi_cdata_value_handlers.get_method = zend_fake_get_method;
zend_ffi_cdata_value_handlers.get_class_name = zend_ffi_cdata_get_class_name;
- zend_ffi_cdata_value_handlers.compare_objects = zend_ffi_cdata_compare_objects;
+ zend_ffi_cdata_value_handlers.compare = zend_ffi_cdata_compare_objects;
zend_ffi_cdata_value_handlers.cast_object = zend_ffi_cdata_cast_object;
zend_ffi_cdata_value_handlers.count_elements = NULL;
zend_ffi_cdata_value_handlers.get_debug_info = zend_ffi_cdata_get_debug_info;
@@ -4814,7 +4814,7 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_cdata_free_handlers.unset_dimension = zend_ffi_free_unset_dimension;
zend_ffi_cdata_free_handlers.get_method = zend_fake_get_method;
zend_ffi_cdata_free_handlers.get_class_name = zend_ffi_cdata_get_class_name;
- zend_ffi_cdata_free_handlers.compare_objects = zend_ffi_cdata_compare_objects;
+ zend_ffi_cdata_free_handlers.compare = zend_ffi_cdata_compare_objects;
zend_ffi_cdata_free_handlers.cast_object = NULL;
zend_ffi_cdata_free_handlers.count_elements = NULL;
zend_ffi_cdata_free_handlers.get_debug_info = zend_ffi_free_get_debug_info;
@@ -4844,7 +4844,7 @@ ZEND_MINIT_FUNCTION(ffi)
zend_ffi_ctype_handlers.unset_dimension = zend_fake_unset_dimension;
zend_ffi_ctype_handlers.get_method = zend_fake_get_method;
zend_ffi_ctype_handlers.get_class_name = zend_ffi_ctype_get_class_name;
- zend_ffi_ctype_handlers.compare_objects = zend_ffi_ctype_compare_objects;
+ zend_ffi_ctype_handlers.compare = zend_ffi_ctype_compare_objects;
zend_ffi_ctype_handlers.cast_object = NULL;
zend_ffi_ctype_handlers.count_elements = NULL;
zend_ffi_ctype_handlers.get_debug_info = zend_ffi_ctype_get_debug_info;
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index de9fce657e..5a4e748702 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -455,13 +455,15 @@ static int gmp_do_operation(zend_uchar opcode, zval *result, zval *op1, zval *op
}
/* }}} */
-static int gmp_compare(zval *result, zval *op1, zval *op2) /* {{{ */
+static int gmp_compare(zval *op1, zval *op2) /* {{{ */
{
- gmp_cmp(result, op1, op2);
- if (Z_TYPE_P(result) == IS_FALSE) {
- ZVAL_LONG(result, 1);
+ zval result;
+
+ gmp_cmp(&result, op1, op2);
+ if (Z_TYPE(result) == IS_FALSE) {
+ return 1;
}
- return SUCCESS;
+ return Z_LVAL(result);
}
/* }}} */
diff --git a/ext/intl/breakiterator/breakiterator_class.cpp b/ext/intl/breakiterator/breakiterator_class.cpp
index 6a9cd85c72..608702ac2b 100644
--- a/ext/intl/breakiterator/breakiterator_class.cpp
+++ b/ext/intl/breakiterator/breakiterator_class.cpp
@@ -82,6 +82,11 @@ static int BreakIterator_compare_objects(zval *object1,
BreakIterator_object *bio1,
*bio2;
+ ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
+ if (Z_TYPE_P(object1) != Z_TYPE_P(object2)) {
+ return 1; /* object and non-object */
+ }
+
bio1 = Z_INTL_BREAKITERATOR_P(object1);
bio2 = Z_INTL_BREAKITERATOR_P(object2);
@@ -318,7 +323,7 @@ U_CFUNC void breakiterator_register_BreakIterator_class(void)
memcpy(&BreakIterator_handlers, &std_object_handlers,
sizeof BreakIterator_handlers);
BreakIterator_handlers.offset = XtOffsetOf(BreakIterator_object, zo);
- BreakIterator_handlers.compare_objects = BreakIterator_compare_objects;
+ BreakIterator_handlers.compare = BreakIterator_compare_objects;
BreakIterator_handlers.clone_obj = BreakIterator_clone_obj;
BreakIterator_handlers.get_debug_info = BreakIterator_get_debug_info;
BreakIterator_handlers.free_obj = BreakIterator_objects_free;
diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp
index a0baa45dce..516b39837c 100644
--- a/ext/intl/timezone/timezone_class.cpp
+++ b/ext/intl/timezone/timezone_class.cpp
@@ -268,6 +268,9 @@ static int TimeZone_compare_objects(zval *object1, zval *object2)
{
TimeZone_object *to1,
*to2;
+
+ ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
+
to1 = Z_INTL_TIMEZONE_P(object1);
to2 = Z_INTL_TIMEZONE_P(object2);
@@ -512,7 +515,7 @@ U_CFUNC void timezone_register_IntlTimeZone_class(void)
sizeof TimeZone_handlers);
TimeZone_handlers.offset = XtOffsetOf(TimeZone_object, zo);
TimeZone_handlers.clone_obj = TimeZone_clone_obj;
- TimeZone_handlers.compare_objects = TimeZone_compare_objects;
+ TimeZone_handlers.compare = TimeZone_compare_objects;
TimeZone_handlers.get_debug_info = TimeZone_get_debug_info;
TimeZone_handlers.dtor_obj = TimeZone_objects_dtor;
TimeZone_handlers.free_obj = TimeZone_objects_free;
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index 021b15ba32..57ae48b021 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -740,13 +740,12 @@ static inline int ct_eval_in_array(zval *result, uint32_t extended_value, zval *
res = zend_hash_exists(ht, ZSTR_EMPTY_ALLOC());
} else {
zend_string *key;
- zval key_tmp, result_tmp;
+ zval key_tmp;
res = 0;
ZEND_HASH_FOREACH_STR_KEY(ht, key) {
ZVAL_STR(&key_tmp, key);
- compare_function(&result_tmp, op1, &key_tmp);
- if (Z_LVAL(result_tmp) == 0) {
+ if (zend_compare(op1, &key_tmp) == 0) {
res = 1;
break;
}
diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c
index 45b74784fc..873aa2d681 100644
--- a/ext/pdo/pdo_dbh.c
+++ b/ext/pdo/pdo_dbh.c
@@ -1375,7 +1375,7 @@ void pdo_dbh_init(void)
pdo_dbh_object_handlers.free_obj = pdo_dbh_free_storage;
pdo_dbh_object_handlers.clone_obj = NULL;
pdo_dbh_object_handlers.get_method = dbh_method_get;
- pdo_dbh_object_handlers.compare_objects = dbh_compare;
+ pdo_dbh_object_handlers.compare = dbh_compare;
pdo_dbh_object_handlers.get_gc = dbh_get_gc;
REGISTER_PDO_CLASS_CONST_LONG("PARAM_BOOL", (zend_long)PDO_PARAM_BOOL);
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index e71bf62132..4acfcb0003 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2692,7 +2692,7 @@ void pdo_stmt_init(void)
pdo_dbstmt_object_handlers.write_property = dbstmt_prop_write;
pdo_dbstmt_object_handlers.unset_property = dbstmt_prop_delete;
pdo_dbstmt_object_handlers.get_method = dbstmt_method_get;
- pdo_dbstmt_object_handlers.compare_objects = dbstmt_compare;
+ pdo_dbstmt_object_handlers.compare = dbstmt_compare;
pdo_dbstmt_object_handlers.clone_obj = NULL;
INIT_CLASS_ENTRY(ce, "PDORow", pdo_row_functions);
@@ -2718,5 +2718,5 @@ void pdo_stmt_init(void)
pdo_row_object_handlers.get_method = row_method_get;
pdo_row_object_handlers.get_constructor = row_get_ctor;
pdo_row_object_handlers.get_class_name = row_get_classname;
- pdo_row_object_handlers.compare_objects = row_compare;
+ pdo_row_object_handlers.compare = row_compare;
}
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index 0950c3365d..563856393a 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -1286,6 +1286,8 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */
php_sxe_object *sxe1;
php_sxe_object *sxe2;
+ ZEND_COMPARE_OBJECTS_FALLBACK(object1, object2);
+
sxe1 = Z_SXEOBJ_P(object1);
sxe2 = Z_SXEOBJ_P(object2);
@@ -2648,7 +2650,7 @@ PHP_MINIT_FUNCTION(simplexml)
sxe_object_handlers.has_dimension = sxe_dimension_exists;
sxe_object_handlers.unset_dimension = sxe_dimension_delete;
sxe_object_handlers.get_properties = sxe_get_properties;
- sxe_object_handlers.compare_objects = sxe_objects_compare;
+ sxe_object_handlers.compare = sxe_objects_compare;
sxe_object_handlers.cast_object = sxe_object_cast;
sxe_object_handlers.count_elements = sxe_count_elements;
sxe_object_handlers.get_debug_info = sxe_get_debug_info;
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index cdba9fc912..b9c58caea0 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -944,6 +944,8 @@ static int spl_array_compare_objects(zval *o1, zval *o2) /* {{{ */
*intern2;
int result = 0;
+ ZEND_COMPARE_OBJECTS_FALLBACK(o1, o2);
+
intern1 = Z_SPLARRAY_P(o1);
intern2 = Z_SPLARRAY_P(o2);
ht1 = spl_array_get_hash_table(intern1);
@@ -2039,7 +2041,7 @@ PHP_MINIT_FUNCTION(spl_array)
spl_handler_ArrayObject.has_property = spl_array_has_property;
spl_handler_ArrayObject.unset_property = spl_array_unset_property;
- spl_handler_ArrayObject.compare_objects = spl_array_compare_objects;
+ spl_handler_ArrayObject.compare = spl_array_compare_objects;
spl_handler_ArrayObject.dtor_obj = zend_objects_destroy_object;
spl_handler_ArrayObject.free_obj = spl_array_object_free_storage;
diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c
index e7ddb741b1..73fdf97d99 100644
--- a/ext/spl/spl_heap.c
+++ b/ext/spl/spl_heap.c
@@ -166,7 +166,6 @@ static void spl_pqueue_extract_helper(zval *result, spl_pqueue_elem *elem, int f
static int spl_ptr_heap_zval_max_cmp(void *x, void *y, zval *object) { /* {{{ */
zval *a = x, *b = y;
- zval result;
if (EG(exception)) {
return 0;
@@ -184,14 +183,12 @@ static int spl_ptr_heap_zval_max_cmp(void *x, void *y, zval *object) { /* {{{ */
}
}
- compare_function(&result, a, b);
- return (int)Z_LVAL(result);
+ return zend_compare(a, b);
}
/* }}} */
static int spl_ptr_heap_zval_min_cmp(void *x, void *y, zval *object) { /* {{{ */
zval *a = x, *b = y;
- zval result;
if (EG(exception)) {
return 0;
@@ -209,8 +206,7 @@ static int spl_ptr_heap_zval_min_cmp(void *x, void *y, zval *object) { /* {{{ */
}
}
- compare_function(&result, b, a);
- return (int)Z_LVAL(result);
+ return zend_compare(b, a);
}
/* }}} */
@@ -219,7 +215,6 @@ static int spl_ptr_pqueue_elem_cmp(void *x, void *y, zval *object) { /* {{{ */
spl_pqueue_elem *b = y;
zval *a_priority_p = &a->priority;
zval *b_priority_p = &b->priority;
- zval result;
if (EG(exception)) {
return 0;
@@ -237,8 +232,7 @@ static int spl_ptr_pqueue_elem_cmp(void *x, void *y, zval *object) { /* {{{ */
}
}
- compare_function(&result, a_priority_p, b_priority_p);
- return (int)Z_LVAL(result);
+ return zend_compare(a_priority_p, b_priority_p);
}
/* }}} */
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index 99065b5716..dfc3e13455 100644
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -343,20 +343,20 @@ static int spl_object_storage_compare_info(zval *e1, zval *e2) /* {{{ */
{
spl_SplObjectStorageElement *s1 = (spl_SplObjectStorageElement*)Z_PTR_P(e1);
spl_SplObjectStorageElement *s2 = (spl_SplObjectStorageElement*)Z_PTR_P(e2);
- zval result;
- if (compare_function(&result, &s1->inf, &s2->inf) == FAILURE) {
- return 1;
- }
-
- return ZEND_NORMALIZE_BOOL(Z_LVAL(result));
+ return zend_compare(&s1->inf, &s2->inf);
}
/* }}} */
static int spl_object_storage_compare_objects(zval *o1, zval *o2) /* {{{ */
{
- zend_object *zo1 = (zend_object *)Z_OBJ_P(o1);
- zend_object *zo2 = (zend_object *)Z_OBJ_P(o2);
+ zend_object *zo1;
+ zend_object *zo2;
+
+ ZEND_COMPARE_OBJECTS_FALLBACK(o1, o2);
+
+ zo1 = (zend_object *)Z_OBJ_P(o1);
+ zo2 = (zend_object *)Z_OBJ_P(o2);
if (zo1->ce != spl_ce_SplObjectStorage || zo2->ce != spl_ce_SplObjectStorage) {
return 1;
@@ -1325,7 +1325,7 @@ PHP_MINIT_FUNCTION(spl_observer)
spl_handler_SplObjectStorage.offset = XtOffsetOf(spl_SplObjectStorage, std);
spl_handler_SplObjectStorage.get_debug_info = spl_object_storage_debug_info;
- spl_handler_SplObjectStorage.compare_objects = spl_object_storage_compare_objects;
+ spl_handler_SplObjectStorage.compare = spl_object_storage_compare_objects;
spl_handler_SplObjectStorage.clone_obj = spl_object_storage_clone;
spl_handler_SplObjectStorage.get_gc = spl_object_storage_get_gc;
spl_handler_SplObjectStorage.dtor_obj = zend_objects_destroy_object;
diff --git a/ext/standard/array.c b/ext/standard/array.c
index c8c58413f0..3b827e519c 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -363,7 +363,6 @@ static int php_array_data_compare(const void *a, const void *b) /* {{{ */
{
Bucket *f;
Bucket *s;
- zval result;
zval *first;
zval *second;
@@ -379,12 +378,7 @@ static int php_array_data_compare(const void *a, const void *b) /* {{{ */
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 ZEND_NORMALIZE_BOOL(Z_LVAL(result));
+ return zend_compare(first, second);
}
/* }}} */