]> granicus.if.org Git - php/commitdiff
Fixed support for references
authorDmitry Stogov <dmitry@zend.com>
Thu, 13 Mar 2014 18:56:18 +0000 (22:56 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 13 Mar 2014 18:56:18 +0000 (22:56 +0400)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 3a8ab486d049ba958853f280bb157168deb924ce..6e4005a1dca015d17d496710c9262a49638c82ca 100644 (file)
@@ -627,13 +627,20 @@ static void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_pt
 /* this should modify object only if it's empty */
 static inline void make_real_object(zval *object_ptr TSRMLS_DC)
 {
-       if (Z_TYPE_P(object_ptr) == IS_NULL
-               || (Z_TYPE_P(object_ptr) == IS_BOOL && Z_LVAL_P(object_ptr) == 0)
-               || (Z_TYPE_P(object_ptr) == IS_STRING && Z_STRLEN_P(object_ptr) == 0)
+       zval *object = object_ptr;
+
+       if (UNEXPECTED(Z_ISREF_P(object_ptr))) {
+               object = Z_REFVAL_P(object);
+       }
+       if (Z_TYPE_P(object) == IS_NULL
+               || (Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0)
+               || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)
        ) {
-               SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
-               zval_dtor(object_ptr);
-               object_init(object_ptr);
+               if (EXPECTED(!Z_ISREF_P(object_ptr))) {
+                       SEPARATE_ZVAL(object);
+               }
+               zval_dtor(object);
+               object_init(object);
                zend_error(E_WARNING, "Creating default object from empty value");
        }
 }
index 7a157575b9bcdfb41f876ecbb98274cf0beb9f91..44ec35e3b64ffa9cc2dbe36f9ef305b9db5be600 100644 (file)
@@ -340,13 +340,22 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (OP1_TYPE == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
index 5bd68abc13dee5423c2b739d819090cf09779582..7b91edfb9194b0c53f663b1125bc77b1774592b4 100644 (file)
@@ -14014,13 +14014,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -16503,13 +16512,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -18570,13 +18588,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -20751,13 +20778,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -22163,13 +22199,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -24085,13 +24130,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -25480,13 +25534,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -26792,13 +26855,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -28105,13 +28177,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -28512,13 +28593,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -31340,13 +31430,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -33611,13 +33710,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -35553,13 +35661,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -37608,13 +37725,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
@@ -38886,13 +39012,22 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
        }
 
-       make_real_object(object TSRMLS_CC);
-
 //???: object may become INDIRECT
        if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
                object = Z_INDIRECT_P(object);
        }
 
+       if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+               make_real_object(object TSRMLS_CC);
+//???
+               if (Z_TYPE_P(object) == IS_INDIRECT) {
+                       object = Z_INDIRECT_P(object);
+               }
+       }
+       if (UNEXPECTED(Z_ISREF_P(object))) {
+               object = Z_REFVAL_P(object);
+       }
+
        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
 
        if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {