Improve fix for #74456

This commit is contained in:
Xinchen Hui 2017-04-18 12:47:53 +08:00
parent 1837eea66d
commit 187f42149d
2 changed files with 27 additions and 7 deletions

View file

@ -186,7 +186,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
COPY_NODE(opline->op1, src->op1);
VAR_SOURCE(op1) = NULL;
MAKE_NOP(src);
} else if (opline->opcode != ZEND_FETCH_LIST && opline->opcode != ZEND_CASE) {
} else {
zval c = ZEND_OP1_LITERAL(src);
zval_copy_ctor(&c);
if (zend_optimizer_update_op1_const(op_array, opline, &c)) {

View file

@ -165,6 +165,10 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
* zend_optimizer_replace_by_const() supports this. */
zval_ptr_dtor(val);
return 0;
case ZEND_CASE:
case ZEND_FETCH_LIST:
zval_ptr_dtor(val);
return 0;
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
case ZEND_FETCH_R:
@ -417,16 +421,27 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
*/
case ZEND_FETCH_LIST: {
zend_op *m = opline;
if (Z_TYPE_P(val) == IS_STRING) {
zend_string_hash_val(Z_STR_P(val));
}
do {
if (m->opcode == ZEND_FETCH_LIST &&
ZEND_OP1_TYPE(m) == type &&
ZEND_OP1(m).var == var) {
zend_optimizer_update_op1_const(op_array, m, val);
zval v;
ZVAL_COPY_VALUE(&v, val);
zval_copy_ctor(&v);
ZEND_OP1(m).constant = zend_optimizer_add_literal(op_array, &v);
ZEND_OP1_TYPE(m) = IS_CONST;
}
m++;
} while (m->opcode != ZEND_FREE || ZEND_OP1_TYPE(m) != type || ZEND_OP1(m).var != var);
ZEND_ASSERT(m->opcode == ZEND_FREE && ZEND_OP1_TYPE(m) == type && ZEND_OP1(m).var == var);
MAKE_NOP(m);
zval_dtor(val);
zend_optimizer_remove_live_range(op_array, var);
return 1;
}
@ -460,17 +475,22 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
} else {
n = op_array->opcodes + op_array->last;
}
if (Z_TYPE_P(val) == IS_STRING) {
zend_string_hash_val(Z_STR_P(val));
}
while (m < n) {
if (ZEND_OP1_TYPE(m) == type &&
ZEND_OP1(m).var == var) {
if (m->opcode == ZEND_CASE
|| m->opcode == ZEND_SWITCH_LONG
|| m->opcode == ZEND_SWITCH_STRING) {
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);
zval v;
ZVAL_COPY_VALUE(&v, val);
zval_copy_ctor(&v);
ZEND_OP1(m).constant = zend_optimizer_add_literal(op_array, &v);
ZEND_OP1_TYPE(m) = IS_CONST;
} else if (m->opcode == ZEND_FREE) {
MAKE_NOP(m);
} else {