From: Nikita Popov Date: Sat, 20 Jun 2015 11:57:37 +0000 (+0200) Subject: Avoid unnecessary separations in VERIFY_RETURN_TYPE X-Git-Tag: php-7.0.0alpha2~2^2~51 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c7f4c5a2feecd165a1fe06b7ff99308921d60a71;p=php Avoid unnecessary separations in VERIFY_RETURN_TYPE --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 686eb2a293..7aea3daaf6 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3942,20 +3942,18 @@ ZEND_VM_HANDLER(124, ZEND_VERIFY_RETURN_TYPE, CONST|TMP|VAR|UNUSED|CV, UNUSED) if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9d7fac449b..8010458b54 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7998,20 +7998,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_ if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); @@ -13877,20 +13875,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UN if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); @@ -19626,20 +19622,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UN if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); @@ -25398,20 +25392,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num)); @@ -35030,20 +35022,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNU if (UNEXPECTED(!ret_info->class_name && ret_info->type_hint != IS_CALLABLE - && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)))) { - /* A cast or an error will happen, so separate the zval to prevent overwriting it */ - - if (EXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) == 0)) { - /* Does not return by reference */ - if (retval_ref != retval_ptr && Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - SEPARATE_ZVAL(retval_ref); - } - retval_ptr = retval_ref; + && !ZEND_SAME_FAKE_TYPE(ret_info->type_hint, Z_TYPE_P(retval_ptr)) + && !(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) + && retval_ref != retval_ptr) + ) { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); } else { - SEPARATE_ZVAL_NOREF(retval_ptr); + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } + retval_ptr = retval_ref; } zend_verify_return_type(EX(func), retval_ptr, CACHE_ADDR(opline->op2.num));