]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.4'
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 20 Dec 2019 09:35:50 +0000 (10:35 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 20 Dec 2019 09:35:50 +0000 (10:35 +0100)
* PHP-7.4:
  Fix early free of assign_obj op_data

1  2 
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 015a766616c49f7bc2abed0adb6e540289e19afe,61242d6130c5c2d40c82086983f09ec10697fd39..a42371cc2615ac1a6853cc1e6fbce0f9f97a6287
@@@ -2433,26 -2557,9 +2439,24 @@@ ZEND_VM_C_LABEL(fast_assign_obj)
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (OP2_TYPE == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      FREE_OP_DATA();
 +                      UNDEF_RESULT();
 +                      ZEND_VM_C_GOTO(exit_assign_obj);
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (OP2_TYPE != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  ZEND_VM_C_LABEL(free_and_exit_assign_obj):
-       FREE_OP_DATA();
- ZEND_VM_C_LABEL(exit_assign_obj):
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
index 784511924593a52134395200c612294d1d2b673e,7fc4d1f691e19cec442c568f87e23e564934a22e..ed67ae5e5f38dea7d5059bdf8a9f725c35493560
@@@ -21527,31 -22665,16 +21533,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -21666,31 -22800,16 +21678,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -21805,31 -22935,16 +21823,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -21944,31 -23070,16 +21968,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -23772,31 -24967,16 +23802,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -23911,31 -25102,16 +23947,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -24050,31 -25237,16 +24092,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -24189,31 -25372,16 +24237,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -27199,31 -28656,16 +27253,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -27338,31 -28791,16 +27398,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -27477,31 -28926,16 +27543,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -27616,31 -29061,16 +27688,31 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
  
 -      if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
  }
@@@ -29654,26 -31146,9 +29732,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -29793,29 -31281,14 +29877,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -29932,29 -31416,14 +30022,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -30071,26 -31551,9 +30167,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -31496,30 -32982,15 +31598,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -31635,30 -33117,15 +31743,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -31774,30 -33252,15 +31888,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -31913,30 -33387,15 +32033,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -33867,26 -35504,9 +33993,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -34006,29 -35639,14 +34138,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -34145,29 -35774,14 +34283,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -34284,26 -35909,9 +34428,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -38116,26 -39865,9 +38266,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -38255,29 -40000,14 +38411,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -38394,29 -40135,14 +38556,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -38533,26 -40270,9 +38701,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CONST == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CONST != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -41541,30 -43371,15 +41715,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -41680,30 -43506,15 +41860,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -41819,30 -43641,15 +42005,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
 -      zval_ptr_dtor_nogc(free_op2);
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -41958,30 -43776,15 +42150,30 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op2);
+ exit_assign_obj:
 +      zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
  
        /* assign_obj has two opcodes! */
        ZEND_VM_NEXT_OPCODE_EX(1, 2);
@@@ -46325,26 -48465,9 +46523,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
@@@ -46464,29 -48600,14 +46668,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -46603,29 -48735,14 +46813,29 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +                      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
-       zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }
 -      zval_ptr_dtor_nogc(free_op_data);
++      zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var));
+ exit_assign_obj:
  
  
        /* assign_obj has two opcodes! */
@@@ -46742,26 -48870,9 +46958,24 @@@ fast_assign_obj
                ZVAL_DEREF(value);
        }
  
 -      value = Z_OBJ_HT_P(object)->write_property(object, property, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +      if (IS_CV == IS_CONST) {
 +              name = Z_STR_P(property);
 +      } else {
 +              name = zval_try_get_tmp_string(property, &tmp_name);
 +              if (UNEXPECTED(!name)) {
 +
 +                      UNDEF_RESULT();
 +                      goto exit_assign_obj;
 +              }
 +      }
 +
 +      value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL);
 +
 +      if (IS_CV != IS_CONST) {
 +              zend_tmp_string_release(tmp_name);
 +      }
  
  free_and_exit_assign_obj:
- exit_assign_obj:
        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                ZVAL_COPY(EX_VAR(opline->result.var), value);
        }