@@ -218,16 +218,22 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */
218
218
CG (context ).opcodes_size = INITIAL_OP_ARRAY_SIZE ;
219
219
CG (context ).vars_size = 0 ;
220
220
CG (context ).literals_size = 0 ;
221
- CG (context ).current_brk_cont = -1 ;
222
221
CG (context ).backpatch_count = 0 ;
223
222
CG (context ).in_finally = 0 ;
224
223
CG (context ).fast_call_var = -1 ;
224
+ CG (context ).current_brk_cont = -1 ;
225
+ CG (context ).last_brk_cont = 0 ;
226
+ CG (context ).brk_cont_array = NULL ;
225
227
CG (context ).labels = NULL ;
226
228
}
227
229
/* }}} */
228
230
229
231
void zend_oparray_context_end (zend_oparray_context * prev_context ) /* {{{ */
230
232
{
233
+ if (CG (context ).brk_cont_array ) {
234
+ efree (CG (context ).brk_cont_array );
235
+ CG (context ).brk_cont_array = NULL ;
236
+ }
231
237
if (CG (context ).labels ) {
232
238
zend_hash_destroy (CG (context ).labels );
233
239
FREE_HASHTABLE (CG (context ).labels );
@@ -567,14 +573,28 @@ void zend_stop_lexing(void)
567
573
LANG_SCNG (yy_cursor ) = LANG_SCNG (yy_limit );
568
574
}
569
575
576
+ static void zend_add_live_range (zend_op_array * op_array , uint32_t start , uint32_t end ) /* {{{ */
577
+ {
578
+ zend_live_range * range ;
579
+
580
+ if (start != end ) {
581
+ op_array -> last_live_range ++ ;
582
+ op_array -> live_range = erealloc (op_array -> live_range , sizeof (zend_live_range ) * op_array -> last_live_range );
583
+ range = op_array -> live_range + op_array -> last_live_range - 1 ;
584
+ range -> start = start ;
585
+ range -> end = end ;
586
+ }
587
+ }
588
+ /* }}} */
589
+
570
590
static inline void zend_begin_loop (zend_uchar free_opcode , const znode * loop_var ) /* {{{ */
571
591
{
572
592
zend_brk_cont_element * brk_cont_element ;
573
593
int parent = CG (context ).current_brk_cont ;
574
594
zend_loop_var info = {0 };
575
595
576
- CG (context ).current_brk_cont = CG (active_op_array ) -> last_brk_cont ;
577
- brk_cont_element = get_next_brk_cont_element (CG ( active_op_array ) );
596
+ CG (context ).current_brk_cont = CG (context ). last_brk_cont ;
597
+ brk_cont_element = get_next_brk_cont_element ();
578
598
brk_cont_element -> parent = parent ;
579
599
580
600
if (loop_var && (loop_var -> op_type & (IS_VAR |IS_TMP_VAR ))) {
@@ -597,7 +617,7 @@ static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var
597
617
static inline void zend_end_loop (int cont_addr ) /* {{{ */
598
618
{
599
619
zend_brk_cont_element * brk_cont_element
600
- = & CG (active_op_array ) -> brk_cont_array [CG (context ).current_brk_cont ];
620
+ = & CG (context ). brk_cont_array [CG (context ).current_brk_cont ];
601
621
brk_cont_element -> cont = cont_addr ;
602
622
brk_cont_element -> brk = get_next_op_number (CG (active_op_array ));
603
623
CG (context ).current_brk_cont = brk_cont_element -> parent ;
@@ -3734,14 +3754,14 @@ void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */
3734
3754
ZVAL_NULL (label );
3735
3755
3736
3756
current = opline -> extended_value ;
3737
- for (; current != dest -> brk_cont ; current = op_array -> brk_cont_array [current ].parent ) {
3757
+ for (; current != dest -> brk_cont ; current = CG ( context ). brk_cont_array [current ].parent ) {
3738
3758
if (current == -1 ) {
3739
3759
CG (in_compilation ) = 1 ;
3740
3760
CG (active_op_array ) = op_array ;
3741
3761
CG (zend_lineno ) = opline -> lineno ;
3742
3762
zend_error_noreturn (E_COMPILE_ERROR , "'goto' into loop or switch statement is disallowed" );
3743
3763
}
3744
- if (op_array -> brk_cont_array [current ].start >= 0 ) {
3764
+ if (CG ( context ). brk_cont_array [current ].start >= 0 ) {
3745
3765
remove_oplines -- ;
3746
3766
}
3747
3767
}
@@ -3989,7 +4009,9 @@ void zend_compile_foreach(zend_ast *ast) /* {{{ */
3989
4009
3990
4010
zend_end_loop (opnum_fetch );
3991
4011
3992
- zend_emit_op (NULL , ZEND_FE_FREE , & reset_node , NULL );
4012
+ opline = zend_emit_op (NULL , ZEND_FE_FREE , & reset_node , NULL );
4013
+ zend_add_live_range (CG (active_op_array ),
4014
+ opnum_fetch , opline - CG (active_op_array )-> opcodes );
3993
4015
}
3994
4016
/* }}} */
3995
4017
@@ -4046,10 +4068,11 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
4046
4068
znode expr_node , case_node ;
4047
4069
zend_op * opline ;
4048
4070
uint32_t * jmpnz_opnums = safe_emalloc (sizeof (uint32_t ), cases -> children , 0 );
4049
- uint32_t opnum_default_jmp ;
4071
+ uint32_t opnum_default_jmp , opnum_start ;
4050
4072
4051
4073
zend_compile_expr (& expr_node , expr_ast );
4052
4074
4075
+ opnum_start = get_next_op_number (CG (active_op_array ));
4053
4076
zend_begin_loop (ZEND_FREE , & expr_node );
4054
4077
4055
4078
case_node .op_type = IS_TMP_VAR ;
@@ -4112,7 +4135,9 @@ void zend_compile_switch(zend_ast *ast) /* {{{ */
4112
4135
zend_end_loop (get_next_op_number (CG (active_op_array )));
4113
4136
4114
4137
if (expr_node .op_type == IS_VAR || expr_node .op_type == IS_TMP_VAR ) {
4115
- zend_emit_op (NULL , ZEND_FREE , & expr_node , NULL );
4138
+ opline = zend_emit_op (NULL , ZEND_FREE , & expr_node , NULL );
4139
+ zend_add_live_range (CG (active_op_array ),
4140
+ opnum_start , opline - CG (active_op_array )-> opcodes );
4116
4141
} else if (expr_node .op_type == IS_CONST ) {
4117
4142
zval_dtor (& expr_node .u .constant );
4118
4143
}
@@ -6426,8 +6451,8 @@ void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */
6426
6451
{
6427
6452
zend_ast * expr_ast = ast -> child [0 ];
6428
6453
znode silence_node ;
6429
- uint32_t begin_opline_num , end_opline_num ;
6430
- zend_brk_cont_element * brk_cont_element ;
6454
+ uint32_t begin_opline_num ;
6455
+ zend_op * opline ;
6431
6456
6432
6457
begin_opline_num = get_next_op_number (CG (active_op_array ));
6433
6458
zend_emit_op_tmp (& silence_node , ZEND_BEGIN_SILENCE , NULL , NULL );
@@ -6440,15 +6465,12 @@ void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */
6440
6465
zend_compile_expr (result , expr_ast );
6441
6466
}
6442
6467
6443
- end_opline_num = get_next_op_number (CG (active_op_array ));
6444
- zend_emit_op (NULL , ZEND_END_SILENCE , & silence_node , NULL );
6468
+ opline = zend_emit_op (NULL , ZEND_END_SILENCE , & silence_node , NULL );
6445
6469
6446
6470
/* Store BEGIN_SILENCE/END_SILENCE pair to restore previous
6447
6471
* EG(error_reporting) value on exception */
6448
- brk_cont_element = get_next_brk_cont_element (CG (active_op_array ));
6449
- brk_cont_element -> start = begin_opline_num ;
6450
- brk_cont_element -> cont = brk_cont_element -> brk = end_opline_num ;
6451
- brk_cont_element -> parent = -1 ;
6472
+ zend_add_live_range (CG (active_op_array ),
6473
+ begin_opline_num + 1 , opline - CG (active_op_array )-> opcodes );
6452
6474
}
6453
6475
/* }}} */
6454
6476
@@ -6768,10 +6790,6 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
6768
6790
GET_NODE (result , opline -> result );
6769
6791
} else {
6770
6792
uint32_t var ;
6771
- zend_brk_cont_element * info = get_next_brk_cont_element (CG (active_op_array ));
6772
- info -> start = rope_init_lineno ;
6773
- info -> parent = CG (context ).current_brk_cont ;
6774
- info -> cont = info -> brk = opline - CG (active_op_array )-> opcodes ;
6775
6793
6776
6794
init_opline -> extended_value = j ;
6777
6795
opline -> opcode = ZEND_ROPE_END ;
@@ -6785,6 +6803,10 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
6785
6803
get_temporary_variable (CG (active_op_array ));
6786
6804
i -- ;
6787
6805
}
6806
+
6807
+ zend_add_live_range (CG (active_op_array ),
6808
+ rope_init_lineno , opline - CG (active_op_array )-> opcodes );
6809
+
6788
6810
/* Update all the previous opcodes to use the same variable */
6789
6811
while (opline != init_opline ) {
6790
6812
opline -- ;
0 commit comments