com php-src: Merge branch 'array_keys_strict_refs' of https://github.com/tony2001/php-src: Zend/ zend_operators.c Zend/zend_operators.h Zend/zend_
vm_def.h Zend/zend_vm_execute.h ext/standard/arra y.c
| From: | Bob Weinand | Date: | Mon, 05 Oct 2015 12:45:15 +0000 |
| Subject: | com php-src: Merge branch 'array_keys_strict_refs' of https://github.com/tony2001/php-src: Zend/ zend_operators.c Zend/zend_operators.h Zend/zend_ vm_def.h Zend/zend_vm_execute.h ext/standard/arra y.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-89293@lists.php.net to get a copy of this message | ||
Commit: e57add010019016b1f6dc84bf3a7ae328ed52428
Author: Bob Weinand <bobwei9@hotmail.com> Mon, 5 Oct 2015 14:45:15 +0200
Parents: 746b37e2d551c89d25364ffefee19445651f93d6 9ac0a8310129ba41b2613938c88ff33bda22b4af
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=e57add010019016b1f6dc84bf3a7ae328ed52428
Log:
Merge branch 'array_keys_strict_refs' of https://github.com/tony2001/php-src
Changed paths:
MM Zend/zend_operators.c
MM Zend/zend_operators.h
MM Zend/zend_vm_def.h
MM Zend/zend_vm_execute.h
MM ext/standard/array.c
diff --cc Zend/zend_operators.c index 2345e0b,2345e0b..c40689e --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@@ -1959,52 -1959,52 +1959,24 @@@ ZEND_API int ZEND_FASTCALL compare_func } /* }}} */ --static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */ --{ -- zval result; -- -- /* is_identical_function() returns 1 in case of identity and 0 in case -- * of a difference; -- * whereas this comparison function is expected to return 0 on identity, -- * and non zero otherwise. -- */ -- ZVAL_DEREF(z1); -- ZVAL_DEREF(z2); -- if (is_identical_function(&result, z1, z2)==FAILURE) { -- return 1; -- } -- return Z_TYPE(result) != IS_TRUE; --} --/* }}} */ -- ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */ { if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 0; -- } -- switch (Z_TYPE_P(op1)) { -- case IS_NULL: -- case IS_FALSE: -- case IS_TRUE: -- return 1; -- case IS_LONG: -- return (Z_LVAL_P(op1) == Z_LVAL_P(op2)); -- case IS_RESOURCE: -- return (Z_RES_P(op1) == Z_RES_P(op2)); -- case IS_DOUBLE: -- return (Z_DVAL_P(op1) == Z_DVAL_P(op2)); -- case IS_STRING: -- return (Z_STR_P(op1) == Z_STR_P(op2) || -- (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) && -- memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0)); -- case IS_ARRAY: -- return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) || -- zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0); -- case IS_OBJECT: -- return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)); -- default: ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ return 0; ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { return 0; ++ } } ++ ++ return zend_is_same_type_identical(op1, op2); } /* }}} */ diff --cc Zend/zend_operators.h index f8c155d,987d055..17ae18c --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@@ -729,24 -729,28 +729,86 @@@ static zend_always_inline int fast_equa return Z_LVAL(result) == 0; } ++static int hash_zval_identical_function(zval *op1, zval *op2); ++ ++static inline int zend_is_same_type_identical(zval *op1, zval *op2) ++{ ++ switch (Z_TYPE_P(op1)) { ++ case IS_NULL: ++ case IS_FALSE: ++ case IS_TRUE: ++ return 1; ++ case IS_LONG: ++ return (Z_LVAL_P(op1) == Z_LVAL_P(op2)); ++ case IS_RESOURCE: ++ return (Z_RES_P(op1) == Z_RES_P(op2)); ++ case IS_DOUBLE: ++ return (Z_DVAL_P(op1) == Z_DVAL_P(op2)); ++ case IS_STRING: ++ return (Z_STR_P(op1) == Z_STR_P(op2) || ++ (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) && ++ memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0)); ++ case IS_ARRAY: ++ return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) || ++ zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0); ++ case IS_OBJECT: ++ return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)); ++ case IS_REFERENCE: ++ return zend_is_identical(Z_REFVAL_P(op1), Z_REFVAL_P(op2)); ++ default: ++ return 0; ++ } ++} ++ static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2) { - ZVAL_DEREF(op1); - ZVAL_DEREF(op2); if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 0; -- } else if (Z_TYPE_P(op1) <= IS_TRUE) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ return 0; ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { ++ return 0; ++ } ++ } ++ ++ if (Z_TYPE_P(op1) <= IS_TRUE) { return 1; } -- return zend_is_identical(op1, op2); ++ return zend_is_same_type_identical(op1, op2); } static zend_always_inline int fast_is_not_identical_function(zval *op1, zval *op2) { - ZVAL_DEREF(op1); - ZVAL_DEREF(op2); if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 1; -- } else if (Z_TYPE_P(op1) <= IS_TRUE) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ return 1; ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { ++ return 1; ++ } ++ } ++ ++ if (Z_TYPE_P(op1) <= IS_TRUE) { return 0; } -- return !zend_is_identical(op1, op2); ++ return !zend_is_same_type_identical(op1, op2); ++} ++ ++static int hash_zval_identical_function(zval *op1, zval *op2) ++{ ++ return !fast_is_identical_function(op1, op2); } #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \ diff --cc Zend/zend_vm_def.h index f0e7278,f0e7278..fd0e354 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@@ -323,8 -323,8 +323,8 @@@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, int result; SAVE_OPLINE(); -- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); -- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R); ++ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); ++ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R); result = fast_is_identical_function(op1, op2); FREE_OP1(); FREE_OP2(); @@@ -344,8 -344,8 +344,8 @@@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTIC int result; SAVE_OPLINE(); -- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); -- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R); ++ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); ++ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R); result = fast_is_not_identical_function(op1, op2); FREE_OP1(); FREE_OP2(); diff --cc Zend/zend_vm_execute.h index 035f4ab,035f4ab..b8da799 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@@ -6824,7 -6824,7 +6824,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -6845,7 -6845,7 +6845,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -8533,7 -8533,7 +8533,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); @@@ -8554,7 -8554,7 +8554,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); @@@ -13304,7 -13304,7 +13304,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -13325,7 -13325,7 +13325,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -13857,7 -13857,7 +13857,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -13878,7 -13878,7 +13878,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -16406,7 -16406,7 +16406,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = EX_CONSTANT(opline->op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -16427,7 -16427,7 +16427,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = EX_CONSTANT(opline->op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18148,7 -18148,7 +18148,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18169,7 -18169,7 +18169,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18360,8 -18360,8 +18360,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -18381,8 -18381,8 +18381,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -19614,8 -19614,8 +19614,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -19635,8 -19635,8 +19635,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -30092,7 -30092,7 +30092,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = EX_CONSTANT(opline->op2); result = fast_is_identical_function(op1, op2); @@@ -30113,7 -30113,7 +30113,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = EX_CONSTANT(opline->op2); result = fast_is_not_identical_function(op1, op2); @@@ -32972,7 -32972,7 +32972,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); @@@ -32993,7 -32993,7 +32993,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); @@@ -33183,8 -33183,8 +33183,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -33204,8 -33204,8 +33204,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -35327,8 -35327,8 +35327,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); @@@ -35348,8 -35348,8 +35348,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); diff --cc ext/standard/array.c index b9d39ea,b9d39ea..773b1ae --- a/ext/standard/array.c +++ b/ext/standard/array.c @@@ -1613,7 -1613,7 +1613,6 @@@ static inline void php_search_array(INT if (strict) { ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { -- ZVAL_DEREF(entry); if (fast_is_identical_function(value, entry)) { if (behavior == 0) { RETURN_TRUE;
diff --cc Zend/zend_operators.c index 2345e0b,2345e0b..c40689e --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@@ -1959,52 -1959,52 +1959,24 @@@ ZEND_API int ZEND_FASTCALL compare_func } /* }}} */ --static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */ --{ -- zval result; -- -- /* is_identical_function() returns 1 in case of identity and 0 in case -- * of a difference; -- * whereas this comparison function is expected to return 0 on identity, -- * and non zero otherwise. -- */ -- ZVAL_DEREF(z1); -- ZVAL_DEREF(z2); -- if (is_identical_function(&result, z1, z2)==FAILURE) { -- return 1; -- } -- return Z_TYPE(result) != IS_TRUE; --} --/* }}} */ -- ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */ { if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 0; -- } -- switch (Z_TYPE_P(op1)) { -- case IS_NULL: -- case IS_FALSE: -- case IS_TRUE: -- return 1; -- case IS_LONG: -- return (Z_LVAL_P(op1) == Z_LVAL_P(op2)); -- case IS_RESOURCE: -- return (Z_RES_P(op1) == Z_RES_P(op2)); -- case IS_DOUBLE: -- return (Z_DVAL_P(op1) == Z_DVAL_P(op2)); -- case IS_STRING: -- return (Z_STR_P(op1) == Z_STR_P(op2) || -- (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) && -- memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0)); -- case IS_ARRAY: -- return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) || -- zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0); -- case IS_OBJECT: -- return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)); -- default: ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ return 0; ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { return 0; ++ } } ++ ++ return zend_is_same_type_identical(op1, op2); } /* }}} */ diff --cc Zend/zend_operators.h index f8c155d,987d055..17ae18c --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@@ -729,24 -729,28 +729,86 @@@ static zend_always_inline int fast_equa return Z_LVAL(result) == 0; } ++static int hash_zval_identical_function(zval *op1, zval *op2); ++ ++static inline int zend_is_same_type_identical(zval *op1, zval *op2) ++{ ++ switch (Z_TYPE_P(op1)) { ++ case IS_NULL: ++ case IS_FALSE: ++ case IS_TRUE: ++ return 1; ++ case IS_LONG: ++ return (Z_LVAL_P(op1) == Z_LVAL_P(op2)); ++ case IS_RESOURCE: ++ return (Z_RES_P(op1) == Z_RES_P(op2)); ++ case IS_DOUBLE: ++ return (Z_DVAL_P(op1) == Z_DVAL_P(op2)); ++ case IS_STRING: ++ return (Z_STR_P(op1) == Z_STR_P(op2) || ++ (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) && ++ memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0)); ++ case IS_ARRAY: ++ return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) || ++ zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0); ++ case IS_OBJECT: ++ return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)); ++ case IS_REFERENCE: ++ return zend_is_identical(Z_REFVAL_P(op1), Z_REFVAL_P(op2)); ++ default: ++ return 0; ++ } ++} ++ static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2) { - ZVAL_DEREF(op1); - ZVAL_DEREF(op2); if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 0; -- } else if (Z_TYPE_P(op1) <= IS_TRUE) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ return 0; ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { ++ return 0; ++ } ++ } ++ ++ if (Z_TYPE_P(op1) <= IS_TRUE) { return 1; } -- return zend_is_identical(op1, op2); ++ return zend_is_same_type_identical(op1, op2); } static zend_always_inline int fast_is_not_identical_function(zval *op1, zval *op2) { - ZVAL_DEREF(op1); - ZVAL_DEREF(op2); if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { -- return 1; -- } else if (Z_TYPE_P(op1) <= IS_TRUE) { ++ if (EXPECTED(Z_TYPE_P(op1) != IS_REFERENCE)) { ++ if (EXPECTED(Z_TYPE_P(op2) != IS_REFERENCE)) { ++ return 1; ++ } else { ++ op2 = Z_REFVAL_P(op2); ++ } ++ } else { ++ op1 = Z_REFVAL_P(op1); ++ } ++ if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) { ++ return 1; ++ } ++ } ++ ++ if (Z_TYPE_P(op1) <= IS_TRUE) { return 0; } -- return !zend_is_identical(op1, op2); ++ return !zend_is_same_type_identical(op1, op2); ++} ++ ++static int hash_zval_identical_function(zval *op1, zval *op2) ++{ ++ return !fast_is_identical_function(op1, op2); } #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op) \ diff --cc Zend/zend_vm_def.h index f0e7278,f0e7278..fd0e354 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@@ -323,8 -323,8 +323,8 @@@ ZEND_VM_HANDLER(15, ZEND_IS_IDENTICAL, int result; SAVE_OPLINE(); -- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); -- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R); ++ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); ++ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R); result = fast_is_identical_function(op1, op2); FREE_OP1(); FREE_OP2(); @@@ -344,8 -344,8 +344,8 @@@ ZEND_VM_HANDLER(16, ZEND_IS_NOT_IDENTIC int result; SAVE_OPLINE(); -- op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); -- op2 = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R); ++ op1 = GET_OP1_ZVAL_PTR(BP_VAR_R); ++ op2 = GET_OP2_ZVAL_PTR(BP_VAR_R); result = fast_is_not_identical_function(op1, op2); FREE_OP1(); FREE_OP2(); diff --cc Zend/zend_vm_execute.h index 035f4ab,035f4ab..b8da799 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@@ -6824,7 -6824,7 +6824,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -6845,7 -6845,7 +6845,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -8533,7 -8533,7 +8533,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); @@@ -8554,7 -8554,7 +8554,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = EX_CONSTANT(opline->op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); @@@ -13304,7 -13304,7 +13304,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -13325,7 -13325,7 +13325,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -13857,7 -13857,7 +13857,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -13878,7 -13878,7 +13878,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -16406,7 -16406,7 +16406,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = EX_CONSTANT(opline->op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -16427,7 -16427,7 +16427,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = EX_CONSTANT(opline->op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18148,7 -18148,7 +18148,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18169,7 -18169,7 +18169,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -18360,8 -18360,8 +18360,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -18381,8 -18381,8 +18381,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); zval_ptr_dtor_nogc(free_op2); @@@ -19614,8 -19614,8 +19614,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -19635,8 -19635,8 +19635,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op1); @@@ -30092,7 -30092,7 +30092,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = EX_CONSTANT(opline->op2); result = fast_is_identical_function(op1, op2); @@@ -30113,7 -30113,7 +30113,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = EX_CONSTANT(opline->op2); result = fast_is_not_identical_function(op1, op2); @@@ -32972,7 -32972,7 +32972,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); @@@ -32993,7 -32993,7 +32993,7 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); op2 = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); @@@ -33183,8 -33183,8 +33183,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -33204,8 -33204,8 +33204,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(free_op2); @@@ -35327,8 -35327,8 +35327,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_identical_function(op1, op2); @@@ -35348,8 -35348,8 +35348,8 @@@ static ZEND_OPCODE_HANDLER_RET ZEND_FAS int result; SAVE_OPLINE(); -- op1 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var); -- op2 = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var); ++ op1 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); ++ op2 = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); result = fast_is_not_identical_function(op1, op2); diff --cc ext/standard/array.c index b9d39ea,b9d39ea..773b1ae --- a/ext/standard/array.c +++ b/ext/standard/array.c @@@ -1613,7 -1613,7 +1613,6 @@@ static inline void php_search_array(INT if (strict) { ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { -- ZVAL_DEREF(entry); if (fast_is_identical_function(value, entry)) { if (behavior == 0) { RETURN_TRUE;