@@ -6641,6 +6641,10 @@ static void zend_compile_pipe(znode *result, zend_ast *ast)
66416641 zend_compile_expr (result , fcall_ast );
66426642}
66436643
6644+ /* Exit in a joined branch for true/false, leaving the evaluated result in the
6645+ * given temporary. */
6646+ #define ZEND_PM_LABEL_EMPTY ((uint32_t)-1)
6647+
66446648typedef struct {
66456649 bool inside_or_pattern ;
66466650 zend_stack labels ;
@@ -6725,51 +6729,16 @@ static void zend_pm_emit_jmpnz_ex(znode *result, uint32_t opnum_target)
67256729 SET_NODE (opline -> result , result );
67266730}
67276731
6728- static void zend_pm_kill_last_op_if_jmp (zend_pm_context * context )
6729- {
6730- zend_op_array * op_array = CG (active_op_array );
6731- zend_op * opline = & op_array -> opcodes [op_array -> last - 1 ];
6732- uint32_t * labels = zend_stack_base (& context -> labels );
6733- uint32_t label_lower_bound = - zend_stack_count (& context -> labels );
6734-
6735- uint32_t label_idx ;
6736- switch (opline -> opcode ) {
6737- case ZEND_JMP :
6738- label_idx = opline -> op1 .opline_num ;
6739- break ;
6740- case ZEND_JMPZ_EX :
6741- case ZEND_JMPNZ_EX :
6742- label_idx = opline -> op2 .opline_num ;
6743- break ;
6744- default :
6745- return ;
6746- }
6747-
6748- ZEND_ASSERT (label_idx >= label_lower_bound );
6749- uint32_t label_target = labels [- label_idx ];
6750- ZEND_ASSERT (label_target == op_array -> last );
6751-
6752- MAKE_NOP (opline );
6753- op_array -> last -- ;
6754-
6755- uint32_t * label = labels ;
6756- uint32_t * label_end = zend_stack_top (& context -> labels );
6757- while (label <= label_end ) {
6758- if (* label == label_target ) {
6759- (* label )-- ;
6760- }
6761- label ++ ;
6762- }
6763- }
6764-
67656732static void zend_pm_compile_expr_like (zend_ast * ast , znode * result , znode * expr_node , bool consume_expr , uint32_t false_opnum )
67666733{
67676734 znode value ;
67686735 zend_compile_expr (& value , ast -> child [0 ]);
67696736 zend_op * opline = zend_emit_op_tmp (NULL , expr_node -> op_type == IS_CV || consume_expr ? ZEND_IS_IDENTICAL : ZEND_CASE_STRICT , expr_node , & value );
67706737 SET_NODE (opline -> result , result );
67716738
6772- zend_pm_emit_jmpz_ex (result , false_opnum );
6739+ if (false_opnum != ZEND_PM_LABEL_EMPTY ) {
6740+ zend_pm_emit_jmpz_ex (result , false_opnum );
6741+ }
67736742}
67746743
67756744static void zend_pm_verify_parenthesized_compound_pattern (zend_ast * ast , zend_ast_kind kind )
@@ -6791,27 +6760,31 @@ static void zend_pm_compile_or(zend_ast *ast, znode *result, znode *expr_node, b
67916760 context -> inside_or_pattern = true;
67926761
67936762 zend_ast_list * ast_list = zend_ast_get_list (ast );
6794- uint32_t true_label = zend_pm_label_create (context );
6795- uint32_t false_label = consume_expr ? zend_pm_label_create (context ) : false_opnum ;
6763+ uint32_t end_label = zend_pm_label_create (context );
6764+ bool create_false_label = consume_expr || false_opnum == ZEND_PM_LABEL_EMPTY ;
6765+ uint32_t false_label = create_false_label ? end_label : false_opnum ;
67966766 uint32_t next_label = 0 ;
67976767
67986768 for (uint32_t i = 0 ; i < ast_list -> children - 1 ; i ++ ) {
67996769 if (next_label ) {
68006770 zend_pm_label_set_next (context , next_label );
68016771 }
68026772 next_label = zend_pm_label_create (context );
6803- zend_compile_pattern (ast_list -> child [i ], result , expr_node , false, ( uint32_t ) -1 , context );
6804- zend_pm_emit_jmpnz_ex (result , true_label );
6773+ zend_compile_pattern (ast_list -> child [i ], result , expr_node , false, ZEND_PM_LABEL_EMPTY , context );
6774+ zend_pm_emit_jmpnz_ex (result , end_label );
68056775 }
68066776 zend_pm_label_set_next (context , next_label );
68076777
68086778 zend_compile_pattern (ast_list -> child [ast_list -> children - 1 ], result , expr_node , false, false_label , context );
68096779
6810- zend_pm_label_set_next (context , true_label );
6811- if (consume_expr ) {
6812- zend_pm_label_set_next (context , false_label );
6813- zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6814- zend_pm_emit_jmpz_ex (result , false_opnum );
6780+ zend_pm_label_set_next (context , end_label );
6781+ if (create_false_label ) {
6782+ if (consume_expr ) {
6783+ zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6784+ }
6785+ if (false_opnum != ZEND_PM_LABEL_EMPTY ) {
6786+ zend_pm_emit_jmpz_ex (result , false_opnum );
6787+ }
68156788 }
68166789
68176790 context -> inside_or_pattern = false;
@@ -6822,16 +6795,21 @@ static void zend_pm_compile_and(zend_ast *ast, znode *result, znode *expr_node,
68226795 zend_pm_verify_parenthesized_compound_pattern (ast , ZEND_AST_OR_PATTERN );
68236796
68246797 zend_ast_list * ast_list = zend_ast_get_list (ast );
6825- uint32_t false_label = consume_expr ? zend_pm_label_create (context ) : false_opnum ;
6798+ bool create_false_label = consume_expr || false_opnum == ZEND_PM_LABEL_EMPTY ;
6799+ uint32_t false_label = create_false_label ? zend_pm_label_create (context ) : false_opnum ;
68266800
68276801 for (uint32_t i = 0 ; i < ast_list -> children ; i ++ ) {
68286802 zend_compile_pattern (ast_list -> child [i ], result , expr_node , false, false_label , context );
68296803 }
68306804
6831- if (consume_expr ) {
6805+ if (create_false_label ) {
68326806 zend_pm_label_set_next (context , false_label );
6833- zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6834- zend_pm_emit_jmpz_ex (result , false_opnum );
6807+ if (consume_expr ) {
6808+ zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6809+ }
6810+ if (false_opnum != ZEND_PM_LABEL_EMPTY ) {
6811+ zend_pm_emit_jmpz_ex (result , false_opnum );
6812+ }
68356813 }
68366814}
68376815
@@ -6858,7 +6836,9 @@ static void zend_pm_compile_type(zend_ast *ast, znode *result, znode *expr_node,
68586836 if (consume_expr ) {
68596837 zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
68606838 }
6861- zend_pm_emit_jmpz_ex (result , false_opnum );
6839+ if (false_opnum != ZEND_PM_LABEL_EMPTY ) {
6840+ zend_pm_emit_jmpz_ex (result , false_opnum );
6841+ }
68626842}
68636843
68646844static void zend_pm_copy_tmp (znode * dest , znode * src , bool consume )
@@ -6910,7 +6890,8 @@ static void zend_pm_compile_container(
69106890) {
69116891 znode expr_copy_node ;
69126892
6913- uint32_t false_label = consume_expr ? zend_pm_label_create (context ) : false_opnum ;
6893+ bool create_false_label = consume_expr || false_opnum == ZEND_PM_LABEL_EMPTY ;
6894+ uint32_t false_label = create_false_label ? zend_pm_label_create (context ) : false_opnum ;
69146895 zend_ast_list * element_list = zend_ast_get_list (ast -> child [0 ]);
69156896
69166897 /* Make sure the value is actually of the right type. */
@@ -6966,10 +6947,14 @@ static void zend_pm_compile_container(
69666947 zend_compile_pattern (element_value_ast , result , & element_value_node , true, false_label , context );
69676948 }
69686949
6969- if (consume_expr ) {
6950+ if (create_false_label ) {
69706951 zend_pm_label_set_next (context , false_label );
6971- zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6972- zend_pm_emit_jmpz_ex (result , false_opnum );
6952+ if (consume_expr ) {
6953+ zend_emit_op (NULL , ZEND_FREE , expr_node , NULL );
6954+ }
6955+ if (false_opnum != ZEND_PM_LABEL_EMPTY ) {
6956+ zend_pm_emit_jmpz_ex (result , false_opnum );
6957+ }
69736958 }
69746959
69756960 if (has_implicit && has_explicit ) {
@@ -6979,11 +6964,6 @@ static void zend_pm_compile_container(
69796964
69806965static void zend_compile_pattern (zend_ast * ast , znode * result , znode * expr_node , bool consume_expr , uint32_t false_opnum , zend_pm_context * context )
69816966{
6982- bool create_label = false_opnum == (uint32_t )-1 ;
6983- if (create_label ) {
6984- false_opnum = zend_pm_label_create (context );
6985- }
6986-
69876967 switch (ast -> kind ) {
69886968 case ZEND_AST_EXPR_LIKE_PATTERN :
69896969 zend_pm_compile_expr_like (ast , result , expr_node , consume_expr , false_opnum );
@@ -7008,11 +6988,6 @@ static void zend_compile_pattern(zend_ast *ast, znode *result, znode *expr_node,
70086988 break ;
70096989 EMPTY_SWITCH_DEFAULT_CASE ();
70106990 }
7011-
7012- if (create_label ) {
7013- zend_pm_label_set_next (context , false_opnum );
7014- zend_pm_kill_last_op_if_jmp (context );
7015- }
70166991}
70176992
70186993static void zend_pm_count_bindings (zend_ast * * ast_ptr , void * context )
@@ -7061,7 +7036,7 @@ static void zend_emit_is(znode *result, znode *expr_node, bool consume_expr, zen
70617036 }
70627037
70637038 uint32_t start_opnum = get_next_op_number ();
7064- uint32_t false_label = context .num_bindings ? zend_pm_label_create (& context ) : -1 ;
7039+ uint32_t false_label = context .num_bindings ? zend_pm_label_create (& context ) : ZEND_PM_LABEL_EMPTY ;
70657040 zend_compile_pattern (pattern_ast , result , & expr_copy_node , consume_expr , false_label , & context );
70667041
70677042 if (context .num_bindings ) {
0 commit comments