@@ -5677,78 +5677,27 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
56775677 zend_ast * value_ast = ast -> child [1 ];
56785678 zend_ast * key_ast = ast -> child [2 ];
56795679 zend_ast * stmt_ast = ast -> child [3 ];
5680+ znode expr_node , reset_node , value_node , key_node ;
5681+ zend_op * opline ;
5682+ uint32_t opnum_reset , opnum_fetch ;
56805683
5681- if (!value_ast && !key_ast ) {
5682- bool by_ref = value_ast && value_ast -> kind == ZEND_AST_REF ;
5683- bool is_variable = zend_is_variable (expr_ast ) && zend_can_write_to_variable (expr_ast );
5684-
5685- znode expr_node , reset_node , value_node , key_node ;
5686- zend_op * opline ;
5687- uint32_t opnum_reset , opnum_fetch ;
5688-
5689- if (key_ast ) {
5690- if (key_ast -> kind == ZEND_AST_REF ) {
5691- zend_error_noreturn (E_COMPILE_ERROR , "Key element cannot be a reference" );
5692- }
5693- if (key_ast -> kind == ZEND_AST_ARRAY ) {
5694- zend_error_noreturn (E_COMPILE_ERROR , "Cannot use list as key element" );
5695- }
5696- }
5697-
5698- if (by_ref ) {
5699- value_ast = value_ast -> child [0 ];
5700- }
5701-
5702- if (value_ast && value_ast -> kind == ZEND_AST_ARRAY && zend_propagate_list_refs (value_ast )) {
5703- by_ref = 1 ;
5704- }
5705-
5706- if (by_ref && is_variable ) {
5707- zend_compile_var (& expr_node , expr_ast , BP_VAR_W , 1 );
5708- } else {
5709- zend_compile_expr (& expr_node , expr_ast );
5710- }
5711-
5712- if (by_ref ) {
5713- zend_separate_if_call_and_write (& expr_node , expr_ast , BP_VAR_W );
5714- }
5684+ if (!value_ast ) {
57155685
5686+ zend_compile_expr (& expr_node , expr_ast );
57165687 opnum_reset = get_next_op_number ();
5717- opline = zend_emit_op (& reset_node , by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R , & expr_node , NULL );
5688+ opline = zend_emit_op (& reset_node , ZEND_FE_RESET_R , & expr_node , NULL );
57185689
57195690 zend_begin_loop (ZEND_FE_FREE , & reset_node , 0 );
57205691
57215692 opnum_fetch = get_next_op_number ();
5722- opline = zend_emit_op (NULL , by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R , & reset_node , NULL );
5723-
5724- if (value_ast && is_this_fetch (value_ast )) {
5725- zend_error_noreturn (E_COMPILE_ERROR , "Cannot re-assign $this" );
5726- } else if (value_ast && value_ast -> kind == ZEND_AST_VAR && zend_try_compile_cv (& value_node , value_ast ) == SUCCESS ) {
5727- SET_NODE (opline -> op2 , & value_node );
5728- } else {
5729- opline -> op2_type = IS_VAR ;
5730- opline -> op2 .var = get_temporary_variable ();
5731- GET_NODE (& value_node , opline -> op2 );
5732- if (value_ast -> kind == ZEND_AST_ARRAY ) {
5733- zend_compile_list_assign (NULL , value_ast , & value_node , value_ast -> attr );
5734- } else if (by_ref ) {
5735- zend_emit_assign_ref_znode (value_ast , & value_node );
5736- } else {
5737- zend_emit_assign_znode (value_ast , & value_node );
5738- }
5739- }
5693+ opline = zend_emit_op (NULL , ZEND_FE_FETCH_R , & reset_node , NULL );
57405694
5741- if (key_ast ) {
5742- opline = & CG (active_op_array )-> opcodes [opnum_fetch ];
5743- zend_make_tmp_result (& key_node , opline );
5744- zend_emit_assign_znode (key_ast , & key_node );
5745- }
5695+ opline -> op2_type = IS_VAR ;
5696+ opline -> op2 .var = get_temporary_variable ();
5697+ GET_NODE (& value_node , opline -> op2 );
57465698
57475699 zend_compile_stmt (stmt_ast );
57485700
5749- /* Place JMP and FE_FREE on the line where foreach starts. It would be
5750- * better to use the end line, but this information is not available
5751- * currently. */
57525701 CG (zend_lineno ) = ast -> lineno ;
57535702 zend_emit_jump (opnum_fetch );
57545703
@@ -5761,14 +5710,11 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
57615710 zend_end_loop (opnum_fetch , & reset_node );
57625711
57635712 opline = zend_emit_op (NULL , ZEND_FE_FREE , & reset_node , NULL );
5713+
57645714 } else {
5765- bool by_ref = value_ast && value_ast -> kind == ZEND_AST_REF ;
5715+ bool by_ref = value_ast -> kind == ZEND_AST_REF ;
57665716 bool is_variable = zend_is_variable (expr_ast ) && zend_can_write_to_variable (expr_ast );
57675717
5768- znode expr_node , reset_node , value_node , key_node ;
5769- zend_op * opline ;
5770- uint32_t opnum_reset , opnum_fetch ;
5771-
57725718 if (key_ast ) {
57735719 if (key_ast -> kind == ZEND_AST_REF ) {
57745720 zend_error_noreturn (E_COMPILE_ERROR , "Key element cannot be a reference" );
@@ -5782,7 +5728,7 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
57825728 value_ast = value_ast -> child [0 ];
57835729 }
57845730
5785- if (value_ast && value_ast -> kind == ZEND_AST_ARRAY && zend_propagate_list_refs (value_ast )) {
5731+ if (value_ast -> kind == ZEND_AST_ARRAY && zend_propagate_list_refs (value_ast )) {
57865732 by_ref = 1 ;
57875733 }
57885734
@@ -5797,31 +5743,27 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
57975743 }
57985744
57995745 opnum_reset = get_next_op_number ();
5800- opline = zend_emit_op (& reset_node , ZEND_FE_RESET_R , & expr_node , NULL );
5746+ opline = zend_emit_op (& reset_node , by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R , & expr_node , NULL );
58015747
58025748 zend_begin_loop (ZEND_FE_FREE , & reset_node , 0 );
58035749
58045750 opnum_fetch = get_next_op_number ();
5805- opline = zend_emit_op (NULL , ZEND_FE_FETCH_R , & reset_node , NULL );
5806- if (value_ast ) {
5807- if (is_this_fetch (value_ast )) {
5808- zend_error_noreturn (E_COMPILE_ERROR , "Cannot re-assign $this" );
5809- } else
5810- if (value_ast -> kind == ZEND_AST_VAR && zend_try_compile_cv (& value_node , value_ast ) == SUCCESS ) {
5811- SET_NODE (opline -> op2 , & value_node );
5812- }
5813- else {
5814- opline -> op2_type = IS_VAR ;
5815- opline -> op2 .var = get_temporary_variable ();
5816- GET_NODE (& value_node , opline -> op2 );
5817- if (value_ast -> kind == ZEND_AST_ARRAY ) {
5818- zend_compile_list_assign (NULL , value_ast , & value_node , value_ast -> attr );
5819- } else
5820- if (by_ref ) {
5821- zend_emit_assign_ref_znode (value_ast , & value_node );
5822- } else {
5823- zend_emit_assign_znode (value_ast , & value_node );
5824- }
5751+ opline = zend_emit_op (NULL , by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R , & reset_node , NULL );
5752+ if (is_this_fetch (value_ast )) {
5753+ zend_error_noreturn (E_COMPILE_ERROR , "Cannot re-assign $this" );
5754+ } else if (value_ast -> kind == ZEND_AST_VAR &&
5755+ zend_try_compile_cv (& value_node , value_ast ) == SUCCESS ) {
5756+ SET_NODE (opline -> op2 , & value_node );
5757+ } else {
5758+ opline -> op2_type = IS_VAR ;
5759+ opline -> op2 .var = get_temporary_variable ();
5760+ GET_NODE (& value_node , opline -> op2 );
5761+ if (value_ast -> kind == ZEND_AST_ARRAY ) {
5762+ zend_compile_list_assign (NULL , value_ast , & value_node , value_ast -> attr );
5763+ } else if (by_ref ) {
5764+ zend_emit_assign_ref_znode (value_ast , & value_node );
5765+ } else {
5766+ zend_emit_assign_znode (value_ast , & value_node );
58255767 }
58265768 }
58275769
0 commit comments