diff options
-rw-r--r-- | UPGRADING.INTERNALS | 5 | ||||
-rw-r--r-- | Zend/zend_closures.c | 7 | ||||
-rw-r--r-- | Zend/zend_iterators.c | 1 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 41 | ||||
-rw-r--r-- | Zend/zend_object_handlers.h | 14 | ||||
-rw-r--r-- | Zend/zend_operators.c | 191 | ||||
-rw-r--r-- | Zend/zend_operators.h | 14 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 35 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 50 | ||||
-rw-r--r-- | ext/com_dotnet/com_handlers.c | 6 | ||||
-rw-r--r-- | ext/com_dotnet/com_saproxy.c | 8 | ||||
-rw-r--r-- | ext/date/php_date.c | 16 | ||||
-rw-r--r-- | ext/ffi/ffi.c | 10 | ||||
-rw-r--r-- | ext/gmp/gmp.c | 12 | ||||
-rw-r--r-- | ext/intl/breakiterator/breakiterator_class.cpp | 7 | ||||
-rw-r--r-- | ext/intl/timezone/timezone_class.cpp | 5 | ||||
-rw-r--r-- | ext/opcache/Optimizer/sccp.c | 5 | ||||
-rw-r--r-- | ext/pdo/pdo_dbh.c | 2 | ||||
-rw-r--r-- | ext/pdo/pdo_stmt.c | 4 | ||||
-rw-r--r-- | ext/simplexml/simplexml.c | 4 | ||||
-rw-r--r-- | ext/spl/spl_array.c | 4 | ||||
-rw-r--r-- | ext/spl/spl_heap.c | 12 | ||||
-rw-r--r-- | ext/spl/spl_observer.c | 18 | ||||
-rw-r--r-- | ext/standard/array.c | 8 |
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); } /* }}} */ |