]> granicus.if.org Git - php/commitdiff
Changed CATCH instruction format (extended_value moved into op2, op2 into result...
authorDmitry Stogov <dmitry@zend.com>
Wed, 31 Jan 2018 19:39:30 +0000 (22:39 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 31 Jan 2018 19:39:30 +0000 (22:39 +0300)
19 files changed:
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_opcode.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h
ext/opcache/Optimizer/block_pass.c
ext/opcache/Optimizer/dfa_pass.c
ext/opcache/Optimizer/zend_cfg.c
ext/opcache/Optimizer/zend_dump.c
ext/opcache/Optimizer/zend_optimizer.c
ext/opcache/zend_file_cache.c
ext/opcache/zend_persist.c
sapi/phpdbg/phpdbg_opcode.c
sapi/phpdbg/phpdbg_utils.c
sapi/phpdbg/tests/exceptions_003.phpt
sapi/phpdbg/tests/stepping_001.phpt

index e8a16c4ef04a53e04e628581d4f8c457a8d36eb8..0b4941e1f463f7a8d9acdba1c17240e818cdd150 100644 (file)
@@ -5201,15 +5201,17 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
                                zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
                        }
 
-                       opline->op2_type = IS_CV;
-                       opline->op2.var = lookup_cv(CG(active_op_array), var_name);
+                       opline->result_type = IS_CV;
+                       opline->result.var = lookup_cv(CG(active_op_array), var_name);
 
-                       opline->result.num = is_last_catch && is_last_class;
+                       if (is_last_catch && is_last_class) {
+                               opline->extended_value = ZEND_LAST_CATCH;
+                       }
 
                        if (!is_last_class) {
                                jmp_multicatch[j] = zend_emit_jump(0);
                                opline = &CG(active_op_array)->opcodes[opnum_catch];
-                               opline->extended_value = get_next_op_number(CG(active_op_array));
+                               opline->op2.opline_num = get_next_op_number(CG(active_op_array));
                        }
                }
 
@@ -5227,7 +5229,7 @@ void zend_compile_try(zend_ast *ast) /* {{{ */
 
                opline = &CG(active_op_array)->opcodes[opnum_catch];
                if (!is_last_catch) {
-                       opline->extended_value = get_next_op_number(CG(active_op_array));
+                       opline->op2.opline_num = get_next_op_number(CG(active_op_array));
                }
        }
 
index 228111e29ebfaf58bdaae5eb91d32c19c3f83ea3..d787a92a7f7373296623fe11c205cb779a6517e4 100644 (file)
@@ -877,6 +877,8 @@ void zend_assert_valid_class_name(const zend_string *const_name);
 
 #define ZEND_FETCH_ARG_MASK         0x0fffffff
 
+#define ZEND_LAST_CATCH                            0x00000001
+
 #define ZEND_FREE_ON_RETURN     (1<<0)
 
 #define ZEND_SEND_BY_VAL     0
index a0301a9add25fa633334cd6cbeb885f6d4b0567c..41b40a2663f0d53183439bcae51141a3eeba376a 100644 (file)
@@ -657,12 +657,16 @@ ZEND_API int pass_two(zend_op_array *op_array)
                        }
                        case ZEND_DECLARE_ANON_CLASS:
                        case ZEND_DECLARE_ANON_INHERITED_CLASS:
-                       case ZEND_CATCH:
                        case ZEND_FE_FETCH_R:
                        case ZEND_FE_FETCH_RW:
                                /* absolute index to relative offset */
                                opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
                                break;
+                       case ZEND_CATCH:
+                               if (opline->extended_value != ZEND_LAST_CATCH) {
+                                       ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
+                               }
+                               break;
                        case ZEND_RETURN:
                        case ZEND_RETURN_BY_REF:
                                if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
index a7fa49c4334bc041005f2e3165010b46b9cf0074..979b4f6c06f20854071ebf571230c97ee73ab34c 100644 (file)
@@ -4082,7 +4082,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
        HANDLE_EXCEPTION();
 }
 
-ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR)
+ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, JMP_ADDR, LAST_CATCH)
 {
        USE_OPLINE
        zend_class_entry *ce, *catch_ce;
@@ -4093,7 +4093,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR)
        /* Check whether an exception has been thrown, if not, jump over code */
        zend_exception_restore();
        if (EG(exception) == NULL) {
-               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+               ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
                ZEND_VM_CONTINUE();
        }
        catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)));
@@ -4112,17 +4112,17 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV, JMP_ADDR)
 
        if (ce != catch_ce) {
                if (!catch_ce || !instanceof_function(ce, catch_ce)) {
-                       if (opline->result.num) {
+                       if (opline->extended_value == ZEND_LAST_CATCH) {
                                zend_rethrow_exception(execute_data);
                                HANDLE_EXCEPTION();
                        }
-                       ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
+                       ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
                        ZEND_VM_CONTINUE();
                }
        }
 
        exception = EG(exception);
-       ex = EX_VAR(opline->op2.var);
+       ex = EX_VAR(opline->result.var);
        if (UNEXPECTED(Z_ISREF_P(ex))) {
                ex = Z_REFVAL_P(ex);
        }
index 1277156fdf26a4aad95c513ab31d54f02f1c1f58..a26a4b6e5a6036ce6a0ba04671eb8d1d8b44e808 100644 (file)
@@ -2904,6 +2904,61 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_
        HANDLE_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_class_entry *ce, *catch_ce;
+       zend_object *exception;
+       zval *ex;
+
+       SAVE_OPLINE();
+       /* Check whether an exception has been thrown, if not, jump over code */
+       zend_exception_restore();
+       if (EG(exception) == NULL) {
+               ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
+               ZEND_VM_CONTINUE();
+       }
+       catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)));
+       if (UNEXPECTED(catch_ce == NULL)) {
+               catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD);
+
+               CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce);
+       }
+       ce = EG(exception)->ce;
+
+#ifdef HAVE_DTRACE
+       if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
+               DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
+       }
+#endif /* HAVE_DTRACE */
+
+       if (ce != catch_ce) {
+               if (!catch_ce || !instanceof_function(ce, catch_ce)) {
+                       if (opline->extended_value == ZEND_LAST_CATCH) {
+                               zend_rethrow_exception(execute_data);
+                               HANDLE_EXCEPTION();
+                       }
+                       ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
+                       ZEND_VM_CONTINUE();
+               }
+       }
+
+       exception = EG(exception);
+       ex = EX_VAR(opline->result.var);
+       if (UNEXPECTED(Z_ISREF_P(ex))) {
+               ex = Z_REFVAL_P(ex);
+       }
+       zval_ptr_dtor(ex);
+       ZVAL_OBJ(ex, EG(exception));
+       if (UNEXPECTED(EG(exception) != exception)) {
+               GC_ADDREF(EG(exception));
+               HANDLE_EXCEPTION();
+       } else {
+               EG(exception) = NULL;
+               ZEND_VM_NEXT_OPCODE();
+       }
+}
+
 static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -10768,61 +10823,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
        ZEND_VM_NEXT_OPCODE();
 }
 
-static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
-       USE_OPLINE
-       zend_class_entry *ce, *catch_ce;
-       zend_object *exception;
-       zval *ex;
-
-       SAVE_OPLINE();
-       /* Check whether an exception has been thrown, if not, jump over code */
-       zend_exception_restore();
-       if (EG(exception) == NULL) {
-               ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
-               ZEND_VM_CONTINUE();
-       }
-       catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)));
-       if (UNEXPECTED(catch_ce == NULL)) {
-               catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), RT_CONSTANT(opline, opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD);
-
-               CACHE_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(opline, opline->op1)), catch_ce);
-       }
-       ce = EG(exception)->ce;
-
-#ifdef HAVE_DTRACE
-       if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) {
-               DTRACE_EXCEPTION_CAUGHT((char *)ce->name);
-       }
-#endif /* HAVE_DTRACE */
-
-       if (ce != catch_ce) {
-               if (!catch_ce || !instanceof_function(ce, catch_ce)) {
-                       if (opline->result.num) {
-                               zend_rethrow_exception(execute_data);
-                               HANDLE_EXCEPTION();
-                       }
-                       ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value);
-                       ZEND_VM_CONTINUE();
-               }
-       }
-
-       exception = EG(exception);
-       ex = EX_VAR(opline->op2.var);
-       if (UNEXPECTED(Z_ISREF_P(ex))) {
-               ex = Z_REFVAL_P(ex);
-       }
-       zval_ptr_dtor(ex);
-       ZVAL_OBJ(ex, EG(exception));
-       if (UNEXPECTED(EG(exception) != exception)) {
-               GC_ADDREF(EG(exception));
-               HANDLE_EXCEPTION();
-       } else {
-               EG(exception) = NULL;
-               ZEND_VM_NEXT_OPCODE();
-       }
-}
-
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -54885,7 +54885,7 @@ ZEND_API void execute_ex(zend_execute_data *ex)
                        (void*)&&ZEND_EXT_NOP_SPEC_LABEL,
                        (void*)&&ZEND_TICKS_SPEC_LABEL,
                        (void*)&&ZEND_SEND_VAR_NO_REF_SPEC_VAR_LABEL,
-                       (void*)&&ZEND_CATCH_SPEC_CONST_CV_LABEL,
+                       (void*)&&ZEND_CATCH_SPEC_CONST_LABEL,
                        (void*)&&ZEND_THROW_SPEC_CONST_LABEL,
                        (void*)&&ZEND_THROW_SPEC_TMP_LABEL,
                        (void*)&&ZEND_THROW_SPEC_VAR_LABEL,
@@ -57012,6 +57012,9 @@ ZEND_API void execute_ex(zend_execute_data *ex)
                        HYBRID_CASE(ZEND_THROW_SPEC_CONST):
                                ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
+                       HYBRID_CASE(ZEND_CATCH_SPEC_CONST):
+                               ZEND_CATCH_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+                               HYBRID_BREAK();
                        HYBRID_CASE(ZEND_SEND_VAL_SPEC_CONST):
                                ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
@@ -57525,9 +57528,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
                        HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_CV):
                                ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
-                       HYBRID_CASE(ZEND_CATCH_SPEC_CONST_CV):
-                               ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
-                               HYBRID_BREAK();
                        HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV):
                                ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
                                HYBRID_BREAK();
@@ -62770,7 +62770,7 @@ void zend_init_opcodes_handlers(void)
                ZEND_EXT_NOP_SPEC_HANDLER,
                ZEND_TICKS_SPEC_HANDLER,
                ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER,
-               ZEND_CATCH_SPEC_CONST_CV_HANDLER,
+               ZEND_CATCH_SPEC_CONST_HANDLER,
                ZEND_THROW_SPEC_CONST_HANDLER,
                ZEND_THROW_SPEC_TMP_HANDLER,
                ZEND_THROW_SPEC_VAR_HANDLER,
index 75afa99624ced8a5ed101fe211282f5cd73ed723..2c392b87609638dc9935d44b804d23e9a4ce9e11 100644 (file)
@@ -78,7 +78,7 @@ $vm_op_flags = array(
        "ZEND_VM_EXT_REF"         => 1<<20,
        "ZEND_VM_EXT_MASK"        => 0x0f000000,
        "ZEND_VM_EXT_NUM"         => 0x01000000,
-    // unused 0x2000000
+       "ZEND_VM_EXT_LAST_CATCH"  => 0x02000000,
        "ZEND_VM_EXT_JMP_ADDR"    => 0x03000000,
        "ZEND_VM_EXT_DIM_OBJ"     => 0x04000000,
     // unused 0x5000000
@@ -119,6 +119,7 @@ $vm_op_decode = array(
 
 $vm_ext_decode = array(
        "NUM"                  => ZEND_VM_EXT_NUM,
+       "LAST_CATCH"           => ZEND_VM_EXT_LAST_CATCH,
        "JMP_ADDR"             => ZEND_VM_EXT_JMP_ADDR,
        "DIM_OBJ"              => ZEND_VM_EXT_DIM_OBJ,
        "VAR_FETCH"            => ZEND_VM_EXT_VAR_FETCH,
index 876dfef315b525187e8817e0c958d3594bbb2c4b..b01d7395d3c1018e24efe5e270a0491555f18cf7 100644 (file)
@@ -331,7 +331,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
        0x00000000,
        0x01000000,
        0x00001001,
-       0x03000103,
+       0x02002003,
        0x00000003,
        0x00000771,
        0x00000057,
index a1191cac2949c45d51ee83a0f79b7a3473fa4217..fc0cba498f8944575bb2125ad3ebe4e76a939cb5 100644 (file)
@@ -55,6 +55,7 @@
 #define ZEND_VM_EXT_REF          0x00100000
 #define ZEND_VM_EXT_MASK         0x0f000000
 #define ZEND_VM_EXT_NUM          0x01000000
+#define ZEND_VM_EXT_LAST_CATCH   0x02000000
 #define ZEND_VM_EXT_JMP_ADDR     0x03000000
 #define ZEND_VM_EXT_DIM_OBJ      0x04000000
 #define ZEND_VM_EXT_TYPE         0x07000000
index 6568bdc1b3266b539dcdbfe799842f14579a769b..65007a9455181642df77c01cf1f7e3a7cebc7b21 100644 (file)
@@ -965,8 +965,8 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op
                                ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start);
                                break;
                        case ZEND_CATCH:
-                               if (!opline->result.var) {
-                                       opline->extended_value = ZEND_OPLINE_TO_OFFSET(opline, new_opcodes + blocks[b->successors[0]].start);
+                               if (opline->extended_value != ZEND_LAST_CATCH) {
+                                       ZEND_SET_OP_JMP_ADDR(opline, opline->op2, new_opcodes + blocks[b->successors[0]].start);
                                }
                                break;
                        case ZEND_DECLARE_ANON_CLASS:
index f24d407eeb0c348899828744d5d1a7c1ae97db1f..13aec486f6fbec2bcd0b042e183bf9b80e69ff67 100644 (file)
@@ -552,9 +552,9 @@ static void zend_ssa_replace_control_link(zend_op_array *op_array, zend_ssa *ssa
                                }
                                break;
                        case ZEND_CATCH:
-                               if (!opline->result.num) {
-                                       if (ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) == old->start) {
-                                               opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, dst->start);
+                               if (opline->extended_value != ZEND_LAST_CATCH) {
+                                       if (ZEND_OP2_JMP_ADDR(opline) == op_array->opcodes + old->start) {
+                                               ZEND_SET_OP_JMP_ADDR(opline, opline->op2, op_array->opcodes + dst->start);
                                        }
                                }
                                break;
index 77371c97c2373483253c57af5fce237a28062d40..a2d021516db0f18aee5bb12d0c80f122d2824ad9 100644 (file)
@@ -385,8 +385,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                BB_START(i + 1);
                                break;
                        case ZEND_CATCH:
-                               if (!opline->result.num) {
-                                       BB_START(ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
+                               if (opline->extended_value != ZEND_LAST_CATCH) {
+                                       BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes);
                                }
                                BB_START(i + 1);
                                break;
@@ -546,9 +546,9 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
                                block->successors[1] = j + 1;
                                break;
                        case ZEND_CATCH:
-                               if (!opline->result.num) {
+                               if (opline->extended_value != ZEND_LAST_CATCH) {
                                        block->successors_count = 2;
-                                       block->successors[0] = block_map[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)];
+                                       block->successors[0] = block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes];
                                        block->successors[1] = j + 1;
                                } else {
                                        block->successors_count = 1;
index 8f874d8bdb40992fe25a9fd641a739ca97cdd164..a2bba55178866cbad081eaad0cb2e5b469301067 100644 (file)
@@ -681,10 +681,12 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
        } else {
                uint32_t op2_flags = ZEND_VM_OP2_FLAGS(flags);
                if (ZEND_VM_OP_JMP_ADDR == (op2_flags & ZEND_VM_OP_MASK)) {
-                       if (b) {
-                               fprintf(stderr, " BB%d", b->successors[n++]);
-                       } else {
-                               fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes));
+                       if (opline->opcode != ZEND_CATCH || opline->extended_value != ZEND_LAST_CATCH) {
+                               if (b) {
+                                       fprintf(stderr, " BB%d", b->successors[n++]);
+                               } else {
+                                       fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes));
+                               }
                        }
                } else {
                        zend_dump_unused_op(opline, opline->op2, op2_flags);
@@ -692,12 +694,10 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
        }
 
        if (ZEND_VM_EXT_JMP_ADDR == (flags & ZEND_VM_EXT_MASK)) {
-               if (opline->opcode != ZEND_CATCH || !opline->result.num) {
-                       if (b) {
-                               fprintf(stderr, " BB%d", b->successors[n++]);
-                       } else {
-                               fprintf(stderr, " L%u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
-                       }
+               if (b) {
+                       fprintf(stderr, " BB%d", b->successors[n++]);
+               } else {
+                       fprintf(stderr, " L%u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
                }
        }
        if (opline->result_type == IS_CONST) {
index 1bf05a50a98f2508c99fd416d3227aca9892fbc6..a7d463030f54ceb781c5274e19e40b578c147691 100644 (file)
@@ -757,17 +757,17 @@ void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, z
                case ZEND_ASSERT_CHECK:
                        ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
                        break;
-               case ZEND_CATCH:
-                       if (!opline->result.num) {
-                               new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
-                       }
-                       break;
                case ZEND_DECLARE_ANON_CLASS:
                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                case ZEND_FE_FETCH_R:
                case ZEND_FE_FETCH_RW:
                        new_opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, new_opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value));
                        break;
+               case ZEND_CATCH:
+                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                               ZEND_SET_OP_JMP_ADDR(new_opline, new_opline->op2, ZEND_OP2_JMP_ADDR(opline));
+                       }
+                       break;
                case ZEND_SWITCH_LONG:
                case ZEND_SWITCH_STRING:
                {
@@ -803,11 +803,15 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
                case ZEND_ASSERT_CHECK:
                        ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]);
                        break;
+               case ZEND_CATCH:
+                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                               ZEND_SET_OP_JMP_ADDR(opline, opline->op2, ZEND_OP2_JMP_ADDR(opline) - shiftlist[ZEND_OP2_JMP_ADDR(opline) - op_array->opcodes]);
+                       }
+                       break;
                case ZEND_DECLARE_ANON_CLASS:
                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                case ZEND_FE_FETCH_R:
                case ZEND_FE_FETCH_RW:
-               case ZEND_CATCH:
                        opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value) - shiftlist[ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)]);
                        break;
                case ZEND_SWITCH_LONG:
@@ -1167,6 +1171,11 @@ static void zend_redo_pass_two(zend_op_array *op_array)
                                case ZEND_ASSERT_CHECK:
                                        opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
                                        break;
+                               case ZEND_CATCH:
+                                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                                               opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
+                                       }
+                                       break;
                                case ZEND_DECLARE_ANON_CLASS:
                                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                case ZEND_FE_FETCH_R:
@@ -1248,6 +1257,11 @@ static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
                                case ZEND_ASSERT_CHECK:
                                        opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
                                        break;
+                               case ZEND_CATCH:
+                                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                                               opline->op2.jmp_addr = &op_array->opcodes[opline->op2.jmp_addr - old_opcodes];
+                                       }
+                                       break;
                                case ZEND_DECLARE_ANON_CLASS:
                                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                case ZEND_FE_FETCH_R:
index c11bff3868c3f15346c86ff3e69294edf3cf1801..db926a517205b5a21af396a0307b0cac81a478c5 100644 (file)
@@ -446,6 +446,11 @@ static void zend_file_cache_serialize_op_array(zend_op_array            *op_arra
                                case ZEND_ASSERT_CHECK:
                                        SERIALIZE_PTR(opline->op2.jmp_addr);
                                        break;
+                               case ZEND_CATCH:
+                                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                                               SERIALIZE_PTR(opline->op2.jmp_addr);
+                                       }
+                                       break;
                                case ZEND_DECLARE_ANON_CLASS:
                                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                case ZEND_FE_FETCH_R:
@@ -1047,6 +1052,11 @@ static void zend_file_cache_unserialize_op_array(zend_op_array           *op_arr
                                case ZEND_ASSERT_CHECK:
                                        UNSERIALIZE_PTR(opline->op2.jmp_addr);
                                        break;
+                               case ZEND_CATCH:
+                                       if (opline->extended_value != ZEND_LAST_CATCH) {
+                                               UNSERIALIZE_PTR(opline->op2.jmp_addr);
+                                       }
+                                       break;
                                case ZEND_DECLARE_ANON_CLASS:
                                case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                case ZEND_FE_FETCH_R:
index f292ce09b05911ddc1881bb473102f46b595958d..a2549308ada579b3f2cd0266f0dd01f529c5a2f2 100644 (file)
@@ -452,6 +452,11 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                                        case ZEND_ASSERT_CHECK:
                                                opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes];
                                                break;
+                                       case ZEND_CATCH:
+                                               if (opline->extended_value != ZEND_LAST_CATCH) {
+                                                       opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes];
+                                               }
+                                               break;
                                        case ZEND_DECLARE_ANON_CLASS:
                                        case ZEND_DECLARE_ANON_INHERITED_CLASS:
                                        case ZEND_FE_FETCH_R:
index 313bb4fae8e0220d84677f45f2117107ec150f2d..4b3bf4c668b6f143ce7cdb55e166255d74ca9689 100644 (file)
@@ -115,7 +115,13 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *opline) /*{{{ */
        /* RESULT */
        switch (opline->opcode) {
        case ZEND_CATCH:
-               spprintf(&decode[3], 0, "%" PRIu32, opline->result.num);
+               if (opline->extended_value == ZEND_LAST_CATCH) {
+                       if (decode[2]) {
+                               efree(decode[2]);
+                               decode[2] = NULL;
+                       }
+               }
+               decode[3] = phpdbg_decode_op(ops, opline, &opline->result, opline->result_type);
                break;
        default:
                decode[3] = phpdbg_decode_op(ops, opline, &opline->result, opline->result_type);
index 005015d850ab161d17b7071b4f01519691cd05b0..cdee919f790522d9131ff73d3334df5a08990ac5 100644 (file)
@@ -760,9 +760,9 @@ PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zen
                                return 1;
                        }
 
-                       do {
+                       cur = &op_array->opcodes[catch];
+                       while (1) {
                                zend_class_entry *ce;
-                               cur = &op_array->opcodes[catch];
 
                                if (!(ce = CACHED_PTR(Z_CACHE_SLOT_P(RT_CONSTANT(cur, cur->op1))))) {
                                        ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(cur, cur->op1)), RT_CONSTANT(cur, cur->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD);
@@ -773,8 +773,12 @@ PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zen
                                        return 1;
                                }
 
-                               catch += cur->extended_value / sizeof(zend_op);
-                       } while (!cur->result.num);
+                               if (cur->extended_value == ZEND_LAST_CATCH) {
+                                       return 0;
+                               }
+
+                               cur = OP_JMP_ADDR(cur, cur->op2);
+                       }
 
                        return 0;
                }
index 9d4abc0739b96e3be8d6a6420da108dc38d17171..e78ff1d489b54f4325327413b1e7dfd686c02da3 100644 (file)
@@ -26,7 +26,7 @@ prompt> [L7 %s ECHO<1>                 "ok\n"
  00009: } catch (Error $e) {
 prompt> ok
 [L7 %s FAST_RET                ~%d                   try-catch(0)                             %s]
-[L9 %s CATCH<-%d>             "Error"              $e                   1                    %s]
+[L9 %s CATCH<1>                "Error"                                   $e                   %s]
 >00005:                x();
  00006:        } finally {
  00007:                print "ok\n";
index e8e32db0beb56367a3b5cc5fdc51aabadcee283b..a7ab9e59aa3464d7d0bc06ea9e1da4262588c21e 100644 (file)
@@ -25,7 +25,7 @@ prompt> [L0 %s HANDLE_EXCEPTION
  00005: }
  00006: 
 prompt> [L0 %s HANDLE_EXCEPTION                                                                       %s]
-[L9 %s CATCH<-%d>             "Exception"          $e                   1                    %s]
+[L9 %s CATCH<1>                "Exception"                               $e                   %s]
 >00008:        foo();
  00009: } catch (Exception $e) {
  00010:        echo "ok";