summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_optimizer.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index a8506fb078..191e13ca1d 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -310,13 +310,35 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
* usually terminated by ZEND_FREE that finally kills the value.
*/
case ZEND_CASE: {
- zval old_val;
- ZVAL_COPY_VALUE(&old_val, val);
- zval_copy_ctor(val);
- zend_optimizer_update_op1_const(op_array, opline, val);
- ZVAL_COPY_VALUE(val, &old_val);
- opline++;
- continue;
+ zend_op *m, *n;
+ int brk = op_array->last_brk_cont;
+ while (brk--) {
+ if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) &&
+ op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) {
+ break;
+ }
+ }
+ m = opline;
+ n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1;
+ while (m < n) {
+ if (ZEND_OP1_TYPE(m) == type &&
+ ZEND_OP1(m).var == var) {
+ if (m->opcode == ZEND_CASE) {
+ zval old_val;
+ ZVAL_COPY_VALUE(&old_val, val);
+ zval_copy_ctor(val);
+ zend_optimizer_update_op1_const(op_array, m, val);
+ ZVAL_COPY_VALUE(val, &old_val);
+ } else if (m->opcode == ZEND_FREE) {
+ MAKE_NOP(m);
+ } else {
+ ZEND_ASSERT(0);
+ }
+ }
+ m++;
+ }
+ zval_dtor(val);
+ return 1;
}
case ZEND_FREE:
MAKE_NOP(opline);