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: