]> granicus.if.org Git - php/commitdiff
ASSIGN_REF optimization
authorDmitry Stogov <dmitry@zend.com>
Thu, 3 Apr 2014 12:53:30 +0000 (16:53 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 3 Apr 2014 12:53:30 +0000 (16:53 +0400)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index b0799ef1c3f5a5a140b1c909c7de0b3ea335ae24..c4d2297a08d45abb3517362a4ca1a5c76fdb90e0 100644 (file)
@@ -501,16 +501,13 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_exec
        return get_zval_ptr(op_type, op, execute_data, should_free, type);
 }
 
-static void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC)
+static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC)
 {
-       if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) {
-               ZVAL_NULL(variable_ptr);
-       } else if (EXPECTED(variable_ptr != value_ptr)) {
-               zval tmp;
+       if (EXPECTED(variable_ptr != value_ptr)) {
                SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
-               ZVAL_COPY(&tmp, value_ptr);
+               Z_ADDREF_P(value_ptr);
                zval_ptr_dtor(variable_ptr);
-               ZVAL_COPY_VALUE(variable_ptr, &tmp);
+               ZVAL_COPY_VALUE(variable_ptr, value_ptr);
        } else if (!Z_ISREF_P(variable_ptr)) {
                ZVAL_NEW_REF(variable_ptr, variable_ptr);
        }
index a3c73b3c12d0f1f6067dc26818abfd50d81ad6f1..758dcaa4bfcb63fd6c5a02cbff8c9eebad9e2126 100644 (file)
@@ -1824,7 +1824,7 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
        }
        if (OP1_TYPE == IS_VAR &&
            UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
-           UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) {
+           UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
                zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
        }
 
@@ -1833,7 +1833,12 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
            (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
                zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
        }
-       zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       if ((OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
+           (OP2_TYPE == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
+               variable_ptr = &EG(uninitialized_zval);
+       } else {
+               zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       }
 
        if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
                if (!OP2_FREE) {
index 3f03f63206739614d3f5799d3bd7a975f2fd8a18..48bbb2b5e61d2888bd298df3cdd864f9e4e39a39 100644 (file)
@@ -19643,7 +19643,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
        }
        if (IS_VAR == IS_VAR &&
            UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
-           UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) {
+           UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
                zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
        }
 
@@ -19652,7 +19652,12 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
            (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
                zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
        }
-       zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
+           (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
+               variable_ptr = &EG(uninitialized_zval);
+       } else {
+               zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       }
 
        if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
                if (!(free_op2.var != NULL)) {
@@ -23024,7 +23029,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
        }
        if (IS_VAR == IS_VAR &&
            UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
-           UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) {
+           UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
                zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
        }
 
@@ -23033,7 +23038,12 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
            (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
                zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
        }
-       zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
+           (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
+               variable_ptr = &EG(uninitialized_zval);
+       } else {
+               zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       }
 
        if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
                if (!0) {
@@ -36414,7 +36424,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
        }
        if (IS_CV == IS_VAR &&
            UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
-           UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) {
+           UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
                zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
        }
 
@@ -36423,7 +36433,12 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
            (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
                zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
        }
-       zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
+           (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
+               variable_ptr = &EG(uninitialized_zval);
+       } else {
+               zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       }
 
        if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
                if (!(free_op2.var != NULL)) {
@@ -39529,7 +39544,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
        }
        if (IS_CV == IS_VAR &&
            UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
-           UNEXPECTED(!Z_ISREF_P(EX_VAR(opline->op1.var)))) {
+           UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
                zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
        }
 
@@ -39538,7 +39553,12 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
            (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) {
                zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
        }
-       zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
+           (IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
+               variable_ptr = &EG(uninitialized_zval);
+       } else {
+               zend_assign_to_variable_reference(variable_ptr, value_ptr TSRMLS_CC);
+       }
 
        if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
                if (!0) {