@@ -5239,8 +5239,24 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
52395239
52405240 uint32_t num_conds = count_match_conds (arms );
52415241 zend_uchar jumptable_type = determine_match_jumptable_type (arms );
5242+ zend_bool uses_jumptable = jumptable_type != IS_UNDEF && should_use_jumptable (num_conds , jumptable_type );
52425243 HashTable * jumptable = NULL ;
5243- if (jumptable_type != IS_UNDEF && should_use_jumptable (num_conds , jumptable_type )) {
5244+ uint32_t * jmpnz_opnums = NULL ;
5245+
5246+ for (uint32_t i = 0 ; i < arms -> children ; ++ i ) {
5247+ zend_ast * arm_ast = arms -> child [i ];
5248+
5249+ if (!arm_ast -> child [0 ]) {
5250+ if (has_default_arm ) {
5251+ CG (zend_lineno ) = arm_ast -> lineno ;
5252+ zend_error_noreturn (E_COMPILE_ERROR ,
5253+ "Match expressions may only contain one default arm" );
5254+ }
5255+ has_default_arm = 1 ;
5256+ }
5257+ }
5258+
5259+ if (uses_jumptable ) {
52445260 znode jumptable_op ;
52455261
52465262 ALLOC_HASHTABLE (jumptable );
@@ -5255,53 +5271,51 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
52555271 Z_TRY_ADDREF_P (CT_CONSTANT (opline -> op1 ));
52565272 }
52575273 opnum_match = opline - CG (active_op_array )-> opcodes ;
5258- }
5259-
5260- uint32_t cond_count = 0 ;
5261- uint32_t * jmpnz_opnums = safe_emalloc (sizeof (uint32_t ), num_conds , 0 );
5262- for (uint32_t i = 0 ; i < arms -> children ; ++ i ) {
5263- zend_ast * arm_ast = arms -> child [i ];
5274+ } else {
5275+ jmpnz_opnums = safe_emalloc (sizeof (uint32_t ), num_conds , 0 );
5276+ int cond_count = 0 ;
5277+ for (uint32_t i = 0 ; i < arms -> children ; ++ i ) {
5278+ zend_ast * arm_ast = arms -> child [i ];
52645279
5265- if (!arm_ast -> child [0 ]) {
5266- if (has_default_arm ) {
5267- CG (zend_lineno ) = arm_ast -> lineno ;
5268- zend_error_noreturn (E_COMPILE_ERROR ,
5269- "Match expressions may only contain one default arm" );
5280+ if (!arm_ast -> child [0 ]) {
5281+ continue ;
52705282 }
5271- has_default_arm = 1 ;
5272- continue ;
5273- }
52745283
5275- zend_ast_list * conds = zend_ast_get_list (arm_ast -> child [0 ]);
5276- for (uint32_t j = 0 ; j < conds -> children ; j ++ ) {
5277- zend_ast * cond_ast = conds -> child [j ];
5284+ zend_ast_list * conds = zend_ast_get_list (arm_ast -> child [0 ]);
5285+ for (uint32_t j = 0 ; j < conds -> children ; j ++ ) {
5286+ zend_ast * cond_ast = conds -> child [j ];
52785287
5279- znode cond_node ;
5280- zend_compile_expr (& cond_node , cond_ast );
5288+ znode cond_node ;
5289+ zend_compile_expr (& cond_node , cond_ast );
52815290
5282- if (expr_node .op_type == IS_CONST
5283- && Z_TYPE (expr_node .u .constant ) == IS_FALSE ) {
5284- jmpnz_opnums [cond_count ] = zend_emit_cond_jump (ZEND_JMPZ , & cond_node , 0 );
5285- } else if (expr_node .op_type == IS_CONST
5286- && Z_TYPE (expr_node .u .constant ) == IS_TRUE ) {
5287- jmpnz_opnums [cond_count ] = zend_emit_cond_jump (ZEND_JMPNZ , & cond_node , 0 );
5288- } else {
5289- zend_op * opline = zend_emit_op (NULL , ZEND_IS_IDENTICAL , & expr_node , & cond_node );
5290- SET_NODE (opline -> result , & case_node );
5291- if (opline -> op1_type == IS_CONST ) {
5292- Z_TRY_ADDREF_P (CT_CONSTANT (opline -> op1 ));
5291+ if (expr_node .op_type == IS_CONST
5292+ && Z_TYPE (expr_node .u .constant ) == IS_FALSE ) {
5293+ jmpnz_opnums [cond_count ] = zend_emit_cond_jump (ZEND_JMPZ , & cond_node , 0 );
5294+ } else if (expr_node .op_type == IS_CONST
5295+ && Z_TYPE (expr_node .u .constant ) == IS_TRUE ) {
5296+ jmpnz_opnums [cond_count ] = zend_emit_cond_jump (ZEND_JMPNZ , & cond_node , 0 );
5297+ } else {
5298+ zend_op * opline = zend_emit_op (NULL , ZEND_IS_IDENTICAL , & expr_node , & cond_node );
5299+ SET_NODE (opline -> result , & case_node );
5300+ if (opline -> op1_type == IS_CONST ) {
5301+ Z_TRY_ADDREF_P (CT_CONSTANT (opline -> op1 ));
5302+ }
5303+
5304+ jmpnz_opnums [cond_count ] = zend_emit_cond_jump (ZEND_JMPNZ , & case_node , 0 );
52935305 }
52945306
5295- jmpnz_opnums [ cond_count ] = zend_emit_cond_jump ( ZEND_JMPNZ , & case_node , 0 ) ;
5307+ cond_count ++ ;
52965308 }
5297-
5298- cond_count ++ ;
52995309 }
53005310 }
53015311
5302- uint32_t opnum_default_jmp = zend_emit_jump (0 );
5312+ uint32_t opnum_default_jmp ;
5313+ if (!uses_jumptable ) {
5314+ opnum_default_jmp = zend_emit_jump (0 );
5315+ }
5316+
53035317 zend_bool is_first_case = 1 ;
5304- cond_count = 0 ;
5318+ uint32_t cond_count = 0 ;
53055319
53065320 for (uint32_t i = 0 ; i < arms -> children ; ++ i ) {
53075321 zend_ast * arm_ast = arms -> child [i ];
@@ -5312,7 +5326,10 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
53125326
53135327 for (uint32_t j = 0 ; j < conds -> children ; j ++ ) {
53145328 zend_ast * cond_ast = conds -> child [j ];
5315- zend_update_jump_target_to_next (jmpnz_opnums [cond_count ]);
5329+
5330+ if (jmpnz_opnums != NULL ) {
5331+ zend_update_jump_target_to_next (jmpnz_opnums [cond_count ]);
5332+ }
53165333
53175334 if (jumptable ) {
53185335 zval * cond_zv = zend_ast_get_zval (cond_ast );
@@ -5331,7 +5348,9 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
53315348 cond_count ++ ;
53325349 }
53335350 } else {
5334- zend_update_jump_target_to_next (opnum_default_jmp );
5351+ if (!uses_jumptable ) {
5352+ zend_update_jump_target_to_next (opnum_default_jmp );
5353+ }
53355354
53365355 if (jumptable ) {
53375356 ZEND_ASSERT (opnum_match != (uint32_t )-1 );
@@ -5364,7 +5383,9 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
53645383 }
53655384
53665385 if (!has_default_arm ) {
5367- zend_update_jump_target_to_next (opnum_default_jmp );
5386+ if (!uses_jumptable ) {
5387+ zend_update_jump_target_to_next (opnum_default_jmp );
5388+ }
53685389
53695390 if (jumptable ) {
53705391 zend_op * opline = & CG (active_op_array )-> opcodes [opnum_match ];
@@ -5392,7 +5413,9 @@ void zend_compile_match(znode *result, zend_ast *ast) /* {{{ */
53925413 zval_ptr_dtor_nogc (& expr_node .u .constant );
53935414 }
53945415
5395- efree (jmpnz_opnums );
5416+ if (jmpnz_opnums != NULL ) {
5417+ efree (jmpnz_opnums );
5418+ }
53965419}
53975420/* }}} */
53985421
0 commit comments