]> granicus.if.org Git - php/commitdiff
Fixed reference counting
authorDmitry Stogov <dmitry@zend.com>
Fri, 11 Apr 2014 08:43:22 +0000 (12:43 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 11 Apr 2014 08:43:22 +0000 (12:43 +0400)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 730450f8b469df63a03d39819922f12c08e0dc62..b11bdfaf60e8f1a011aaf779fd4d84f37a71e867 100644 (file)
@@ -3152,14 +3152,17 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
 
        if (Z_ISREF_P(varptr)) {
                Z_ADDREF_P(varptr);
+       } else if (OP1_TYPE == IS_VAR &&
+               EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+               zval tmp;
+               ZVAL_COPY_VALUE(&tmp, varptr);
+               varptr = &tmp;
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
        } else {
                SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
-//??? don't increment refcount of overloaded element
-               if (OP1_TYPE != IS_VAR ||       
-                   EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_INDIRECT)) {
-                       Z_ADDREF_P(varptr);
-               }
+               Z_ADDREF_P(varptr);
        }
+
        zend_vm_stack_push(varptr TSRMLS_CC);
 
        FREE_OP1_VAR_PTR();
index 8a108cd94290c11c5614edfe189f0fe67bc5c159..6deaa6dc01b0adaedacbb5b15d14adb8ee5cc551 100644 (file)
@@ -12651,14 +12651,17 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
        if (Z_ISREF_P(varptr)) {
                Z_ADDREF_P(varptr);
+       } else if (IS_VAR == IS_VAR &&
+               EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+               zval tmp;
+               ZVAL_COPY_VALUE(&tmp, varptr);
+               varptr = &tmp;
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
        } else {
                SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
-//??? don't increment refcount of overloaded element
-               if (IS_VAR != IS_VAR ||
-                   EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_INDIRECT)) {
-                       Z_ADDREF_P(varptr);
-               }
+               Z_ADDREF_P(varptr);
        }
+
        zend_vm_stack_push(varptr TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
@@ -30182,14 +30185,17 @@ static int ZEND_FASTCALL  ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
        if (Z_ISREF_P(varptr)) {
                Z_ADDREF_P(varptr);
+       } else if (IS_CV == IS_VAR &&
+               EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) {
+               zval tmp;
+               ZVAL_COPY_VALUE(&tmp, varptr);
+               varptr = &tmp;
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
        } else {
                SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr);
-//??? don't increment refcount of overloaded element
-               if (IS_CV != IS_VAR ||
-                   EXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) == IS_INDIRECT)) {
-                       Z_ADDREF_P(varptr);
-               }
+               Z_ADDREF_P(varptr);
        }
+
        zend_vm_stack_push(varptr TSRMLS_CC);
 
        CHECK_EXCEPTION();