summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-07-05 12:16:30 +0300
committerDmitry Stogov <dmitry@zend.com>2019-07-05 12:16:30 +0300
commit1b5b8175aff0fba41ce94d75d1ddf0f7be630b9c (patch)
tree7fef7cefe333517cf9640eee34b198e865a4f9e5 /ext
parent215e9d069c3dae40d94894d1a938d771cecc2549 (diff)
parent48ca5a1e176c5301fedd1bc4f661969d6f9a49eb (diff)
downloadphp-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')
-rw-r--r--ext/opcache/Optimizer/block_pass.c16
-rw-r--r--ext/opcache/Optimizer/compact_literals.c112
-rw-r--r--ext/opcache/Optimizer/dce.c32
-rw-r--r--ext/opcache/Optimizer/dfa_pass.c30
-rw-r--r--ext/opcache/Optimizer/escape_analysis.c38
-rw-r--r--ext/opcache/Optimizer/pass2.c55
-rw-r--r--ext/opcache/Optimizer/pass3.c43
-rw-r--r--ext/opcache/Optimizer/sccp.c86
-rw-r--r--ext/opcache/Optimizer/zend_dfg.c16
-rw-r--r--ext/opcache/Optimizer/zend_dump.c10
-rw-r--r--ext/opcache/Optimizer/zend_inference.c211
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c79
-rw-r--r--ext/opcache/Optimizer/zend_optimizer_internal.h1
-rw-r--r--ext/opcache/Optimizer/zend_ssa.c16
-rw-r--r--ext/opcache/jit/zend_jit.c184
-rw-r--r--ext/opcache/jit/zend_jit_helpers.c44
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc248
17 files changed, 416 insertions, 805 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 505f004de3..b3014257ef 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -1712,18 +1712,10 @@ static void zend_t_usage(zend_cfg *cfg, zend_op_array *op_array, zend_bitset use
if (opline->result_type == IS_VAR) {
if (!zend_bitset_in(usage, VAR_NUM(opline->result.var))) {
switch (opline->opcode) {
- 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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
+ case ZEND_ASSIGN_OP:
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_ASSIGN:
diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c
index 50ccd7d256..b70f0cacd1 100644
--- a/ext/opcache/Optimizer/compact_literals.c
+++ b/ext/opcache/Optimizer/compact_literals.c
@@ -197,7 +197,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_POST_INC_STATIC_PROP:
case ZEND_POST_DEC_STATIC_PROP:
-literals_handle_static_prop:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
if (opline->op2_type == IS_CONST) {
LITERAL_INFO(opline->op2.constant, LITERAL_CLASS, 2);
}
@@ -230,39 +230,11 @@ literals_handle_static_prop:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
+ case ZEND_ASSIGN_OBJ_OP:
if (opline->op2_type == IS_CONST) {
LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
}
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
- goto literals_handle_static_prop;
- }
- if (opline->op2_type == IS_CONST) {
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- LITERAL_INFO(opline->op2.constant, LITERAL_PROPERTY, 1);
- } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
- if (Z_EXTRA(op_array->literals[opline->op2.constant]) == ZEND_EXTRA_VALUE) {
- LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 2);
- } else {
- LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
- }
- } else {
- LITERAL_INFO(opline->op2.constant, LITERAL_VALUE, 1);
- }
- }
- break;
case ZEND_BIND_GLOBAL:
LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 1);
break;
@@ -290,6 +262,7 @@ literals_handle_static_prop:
case ZEND_FETCH_DIM_UNSET:
case ZEND_FETCH_LIST_R:
case ZEND_FETCH_LIST_W:
+ case ZEND_ASSIGN_DIM_OP:
if (opline->op1_type == IS_CONST) {
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1);
}
@@ -548,54 +521,41 @@ literals_handle_static_prop:
cache_size += sizeof(void *);
}
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
- if (opline->op1_type == IS_CONST) {
- // op1 static property
- if (opline->op2_type == IS_CONST) {
- (opline+1)->extended_value = add_static_slot(&hash, op_array,
- opline->op2.constant,
- opline->op1.constant,
- LITERAL_STATIC_PROPERTY,
- &cache_size);
- } else {
- (opline+1)->extended_value = cache_size;
- cache_size += 3 * sizeof(void *);
- }
- } else if (opline->op2_type == IS_CONST) {
- // op2 class
- if (class_slot[opline->op2.constant] >= 0) {
- (opline+1)->extended_value = class_slot[opline->op2.constant];
- } else {
- (opline+1)->extended_value = cache_size;
- class_slot[opline->op2.constant] = cache_size;
- cache_size += sizeof(void *);
- }
+ case ZEND_ASSIGN_STATIC_PROP_OP:
+ if (opline->op1_type == IS_CONST) {
+ // op1 static property
+ if (opline->op2_type == IS_CONST) {
+ (opline+1)->extended_value = add_static_slot(&hash, op_array,
+ opline->op2.constant,
+ opline->op1.constant,
+ LITERAL_STATIC_PROPERTY,
+ &cache_size);
+ } else {
+ (opline+1)->extended_value = cache_size;
+ cache_size += 3 * sizeof(void *);
+ }
+ } else if (opline->op2_type == IS_CONST) {
+ // op2 class
+ if (class_slot[opline->op2.constant] >= 0) {
+ (opline+1)->extended_value = class_slot[opline->op2.constant];
+ } else {
+ (opline+1)->extended_value = cache_size;
+ class_slot[opline->op2.constant] = cache_size;
+ cache_size += sizeof(void *);
}
}
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- if (opline->op2_type == IS_CONST) {
- // op2 property
- if (opline->op1_type == IS_UNUSED &&
- property_slot[opline->op2.constant] >= 0) {
- (opline+1)->extended_value = property_slot[opline->op2.constant];
- } else {
- (opline+1)->extended_value = cache_size;
- cache_size += 3 * sizeof(void *);
- if (opline->op1_type == IS_UNUSED) {
- property_slot[opline->op2.constant] = (opline+1)->extended_value;
- }
+ break;
+ case ZEND_ASSIGN_OBJ_OP:
+ if (opline->op2_type == IS_CONST) {
+ // op2 property
+ if (opline->op1_type == IS_UNUSED &&
+ property_slot[opline->op2.constant] >= 0) {
+ (opline+1)->extended_value = property_slot[opline->op2.constant];
+ } else {
+ (opline+1)->extended_value = cache_size;
+ cache_size += 3 * sizeof(void *);
+ if (opline->op1_type == IS_UNUSED) {
+ property_slot[opline->op2.constant] = (opline+1)->extended_value;
}
}
}
diff --git a/ext/opcache/Optimizer/dce.c b/ext/opcache/Optimizer/dce.c
index c9ef7111ca..8370bdc779 100644
--- a/ext/opcache/Optimizer/dce.c
+++ b/ext/opcache/Optimizer/dce.c
@@ -201,21 +201,9 @@ static inline zend_bool may_have_side_effects(
case ZEND_PRE_DEC:
case ZEND_POST_DEC:
return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def);
- 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:
return is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)
- || (opline->extended_value
- && ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE);
+ || ssa->vars[ssa_op->op1_def].escape_state != ESCAPE_STATE_NO_ESCAPE;
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
if (is_bad_mod(ssa, ssa_op->op1_use, ssa_op->op1_def)
@@ -349,18 +337,10 @@ static zend_bool try_remove_var_def(context *ctx, int free_var, int use_chain, z
case ZEND_ASSIGN_OBJ_REF:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_STATIC_PROP_REF:
- 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_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_PRE_INC_OBJ:
diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c
index c9528918e3..b0d58f9566 100644
--- a/ext/opcache/Optimizer/dfa_pass.c
+++ b/ext/opcache/Optimizer/dfa_pass.c
@@ -1180,8 +1180,8 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
}
}
- } else if (opline->opcode == ZEND_ASSIGN_ADD
- && opline->extended_value == 0
+ } else if (opline->opcode == ZEND_ASSIGN_OP
+ && opline->extended_value == ZEND_ADD
&& ssa->ops[op_1].op1_def == v
&& opline->op2_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG
@@ -1192,10 +1192,11 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
// op_1: ASSIGN_ADD #?.CV [undef,null,int,foat] ->#v.CV, int(1) => PRE_INC #?.CV ->#v.CV
opline->opcode = ZEND_PRE_INC;
+ opline->extended_value = 0;
SET_UNUSED(opline->op2);
- } else if (opline->opcode == ZEND_ASSIGN_SUB
- && opline->extended_value == 0
+ } else if (opline->opcode == ZEND_ASSIGN_OP
+ && opline->extended_value == ZEND_SUB
&& ssa->ops[op_1].op1_def == v
&& opline->op2_type == IS_CONST
&& Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) == IS_LONG
@@ -1206,6 +1207,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
// op_1: ASSIGN_SUB #?.CV [undef,null,int,foat] -> #v.CV, int(1) => PRE_DEC #?.CV ->#v.CV
opline->opcode = ZEND_PRE_DEC;
+ opline->extended_value = 0;
SET_UNUSED(opline->op2);
} else if (opline->opcode == ZEND_VERIFY_RETURN_TYPE
@@ -1240,26 +1242,18 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx
&& !RETURN_VALUE_USED(opline)
&& ssa->ops[op_1].op1_use >= 0
&& !(ssa->var_info[ssa->ops[op_1].op1_use].type & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))
- && (opline->opcode == ZEND_ASSIGN_ADD
- || opline->opcode == ZEND_ASSIGN_SUB
- || opline->opcode == ZEND_ASSIGN_MUL
- || opline->opcode == ZEND_ASSIGN_DIV
- || opline->opcode == ZEND_ASSIGN_MOD
- || opline->opcode == ZEND_ASSIGN_SL
- || opline->opcode == ZEND_ASSIGN_SR
- || opline->opcode == ZEND_ASSIGN_BW_OR
- || opline->opcode == ZEND_ASSIGN_BW_AND
- || opline->opcode == ZEND_ASSIGN_BW_XOR)
- && opline->extended_value == 0) {
-
-// op_1: ASSIGN_ADD #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ?
+ && opline->opcode == ZEND_ASSIGN_OP
+ && opline->extended_value != ZEND_CONCAT) {
+
+// op_1: ASSIGN_OP #orig_var.CV [undef,null,bool,int,double] -> #v.CV, ? => #v.CV = ADD #orig_var.CV, ?
/* Reconstruct SSA */
ssa->ops[op_1].result_def = ssa->ops[op_1].op1_def;
ssa->ops[op_1].op1_def = -1;
/* Update opcode */
- opline->opcode -= (ZEND_ASSIGN_ADD - ZEND_ADD);
+ opline->opcode = opline->extended_value;
+ opline->extended_value = 0;
opline->result_type = opline->op1_type;
opline->result.var = opline->op1.var;
diff --git a/ext/opcache/Optimizer/escape_analysis.c b/ext/opcache/Optimizer/escape_analysis.c
index 948feeef84..c561bec9dc 100644
--- a/ext/opcache/Optimizer/escape_analysis.c
+++ b/ext/opcache/Optimizer/escape_analysis.c
@@ -257,24 +257,11 @@ static int is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int var
} else if (op->op1_def == var) {
switch (opline->opcode) {
case ZEND_ASSIGN:
- return 1;
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:
- return 1;
- 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:
- return (opline->extended_value != 0);
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
@@ -312,22 +299,11 @@ static int is_escape_use(zend_op_array *op_array, zend_ssa *ssa, int use, int va
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_OBJ_IS:
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_POW:
- if (!opline->extended_value) {
- return 1;
- }
- /* break missing intentionally */
+ case ZEND_ASSIGN_OP:
+ return 1;
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:
diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c
index 3613fd57de..01e118e7e3 100644
--- a/ext/opcache/Optimizer/pass2.c
+++ b/ext/opcache/Optimizer/pass2.c
@@ -53,16 +53,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
}
}
- /* break missing *intentionally* - the assign_op's may only optimize op2 */
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
- case ZEND_ASSIGN_DIV:
- case ZEND_ASSIGN_POW:
- if (opline->extended_value != 0) {
- /* object tristate op - don't attempt to optimize it! */
- break;
- }
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
/* don't optimise if it should produce a runtime numeric string error */
@@ -85,14 +75,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
}
}
- /* break missing *intentionally - the assign_op's may only optimize op2 */
- case ZEND_ASSIGN_MOD:
- case ZEND_ASSIGN_SL:
- case ZEND_ASSIGN_SR:
- if (opline->extended_value != 0) {
- /* object tristate op - don't attempt to optimize it! */
- break;
- }
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
/* don't optimise if it should produce a runtime numeric string error */
@@ -111,12 +93,6 @@ void zend_optimizer_pass2(zend_op_array *op_array)
convert_to_string(&ZEND_OP1_LITERAL(opline));
}
}
- /* break missing *intentionally - the assign_op's may only optimize op2 */
- case ZEND_ASSIGN_CONCAT:
- if (opline->extended_value != 0) {
- /* object tristate op - don't attempt to optimize it! */
- break;
- }
if (opline->op2_type == IS_CONST) {
if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP2_LITERAL(opline));
@@ -124,6 +100,37 @@ void zend_optimizer_pass2(zend_op_array *op_array)
}
break;
+ case ZEND_ASSIGN_OP:
+ if (opline->op2_type == IS_CONST) {
+ if (opline->extended_value == ZEND_ADD
+ || opline->extended_value == ZEND_SUB
+ || opline->extended_value == ZEND_MUL
+ || opline->extended_value == ZEND_DIV
+ || opline->extended_value == ZEND_POW) {
+ if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) {
+ /* don't optimise if it should produce a runtime numeric string error */
+ if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) {
+ convert_scalar_to_number(&ZEND_OP2_LITERAL(opline));
+ }
+ }
+ } else if (opline->extended_value == ZEND_MOD
+ || opline->extended_value == ZEND_SL
+ || opline->extended_value == ZEND_SR) {
+ if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
+ /* don't optimise if it should produce a runtime numeric string error */
+ if (!(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING
+ && !is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0))) {
+ convert_to_long(&ZEND_OP2_LITERAL(opline));
+ }
+ }
+ } else if (opline->extended_value == ZEND_CONCAT) {
+ if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
+ convert_to_string(&ZEND_OP2_LITERAL(opline));
+ }
+ }
+ }
+ break;
+
case ZEND_JMPZ_EX:
case ZEND_JMPNZ_EX:
/* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */
diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c
index a700893cee..5bbb2b0854 100644
--- a/ext/opcache/Optimizer/pass3.c
+++ b/ext/opcache/Optimizer/pass3.c
@@ -113,47 +113,12 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
}
}
- if ((opline->op1_type & (IS_VAR | IS_CV))
+ if (ZEND_IS_BINARY_ASSIGN_OP_OPCODE(opline->opcode)
+ && (opline->op1_type & (IS_VAR | IS_CV))
&& opline->op1.var == next_opline->op1.var
&& opline->op1_type == next_opline->op1_type) {
- switch (opline->opcode) {
- case ZEND_ADD:
- opline->opcode = ZEND_ASSIGN_ADD;
- break;
- case ZEND_SUB:
- opline->opcode = ZEND_ASSIGN_SUB;
- break;
- case ZEND_MUL:
- opline->opcode = ZEND_ASSIGN_MUL;
- break;
- case ZEND_DIV:
- opline->opcode = ZEND_ASSIGN_DIV;
- break;
- case ZEND_MOD:
- opline->opcode = ZEND_ASSIGN_MOD;
- break;
- case ZEND_POW:
- opline->opcode = ZEND_ASSIGN_POW;
- break;
- case ZEND_CONCAT:
- opline->opcode = ZEND_ASSIGN_CONCAT;
- break;
- case ZEND_SL:
- opline->opcode = ZEND_ASSIGN_SL;
- break;
- case ZEND_SR:
- opline->opcode = ZEND_ASSIGN_SR;
- break;
- case ZEND_BW_OR:
- opline->opcode = ZEND_ASSIGN_BW_OR;
- break;
- case ZEND_BW_AND:
- opline->opcode = ZEND_ASSIGN_BW_AND;
- break;
- case ZEND_BW_XOR:
- opline->opcode = ZEND_ASSIGN_BW_XOR;
- break;
- }
+ opline->extended_value = opline->opcode;
+ opline->opcode = ZEND_ASSIGN_OP;
COPY_NODE(opline->result, next_opline->result);
MAKE_NOP(next_opline);
opline++;
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index 9715f3e238..f5989dffdf 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -222,18 +222,10 @@ static zend_bool can_replace_op1(
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_OBJ_REF:
- 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_FETCH_DIM_W:
case ZEND_FETCH_DIM_RW:
case ZEND_FETCH_DIM_UNSET:
@@ -1489,32 +1481,24 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
}
SET_RESULT_BOT(result);
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_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:
if (op1) {
SKIP_IF_TOP(op1);
}
if (op2) {
SKIP_IF_TOP(op2);
}
- if (opline->extended_value == 0) {
- if (ct_eval_binary_op(&zv, zend_compound_assign_to_binary_op(opline->opcode), op1, op2) == SUCCESS) {
+ if (opline->opcode == ZEND_ASSIGN_OP) {
+ if (ct_eval_binary_op(&zv, opline->extended_value, op1, op2) == SUCCESS) {
SET_RESULT(op1, &zv);
SET_RESULT(result, &zv);
zval_ptr_dtor_nogc(&zv);
break;
}
- } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
+ } else if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
if ((IS_PARTIAL_ARRAY(op1) || Z_TYPE_P(op1) == IS_ARRAY)
&& ssa_op->op1_def >= 0 && op2) {
zval tmp;
@@ -1533,7 +1517,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
}
- if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
+ if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) {
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
zval_ptr_dtor_nogc(&tmp);
@@ -1558,7 +1542,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
zval_ptr_dtor_nogc(&zv);
}
}
- } else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
if (op1 && IS_PARTIAL_OBJECT(op1)
&& ssa_op->op1_def >= 0
&& ctx->scdf.ssa->vars[ssa_op->op1_def].escape_state == ESCAPE_STATE_NO_ESCAPE) {
@@ -1578,7 +1562,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
break;
}
- if (ct_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
+ if (ct_eval_binary_op(&tmp, opline->extended_value, &tmp, data) != SUCCESS) {
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
zval_ptr_dtor_nogc(&tmp);
@@ -1599,11 +1583,6 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
zval_ptr_dtor_nogc(&zv);
}
}
- } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
- SET_RESULT_BOT(result);
- break;
- } else {
- ZEND_ASSERT(0 && "Invalid compound assignment kind");
}
SET_RESULT_BOT(result);
SET_RESULT_BOT(op1);
@@ -2347,18 +2326,10 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
switch (opline->opcode) {
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
- 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:
if ((ssa_op->op2_use >= 0 && !value_known(&ctx->values[ssa_op->op2_use]))
|| ((ssa_op+1)->op1_use >= 0 &&!value_known(&ctx->values[(ssa_op+1)->op1_use]))) {
return 0;
@@ -2411,22 +2382,11 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
removed_ops++;
zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_POW:
- if (opline->extended_value) {
- removed_ops++;
- zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
- }
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
+ removed_ops++;
+ zend_ssa_remove_instr(ssa, opline + 1, ssa_op + 1);
break;
default:
break;
diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c
index a1104614f2..e995b673b7 100644
--- a/ext/opcache/Optimizer/zend_dfg.c
+++ b/ext/opcache/Optimizer/zend_dfg.c
@@ -107,18 +107,10 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
case ZEND_SEND_VAR_NO_REF:
case ZEND_SEND_VAR_NO_REF_EX:
case ZEND_FE_RESET_RW:
- 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_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_POST_INC:
diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c
index cf1c1ccbee..8dcbd33b54 100644
--- a/ext/opcache/Optimizer/zend_dump.c
+++ b/ext/opcache/Optimizer/zend_dump.c
@@ -443,14 +443,8 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *
if (ZEND_VM_EXT_NUM == (flags & ZEND_VM_EXT_MASK)) {
fprintf(stderr, " %u", opline->extended_value);
- } else if (ZEND_VM_EXT_DIM_OBJ == (flags & ZEND_VM_EXT_MASK)) {
- if (opline->extended_value == ZEND_ASSIGN_DIM) {
- fprintf(stderr, " (dim)");
- } else if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- fprintf(stderr, " (obj)");
- } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
- fprintf(stderr, " (static prop)");
- }
+ } else if (ZEND_VM_EXT_OP == (flags & ZEND_VM_EXT_MASK)) {
+ fprintf(stderr, " (%s)", zend_get_opcode_name(opline->extended_value) + 5);
} else if (ZEND_VM_EXT_TYPE == (flags & ZEND_VM_EXT_MASK)) {
switch (opline->extended_value) {
case IS_NULL:
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;
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 1ed57ce3d8..4a2ef02513 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -53,25 +53,6 @@ void zend_optimizer_collect_constant(zend_optimizer_ctx *ctx, zval *name, zval*
zend_hash_add(ctx->constants, Z_STR_P(name), &val);
}
-zend_uchar zend_compound_assign_to_binary_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()
- }
-}
-
int zend_optimizer_eval_binary_op(zval *result, zend_uchar opcode, zval *op1, zval *op2) /* {{{ */
{
binary_op_type binary_op = get_binary_op(opcode);
@@ -320,21 +301,11 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
}
zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_POW:
- if (opline->extended_value != ZEND_ASSIGN_STATIC_PROP) {
- break;
- }
+ case ZEND_ASSIGN_OP:
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ break;
+ case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_STATIC_PROP_REF:
case ZEND_FETCH_STATIC_PROP_R:
@@ -440,7 +411,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_POST_INC_STATIC_PROP:
case ZEND_POST_DEC_STATIC_PROP:
-handle_static_prop:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
REQUIRES_STRING(val);
drop_leading_backslash(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
@@ -509,6 +480,7 @@ handle_static_prop:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
+ case ZEND_ASSIGN_OBJ_OP:
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
opline->extended_value = alloc_cache_slots(op_array, 3);
@@ -518,42 +490,7 @@ handle_static_prop:
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
opline->extended_value = alloc_cache_slots(op_array, 3) | (opline->extended_value & ZEND_ISEMPTY);
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- TO_STRING_NOWARN(val);
- opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- (opline+1)->extended_value = alloc_cache_slots(op_array, 3);
- } else if (opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
- goto handle_static_prop;
- } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
- if (Z_TYPE_P(val) == IS_STRING) {
- zend_ulong index;
-
- if (ZEND_HANDLE_NUMERIC(Z_STR_P(val), index)) {
- ZVAL_LONG(&tmp, index);
- opline->op2.constant = zend_optimizer_add_literal(op_array, &tmp);
- zend_string_hash_val(Z_STR_P(val));
- zend_optimizer_add_literal(op_array, val);
- Z_EXTRA(op_array->literals[opline->op2.constant]) = ZEND_EXTRA_VALUE;
- break;
- }
- }
- opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- } else {
- opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- }
- break;
+ case ZEND_ASSIGN_DIM_OP:
case ZEND_ISSET_ISEMPTY_DIM_OBJ:
case ZEND_ASSIGN_DIM:
case ZEND_UNSET_DIM:
diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h
index 9997506bf0..9ab18f6398 100644
--- a/ext/opcache/Optimizer/zend_optimizer_internal.h
+++ b/ext/opcache/Optimizer/zend_optimizer_internal.h
@@ -110,7 +110,6 @@ zend_function *zend_optimizer_get_called_func(
uint32_t zend_optimizer_classify_function(zend_string *name, uint32_t num_args);
void zend_optimizer_migrate_jump(zend_op_array *op_array, zend_op *new_opline, zend_op *opline);
void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_t *shiftlist);
-zend_uchar zend_compound_assign_to_binary_op(zend_uchar opcode);
int sccp_optimize_op_array(zend_optimizer_ctx *ctx, zend_op_array *op_arrya, zend_ssa *ssa, zend_call_info **call_map);
int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reorder_dtor_effects);
int zend_ssa_escape_analysis(const zend_script *script, zend_op_array *op_array, zend_ssa *ssa);
diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c
index dca4781382..7520b719f1 100644
--- a/ext/opcache/Optimizer/zend_ssa.c
+++ b/ext/opcache/Optimizer/zend_ssa.c
@@ -716,18 +716,10 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
//NEW_SSA_VAR(opline->op1.var)
}
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_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_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_POST_INC:
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index f4fbcb28d0..ca0fb04a9c 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -123,12 +123,7 @@ static zend_bool zend_is_commutative(zend_uchar opcode)
opcode == ZEND_MUL ||
opcode == ZEND_BW_OR ||
opcode == ZEND_BW_AND ||
- opcode == ZEND_BW_XOR ||
- opcode == ZEND_ASSIGN_ADD ||
- opcode == ZEND_ASSIGN_MUL||
- opcode == ZEND_ASSIGN_BW_OR ||
- opcode == ZEND_ASSIGN_BW_AND ||
- opcode == ZEND_ASSIGN_BW_XOR;
+ opcode == ZEND_BW_XOR;
}
static zend_bool zend_long_is_power_of_two(zend_long x)
@@ -496,86 +491,79 @@ static int zend_may_overflow(const zend_op *opline, zend_op_array *op_array, zen
!ssa->var_info[res].has_range ||
ssa->var_info[res].range.underflow ||
ssa->var_info[res].range.overflow);
- case ZEND_ASSIGN_ADD:
- if (opline->extended_value != 0) {
- return 1;
- }
- num = opline - op_array->opcodes;
- res = ssa->ops[num].op1_def;
- if (res < 0 ||
- !ssa->var_info[res].has_range) {
- return 1;
- }
- if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_min;
-
- if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
- return 1;
- }
- op1_min = OP1_MIN_RANGE();
- op2_min = OP2_MIN_RANGE();
- if (zend_add_will_overflow(op1_min, op2_min)) {
+ case ZEND_ASSIGN_OP:
+ if (opline->extended_value == ZEND_ADD) {
+ num = opline - op_array->opcodes;
+ res = ssa->ops[num].op1_def;
+ if (res < 0 ||
+ !ssa->var_info[res].has_range) {
return 1;
}
- }
- if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_max;
+ if (ssa->var_info[res].range.underflow) {
+ zend_long op1_min, op2_min;
- if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
- return 1;
- }
- op1_max = OP1_MAX_RANGE();
- op2_max = OP2_MAX_RANGE();
- if (zend_add_will_overflow(op1_max, op2_max)) {
- return 1;
+ if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
+ return 1;
+ }
+ op1_min = OP1_MIN_RANGE();
+ op2_min = OP2_MIN_RANGE();
+ if (zend_add_will_overflow(op1_min, op2_min)) {
+ return 1;
+ }
}
- }
- return 0;
- case ZEND_ASSIGN_SUB:
- if (opline->extended_value != 0) {
- return 1;
- }
- num = opline - op_array->opcodes;
- res = ssa->ops[num].op1_def;
- if (res < 0 ||
- !ssa->var_info[res].has_range) {
- return 1;
- }
- if (ssa->var_info[res].range.underflow) {
- zend_long op1_min, op2_max;
+ if (ssa->var_info[res].range.overflow) {
+ zend_long op1_max, op2_max;
- if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
- return 1;
+ if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
+ return 1;
+ }
+ op1_max = OP1_MAX_RANGE();
+ op2_max = OP2_MAX_RANGE();
+ if (zend_add_will_overflow(op1_max, op2_max)) {
+ return 1;
+ }
}
- op1_min = OP1_MIN_RANGE();
- op2_max = OP2_MAX_RANGE();
- if (zend_sub_will_overflow(op1_min, op2_max)) {
+ return 0;
+ } else if (opline->extended_value == ZEND_SUB) {
+ num = opline - op_array->opcodes;
+ res = ssa->ops[num].op1_def;
+ if (res < 0 ||
+ !ssa->var_info[res].has_range) {
return 1;
}
- }
- if (ssa->var_info[res].range.overflow) {
- zend_long op1_max, op2_min;
+ if (ssa->var_info[res].range.underflow) {
+ zend_long op1_min, op2_max;
- if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
- return 1;
+ if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
+ return 1;
+ }
+ op1_min = OP1_MIN_RANGE();
+ op2_max = OP2_MAX_RANGE();
+ if (zend_sub_will_overflow(op1_min, op2_max)) {
+ return 1;
+ }
}
- op1_max = OP1_MAX_RANGE();
- op2_min = OP2_MIN_RANGE();
- if (zend_sub_will_overflow(op1_max, op2_min)) {
- return 1;
+ if (ssa->var_info[res].range.overflow) {
+ zend_long op1_max, op2_min;
+
+ if (!OP1_HAS_RANGE() || !OP2_HAS_RANGE()) {
+ return 1;
+ }
+ op1_max = OP1_MAX_RANGE();
+ op2_min = OP2_MIN_RANGE();
+ if (zend_sub_will_overflow(op1_max, op2_min)) {
+ return 1;
+ }
}
+ return 0;
+ } else if (opline->extended_value == ZEND_MUL) {
+ num = opline - op_array->opcodes;
+ res = ssa->ops[num].op1_def;
+ return (res < 0 ||
+ !ssa->var_info[res].has_range ||
+ ssa->var_info[res].range.underflow ||
+ ssa->var_info[res].range.overflow);
}
- return 0;
- case ZEND_ASSIGN_MUL:
- if (opline->extended_value != 0) {
- return 1;
- }
- num = opline - op_array->opcodes;
- res = ssa->ops[num].op1_def;
- return (res < 0 ||
- !ssa->var_info[res].has_range ||
- ssa->var_info[res].range.underflow ||
- ssa->var_info[res].range.overflow);
default:
return 1;
}
@@ -1471,10 +1459,10 @@ static int zend_jit_try_allocate_free_reg(zend_op_array *op_array, zend_ssa *ssa
case ZEND_MUL:
hint = ssa->ops[current->start].op1_use;
break;
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
- if (opline->extended_value) {
+ case ZEND_ASSIGN_OP:
+ if (opline->extended_value == ZEND_ADD
+ || opline->extended_value == ZEND_SUB
+ || opline->extended_value == ZEND_MUL) {
hint = ssa->ops[current->start].op1_use;
}
break;
@@ -1920,21 +1908,7 @@ static void zend_calc_checked_this_r(zend_bitset checked_this, zend_op_array *op
for (; opline < end; opline++) {
switch (opline->opcode) {
- 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:
- if (opline->extended_value != ZEND_ASSIGN_OBJ) {
- break;
- }
+ case ZEND_ASSIGN_OBJ_OP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
@@ -2232,21 +2206,17 @@ static int zend_jit(zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_op
goto jit_failure;
}
goto done;
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
-// case ZEND_ASSIGN_DIV: // TODO: check for division by zero ???
- case ZEND_ASSIGN_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_SL:
- case ZEND_ASSIGN_SR:
- case ZEND_ASSIGN_MOD:
- if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) {
- goto jit_failure;
+ case ZEND_ASSIGN_OP:
+ case ZEND_ASSIGN_DIM_OP:
+ if (opline->extended_value != ZEND_POW
+ && opline->extended_value != ZEND_DIV) {
+ // TODO: check for division by zero ???
+ if (!zend_jit_assign_op(&dasm_state, opline, op_array, ssa)) {
+ goto jit_failure;
+ }
+ goto done;
}
- goto done;
+ break;
case ZEND_ASSIGN_DIM:
if (!zend_jit_assign_dim(&dasm_state, opline, op_array, ssa)) {
goto jit_failure;
diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c
index cfad5786ac..f45bfa8a39 100644
--- a/ext/opcache/jit/zend_jit_helpers.c
+++ b/ext/opcache/jit/zend_jit_helpers.c
@@ -757,18 +757,10 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
uint32_t var;
switch (opline->opcode) {
- 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:
msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_FETCH_DIM_W:
@@ -783,25 +775,15 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
while (opline < end) {
if (opline->op1_type == IS_VAR && opline->op1.var == var) {
switch (opline->opcode) {
- 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:
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- msg = "Cannot use string offset as an object";
- } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
- msg = "Cannot use string offset as an array";
- } else {
- msg = "Cannot use assign-op operators with string offsets";
- }
+ case ZEND_ASSIGN_OBJ_OP:
+ msg = "Cannot use string offset as an object";
+ break;
+ case ZEND_ASSIGN_DIM_OP:
+ msg = "Cannot use string offset as an array";
+ break;
+ case ZEND_ASSIGN_OP:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
+ msg = "Cannot use assign-op operators with string offsets";
break;
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 7a46588e90..8e2c0f529b 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -533,19 +533,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro FPU_MATH, opcode, addr
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| FPU_OP fadd, addr
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| FPU_OP fsub, addr
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| FPU_OP fmul, addr
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| FPU_OP fdiv, addr
|| break;
|| }
@@ -664,19 +660,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro SSE_MATH, opcode, reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| SSE_OP addsd, reg, addr
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| SSE_OP subsd, reg, addr
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| SSE_OP mulsd, reg, addr
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| SSE_OP divsd, reg, addr
|| break;
|| }
@@ -685,19 +677,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro SSE_MATH_REG, opcode, dst_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| addsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| subsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| mulsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| divsd xmm(dst_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| }
@@ -729,19 +717,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro AVX_MATH, opcode, reg, op1_reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| AVX_OP vaddsd, reg, op1_reg, addr
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| AVX_OP vsubsd, reg, op1_reg, addr
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| AVX_OP vmulsd, reg, op1_reg, addr
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| AVX_OP vdivsd, reg, op1_reg, addr
|| break;
|| }
@@ -750,19 +734,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro AVX_MATH_REG, opcode, dst_reg, op1_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| vaddsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| vsubsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| vmulsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| vdivsd xmm(dst_reg-ZREG_XMM0), xmm(op1_reg-ZREG_XMM0), xmm(src_reg-ZREG_XMM0)
|| break;
|| }
@@ -851,27 +831,21 @@ static void* dasm_labels[zend_lb_MAX];
|.macro LONG_MATH, opcode, reg, addr
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| LONG_OP add, reg, addr
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| LONG_OP sub, reg, addr
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| LONG_OP imul, reg, addr
|| break;
|| case ZEND_BW_OR:
-|| case ZEND_ASSIGN_BW_OR:
| LONG_OP or, reg, addr
|| break;
|| case ZEND_BW_AND:
-|| case ZEND_ASSIGN_BW_AND:
| LONG_OP and, reg, addr
|| break;
|| case ZEND_BW_XOR:
-|| case ZEND_ASSIGN_BW_XOR:
| LONG_OP xor, reg, addr
|| break;
|| default:
@@ -882,27 +856,21 @@ static void* dasm_labels[zend_lb_MAX];
|.macro LONG_MATH_REG, opcode, dst_reg, src_reg
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| add dst_reg, src_reg
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| sub dst_reg, src_reg
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| imul dst_reg, src_reg
|| break;
|| case ZEND_BW_OR:
-|| case ZEND_ASSIGN_BW_OR:
| or dst_reg, src_reg
|| break;
|| case ZEND_BW_AND:
-|| case ZEND_ASSIGN_BW_AND:
| and dst_reg, src_reg
|| break;
|| case ZEND_BW_XOR:
-|| case ZEND_ASSIGN_BW_XOR:
| xor dst_reg, src_reg
|| break;
|| default:
@@ -938,19 +906,15 @@ static void* dasm_labels[zend_lb_MAX];
|.macro FPU_MATH_REG, opcode, reg
|| switch (opcode) {
|| case ZEND_ADD:
-|| case ZEND_ASSIGN_ADD:
| fadd reg
|| break;
|| case ZEND_SUB:
-|| case ZEND_ASSIGN_SUB:
| fsub reg
|| break;
|| case ZEND_MUL:
-|| case ZEND_ASSIGN_MUL:
| fmul reg
|| break;
|| case ZEND_DIV:
-|| case ZEND_ASSIGN_DIV:
| fdiv reg
|| break;
|| }
@@ -2786,26 +2750,13 @@ static int zend_jit_handler(dasm_State **Dst, const zend_op *opline, int may_thr
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
+ case ZEND_ASSIGN_DIM_OP:
+ case ZEND_ASSIGN_OBJ_OP:
+ case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_ASSIGN_STATIC_PROP_REF:
case ZEND_ASSIGN_OBJ_REF:
last_valid_opline++;
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_CONCAT:
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_POW:
- if (opline->extended_value) {
- last_valid_opline++;
- }
- break;
default:
break;
}
@@ -3261,6 +3212,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
+ zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@@ -3278,7 +3230,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
result_reg = ZREG_R0;
}
- if (opline->opcode == ZEND_MUL &&
+ if (opcode == ZEND_MUL &&
((Z_MODE(op2_addr) == IS_CONST_ZVAL &&
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr))) &&
is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) ||
@@ -3292,17 +3244,17 @@ static int zend_jit_math_long_long(dasm_State **Dst,
| GET_ZVAL_LVAL result_reg, op2_addr
| shl Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op1_addr)))
}
- } else if (opline->opcode == ZEND_DIV &&
+ } else if (opcode == ZEND_DIV &&
(Z_MODE(op2_addr) == IS_CONST_ZVAL &&
is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr))))) {
| GET_ZVAL_LVAL result_reg, op1_addr
| shr Ra(result_reg), floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
} else {
| GET_ZVAL_LVAL result_reg, op1_addr
- if (same_ops && opline->opcode != ZEND_DIV) {
- | LONG_MATH_REG opline->opcode, Ra(result_reg), Ra(result_reg)
+ if (same_ops && opcode != ZEND_DIV) {
+ | LONG_MATH_REG opcode, Ra(result_reg), Ra(result_reg)
} else {
- | LONG_MATH opline->opcode, result_reg, op2_addr
+ | LONG_MATH opcode, result_reg, op2_addr
}
}
if ((res_info & MAY_BE_DOUBLE) && zend_may_overflow(opline, op_array, ssa)) {
@@ -3316,15 +3268,15 @@ static int zend_jit_math_long_long(dasm_State **Dst,
| SSE_GET_ZVAL_LVAL tmp_reg1, op1_addr
| SSE_GET_ZVAL_LVAL tmp_reg2, op2_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
- | AVX_MATH_REG opline->opcode, tmp_reg1, tmp_reg1, tmp_reg2
+ | AVX_MATH_REG opcode, tmp_reg1, tmp_reg1, tmp_reg2
} else {
- | SSE_MATH_REG opline->opcode, tmp_reg1, tmp_reg2
+ | SSE_MATH_REG opcode, tmp_reg1, tmp_reg2
}
| SSE_SET_ZVAL_DVAL res_addr, tmp_reg1
|.else
| FPU_GET_ZVAL_LVAL op2_addr
| FPU_GET_ZVAL_LVAL op1_addr
- | FPU_MATH_REG opline->opcode, st1
+ | FPU_MATH_REG opcode, st1
| FPU_SET_ZVAL_DVAL res_addr
|.endif
if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_DOUBLE) {
@@ -3355,6 +3307,7 @@ static int zend_jit_math_long_double(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
+ zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@@ -3366,14 +3319,14 @@ static int zend_jit_math_long_double(dasm_State **Dst,
| SSE_GET_ZVAL_LVAL result_reg, op1_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
- | AVX_MATH opline->opcode, result_reg, result_reg, op2_addr
+ | AVX_MATH opcode, result_reg, result_reg, op2_addr
} else {
- | SSE_MATH opline->opcode, result_reg, op2_addr
+ | SSE_MATH opcode, result_reg, op2_addr
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_LVAL op1_addr
- | FPU_MATH opline->opcode, op2_addr
+ | FPU_MATH opcode, op2_addr
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@@ -3390,6 +3343,7 @@ static int zend_jit_math_double_long(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
+ zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@@ -3398,7 +3352,7 @@ static int zend_jit_math_double_long(dasm_State **Dst,
|.if SSE
zend_reg result_reg;
- if (zend_is_commutative(opline->opcode)) {
+ if (zend_is_commutative(opcode)) {
if (Z_MODE(res_addr) == IS_REG) {
result_reg = Z_REG(res_addr);
} else {
@@ -3406,9 +3360,9 @@ static int zend_jit_math_double_long(dasm_State **Dst,
}
| SSE_GET_ZVAL_LVAL result_reg, op2_addr
if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) {
- | AVX_MATH opline->opcode, result_reg, result_reg, op1_addr
+ | AVX_MATH opcode, result_reg, result_reg, op1_addr
} else {
- | SSE_MATH opline->opcode, result_reg, op1_addr
+ | SSE_MATH opcode, result_reg, op1_addr
}
} else {
zend_reg tmp_reg;
@@ -3433,21 +3387,21 @@ static int zend_jit_math_double_long(dasm_State **Dst,
op1_reg = result_reg;
}
| SSE_GET_ZVAL_LVAL tmp_reg, op2_addr
- | AVX_MATH_REG opline->opcode, result_reg, op1_reg, tmp_reg
+ | AVX_MATH_REG opcode, result_reg, op1_reg, tmp_reg
} else {
| SSE_GET_ZVAL_DVAL result_reg, op1_addr
| SSE_GET_ZVAL_LVAL tmp_reg, op2_addr
- | SSE_MATH_REG opline->opcode, result_reg, tmp_reg
+ | SSE_MATH_REG opcode, result_reg, tmp_reg
}
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_LVAL op2_addr
- if (zend_is_commutative(opline->opcode)) {
- | FPU_MATH opline->opcode, op1_addr
+ if (zend_is_commutative(opcode)) {
+ | FPU_MATH opcode, op1_addr
} else {
| FPU_GET_ZVAL_DVAL op1_addr
- | FPU_MATH_REG opline->opcode, st1
+ | FPU_MATH_REG opcode, st1
}
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@@ -3467,6 +3421,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
zend_op_array *op_array,
zend_ssa *ssa,
const zend_op *opline,
+ zend_uchar opcode,
zend_jit_addr op1_addr,
zend_jit_addr op2_addr,
zend_jit_addr res_addr,
@@ -3492,7 +3447,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
if (Z_MODE(op1_addr) == IS_REG) {
op1_reg = Z_REG(op1_addr);
val_addr = op2_addr;
- } else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) {
+ } else if (Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) {
op1_reg = Z_REG(op2_addr);
val_addr = op1_addr;
} else {
@@ -3500,16 +3455,16 @@ static int zend_jit_math_double_double(dasm_State **Dst,
op1_reg = result_reg;
val_addr = op2_addr;
}
- if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) &&
+ if ((opcode == ZEND_MUL) &&
Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) {
| AVX_MATH_REG ZEND_ADD, result_reg, op1_reg, op1_reg
} else {
- | AVX_MATH opline->opcode, result_reg, op1_reg, val_addr
+ | AVX_MATH opcode, result_reg, op1_reg, val_addr
}
} else {
zend_jit_addr val_addr;
- if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opline->opcode)) {
+ if (Z_MODE(op1_addr) != IS_REG && Z_MODE(op2_addr) == IS_REG && zend_is_commutative(opcode)) {
| SSE_GET_ZVAL_DVAL result_reg, op2_addr
val_addr = op1_addr;
} else {
@@ -3517,18 +3472,18 @@ static int zend_jit_math_double_double(dasm_State **Dst,
val_addr = op2_addr;
}
if (same_ops) {
- | SSE_MATH_REG opline->opcode, result_reg, result_reg
- } else if ((opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) &&
+ | SSE_MATH_REG opcode, result_reg, result_reg
+ } else if ((opcode == ZEND_MUL) &&
Z_MODE(val_addr) == IS_CONST_ZVAL && Z_DVAL_P(Z_ZV(val_addr)) == 2.0) {
| SSE_MATH_REG ZEND_ADD, result_reg, result_reg
} else {
- | SSE_MATH opline->opcode, result_reg, val_addr
+ | SSE_MATH opcode, result_reg, val_addr
}
}
| SSE_SET_ZVAL_DVAL res_addr, result_reg
|.else
| FPU_GET_ZVAL_DVAL op1_addr
- | FPU_MATH opline->opcode, op2_addr
+ | FPU_MATH opcode, op2_addr
| FPU_SET_ZVAL_DVAL res_addr
|.endif
@@ -3545,6 +3500,7 @@ static int zend_jit_math_double_double(dasm_State **Dst,
static int zend_jit_math_helper(dasm_State **Dst,
const zend_op *opline,
+ zend_uchar opcode,
zend_op_array *op_array,
zend_ssa *ssa,
zend_uchar op1_type,
@@ -3579,7 +3535,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6
}
- if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@@ -3588,7 +3544,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
}
- if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_info, res_use_info)) {
+ if (!zend_jit_math_long_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_info, res_use_info)) {
return 0;
}
if (op1_info & MAY_BE_DOUBLE) {
@@ -3605,7 +3561,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE, op2_addr, IS_DOUBLE, >6
}
}
- if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@@ -3615,7 +3571,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_LONG|MAY_BE_DOUBLE))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
- if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
| jmp >5
@@ -3636,7 +3592,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op2_addr, IS_DOUBLE, >6
}
}
- if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
}
@@ -3648,7 +3604,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op2_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) {
| IF_NOT_ZVAL_TYPE op2_addr, IS_LONG, >6
}
- if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_double_long(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
if (op2_info & MAY_BE_DOUBLE) {
@@ -3670,7 +3626,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
| IF_NOT_ZVAL_TYPE op1_addr, IS_DOUBLE, >6
}
}
- if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_double_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
}
@@ -3682,7 +3638,7 @@ static int zend_jit_math_helper(dasm_State **Dst,
if (op1_info & (MAY_BE_ANY-(MAY_BE_DOUBLE|MAY_BE_LONG))) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_LONG, >6
}
- if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, op1_addr, op2_addr, res_addr, res_use_info)) {
+ if (!zend_jit_math_long_double(Dst, op_array, ssa, opline, opcode, op1_addr, op2_addr, res_addr, res_use_info)) {
return 0;
}
if (op1_info & MAY_BE_DOUBLE) {
@@ -3729,13 +3685,13 @@ static int zend_jit_math_helper(dasm_State **Dst,
| sub r4, 12
| PUSH_ZVAL_ADDR op2_addr, r0
|.endif
- if (opline->opcode == ZEND_ADD || opline->opcode == ZEND_ASSIGN_ADD) {
+ if (opcode == ZEND_ADD) {
| EXT_CALL add_function, r0
- } else if (opline->opcode == ZEND_SUB || opline->opcode == ZEND_ASSIGN_SUB) {
+ } else if (opcode == ZEND_SUB) {
| EXT_CALL sub_function, r0
- } else if (opline->opcode == ZEND_MUL || opline->opcode == ZEND_ASSIGN_MUL) {
+ } else if (opcode == ZEND_MUL) {
| EXT_CALL mul_function, r0
- } else if (opline->opcode == ZEND_DIV || opline->opcode == ZEND_ASSIGN_DIV) {
+ } else if (opcode == ZEND_DIV) {
| EXT_CALL div_function, r0
} else {
ZEND_ASSERT(0);
@@ -3806,7 +3762,7 @@ static int zend_jit_math(dasm_State **Dst, const zend_op *opline, int *opnum, ze
res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def);
}
- if (!zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
+ if (!zend_jit_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
return 0;
}
if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) {
@@ -3821,6 +3777,7 @@ fallback:
static int zend_jit_long_math_helper(dasm_State **Dst,
const zend_op *opline,
+ zend_uchar opcode,
zend_op_array *op_array,
zend_ssa *ssa,
zend_uchar op1_type,
@@ -3841,7 +3798,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
{
zend_bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
zend_reg result_reg;
- zend_uchar opcode = opline->opcode;
zval tmp;
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)) {
@@ -3875,7 +3831,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
result_reg = ZREG_R0;
}
- if (opcode == ZEND_SL || opcode == ZEND_ASSIGN_SL) {
+ if (opcode == ZEND_SL) {
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@@ -3913,7 +3869,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| shl Ra(result_reg), cl
|1:
}
- } else if (opcode == ZEND_SR || opcode == ZEND_ASSIGN_SR) {
+ } else if (opcode == ZEND_SR) {
| GET_ZVAL_LVAL result_reg, op1_addr
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@@ -3950,7 +3906,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
|1:
| sar Ra(result_reg), cl
}
- } else if (opcode == ZEND_MOD || opcode == ZEND_ASSIGN_MOD) {
+ } else if (opcode == ZEND_MOD) {
if (Z_MODE(op2_addr) == IS_CONST_ZVAL) {
zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr));
@@ -4056,17 +4012,17 @@ static int zend_jit_long_math_helper(dasm_State **Dst,
| sub r4, 12
| PUSH_ZVAL_ADDR op2_addr, r0
|.endif
- if (opline->opcode == ZEND_BW_OR || opline->opcode == ZEND_ASSIGN_BW_OR) {
+ if (opcode == ZEND_BW_OR) {
| EXT_CALL bitwise_or_function, r0
- } else if (opline->opcode == ZEND_BW_AND || opline->opcode == ZEND_ASSIGN_BW_AND) {
+ } else if (opcode == ZEND_BW_AND) {
| EXT_CALL bitwise_and_function, r0
- } else if (opline->opcode == ZEND_BW_XOR || opline->opcode == ZEND_ASSIGN_BW_XOR) {
+ } else if (opcode == ZEND_BW_XOR) {
| EXT_CALL bitwise_xor_function, r0
- } else if (opline->opcode == ZEND_SL || opline->opcode == ZEND_ASSIGN_SL) {
+ } else if (opcode == ZEND_SL) {
| EXT_CALL shift_left_function, r0
- } else if (opline->opcode == ZEND_SR || opline->opcode == ZEND_ASSIGN_SR) {
+ } else if (opcode == ZEND_SR) {
| EXT_CALL shift_right_function, r0
- } else if (opline->opcode == ZEND_MOD || opline->opcode == ZEND_ASSIGN_MOD) {
+ } else if (opcode == ZEND_MOD) {
| EXT_CALL mod_function, r0
} else {
ZEND_ASSERT(0);
@@ -4140,7 +4096,7 @@ static int zend_jit_long_math(dasm_State **Dst, const zend_op *opline, int *opnu
res_addr = zend_jit_decode_op(op_array, opline->result_type, opline->result, opline, ra, ssa->ops[opline - op_array->opcodes].result_def);
}
- if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
+ if (!zend_jit_long_math_helper(Dst, opline, opline->opcode, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->result.var, res_addr, RES_INFO(), res_use_info)) {
return 0;
}
if (ra && !zend_jit_store_ssa_var_if_necessary(Dst, ssa, ra, res_addr, ssa->ops[opline - op_array->opcodes].result_def, ssa->ops[opline - op_array->opcodes].result_use)) {
@@ -5186,26 +5142,26 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_
}
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
- switch (opline->opcode) {
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
- case ZEND_ASSIGN_DIV:
- if (!zend_jit_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) {
+ switch (opline->extended_value) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
+ if (!zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), 0, var_addr, var_def_info, var_info)) {
return 0;
}
break;
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_SL:
- case ZEND_ASSIGN_SR:
- case ZEND_ASSIGN_MOD:
- if (!zend_jit_long_math_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) {
+ case ZEND_BW_OR:
+ case ZEND_BW_AND:
+ case ZEND_BW_XOR:
+ case ZEND_SL:
+ case ZEND_SR:
+ case ZEND_MOD:
+ if (!zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), op3_ssa_var, 0, var_addr, OP1_DEF_INFO(), var_info)) {
return 0;
}
break;
- case ZEND_ASSIGN_CONCAT:
+ case ZEND_CONCAT:
if (!zend_jit_concat_helper(Dst, opline, op_array, ssa, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, op3_addr, OP1_DATA_INFO(), var_addr, OP1_DEF_INFO())) {
return 0;
}
@@ -5235,7 +5191,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, zend_
} else {
| LOAD_ZVAL_ADDR FCARG2a, op2_addr
}
- binary_op = get_binary_op(opline->opcode);
+ binary_op = get_binary_op(opline->extended_value);
|.if X64
| LOAD_ZVAL_ADDR CARG3, op3_addr
| LOAD_ADDR CARG4, binary_op
@@ -5269,9 +5225,9 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
zend_jit_addr op1_addr, op2_addr;
int op1_ssa_var, op2_ssa_var;
- if (opline->extended_value == ZEND_ASSIGN_DIM) {
+ if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
return zend_jit_assign_dim_op(Dst, opline, op_array, ssa);
- } else if (opline->extended_value == ZEND_ASSIGN_OBJ || opline->extended_value == ZEND_ASSIGN_STATIC_PROP) {
+ } else if (opline->opcode == ZEND_ASSIGN_OBJ_OP || opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
goto fallback;
}
@@ -5295,28 +5251,28 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
goto fallback;
}
- switch (opline->opcode) {
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
- case ZEND_ASSIGN_DIV:
+ switch (opline->extended_value) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE)) ||
!(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
goto fallback;
}
break;
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_SL:
- case ZEND_ASSIGN_SR:
- case ZEND_ASSIGN_MOD:
+ case ZEND_BW_OR:
+ case ZEND_BW_AND:
+ case ZEND_BW_XOR:
+ case ZEND_SL:
+ case ZEND_SR:
+ case ZEND_MOD:
if (!(op1_info & MAY_BE_LONG) ||
!(op2_info & MAY_BE_LONG)) {
goto fallback;
}
break;
- case ZEND_ASSIGN_CONCAT:
+ case ZEND_CONCAT:
if (!(op1_info & MAY_BE_STRING) ||
!(op2_info & MAY_BE_STRING)) {
goto fallback;
@@ -5332,20 +5288,20 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, zend_op_a
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
}
- switch (opline->opcode) {
- case ZEND_ASSIGN_ADD:
- case ZEND_ASSIGN_SUB:
- case ZEND_ASSIGN_MUL:
- case ZEND_ASSIGN_DIV:
- return zend_jit_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
- case ZEND_ASSIGN_BW_OR:
- case ZEND_ASSIGN_BW_AND:
- case ZEND_ASSIGN_BW_XOR:
- case ZEND_ASSIGN_SL:
- case ZEND_ASSIGN_SR:
- case ZEND_ASSIGN_MOD:
- return zend_jit_long_math_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
- case ZEND_ASSIGN_CONCAT:
+ switch (opline->extended_value) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
+ return zend_jit_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
+ case ZEND_BW_OR:
+ case ZEND_BW_AND:
+ case ZEND_BW_XOR:
+ case ZEND_SL:
+ case ZEND_SR:
+ case ZEND_MOD:
+ return zend_jit_long_math_helper(Dst, opline, opline->extended_value, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, op1_ssa_var, opline->op2_type, opline->op2, op2_addr, op2_info, op2_ssa_var, opline->op1.var, op1_addr, OP1_DEF_INFO(), op1_info);
+ case ZEND_CONCAT:
return zend_jit_concat_helper(Dst, opline, op_array, ssa, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, op1_addr, OP1_DEF_INFO());
default:
ZEND_ASSERT(0);