From: Dmitry Stogov Date: Fri, 4 Apr 2014 11:22:41 +0000 (+0400) Subject: Tergets of ASSIGN and ASSIGN_REF don't have to be initialized X-Git-Tag: POST_PHPNG_MERGE~412^2~168 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cea26aa2ebb172d3afa0f22a5eb1af1c3b0c703f;p=php Tergets of ASSIGN and ASSIGN_REF don't have to be initialized --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 75ced021bb..613a82de83 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1738,7 +1738,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV) SAVE_OPLINE(); value = GET_OP2_ZVAL_PTR(BP_VAR_R); - variable_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); + variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { zend_assign_to_string_offset(variable_ptr, value, OP2_TYPE, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); @@ -1781,10 +1781,9 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) value_ptr = GET_OP2_ZVAL_PTR_PTR(BP_VAR_W); if (OP2_TYPE == IS_VAR && - value_ptr && - !Z_ISREF_P(value_ptr) && opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)) { + !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) && + !Z_ISREF_P(value_ptr)) { if (!OP2_FREE) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } @@ -1799,13 +1798,13 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV) PZVAL_LOCK(value_ptr); } } + + variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - - variable_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); if ((OP2_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || (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"); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a1360caeae..8187956cf6 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -19554,10 +19554,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (IS_VAR == IS_VAR && - value_ptr && - !Z_ISREF_P(value_ptr) && opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)) { + !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) && + !Z_ISREF_P(value_ptr)) { if (!(free_op2.var != NULL)) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } @@ -19572,13 +19571,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL PZVAL_LOCK(value_ptr); } } + + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || (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"); @@ -22904,10 +22903,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC); if (IS_CV == IS_VAR && - value_ptr && - !Z_ISREF_P(value_ptr) && opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)) { + !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) && + !Z_ISREF_P(value_ptr)) { if (!0) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } @@ -22922,13 +22920,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE PZVAL_LOCK(value_ptr); } } + + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || (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"); @@ -32050,7 +32048,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); value = opline->op2.zv; - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { zend_assign_to_string_offset(variable_ptr, value, IS_CONST, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); @@ -34094,7 +34092,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { zend_assign_to_string_offset(variable_ptr, value, IS_TMP_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); @@ -36172,7 +36170,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { zend_assign_to_string_offset(variable_ptr, value, IS_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); @@ -36215,10 +36213,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); if (IS_VAR == IS_VAR && - value_ptr && - !Z_ISREF_P(value_ptr) && opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)) { + !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) && + !Z_ISREF_P(value_ptr)) { if (!(free_op2.var != NULL)) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } @@ -36233,13 +36230,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE PZVAL_LOCK(value_ptr); } } + + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || (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"); @@ -39257,7 +39254,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { zend_assign_to_string_offset(variable_ptr, value, IS_CV, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); @@ -39299,10 +39296,9 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC); if (IS_CV == IS_VAR && - value_ptr && - !Z_ISREF_P(value_ptr) && opline->extended_value == ZEND_RETURNS_FUNCTION && - !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)) { + !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) && + !Z_ISREF_P(value_ptr)) { if (!0) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } @@ -39317,13 +39313,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER PZVAL_LOCK(value_ptr); } } + + variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) && UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - - variable_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || (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"); diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 56a923b6a5..5614052520 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -171,6 +171,24 @@ $op2_get_zval_ptr_deref = array( "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); +$op1_get_zval_ptr_ptr_undef = array( + "ANY" => "get_zval_ptr_ptr_undef(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var TSRMLS_CC)", +); + +$op2_get_zval_ptr_ptr_undef = array( + "ANY" => "get_zval_ptr_ptr_undef(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", + "TMP" => "NULL", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "CONST" => "NULL", + "UNUSED" => "NULL", + "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var TSRMLS_CC)", +); + $op1_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", @@ -348,6 +366,7 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr, $op1_get_zval_ptr_deref, $op2_get_zval_ptr_deref, $op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr, + $op1_get_zval_ptr_ptr_undef, $op2_get_zval_ptr_ptr_undef, $op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr, $op1_get_obj_zval_ptr_deref, $op2_get_obj_zval_ptr_deref, $op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr, @@ -369,6 +388,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { "/GET_OP2_ZVAL_PTR_DEREF\(([^)]*)\)/", "/GET_OP1_ZVAL_PTR_PTR\(([^)]*)\)/", "/GET_OP2_ZVAL_PTR_PTR\(([^)]*)\)/", + "/GET_OP1_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/", + "/GET_OP2_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/", "/GET_OP1_OBJ_ZVAL_PTR\(([^)]*)\)/", "/GET_OP2_OBJ_ZVAL_PTR\(([^)]*)\)/", "/GET_OP1_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/", @@ -407,6 +428,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) { $op2_get_zval_ptr_deref[$op2], $op1_get_zval_ptr_ptr[$op1], $op2_get_zval_ptr_ptr[$op2], + $op1_get_zval_ptr_ptr_undef[$op1], + $op2_get_zval_ptr_ptr_undef[$op2], $op1_get_obj_zval_ptr[$op1], $op2_get_obj_zval_ptr[$op2], $op1_get_obj_zval_ptr_deref[$op1],