]> granicus.if.org Git - php/commitdiff
More effecient fix for bug #71756
authorDmitry Stogov <dmitry@zend.com>
Thu, 10 Mar 2016 10:33:36 +0000 (13:33 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 10 Mar 2016 10:33:36 +0000 (13:33 +0300)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 432db9be6795b95c68df127957b581d0ef8abdf0..8253fd5d85ae6648fa774c59758a87b696a7351e 100644 (file)
@@ -1561,8 +1561,6 @@ num_index:
                                        retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
                                        break;
                        }
-               } else if (type == BP_VAR_R) {
-                       ZVAL_DEREF(retval);
                }
        } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
                offset_key = Z_STR_P(dim);
@@ -1593,11 +1591,7 @@ str_index:
                                                        ZVAL_NULL(retval);
                                                        break;
                                        }
-                               } else if (type == BP_VAR_R) {
-                                       ZVAL_DEREF(retval);
                                }
-                       } else if (type == BP_VAR_R) {
-                               ZVAL_DEREF(retval);
                        }
                } else {
                        switch (type) {
index 23aa3f3afdfff3d15e0401aa684009ee3039facf..35013c157164a9b24692c7d18984d83cf79e3baa 100644 (file)
@@ -4891,6 +4891,14 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
        SAVE_OPLINE();
        if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((OP1_TYPE & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
index e181246ede8169303c123edf11f51c7de4428e9e..8b62a834a46f8b15ec4a791c1ed256b92e96d5f0 100644 (file)
@@ -5858,6 +5858,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
        SAVE_OPLINE();
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -9646,6 +9654,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
        SAVE_OPLINE();
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -11412,6 +11428,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
        SAVE_OPLINE();
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CONST & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -32076,6 +32100,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
        SAVE_OPLINE();
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -37152,6 +37184,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
        SAVE_OPLINE();
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -39725,6 +39765,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
        SAVE_OPLINE();
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if ((IS_CV & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -41952,6 +42000,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
        SAVE_OPLINE();
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -44092,6 +44148,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
        SAVE_OPLINE();
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
@@ -45231,6 +45295,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
        SAVE_OPLINE();
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
                op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+       } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && UNEXPECTED(Z_ISREF_P(op1))) {
+               /* Don't keep lock on reference, lock the value instead */
+               if (UNEXPECTED(Z_REFCOUNT_P(op1) == 1)) {
+                       ZVAL_UNREF(op1);
+               } else {
+                       Z_DELREF_P(op1);
+                       ZVAL_COPY(op1, Z_REFVAL_P(op1));
+               }
        }
        if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
                op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);