From: Dmitry Stogov Date: Tue, 15 Jan 2019 15:49:05 +0000 (+0300) Subject: Separated zend_binary_assign_op_typed_ref() and zend_binary_assign_op_typed_prop... X-Git-Tag: php-7.4.0alpha1~1216 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=938ba93f4a76db49e2bb43d0aaa33ca4772be2d3;p=php Separated zend_binary_assign_op_typed_ref() and zend_binary_assign_op_typed_prop() helpers --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3dbcff34b6..c86f7df169 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1331,6 +1331,32 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * } } +static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *ref, zval *value, binary_op_type binary_op EXECUTE_DATA_DC) +{ + zval z_copy; + + binary_op(&z_copy, &ref->val, value); + if (EXPECTED(zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(&ref->val); + ZVAL_COPY_VALUE(&ref->val, &z_copy); + } else { + zval_ptr_dtor(&z_copy); + } +} + +static zend_never_inline void zend_binary_assign_op_typed_prop(zend_property_info *prop_info, zval *zptr, zval *value, binary_op_type binary_op EXECUTE_DATA_DC) +{ + zval z_copy; + + binary_op(&z_copy, zptr, value); + if (EXPECTED(zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(zptr); + ZVAL_COPY_VALUE(zptr, &z_copy); + } else { + zval_ptr_dtor(&z_copy); + } +} + static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type EXECUTE_DATA_DC) { zend_long offset; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 884a8552e4..bfbd371b38 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -836,33 +836,29 @@ ZEND_VM_C_LABEL(assign_op_object): } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - if (OP2_TYPE == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; - - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (OP2_TYPE == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -889,7 +885,6 @@ ZEND_VM_HELPER(zend_binary_assign_op_static_prop_helper, CONST|TMP|VAR|CV, UNUSE zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -902,26 +897,23 @@ ZEND_VM_HELPER(zend_binary_assign_op_static_prop_helper, CONST|TMP|VAR|CV, UNUSE value = GET_OP_DATA_ZVAL_PTR(BP_VAR_R); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -966,28 +958,17 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (OP2_TYPE != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - FREE_OP2(); - FREE_OP(free_op_data1); - FREE_OP1_VAR_PTR(); - HANDLE_EXCEPTION(); + do { + if (OP2_TYPE != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -1059,25 +1040,17 @@ ZEND_VM_HELPER(zend_binary_assign_op_simple_helper, VAR|CV, CONST|TMPVAR|CV, bin ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 22b96eb822..7ff5be8c29 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4441,7 +4441,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -4454,26 +4453,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -7118,7 +7114,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -7131,26 +7126,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -9018,7 +9010,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -9031,26 +9022,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -20345,7 +20333,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -20358,26 +20345,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -20904,7 +20888,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -20917,26 +20900,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -21596,7 +21576,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -21609,26 +21588,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -24258,33 +24234,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CONST == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -24311,7 +24283,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -24324,26 +24295,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -24388,28 +24356,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); + do { + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -24480,25 +24437,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -27193,33 +27142,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -27246,7 +27191,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -27259,26 +27203,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -27323,28 +27264,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); + do { + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -27416,25 +27346,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -30303,7 +30225,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -30316,26 +30237,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -30380,28 +30298,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -31874,33 +31781,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CV == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -31952,28 +31855,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; - HANDLE_EXCEPTION(); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -32044,25 +31936,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -34882,33 +34766,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CONST == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -36929,33 +36809,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -39627,33 +39503,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CV == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -43968,33 +43840,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CONST == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -44021,7 +43889,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -44034,26 +43901,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -44098,28 +43962,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); + do { + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -44190,25 +44043,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -48658,33 +48503,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -48711,7 +48552,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -48724,26 +48564,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -48788,28 +48625,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - zval_ptr_dtor_nogc(free_op2); - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); + do { + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -48881,25 +48707,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -52761,7 +52579,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h zval *prop, *value; zend_property_info *prop_info; zend_reference *ref; - zend_bool is_typed_ref = 0; SAVE_OPLINE(); @@ -52774,26 +52591,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_static_prop_h value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data); - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - prop = Z_REFVAL_P(prop); - } - - if (UNEXPECTED(prop_info->type || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + prop = Z_REFVAL_P(prop); + } - binary_op(&z_copy, prop, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(prop); - ZVAL_COPY_VALUE(prop, &z_copy); + if (UNEXPECTED(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value, binary_op); } else { - zval_ptr_dtor(&z_copy); + binary_op(prop, prop, value); } - } else { - binary_op(prop, prop, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), prop); @@ -52838,28 +52652,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -55635,33 +55438,29 @@ assign_op_object: } else { zval *orig_zptr = zptr; zend_reference *ref; - zend_bool is_typed_ref = 0; - - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - is_typed_ref = ZEND_REF_HAS_TYPE_SOURCES(ref); - zptr = Z_REFVAL_P(zptr); - } - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } - if (UNEXPECTED(prop_info || is_typed_ref)) { - /* special case for typed properties */ - zval z_copy; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + zptr = Z_REFVAL_P(zptr); + } - binary_op(&z_copy, zptr, value); - if (EXPECTED(is_typed_ref ? zend_verify_ref_assignable_zval(ref, &z_copy, EX_USES_STRICT_TYPES()) : zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(zptr); - ZVAL_COPY_VALUE(zptr, &z_copy); + if (IS_CV == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); } else { - zval_ptr_dtor(&z_copy); + prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); } - } else { - binary_op(zptr, zptr, value); - } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), zptr); @@ -55713,28 +55512,17 @@ assign_dim_op_new_array: value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - if (EXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); - - FREE_OP(free_op_data1); - - HANDLE_EXCEPTION(); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; } - } else { - binary_op(var_ptr, var_ptr, value); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); @@ -55805,25 +55593,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_simple_helper ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zend_reference *ref = NULL; - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - } - - if (UNEXPECTED(ref && ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zval tmp; - binary_op(&tmp, var_ptr, value); - - if (UNEXPECTED(zend_verify_ref_assignable_zval(ref, &tmp, EX_USES_STRICT_TYPES()))) { - zval_ptr_dtor(var_ptr); - ZVAL_COPY_VALUE(var_ptr, &tmp); - } else { - zval_ptr_dtor(&tmp); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value, binary_op); + break; + } + var_ptr = Z_REFVAL_P(var_ptr); } - } else { binary_op(var_ptr, var_ptr, value); - } + } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);