]> granicus.if.org Git - php/commitdiff
Avoid unnecessary separations in VERIFY_RETURN_TYPE
authorNikita Popov <nikic@php.net>
Sat, 20 Jun 2015 11:57:37 +0000 (13:57 +0200)
committerNikita Popov <nikic@php.net>
Sat, 20 Jun 2015 12:12:59 +0000 (14:12 +0200)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 686eb2a2931c4560cb6dbd22307086cbbeb8b637..7aea3daaf64e7195b0cb3e9d3ba9c6cf4b9af6b5 100644 (file)
@@ -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));
 
index 9d7fac449b699e65a3ba22078cd9e2ac0ee85af8..8010458b54b54fc2175019944a081d837fd9d095 100644 (file)
@@ -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));