From ee3254a2e8ed84e80599e4757d3c3662c1e87e02 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Feb 2014 13:06:11 +0400 Subject: [PATCH] Temporary refcounting fix --- Zend/zend_vm_def.h | 12 ++++- Zend/zend_vm_execute.h | 115 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 6 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 538f0701cb..b459bbce7f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1178,6 +1178,8 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) USE_OPLINE zend_free_op free_op1, free_op2; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = GET_OP1_ZVAL_PTR(BP_VAR_W); @@ -1185,12 +1187,20 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (OP1_TYPE == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W TSRMLS_CC); FREE_OP2(); //??? if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - FREE_OP1_VAR_PTR(); + +//??? + if (OP1_TYPE == IS_VAR && do_free) { + FREE_OP1_VAR_PTR(); + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 4846466b78..7151013967 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -14484,6 +14484,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -14491,12 +14493,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_VAR == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W TSRMLS_CC); //??? if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + +//??? + if (IS_VAR == IS_VAR && do_free) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -16740,6 +16750,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND USE_OPLINE zend_free_op free_op1, free_op2; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -16747,12 +16759,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_VAR == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); //??? if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + +//??? + if (IS_VAR == IS_VAR && do_free) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -18894,6 +18914,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND USE_OPLINE zend_free_op free_op1, free_op2; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -18901,12 +18923,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_VAR == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); //??? if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + +//??? + if (IS_VAR == IS_VAR && do_free) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -20794,6 +20824,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -20801,12 +20833,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_VAR == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W TSRMLS_CC); //??? if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + +//??? + if (IS_VAR == IS_VAR && do_free) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -22227,6 +22267,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); @@ -22234,12 +22276,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_VAR == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC); //??? if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + +//??? + if (IS_VAR == IS_VAR && do_free) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + } /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { @@ -31265,6 +31315,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -31272,12 +31324,21 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_CV == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W TSRMLS_CC); //??? if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } +//??? + if (IS_CV == IS_VAR && do_free) { + + } + /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { zval *retval_ptr = EX_VAR(opline->result.var); @@ -33302,6 +33363,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL USE_OPLINE zend_free_op free_op1, free_op2; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -33309,12 +33372,21 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_CV == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); //??? if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } +//??? + if (IS_CV == IS_VAR && do_free) { + + } + /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { zval *retval_ptr = EX_VAR(opline->result.var); @@ -35330,6 +35402,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL USE_OPLINE zend_free_op free_op1, free_op2; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -35337,12 +35411,21 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_CV == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); //??? if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } +//??? + if (IS_CV == IS_VAR && do_free) { + + } + /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { zval *retval_ptr = EX_VAR(opline->result.var); @@ -37104,6 +37187,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -37111,12 +37196,21 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_CV == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W TSRMLS_CC); //??? if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } +//??? + if (IS_CV == IS_VAR && do_free) { + + } + /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { zval *retval_ptr = EX_VAR(opline->result.var); @@ -38405,6 +38499,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE USE_OPLINE zend_free_op free_op1; zval *container; +//??? + int do_free = 1; SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -38412,12 +38508,21 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } +//??? we must not free implicitly created array (it should be fixed in another way) + if (IS_CV == IS_VAR && !Z_REFCOUNTED_P(container)) { + do_free = 0; + } zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC); //??? if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) { //??? EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); //??? } +//??? + if (IS_CV == IS_VAR && do_free) { + + } + /* We are going to assign the result by reference */ if (UNEXPECTED(opline->extended_value != 0)) { zval *retval_ptr = EX_VAR(opline->result.var); -- 2.40.0