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.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 933c75a706..7365d6a518 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -666,6 +666,20 @@ static void zend_resolve_finally_ret(zend_op_array *op_array, uint32_t op_num)
}
}
+static uint32_t zend_get_brk_cont_target(const zend_op_array *op_array, const zend_op *opline) {
+ int nest_levels = opline->op2.num;
+ int array_offset = opline->op1.num;
+ zend_brk_cont_element *jmp_to;
+ do {
+ jmp_to = &op_array->brk_cont_array[array_offset];
+ if (nest_levels > 1) {
+ array_offset = jmp_to->parent;
+ }
+ } while (--nest_levels > 0);
+
+ return opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont;
+}
+
static void zend_resolve_finally_calls(zend_op_array *op_array)
{
uint32_t i, j;
@@ -681,22 +695,8 @@ static void zend_resolve_finally_calls(zend_op_array *op_array)
break;
case ZEND_BRK:
case ZEND_CONT:
- {
- int nest_levels = opline->op2.num;
- int array_offset = opline->op1.num;
- zend_brk_cont_element *jmp_to;
-
- if (array_offset != -1) {
- do {
- jmp_to = &op_array->brk_cont_array[array_offset];
- if (nest_levels > 1) {
- array_offset = jmp_to->parent;
- }
- } while (--nest_levels > 0);
- zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont);
- break;
- }
- }
+ zend_resolve_finally_call(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) {
uint32_t num = opline->op2.constant;
@@ -774,6 +774,16 @@ ZEND_API int pass_two(zend_op_array *op_array)
case ZEND_DECLARE_INHERITED_CLASS_DELAYED:
opline->extended_value = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->extended_value);
break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ {
+ uint32_t jmp_target = zend_get_brk_cont_target(op_array, opline);
+ opline->opcode = ZEND_JMP;
+ opline->op1.opline_num = jmp_target;
+ opline->op2.num = 0;
+ ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
+ }
+ break;
case ZEND_GOTO:
if (Z_TYPE_P(RT_CONSTANT(op_array, opline->op2)) != IS_LONG) {
zend_resolve_goto_label(op_array, opline, 1);