]> granicus.if.org Git - php/commitdiff
Changed "finally" handling. Removed EX(fast_ret) and EX(delayed_exception). Allocate...
authorDmitry Stogov <dmitry@zend.com>
Thu, 27 Nov 2014 06:56:43 +0000 (09:56 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 27 Nov 2014 06:56:43 +0000 (09:56 +0300)
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_generators.c
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 0905c3ce5f31f7fff3f404436cd3bb207caeefdf..ea4b355b92abe18029eb09e7ae5a47ef4b9910e5 100644 (file)
@@ -159,6 +159,7 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
        CG(context).current_brk_cont = -1;
        CG(context).backpatch_count = 0;
        CG(context).in_finally = 0;
+       CG(context).fast_call_var = -1;
        CG(context).labels = NULL;
 }
 /* }}} */
@@ -3126,7 +3127,9 @@ void zend_compile_return(zend_ast *ast TSRMLS_DC) /* {{{ */
        zend_free_foreach_and_switch_variables(TSRMLS_C);
 
        if (CG(context).in_finally) {
-               zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL TSRMLS_CC);
+               opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL TSRMLS_CC);
+               opline->op1_type = IS_TMP_VAR;
+               opline->op1.var = CG(context).fast_call_var;
        }
 
        opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
@@ -3621,8 +3624,15 @@ void zend_compile_try(zend_ast *ast TSRMLS_DC) /* {{{ */
        if (finally_ast) {
                uint32_t opnum_jmp = get_next_op_number(CG(active_op_array)) + 1;
 
+               if (!(CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
+                       CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK;
+                       CG(context).fast_call_var = get_temporary_variable(CG(active_op_array));
+               }
+
                opline = zend_emit_op(NULL, ZEND_FAST_CALL, NULL, NULL TSRMLS_CC);
                opline->op1.opline_num = opnum_jmp + 1;
+               opline->result_type = IS_TMP_VAR;
+               opline->result.var = CG(context).fast_call_var;
 
                zend_emit_op(NULL, ZEND_JMP, NULL, NULL TSRMLS_CC);
 
@@ -3633,9 +3643,10 @@ void zend_compile_try(zend_ast *ast TSRMLS_DC) /* {{{ */
                CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = opnum_jmp + 1;
                CG(active_op_array)->try_catch_array[try_catch_offset].finally_end
                        = get_next_op_number(CG(active_op_array));
-               CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK;
 
-               zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL TSRMLS_CC);
+               opline = zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL TSRMLS_CC);
+               opline->op1_type = IS_TMP_VAR;
+               opline->op1.var = CG(context).fast_call_var;
 
                zend_update_jump_target_to_next(opnum_jmp TSRMLS_CC);
        }
index d6184c9dc33920cfb47c3a56e693095a1fef8d34..4cf60c618146f2ef3ceff72ad0b5d498664aaf13 100644 (file)
@@ -52,6 +52,7 @@ typedef struct _zend_compiler_context {
        int        current_brk_cont;
        int        backpatch_count;
        int        in_finally;
+       uint32_t   fast_call_var;
        HashTable *labels;
 } zend_compiler_context;
 
@@ -376,8 +377,6 @@ struct _zend_execute_data {
        zval                *return_value;
        zend_class_entry    *scope;            /* function scope (self)          */
        zend_array          *symbol_table;
-       const zend_op       *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
-       zend_object         *delayed_exception;
 };
 
 #define VM_FRAME_KIND_MASK           0x000000ff
index fc8cd57cedb7cf851f7d3d38d968bd532645bfbc..94197857f455e153366c3520f8f7ffbc2907007a 100644 (file)
@@ -1485,7 +1485,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
        EX(opline) = op_array->opcodes;
        EX(call) = NULL;
        EX(return_value) = return_value;
-       EX(delayed_exception) = NULL;
 
        /* Handle arguments */
        first_extra_arg = op_array->num_args;
@@ -1551,7 +1550,6 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
        EX(call) = NULL;
        EX(return_value) = return_value;
        EX(scope) = EG(scope);
-       EX(delayed_exception) = NULL;
 
        zend_attach_symbol_table(execute_data);
 
@@ -1577,7 +1575,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
        EX(call) = NULL;
        EX(return_value) = return_value;
        EX(scope) = EG(scope);
-       EX(delayed_exception) = NULL;
 
        if (UNEXPECTED(EX(symbol_table) != NULL)) {
                zend_attach_symbol_table(execute_data);
index b38657f7b778c74f01509f36ef4d5ed7a579c54b..ef0b520eb060aabc5bae93f886631e6e710b3222 100644 (file)
@@ -133,7 +133,7 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
 {
        zend_generator *generator = (zend_generator*) object;
        zend_execute_data *ex = generator->execute_data;
-       uint32_t op_num, finally_op_num;
+       uint32_t op_num, finally_op_num, finally_op_end;
        int i;
 
        if (!ex || !(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
@@ -146,6 +146,7 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
 
        /* Find next finally block */
        finally_op_num = 0;
+       finally_op_end = 0;
        for (i = 0; i < ex->func->op_array.last_try_catch; i++) {
                zend_try_catch_element *try_catch = &ex->func->op_array.try_catch_array[i];
 
@@ -155,14 +156,17 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */
 
                if (op_num < try_catch->finally_op) {
                        finally_op_num = try_catch->finally_op;
+                       finally_op_end = try_catch->finally_end;
                }
        }
 
        /* If a finally block was found we jump directly to it and
         * resume the generator. */
        if (finally_op_num) {
+               zval *fast_call = EX_VAR_2(ex, ex->func->op_array.opcodes[finally_op_end].op1.var);
+
+               fast_call->u2.lineno = (uint32_t)-1;
                ex->opline = &ex->func->op_array.opcodes[finally_op_num];
-               ex->fast_ret = NULL;
                generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
                zend_generator_resume(generator TSRMLS_CC);
        }
index 5902abd4c548c0fca8a3913725539c4292eb66b7..1bbd35f40fadaa834a83511ce8ff6f9cef8a341a 100644 (file)
@@ -532,12 +532,19 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num,
                    (dst_num < op_array->try_catch_array[i].try_op ||
                     dst_num > op_array->try_catch_array[i].finally_end)) {
                        /* we have a jump out of try block that needs executing finally */
+                       uint32_t fast_call_var;
+                       
+                       /* Must be ZEND_FAST_RET */
+                       ZEND_ASSERT(op_array->opcodes[op_array->try_catch_array[i].finally_end].opcode == ZEND_FAST_RET);
+                       fast_call_var = op_array->opcodes[op_array->try_catch_array[i].finally_end].op1.var;
 
                        /* generate a FAST_CALL to finally block */
                    start_op = get_next_op_number(op_array);
 
                        opline = get_next_op(op_array TSRMLS_CC);
                        opline->opcode = ZEND_FAST_CALL;
+                       opline->result_type = IS_TMP_VAR;
+                       opline->result.var = fast_call_var;
                        SET_UNUSED(opline->op1);
                        SET_UNUSED(opline->op2);
                        zend_adjust_fast_call(op_array, start_op,
@@ -550,6 +557,8 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num,
                                /* generate a FAST_CALL to hole CALL_FROM_FINALLY */
                                opline = get_next_op(op_array TSRMLS_CC);
                                opline->opcode = ZEND_FAST_CALL;
+                               opline->result_type = IS_TMP_VAR;
+                               opline->result.var = fast_call_var;
                                SET_UNUSED(opline->op1);
                                SET_UNUSED(opline->op2);
                                zend_resolve_fast_call(op_array, start_op + 1, op_array->try_catch_array[i].finally_op - 2 TSRMLS_CC);
@@ -569,6 +578,8 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num,
 
                                        opline = get_next_op(op_array TSRMLS_CC);
                                        opline->opcode = ZEND_FAST_CALL;
+                                       opline->result_type = IS_TMP_VAR;
+                                       opline->result.var = fast_call_var;
                                        SET_UNUSED(opline->op1);
                                        SET_UNUSED(opline->op2);
                                        opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
index 85342eaf43bfe1589d0adab62b248fee0c9814a5..760f5f99f72dff0957dae090f9f56e9fd272ef54 100644 (file)
@@ -5469,6 +5469,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
                }
                if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
                        finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
+                       finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
                }
                if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
                                op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
@@ -5526,28 +5527,36 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        }
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
-               if (EX(delayed_exception)) {
-                       zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
+               zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+               if (Z_OBJ_P(fast_call)) {
+                       zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
                } 
-               EX(delayed_exception) = EG(exception);
+               Z_OBJ_P(fast_call) = EG(exception);
                EG(exception) = NULL;
-               EX(fast_ret) = NULL;
+               fast_call->u2.lineno = (uint32_t)-1;
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
                ZEND_VM_CONTINUE();
        } else if (catch_op_num) {
                if (finally_op_end && catch_op_num > finally_op_end) {
                        /* we are going out of current finally scope */
-                       if (EX(delayed_exception)) {
-                               zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
-                               EX(delayed_exception) = NULL;
+                       zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+                       if (Z_OBJ_P(fast_call)) {
+                               zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+                               Z_OBJ_P(fast_call) = NULL;
                        }
                }
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
                ZEND_VM_CONTINUE();
        } else {
-               if (EX(delayed_exception)) {
-                       zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
-                       EX(delayed_exception) = NULL;
+               if (finally_op_end) {
+                       zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+                       if (Z_OBJ_P(fast_call)) {
+                               zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+                               Z_OBJ_P(fast_call) = NULL;
+                       }
                }
                if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
@@ -5807,10 +5816,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
 
 ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
 {
-       if (EX(delayed_exception) != NULL) {
+       USE_OPLINE
+       zval *fast_call = EX_VAR(opline->op1.var);
+       
+       /* check for delayed exception */
+       if (Z_OBJ_P(fast_call) != NULL) {
                /* discard the previously thrown exception */
-               OBJ_RELEASE(EX(delayed_exception));
-               EX(delayed_exception) = NULL;
+               OBJ_RELEASE(Z_OBJ_P(fast_call));
+               Z_OBJ_P(fast_call) = NULL;
        }
 
        ZEND_VM_NEXT_OPCODE();
@@ -5819,6 +5832,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
 ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
 {
        USE_OPLINE
+       zval *fast_call = EX_VAR(opline->result.var);
 
        if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
            UNEXPECTED(EG(prev_exception) != NULL)) {
@@ -5826,18 +5840,24 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                ZEND_VM_CONTINUE();
        }
-       EX(fast_ret) = opline;
-       EX(delayed_exception) = NULL;
+       /* set no delayed exception */
+       Z_OBJ_P(fast_call) = NULL;
+       /* set return address */
+       fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
        ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
        ZEND_VM_CONTINUE();
 }
 
 ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
 {
-       if (EX(fast_ret)) {
-               ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
-               if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
-                       EX(fast_ret) = &EX(func)->op_array.opcodes[EX(fast_ret)->op2.opline_num];
+       USE_OPLINE
+       zval *fast_call = EX_VAR(opline->op1.var);
+
+       if (fast_call->u2.lineno != (uint32_t)-1) {
+               const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
+               ZEND_VM_SET_OPCODE(fast_ret + 1);
+               if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
+                       fast_call->u2.lineno = fast_ret->op2.opline_num;
                }
                ZEND_VM_CONTINUE();
        } else {
@@ -5848,8 +5868,8 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
                        ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                        ZEND_VM_CONTINUE();
                } else {
-                       EG(exception) = EX(delayed_exception);
-                       EX(delayed_exception) = NULL;
+                       EG(exception) = Z_OBJ_P(fast_call);
+                       Z_OBJ_P(fast_call) = NULL;
                        if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
                                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                                ZEND_VM_CONTINUE();
index c80229f738f0efb799d4dcfded209b524d5025b6..dc3ee25c5219a301db1026aef2d503aee7d39742 100644 (file)
@@ -1214,6 +1214,7 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
                }
                if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) {
                        finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op;
+                       finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end;
                }
                if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op &&
                                op_num < EX(func)->op_array.try_catch_array[i].finally_end) {
@@ -1271,28 +1272,36 @@ static int ZEND_FASTCALL  ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
        }
 
        if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
-               if (EX(delayed_exception)) {
-                       zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
+               zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+               if (Z_OBJ_P(fast_call)) {
+                       zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
                }
-               EX(delayed_exception) = EG(exception);
+               Z_OBJ_P(fast_call) = EG(exception);
                EG(exception) = NULL;
-               EX(fast_ret) = NULL;
+               fast_call->u2.lineno = (uint32_t)-1;
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]);
                ZEND_VM_CONTINUE();
        } else if (catch_op_num) {
                if (finally_op_end && catch_op_num > finally_op_end) {
                        /* we are going out of current finally scope */
-                       if (EX(delayed_exception)) {
-                               zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
-                               EX(delayed_exception) = NULL;
+                       zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+                       if (Z_OBJ_P(fast_call)) {
+                               zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+                               Z_OBJ_P(fast_call) = NULL;
                        }
                }
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]);
                ZEND_VM_CONTINUE();
        } else {
-               if (EX(delayed_exception)) {
-                       zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC);
-                       EX(delayed_exception) = NULL;
+               if (finally_op_end) {
+                       zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var);
+
+                       if (Z_OBJ_P(fast_call)) {
+                               zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC);
+                               Z_OBJ_P(fast_call) = NULL;
+                       }
                }
                if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -1343,10 +1352,14 @@ static int ZEND_FASTCALL  ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 
 static int ZEND_FASTCALL  ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       if (EX(delayed_exception) != NULL) {
+       USE_OPLINE
+       zval *fast_call = EX_VAR(opline->op1.var);
+
+       /* check for delayed exception */
+       if (Z_OBJ_P(fast_call) != NULL) {
                /* discard the previously thrown exception */
-               OBJ_RELEASE(EX(delayed_exception));
-               EX(delayed_exception) = NULL;
+               OBJ_RELEASE(Z_OBJ_P(fast_call));
+               Z_OBJ_P(fast_call) = NULL;
        }
 
        ZEND_VM_NEXT_OPCODE();
@@ -1355,6 +1368,7 @@ static int ZEND_FASTCALL  ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLE
 static int ZEND_FASTCALL  ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
+       zval *fast_call = EX_VAR(opline->result.var);
 
        if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) &&
            UNEXPECTED(EG(prev_exception) != NULL)) {
@@ -1362,18 +1376,24 @@ static int ZEND_FASTCALL  ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                ZEND_VM_CONTINUE();
        }
-       EX(fast_ret) = opline;
-       EX(delayed_exception) = NULL;
+       /* set no delayed exception */
+       Z_OBJ_P(fast_call) = NULL;
+       /* set return address */
+       fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
        ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
        ZEND_VM_CONTINUE();
 }
 
 static int ZEND_FASTCALL  ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       if (EX(fast_ret)) {
-               ZEND_VM_SET_OPCODE(EX(fast_ret) + 1);
-               if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) {
-                       EX(fast_ret) = &EX(func)->op_array.opcodes[EX(fast_ret)->op2.opline_num];
+       USE_OPLINE
+       zval *fast_call = EX_VAR(opline->op1.var);
+
+       if (fast_call->u2.lineno != (uint32_t)-1) {
+               const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno;
+               ZEND_VM_SET_OPCODE(fast_ret + 1);
+               if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) {
+                       fast_call->u2.lineno = fast_ret->op2.opline_num;
                }
                ZEND_VM_CONTINUE();
        } else {
@@ -1384,8 +1404,8 @@ static int ZEND_FASTCALL  ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                        ZEND_VM_CONTINUE();
                } else {
-                       EG(exception) = EX(delayed_exception);
-                       EX(delayed_exception) = NULL;
+                       EG(exception) = Z_OBJ_P(fast_call);
+                       Z_OBJ_P(fast_call) = NULL;
                        if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
                                ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]);
                                ZEND_VM_CONTINUE();