diff options
author | Dmitry Stogov <dmitry@php.net> | 2008-01-21 19:10:25 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2008-01-21 19:10:25 +0000 |
commit | 7390459e2664346c17d10c2347a0f3b766b6ab83 (patch) | |
tree | 9365952d2a6112d6e0aac192392137e5463159c1 /Zend/zend_operators.c | |
parent | 13be31db35b74b38d8680aea4b08b4d3831d9092 (diff) | |
download | php-git-7390459e2664346c17d10c2347a0f3b766b6ab83.tar.gz |
Yet another comparison optimisation for usual cases
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 99 |
1 files changed, 51 insertions, 48 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 415cdd1a00..d80dcffe3c 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1359,74 +1359,70 @@ static inline void zend_free_obj_get_result(zval *op) } } -#define COMPARE_RETURN_AND_FREE(retval) \ - if (op1_free) {zend_free_obj_get_result(op1_free);} \ - if (op2_free) {zend_free_obj_get_result(op2_free);} \ - return retval; - ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) { + int ret; int converted = 0; zval op1_copy, op2_copy; - zval *op1_free = NULL, *op2_free = NULL; + zval *op_free; 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)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_DOUBLE, IS_LONG): ZVAL_LONG(result, Z_DVAL_P(op1)>((double)Z_LVAL_P(op2))?1:(Z_DVAL_P(op1)<((double)Z_LVAL_P(op2))?-1:0)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_LONG, IS_DOUBLE): ZVAL_LONG(result, ((double)Z_LVAL_P(op1))>Z_DVAL_P(op2)?1:(((double)Z_LVAL_P(op1))<Z_DVAL_P(op2)?-1:0)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): ZVAL_LONG(result, Z_DVAL_P(op1)>Z_DVAL_P(op2)?1:(Z_DVAL_P(op1)<Z_DVAL_P(op2)?-1:0)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_ARRAY, IS_ARRAY): zend_compare_arrays(result, op1, op2 TSRMLS_CC); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_NULL, IS_NULL): ZVAL_LONG(result, 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_NULL, IS_BOOL): ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_BOOL, IS_NULL): ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_BOOL, IS_BOOL): ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2))); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_STRING, IS_STRING): zendi_smart_strcmp(result, op1, op2); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_NULL, IS_STRING): ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2))); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_STRING, IS_NULL): ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_OBJECT, IS_NULL): ZVAL_LONG(result, 1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_NULL, IS_OBJECT): ZVAL_LONG(result, -1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; case TYPE_PAIR(IS_OBJECT, IS_OBJECT): /* If both are objects sharing the same comparision handler then use is */ @@ -1434,62 +1430,69 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) { /* object handles are identical, apprently this is the same object */ ZVAL_LONG(result, 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC)); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } /* break missing intentionally */ default: - if (Z_TYPE_P(op1) == IS_OBJECT && !op1_free) { + if (Z_TYPE_P(op1) == IS_OBJECT) { if (Z_OBJ_HT_P(op1)->get) { - op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC); - continue; + op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC); + ret = compare_function(result, op_free, op2 TSRMLS_CC); + zend_free_obj_get_result(op_free); + return ret; } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) { - ALLOC_INIT_ZVAL(op1_free); - if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) { - op2_free = NULL; + ALLOC_INIT_ZVAL(op_free); + if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) { ZVAL_LONG(result, 1); - COMPARE_RETURN_AND_FREE(SUCCESS); + zend_free_obj_get_result(op_free); + return SUCCESS; } - op1 = op1_free; - continue; + ret = compare_function(result, op_free, op2 TSRMLS_CC); + zend_free_obj_get_result(op_free); + return ret; } } - if (Z_TYPE_P(op2) == IS_OBJECT && !op2_free) { + if (Z_TYPE_P(op2) == IS_OBJECT) { if (Z_OBJ_HT_P(op2)->get) { - op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC); - continue; + op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC); + ret = compare_function(result, op1, op_free TSRMLS_CC); + zend_free_obj_get_result(op_free); + return ret; } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) { - ALLOC_INIT_ZVAL(op2_free); - if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) { + ALLOC_INIT_ZVAL(op_free); + if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) { ZVAL_LONG(result, -1); - COMPARE_RETURN_AND_FREE(SUCCESS); + zend_free_obj_get_result(op_free); + return SUCCESS; } - op2 = op2_free; - continue; + ret = compare_function(result, op1, op_free TSRMLS_CC); + zend_free_obj_get_result(op_free); + return ret; } } if (!converted) { if (Z_TYPE_P(op1) == IS_NULL) { zendi_convert_to_boolean(op2, op2_copy, result); ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op2) == IS_NULL) { zendi_convert_to_boolean(op1, op1_copy, result); ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op1) == IS_BOOL) { zendi_convert_to_boolean(op2, op2_copy, result); ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2))); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op2) == IS_BOOL) { zendi_convert_to_boolean(op1, op1_copy, result); ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2))); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else { zendi_convert_scalar_to_number(op1, op1_copy, result); zendi_convert_scalar_to_number(op2, op2_copy, result); @@ -1497,19 +1500,19 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) } } else if (Z_TYPE_P(op1)==IS_ARRAY) { ZVAL_LONG(result, 1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op2)==IS_ARRAY) { ZVAL_LONG(result, -1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op1)==IS_OBJECT) { ZVAL_LONG(result, 1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else if (Z_TYPE_P(op2)==IS_OBJECT) { ZVAL_LONG(result, -1); - COMPARE_RETURN_AND_FREE(SUCCESS); + return SUCCESS; } else { ZVAL_LONG(result, 0); - COMPARE_RETURN_AND_FREE(FAILURE); + return FAILURE; } } } |