diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-10-07 17:57:49 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-10-07 17:57:49 +0300 |
commit | b02b81299ccef7de244bac7ffc605e3d2943fa88 (patch) | |
tree | f07036f89b7f4c8f3162f20702881061d59a13a3 /Zend | |
parent | e2100619ac064fdd4e7fe79e296a2ca087409e7d (diff) | |
download | php-git-b02b81299ccef7de244bac7ffc605e3d2943fa88.tar.gz |
Comparison cleanup:
- introduce zend_compare() that returns -1,0,1 dirctly (without intermediate zval)
- remove compare_objects() object handler, and keep only compare() handler
Diffstat (limited to 'Zend')
-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 |
8 files changed, 147 insertions, 206 deletions
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; } |