]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-5.6'
authorXinchen Hui <laruence@php.net>
Wed, 25 Feb 2015 12:16:15 +0000 (20:16 +0800)
committerXinchen Hui <laruence@php.net>
Wed, 25 Feb 2015 12:16:15 +0000 (20:16 +0800)
Conflicts:
ext/opcache/Optimizer/zend_optimizer.c

1  2 
ext/opcache/Optimizer/zend_optimizer.c

index c9ee97f49d18ead34216121f6953b0218128f25f,08ce46c356a518cfaa51c30bcc86af9285b7b3c6..62409e6530f57728b96ae956c9589a153cc88514
@@@ -307,28 -325,22 +307,39 @@@ int zend_optimizer_replace_by_const(zen
                                                if (opline->extended_value & ZEND_ARG_SEND_BY_REF) {
                                                        return 0;
                                                }
 -                                              opline->extended_value = ZEND_DO_FCALL;
 +                                              opline->extended_value = 0;
 +                                              opline->opcode = ZEND_SEND_VAL_EX;
                                        } else {
 -                                              opline->extended_value = ZEND_DO_FCALL_BY_NAME;
 +                                              opline->extended_value = 0;
 +                                              opline->opcode = ZEND_SEND_VAL;
                                        }
 -                                      opline->opcode = ZEND_SEND_VAL;
                                        break;
 -                              case ZEND_SWITCH_FREE:
 +                              /* In most cases IS_TMP_VAR operand may be used only once.
 +                               * The operands are usually destroyed by the opcode handler.
 +                               * ZEND_CASE is an exception, that keeps operand unchanged,
 +                               * and allows its reuse. The number of ZEND_CASE instructions
 +                               * usually terminated by ZEND_FREE that finally kills the value.
 +                               */
++                              case ZEND_FREE:
                                case ZEND_CASE: {
                                        zend_op *m, *n;
                                        int brk = op_array->last_brk_cont;
++                                      zend_bool in_switch = 0;
                                        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)) {
++                                                      in_switch = 1;
                                                        break;
                                                }
                                        }
++
++                                      if (!in_switch) {
++                                              ZEND_ASSERT(opline->opcode == ZEND_FREE);
++                                              MAKE_NOP(opline);
++                                              zval_dtor(val);
++                                              return 1;
++                                      }
++
                                        m = opline;
                                        n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1;
                                        while (m < n) {
                                        zval_dtor(val);
                                        return 1;
                                }
--                              case ZEND_FREE:
--                                      MAKE_NOP(opline);
--                                      zval_dtor(val);
-                                       return 1;
 -                                      break;
                                default:
                                        break;
 -                      } 
 -                      update_op1_const(op_array, opline, val TSRMLS_CC);
 +                      }
 +                      zend_optimizer_update_op1_const(op_array, opline, val);
                        break;
                }
 -              
 -              if (ZEND_OP2_TYPE(opline) == IS_VAR &&
 +
 +              if (ZEND_OP2_TYPE(opline) == type &&
                        ZEND_OP2(opline).var == var) {
                        switch (opline->opcode) {
                                case ZEND_ASSIGN_REF: