summaryrefslogtreecommitdiff
path: root/Zend/zend_opcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_opcode.c')
-rw-r--r--Zend/zend_opcode.c40
1 files changed, 14 insertions, 26 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 347761e9a8..9ead514650 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -561,7 +561,7 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num,
zend_check_finally_breakout(op_array, op_num, dst_num);
}
- /* the backward order is mater */
+ /* the backward order matters */
while (i > 0) {
i--;
if (op_array->try_catch_array[i].finally_op &&
@@ -591,22 +591,16 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num,
zend_resolve_fast_call(op_array, start_op, op_array->try_catch_array[i].finally_op - 2);
opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
- /* generate a sequence of FAST_CALL to upward finally block */
+ /* We should not generate JMPs that require handling multiple finally blocks */
while (i > 0) {
i--;
if (op_array->try_catch_array[i].finally_op &&
op_num >= op_array->try_catch_array[i].try_op &&
op_num < op_array->try_catch_array[i].finally_op - 1 &&
(dst_num < op_array->try_catch_array[i].try_op ||
- dst_num > op_array->try_catch_array[i].finally_end)) {
-
- opline = get_next_op(op_array);
- 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;
+ dst_num > op_array->try_catch_array[i].finally_end)
+ ) {
+ ZEND_ASSERT(0);
}
}
@@ -676,31 +670,27 @@ static void zend_resolve_finally_calls(zend_op_array *op_array)
for (i = 0, j = op_array->last; i < j; i++) {
opline = op_array->opcodes + i;
switch (opline->opcode) {
- case ZEND_RETURN:
- case ZEND_RETURN_BY_REF:
- case ZEND_GENERATOR_RETURN:
- zend_resolve_finally_call(op_array, i, (uint32_t)-1);
- break;
case ZEND_BRK:
case ZEND_CONT:
- zend_resolve_finally_call(op_array, i, zend_get_brk_cont_target(op_array, opline));
+ zend_check_finally_breakout(op_array, i, zend_get_brk_cont_target(op_array, opline));
break;
case ZEND_GOTO:
- if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
- zend_resolve_goto_label(op_array, NULL, opline);
- }
- /* break omitted intentionally */
+ zend_check_finally_breakout(op_array, i,
+ zend_resolve_goto_label(op_array, opline)->op1.opline_num);
+ break;
case ZEND_JMP:
zend_resolve_finally_call(op_array, i, opline->op1.opline_num);
break;
case ZEND_FAST_CALL:
+ if (opline->extended_value == ZEND_FAST_CALL_UNBOUND) {
+ opline->op1.opline_num = op_array->try_catch_array[opline->op1.num].finally_op;
+ opline->extended_value = 0;
+ }
zend_resolve_fast_call(op_array, i, i);
break;
case ZEND_FAST_RET:
zend_resolve_finally_ret(op_array, i);
break;
- default:
- break;
}
}
}
@@ -756,9 +746,7 @@ ZEND_API int pass_two(zend_op_array *op_array)
}
break;
case ZEND_GOTO:
- if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
- zend_resolve_goto_label(op_array, NULL, opline);
- }
+ opline = zend_resolve_goto_label(op_array, opline);
/* break omitted intentionally */
case ZEND_JMP:
case ZEND_FAST_CALL: