From b8089696c4c4874b02dd9995891ba74835f29e34 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 13 Mar 2014 22:56:18 +0400 Subject: [PATCH] Fixed support for references --- Zend/zend_execute.c | 19 ++-- Zend/zend_vm_def.h | 13 ++- Zend/zend_vm_execute.h | 195 ++++++++++++++++++++++++++++++++++------- 3 files changed, 189 insertions(+), 38 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3a8ab486d0..6e4005a1dc 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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"); } } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7a157575b9..44ec35e3b6 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5bd68abc13..7b91edfb91 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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)) { -- 2.40.0