@@ -509,6 +509,49 @@ static void zend_check_finally_breakout(zend_op_array *op_array, zend_uint op_nu
509
509
}
510
510
}
511
511
512
+ static void zend_adjust_fast_call (zend_op_array * op_array , zend_uint fast_call , zend_uint start , zend_uint end TSRMLS_DC )
513
+ {
514
+ int i ;
515
+ zend_uint op_num = 0 ;
516
+
517
+ for (i = 0 ; i < op_array -> last_try_catch ; i ++ ) {
518
+ if (op_array -> try_catch_array [i ].finally_op > start
519
+ && op_array -> try_catch_array [i ].finally_end < end ) {
520
+ op_num = op_array -> try_catch_array [i ].finally_op ;
521
+ start = op_array -> try_catch_array [i ].finally_end ;
522
+ }
523
+ }
524
+
525
+ if (op_num ) {
526
+ /* Must be ZEND_FAST_CALL */
527
+ ZEND_ASSERT (op_array -> opcodes [op_num - 2 ].opcode == ZEND_FAST_CALL );
528
+ op_array -> opcodes [op_num - 2 ].extended_value = ZEND_FAST_CALL_FROM_FINALLY ;
529
+ op_array -> opcodes [op_num - 2 ].op2 .opline_num = fast_call ;
530
+ }
531
+ }
532
+
533
+ static void zend_resolve_fast_call (zend_op_array * op_array , zend_uint fast_call , zend_uint op_num TSRMLS_DC )
534
+ {
535
+ int i ;
536
+ zend_uint finally_op_num = 0 ;
537
+
538
+ for (i = 0 ; i < op_array -> last_try_catch ; i ++ ) {
539
+ if (op_num >= op_array -> try_catch_array [i ].finally_op
540
+ && op_num < op_array -> try_catch_array [i ].finally_end ) {
541
+ finally_op_num = op_array -> try_catch_array [i ].finally_op ;
542
+ }
543
+ }
544
+
545
+ if (finally_op_num ) {
546
+ /* Must be ZEND_FAST_CALL */
547
+ ZEND_ASSERT (op_array -> opcodes [finally_op_num - 2 ].opcode == ZEND_FAST_CALL );
548
+ if (op_array -> opcodes [fast_call ].extended_value == 0 ) {
549
+ op_array -> opcodes [fast_call ].extended_value = ZEND_FAST_CALL_FROM_FINALLY ;
550
+ op_array -> opcodes [fast_call ].op2 .opline_num = finally_op_num - 2 ;
551
+ }
552
+ }
553
+ }
554
+
512
555
static void zend_resolve_finally_call (zend_op_array * op_array , zend_uint op_num , zend_uint dst_num TSRMLS_DC )
513
556
{
514
557
zend_uint start_op ;
@@ -536,11 +579,23 @@ static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num,
536
579
opline -> opcode = ZEND_FAST_CALL ;
537
580
SET_UNUSED (opline -> op1 );
538
581
SET_UNUSED (opline -> op2 );
539
- opline -> op1 .opline_num = op_array -> try_catch_array [i ].finally_op ;
582
+ zend_adjust_fast_call (op_array , start_op ,
583
+ op_array -> try_catch_array [i ].finally_op ,
584
+ op_array -> try_catch_array [i ].finally_end TSRMLS_CC );
540
585
if (op_array -> try_catch_array [i ].catch_op ) {
541
- opline -> extended_value = ZEND_FAST_CALL_FOR_CATCH ;
586
+ opline -> extended_value = ZEND_FAST_CALL_FROM_CATCH ;
542
587
opline -> op2 .opline_num = op_array -> try_catch_array [i ].catch_op ;
588
+ opline -> op1 .opline_num = get_next_op_number (op_array );
589
+ /* generate a FAST_CALL to hole CALL_FROM_FINALLY */
590
+ opline = get_next_op (op_array TSRMLS_CC );
591
+ opline -> opcode = ZEND_FAST_CALL ;
592
+ SET_UNUSED (opline -> op1 );
593
+ SET_UNUSED (opline -> op2 );
594
+ zend_resolve_fast_call (op_array , start_op + 1 , op_array -> try_catch_array [i ].finally_op - 2 TSRMLS_CC );
595
+ } else {
596
+ zend_resolve_fast_call (op_array , start_op , op_array -> try_catch_array [i ].finally_op - 2 TSRMLS_CC );
543
597
}
598
+ opline -> op1 .opline_num = op_array -> try_catch_array [i ].finally_op ;
544
599
545
600
/* generate a sequence of FAST_CALL to upward finally block */
546
601
while (i > 0 ) {
@@ -603,26 +658,6 @@ static void zend_resolve_finally_ret(zend_op_array *op_array, zend_uint op_num T
603
658
}
604
659
}
605
660
606
- static void zend_resolve_fast_call (zend_op_array * op_array , zend_uint op_num TSRMLS_DC )
607
- {
608
- int i ;
609
- zend_uint finally_op_num = 0 ;
610
-
611
- for (i = 0 ; i < op_array -> last_try_catch ; i ++ ) {
612
- if (op_array -> try_catch_array [i ].finally_op > op_num ) {
613
- break ;
614
- }
615
- if (op_num < op_array -> try_catch_array [i ].finally_end ) {
616
- finally_op_num = op_array -> try_catch_array [i ].finally_op ;
617
- }
618
- }
619
-
620
- if (finally_op_num ) {
621
- op_array -> opcodes [op_num ].extended_value = ZEND_FAST_CALL_FOR_FINALLY ;
622
- op_array -> opcodes [op_num ].op2 .opline_num = finally_op_num - 2 ; /* it must be ZEND_FAST_CALL */
623
- }
624
- }
625
-
626
661
static void zend_resolve_finally_calls (zend_op_array * op_array TSRMLS_DC )
627
662
{
628
663
zend_uint i , j ;
@@ -666,7 +701,7 @@ static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
666
701
zend_resolve_finally_call (op_array , i , opline -> op1 .opline_num TSRMLS_CC );
667
702
break ;
668
703
case ZEND_FAST_CALL :
669
- zend_resolve_fast_call (op_array , i TSRMLS_CC );
704
+ zend_resolve_fast_call (op_array , i , i TSRMLS_CC );
670
705
break ;
671
706
case ZEND_FAST_RET :
672
707
zend_resolve_finally_ret (op_array , i TSRMLS_CC );
0 commit comments