Skip to content

Commit c3501fb

Browse files
committed
Move object to bool comparison logic to zend_compare
Suggested by Arnaud. This avoids handling boolean semantics in each compare handler, as they should be consistent across the language.
1 parent 3ed05cf commit c3501fb

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

Zend/zend_object_handlers.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,8 +2063,9 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
20632063
object_lhs = false;
20642064
}
20652065
ZEND_ASSERT(Z_TYPE_P(value) != IS_OBJECT);
2066-
uint8_t target_type = (Z_TYPE_P(value) == IS_FALSE || Z_TYPE_P(value) == IS_TRUE)
2067-
? _IS_BOOL : Z_TYPE_P(value);
2066+
uint8_t target_type = Z_TYPE_P(value);
2067+
/* Should be handled in zend_compare(). */
2068+
ZEND_ASSERT(target_type != IS_FALSE && target_type != IS_TRUE);
20682069
if (Z_OBJ_HT_P(object)->cast_object(Z_OBJ_P(object), &casted, target_type) == FAILURE) {
20692070
// TODO: Less crazy.
20702071
if (target_type == IS_LONG || target_type == IS_DOUBLE) {
@@ -2158,13 +2159,6 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
21582159

21592160
ZEND_API int zend_objects_not_comparable(zval *o1, zval *o2)
21602161
{
2161-
zval *other = Z_TYPE_P(o1) == IS_OBJECT ? o2 : o1;
2162-
2163-
/* Fall back to zend_std_compare_objects() for bool. */
2164-
if (Z_TYPE_P(other) == IS_TRUE || Z_TYPE_P(other) == IS_FALSE) {
2165-
return zend_std_compare_objects(o1, o2);
2166-
}
2167-
21682162
return ZEND_UNCOMPARABLE;
21692163
}
21702164

Zend/zend_operators.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,13 +2333,29 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */
23332333
}
23342334

23352335
if (Z_TYPE_P(op1) == IS_OBJECT
2336-
&& Z_TYPE_P(op2) == IS_OBJECT
2337-
&& Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
2338-
return 0;
2339-
} else if (Z_TYPE_P(op1) == IS_OBJECT) {
2340-
return Z_OBJ_HANDLER_P(op1, compare)(op1, op2);
2341-
} else if (Z_TYPE_P(op2) == IS_OBJECT) {
2342-
return Z_OBJ_HANDLER_P(op2, compare)(op1, op2);
2336+
|| Z_TYPE_P(op2) == IS_OBJECT) {
2337+
zval *object, *other;
2338+
if (Z_TYPE_P(op1) == IS_OBJECT) {
2339+
object = op1;
2340+
other = op2;
2341+
} else {
2342+
object = op2;
2343+
other = op1;
2344+
}
2345+
if (EXPECTED(Z_TYPE_P(other) == IS_OBJECT)) {
2346+
if (Z_OBJ_P(object) == Z_OBJ_P(other)) {
2347+
return 0;
2348+
}
2349+
} else if (Z_TYPE_P(other) == IS_TRUE || Z_TYPE_P(other) == IS_FALSE) {
2350+
zval casted;
2351+
if (Z_OBJ_HANDLER_P(object, cast_object)(Z_OBJ_P(object), &casted, _IS_BOOL) == FAILURE) {
2352+
return object == op1 ? 1 : -1;
2353+
}
2354+
int ret = object == op1 ? zend_compare(&casted, other) : zend_compare(other, &casted);
2355+
ZEND_ASSERT(!Z_REFCOUNTED_P(&casted));
2356+
return ret;
2357+
}
2358+
return Z_OBJ_HANDLER_P(object, compare)(op1, op2);
23432359
}
23442360

23452361
if (!converted) {

0 commit comments

Comments
 (0)