mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Changed CATCH instruction format (extended_value moved into op2, op2 into result, result into extended_value)
This commit is contained in:
parent
3c6e1c2b81
commit
ba298725d1
19 changed files with 154 additions and 105 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -331,7 +331,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
|
|||
0x00000000,
|
||||
0x01000000,
|
||||
0x00001001,
|
||||
0x03000103,
|
||||
0x02002003,
|
||||
0x00000003,
|
||||
0x00000771,
|
||||
0x00000057,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -681,25 +681,25 @@ 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 (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);
|
||||
}
|
||||
}
|
||||
|
||||
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 (opline->result_type == IS_CONST) {
|
||||
zend_dump_const(CRT_CONSTANT_EX(op_array, opline, opline->result, (dump_flags & ZEND_DUMP_RT_CONSTANTS)));
|
||||
} else if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_use >= 0) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -760,9 +760,9 @@ PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zen
|
|||
return 1;
|
||||
}
|
||||
|
||||
do {
|
||||
zend_class_entry *ce;
|
||||
cur = &op_array->opcodes[catch];
|
||||
while (1) {
|
||||
zend_class_entry *ce;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue