@@ -6232,8 +6232,14 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit,
62326232 ir_IF_TRUE_cold(if_typed);
62336233 jit_SET_EX_OPLINE(jit, opline);
62346234 if (Z_MODE(val_addr) == IS_REG) {
6235- ZEND_ASSERT(opline->opcode == ZEND_ASSIGN);
6236- zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
6235+ zend_jit_addr real_addr;
6236+
6237+ if (opline->opcode == ZEND_ASSIGN_DIM) {
6238+ real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, (opline+1)->op1.var);
6239+ } else {
6240+ ZEND_ASSERT(opline->opcode == ZEND_ASSIGN);
6241+ real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var);
6242+ }
62376243 if (!zend_jit_spill_store_inv(jit, val_addr, real_addr, val_info)) {
62386244 return 0;
62396245 }
@@ -12788,18 +12794,29 @@ static int zend_jit_isset_isempty_dim(zend_jit_ctx *jit,
1278812794 return 1;
1278912795}
1279012796
12791- static int zend_jit_assign_dim(zend_jit_ctx *jit, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t val_info, uint8_t dim_type, int may_throw)
12797+ static int zend_jit_assign_dim(zend_jit_ctx *jit,
12798+ const zend_op *opline,
12799+ uint32_t op1_info,
12800+ zend_jit_addr op1_addr,
12801+ uint32_t op2_info,
12802+ zend_jit_addr op2_addr,
12803+ uint32_t val_info,
12804+ zend_jit_addr op3_addr,
12805+ zend_jit_addr op3_def_addr,
12806+ zend_jit_addr res_addr,
12807+ uint8_t dim_type,
12808+ int may_throw)
1279212809{
12793- zend_jit_addr op2_addr, op3_addr, res_addr;
1279412810 ir_ref if_type = IR_UNUSED;
1279512811 ir_ref end_inputs = IR_UNUSED, ht_ref;
1279612812
12797- op2_addr = (opline->op2_type != IS_UNUSED) ? OP2_ADDR() : 0;
12798- op3_addr = OP1_DATA_ADDR();
12799- if (opline->result_type == IS_UNUSED) {
12800- res_addr = 0;
12801- } else {
12802- res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
12813+ if (op3_addr != op3_def_addr && op3_def_addr) {
12814+ if (!zend_jit_update_regs(jit, (opline+1)->op1.var, op3_addr, op3_def_addr, val_info)) {
12815+ return 0;
12816+ }
12817+ if (Z_MODE(op3_def_addr) == IS_REG && Z_MODE(op3_addr) != IS_REG) {
12818+ op3_addr = op3_def_addr;
12819+ }
1280312820 }
1280412821
1280512822 if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && (val_info & MAY_BE_UNDEF)) {
@@ -12852,7 +12869,7 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, const zend_op *opline, uint32_
1285212869 ir_refs_init(found_values, 8);
1285312870
1285412871 if (!zend_jit_fetch_dimension_address_inner(jit, opline, BP_VAR_W, op1_info,
12855- op2_info, OP2_ADDR() , dim_type, NULL, NULL, NULL,
12872+ op2_info, op2_addr , dim_type, NULL, NULL, NULL,
1285612873 0, ht_ref, found_inputs, found_values, &end_inputs, NULL)) {
1285712874 return 0;
1285812875 }
@@ -12870,7 +12887,9 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit, const zend_op *opline, uint32_
1287012887 var_addr = ZEND_ADDR_REF_ZVAL(ref);
1287112888
1287212889 // JIT: value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
12873- if (opline->op1_type == IS_VAR) {
12890+ if (opline->op1_type == IS_VAR
12891+ && Z_MODE(op3_addr) != IS_REG
12892+ && (res_addr == 0 || Z_MODE(res_addr) != IS_REG)) {
1287412893 ZEND_ASSERT(opline->result_type == IS_UNUSED);
1287512894 if (!zend_jit_assign_to_variable_call(jit, opline, var_addr, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0)) {
1287612895 return 0;
@@ -16552,6 +16571,31 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1655216571 return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&
1655316572 (((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) ||
1655416573 ((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING));
16574+ case ZEND_ASSIGN_DIM:
16575+ op1_info = OP1_INFO();
16576+ op2_info = OP2_INFO();
16577+ if (trace) {
16578+ if (opline->op1_type == IS_CV) {
16579+ if ((opline+1)->op1_type == IS_CV
16580+ && (opline+1)->op1.var == opline->op1.var) {
16581+ /* skip $a[x] = $a; */
16582+ return 0;
16583+ }
16584+ } else if (opline->op1_type == IS_VAR) {
16585+ if (trace->op1_type == IS_UNKNOWN
16586+ || !(trace->op1_type & IS_TRACE_INDIRECT)
16587+ || opline->result_type != IS_UNUSED) {
16588+ return 0;
16589+ }
16590+ }
16591+ if (trace->op1_type != IS_UNKNOWN
16592+ && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_ARRAY) {
16593+ op1_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY);
16594+ }
16595+ }
16596+ return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&
16597+ (((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_LONG) ||
16598+ ((op2_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING));
1655516599 }
1655616600 return 0;
1655716601}
0 commit comments