summaryrefslogtreecommitdiff
path: root/ext/opcache/Optimizer/zend_optimizer.c
diff options
context:
space:
mode:
authorTimm Friebe <thekid@thekid.de>2014-07-06 17:07:01 +0200
committerTimm Friebe <thekid@thekid.de>2014-07-06 17:07:01 +0200
commita1554ca6343598c38e4fb4fbcc46419ce0bdf058 (patch)
treee66e73ff23a340cf7343459a0331a57b8eff65aa /ext/opcache/Optimizer/zend_optimizer.c
parente0d51d1cf00d43c57104764b620bb9219889a86d (diff)
parent5b925824edf3edc951fc41608d5cbd07a0baab08 (diff)
downloadphp-git-a1554ca6343598c38e4fb4fbcc46419ce0bdf058.tar.gz
Merge in changes from master
Now also includes "on [TYPE]" in "Call to a member function" error
Diffstat (limited to 'ext/opcache/Optimizer/zend_optimizer.c')
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c29
1 files changed, 25 insertions, 4 deletions
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 973ba3aaac..fc7d0a29b3 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -367,20 +367,41 @@ static void replace_tmp_by_const(zend_op_array *op_array,
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP1(opline).var == var) {
- update_op1_const(op_array, opline, val TSRMLS_CC);
- /* TMP_VAR my be used only once */
- break;
+ /* 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.
+ */
+ if (opline->opcode == ZEND_CASE) {
+ zval old_val;
+ old_val = *val;
+ zval_copy_ctor(val);
+ update_op1_const(op_array, opline, val TSRMLS_CC);
+ *val = old_val;
+ } else if (opline->opcode == ZEND_FREE) {
+ MAKE_NOP(opline);
+ break;
+ } else {
+ update_op1_const(op_array, opline, val TSRMLS_CC);
+ val = NULL;
+ break;
+ }
}
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
ZEND_OP2(opline).var == var) {
update_op2_const(op_array, opline, val TSRMLS_CC);
- /* TMP_VAR my be used only once */
+ /* TMP_VAR may be used only once */
+ val = NULL;
break;
}
opline++;
}
+ if (val) {
+ zval_dtor(val);
+ }
}
#include "Optimizer/nop_removal.c"