diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2019-07-05 12:16:30 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2019-07-05 12:16:30 +0300 |
| commit | 1b5b8175aff0fba41ce94d75d1ddf0f7be630b9c (patch) | |
| tree | 7fef7cefe333517cf9640eee34b198e865a4f9e5 /ext/opcache/Optimizer/zend_inference.c | |
| parent | 215e9d069c3dae40d94894d1a938d771cecc2549 (diff) | |
| parent | 48ca5a1e176c5301fedd1bc4f661969d6f9a49eb (diff) | |
| download | php-git-1b5b8175aff0fba41ce94d75d1ddf0f7be630b9c.tar.gz | |
Merge branch 'PHP-7.4'
* PHP-7.4:
Replace ZEND_ASSIGN_ADD (and others) by ZEND_ASSIGN_OP, ZEND_ASSIGN_DIM_OP, ZEND_ASSGIN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP
Diffstat (limited to 'ext/opcache/Optimizer/zend_inference.c')
| -rw-r--r-- | ext/opcache/Optimizer/zend_inference.c | 211 |
1 files changed, 83 insertions, 128 deletions
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index f3c228f214..d2982e5cf5 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -548,25 +548,6 @@ static inline zend_bool shift_left_overflows(zend_long n, zend_long s) { } } -/* Get the normal op corresponding to a compound assignment op */ -static inline zend_uchar get_compound_assign_op(zend_uchar opcode) { - switch (opcode) { - case ZEND_ASSIGN_ADD: return ZEND_ADD; - case ZEND_ASSIGN_SUB: return ZEND_SUB; - case ZEND_ASSIGN_MUL: return ZEND_MUL; - case ZEND_ASSIGN_DIV: return ZEND_DIV; - case ZEND_ASSIGN_MOD: return ZEND_MOD; - case ZEND_ASSIGN_SL: return ZEND_SL; - case ZEND_ASSIGN_SR: return ZEND_SR; - case ZEND_ASSIGN_CONCAT: return ZEND_CONCAT; - case ZEND_ASSIGN_BW_OR: return ZEND_BW_OR; - case ZEND_ASSIGN_BW_AND: return ZEND_BW_AND; - case ZEND_ASSIGN_BW_XOR: return ZEND_BW_XOR; - case ZEND_ASSIGN_POW: return ZEND_POW; - EMPTY_SWITCH_DEFAULT_CASE() - } -} - static int zend_inference_calc_binary_op_range( const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op *ssa_op, zend_uchar opcode, zend_ssa_range *tmp) { @@ -1381,23 +1362,20 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int } } break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value == 0) { + case ZEND_ASSIGN_OP: + if (opline->extended_value != ZEND_CONCAT + && opline->extended_value != ZEND_POW) { if (ssa->ops[line].op1_def == var || ssa->ops[line].result_def == var) { return zend_inference_calc_binary_op_range( op_array, ssa, opline, &ssa->ops[line], - get_compound_assign_op(opline->opcode), tmp); + opline->extended_value, tmp); } - } else if ((opline+1)->opcode == ZEND_OP_DATA) { + } + break; + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + if ((opline+1)->opcode == ZEND_OP_DATA) { if (ssa->ops[line+1].op1_def == var) { opline++; if (OP1_HAS_RANGE()) { @@ -1410,13 +1388,13 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int } } break; -// case ZEND_ASSIGN_CONCAT: case ZEND_OP_DATA: if ((opline-1)->opcode == ZEND_ASSIGN_DIM || (opline-1)->opcode == ZEND_ASSIGN_OBJ || - (opline-1)->opcode == ZEND_ASSIGN_ADD || - (opline-1)->opcode == ZEND_ASSIGN_SUB || - (opline-1)->opcode == ZEND_ASSIGN_MUL) { + ((opline-1)->opcode == ZEND_ASSIGN_OP && + ((opline-1)->extended_value == ZEND_ADD || + (opline-1)->extended_value == ZEND_SUB || + (opline-1)->extended_value == ZEND_MUL))) { if (ssa->ops[line].op1_def == var) { if (OP1_HAS_RANGE()) { tmp->min = OP1_MIN_RANGE(); @@ -2599,34 +2577,27 @@ static int zend_update_type_info(const zend_op_array *op_array, UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].result_def); break; - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_POW: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_CONCAT: { + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: + { zend_property_info *prop_info = NULL; orig = 0; tmp = 0; - if (opline->extended_value == ZEND_ASSIGN_OBJ) { + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { prop_info = zend_fetch_prop_info(op_array, ssa, opline, i); orig = t1; t1 = zend_fetch_prop_type(script, prop_info, &ce); t2 = OP1_DATA_INFO(); - } else if (opline->extended_value == ZEND_ASSIGN_DIM) { + } else if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (t1 & MAY_BE_ARRAY_OF_REF) { tmp |= MAY_BE_REF; } orig = t1; t1 = zend_array_element_type(t1, 1, 0); t2 = OP1_DATA_INFO(); - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) { prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline); t1 = zend_fetch_prop_type(script, prop_info, &ce); t2 = OP1_DATA_INFO(); @@ -2637,7 +2608,7 @@ static int zend_update_type_info(const zend_op_array *op_array, } tmp |= binary_op_result_type( - ssa, get_compound_assign_op(opline->opcode), t1, t2, ssa_ops[i].op1_def, optimization_level); + ssa, opline->extended_value, t1, t2, ssa_ops[i].op1_def, optimization_level); if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) { tmp |= MAY_BE_RC1; } @@ -2645,13 +2616,13 @@ static int zend_update_type_info(const zend_op_array *op_array, tmp |= MAY_BE_RC1 | MAY_BE_RCN; } - if (opline->extended_value == ZEND_ASSIGN_DIM) { + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (opline->op1_type == IS_CV) { orig = assign_dim_result_type(orig, OP2_INFO(), tmp, opline->op2_type); UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def); } - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { if (opline->op1_type == IS_CV) { if (!(orig & MAY_BE_REF)) { if (orig & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) { @@ -2665,14 +2636,14 @@ static int zend_update_type_info(const zend_op_array *op_array, UPDATE_SSA_TYPE(orig, ssa_ops[i].op1_def); COPY_SSA_OBJ_TYPE(ssa_ops[i].op1_use, ssa_ops[i].op1_def); } - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP) { /* Nothing to do */ } else { UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def); } if (ssa_ops[i].result_def >= 0) { ce = NULL; - if (opline->extended_value == ZEND_ASSIGN_DIM) { + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { if (opline->op2_type == IS_UNUSED) { /* When appending to an array and the LONG_MAX key is already used * null will be returned. */ @@ -2687,7 +2658,7 @@ static int zend_update_type_info(const zend_op_array *op_array, * results in a null return value. */ tmp |= MAY_BE_NULL; } - } else if (opline->extended_value == ZEND_ASSIGN_OBJ) { + } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { if (orig & (MAY_BE_ANY - (MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_OBJECT))) { /* null and false (and empty string) are implicitly converted to object, * anything else results in a null return value. */ @@ -2698,7 +2669,7 @@ static int zend_update_type_info(const zend_op_array *op_array, if (prop_info) { tmp &= zend_fetch_prop_type(script, prop_info, NULL); } - } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) { + } else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) { /* The return value must also satisfy the property type */ if (prop_info) { tmp &= zend_fetch_prop_type(script, prop_info, NULL); @@ -3441,18 +3412,10 @@ static int zend_update_type_info(const zend_op_array *op_array, case ZEND_FETCH_DIM_RW: case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_LIST_W: - case ZEND_ASSIGN_ADD: - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - case ZEND_ASSIGN_CONCAT: - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - case ZEND_ASSIGN_POW: + case ZEND_ASSIGN_OP: + case ZEND_ASSIGN_DIM_OP: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_DIM: tmp |= MAY_BE_ARRAY | MAY_BE_ARRAY_OF_ARRAY; break; @@ -3957,13 +3920,19 @@ static zend_bool can_convert_to_double( return 0; } } else { + zend_uchar opcode = opline->opcode; + + if (opcode == ZEND_ASSIGN_OP) { + opcode = opline->extended_value; + } + /* Avoid division by zero */ - if (opline->opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) { + if (opcode == ZEND_DIV && zval_get_double(&orig_op2) == 0.0) { return 0; } - get_binary_op(opline->opcode)(&orig_result, &orig_op1, &orig_op2); - get_binary_op(opline->opcode)(&dval_result, &dval_op1, &dval_op2); + get_binary_op(opcode)(&orig_result, &orig_op1, &orig_op2); + get_binary_op(opcode)(&dval_result, &dval_op1, &dval_op2); ZEND_ASSERT(Z_TYPE(dval_result) == IS_DOUBLE); if (zval_get_double(&orig_result) != Z_DVAL(dval_result)) { return 0; @@ -4571,62 +4540,48 @@ int zend_may_throw(const zend_op *opline, zend_op_array *op_array, zend_ssa *ssa return 0; } return (t1 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT)) || (t2 & (MAY_BE_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT)); - case ZEND_ASSIGN_ADD: - if (opline->extended_value != 0) { - return 1; - } - if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY - && (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) { - return 0; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_DIV: - case ZEND_ASSIGN_MOD: - if (opline->extended_value != 0) { - return 1; - } - if (!OP2_HAS_RANGE() || - (OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) { - /* Division by zero */ - return 1; - } - /* break missing intentionally */ - case ZEND_ASSIGN_SUB: - case ZEND_ASSIGN_MUL: - case ZEND_ASSIGN_POW: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_SL: - case ZEND_ASSIGN_SR: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - !OP2_HAS_RANGE() || - OP2_MIN_RANGE() < 0; - case ZEND_ASSIGN_CONCAT: - if (opline->extended_value != 0) { - return 1; - } - return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); - case ZEND_ASSIGN_BW_OR: - case ZEND_ASSIGN_BW_AND: - case ZEND_ASSIGN_BW_XOR: - if (opline->extended_value != 0) { - return 1; - } - if ((t1 & MAY_BE_ANY) == MAY_BE_STRING - && (t2 & MAY_BE_ANY) == MAY_BE_STRING) { - return 0; + case ZEND_ASSIGN_OP: + if (opline->extended_value == ZEND_ADD) { + if ((t1 & MAY_BE_ANY) == MAY_BE_ARRAY + && (t2 & MAY_BE_ANY) == MAY_BE_ARRAY) { + return 0; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_DIV || + opline->extended_value == ZEND_MOD) { + if (!OP2_HAS_RANGE() || + (OP2_MIN_RANGE() <= 0 && OP2_MAX_RANGE() >= 0)) { + /* Division by zero */ + return 1; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_SUB || + opline->extended_value == ZEND_MUL || + opline->extended_value == ZEND_POW) { + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_SL || + opline->extended_value == ZEND_SR) { + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + !OP2_HAS_RANGE() || + OP2_MIN_RANGE() < 0; + } else if (opline->extended_value == ZEND_CONCAT) { + return (t1 & (MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_ARRAY|MAY_BE_OBJECT)); + } else if (opline->extended_value == ZEND_BW_OR || + opline->extended_value == ZEND_BW_AND || + opline->extended_value == ZEND_BW_XOR) { + if ((t1 & MAY_BE_ANY) == MAY_BE_STRING + && (t2 & MAY_BE_ANY) == MAY_BE_STRING) { + return 0; + } + return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || + (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); } - return (t1 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)) || - (t2 & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT)); + return 1; case ZEND_ASSIGN: if (t1 & MAY_BE_REF) { return 1; |
