Skip to content

Commit 24a86db

Browse files
committed
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: Fixed issue #183 (TMP_VAR is not only used once)
2 parents 370256a + 19be8b6 commit 24a86db

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

ext/opcache/Optimizer/zend_optimizer.c

+25-4
Original file line numberDiff line numberDiff line change
@@ -367,20 +367,41 @@ static void replace_tmp_by_const(zend_op_array *op_array,
367367
if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
368368
ZEND_OP1(opline).var == var) {
369369

370-
update_op1_const(op_array, opline, val TSRMLS_CC);
371-
/* TMP_VAR my be used only once */
372-
break;
370+
/* In most cases IS_TMP_VAR operand may be used only once.
371+
* The operands are usually destroyed by the opcode handler.
372+
* ZEND_CASE is an exception, that keeps operand unchanged,
373+
* and allows its reuse. The number of ZEND_CASE instructions
374+
* usually terminated by ZEND_FREE that finally kills the value.
375+
*/
376+
if (opline->opcode == ZEND_CASE) {
377+
zval old_val;
378+
old_val = *val;
379+
zval_copy_ctor(val);
380+
update_op1_const(op_array, opline, val TSRMLS_CC);
381+
*val = old_val;
382+
} else if (opline->opcode == ZEND_FREE) {
383+
MAKE_NOP(opline);
384+
break;
385+
} else {
386+
update_op1_const(op_array, opline, val TSRMLS_CC);
387+
val = NULL;
388+
break;
389+
}
373390
}
374391

375392
if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
376393
ZEND_OP2(opline).var == var) {
377394

378395
update_op2_const(op_array, opline, val TSRMLS_CC);
379-
/* TMP_VAR my be used only once */
396+
/* TMP_VAR may be used only once */
397+
val = NULL;
380398
break;
381399
}
382400
opline++;
383401
}
402+
if (val) {
403+
zval_dtor(val);
404+
}
384405
}
385406

386407
#include "Optimizer/nop_removal.c"

0 commit comments

Comments
 (0)