@@ -2381,6 +2381,7 @@ ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_
23812381 zval * object , * value , tmp ;
23822382 zend_object * zobj ;
23832383 zend_string * name , * tmp_name ;
2384+ zend_refcounted * garbage = NULL ;
23842385
23852386 SAVE_OPLINE ();
23862387 object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF (BP_VAR_W );
@@ -2410,11 +2411,11 @@ ZEND_VM_C_LABEL(assign_object):
24102411 zend_property_info * prop_info = (zend_property_info * ) CACHED_PTR_EX (cache_slot + 2 );
24112412
24122413 if (UNEXPECTED (prop_info != NULL )) {
2413- value = zend_assign_to_typed_prop (prop_info , property_val , value EXECUTE_DATA_CC );
2414+ value = zend_assign_to_typed_prop (prop_info , property_val , value , & garbage EXECUTE_DATA_CC );
24142415 ZEND_VM_C_GOTO (free_and_exit_assign_obj );
24152416 } else {
24162417ZEND_VM_C_LABEL (fast_assign_obj ):
2417- value = zend_assign_to_variable (property_val , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES ());
2418+ value = zend_assign_to_variable_ex (property_val , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES (), & garbage );
24182419 if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
24192420 ZVAL_COPY (EX_VAR (opline -> result .var ), value );
24202421 }
@@ -2498,6 +2499,13 @@ ZEND_VM_C_LABEL(free_and_exit_assign_obj):
24982499 }
24992500 FREE_OP_DATA ();
25002501ZEND_VM_C_LABEL (exit_assign_obj ):
2502+ if (garbage ) {
2503+ if (GC_DELREF (garbage ) == 0 ) {
2504+ rc_dtor_func (garbage );
2505+ } else {
2506+ gc_check_possible_root_no_ref (garbage );
2507+ }
2508+ }
25012509 FREE_OP2 ();
25022510 FREE_OP1 ();
25032511 /* assign_obj has two opcodes! */
@@ -2510,6 +2518,7 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=
25102518 USE_OPLINE
25112519 zval * prop , * value ;
25122520 zend_property_info * prop_info ;
2521+ zend_refcounted * garbage = NULL ;
25132522
25142523 SAVE_OPLINE ();
25152524
@@ -2522,16 +2531,24 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=
25222531 value = GET_OP_DATA_ZVAL_PTR (BP_VAR_R );
25232532
25242533 if (UNEXPECTED (ZEND_TYPE_IS_SET (prop_info -> type ))) {
2525- value = zend_assign_to_typed_prop (prop_info , prop , value EXECUTE_DATA_CC );
2534+ value = zend_assign_to_typed_prop (prop_info , prop , value , & garbage EXECUTE_DATA_CC );
25262535 FREE_OP_DATA ();
25272536 } else {
2528- value = zend_assign_to_variable (prop , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES ());
2537+ value = zend_assign_to_variable_ex (prop , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES (), & garbage );
25292538 }
25302539
25312540 if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
25322541 ZVAL_COPY (EX_VAR (opline -> result .var ), value );
25332542 }
25342543
2544+ if (garbage ) {
2545+ if (GC_DELREF (garbage ) == 0 ) {
2546+ rc_dtor_func (garbage );
2547+ } else {
2548+ gc_check_possible_root_no_ref (garbage );
2549+ }
2550+ }
2551+
25352552 /* assign_static_prop has two opcodes! */
25362553 ZEND_VM_NEXT_OPCODE_EX (1 , 2 );
25372554}
@@ -2543,6 +2560,7 @@ ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(O
25432560 zval * value ;
25442561 zval * variable_ptr ;
25452562 zval * dim ;
2563+ zend_refcounted * garbage = NULL ;
25462564
25472565 SAVE_OPLINE ();
25482566 orig_object_ptr = object_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF (BP_VAR_W );
@@ -2598,11 +2616,18 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
25982616 ZEND_VM_C_GOTO (assign_dim_error );
25992617 }
26002618 value = GET_OP_DATA_ZVAL_PTR (BP_VAR_R );
2601- value = zend_assign_to_variable (variable_ptr , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES ());
2619+ value = zend_assign_to_variable_ex (variable_ptr , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES (), & garbage );
26022620 }
26032621 if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
26042622 ZVAL_COPY (EX_VAR (opline -> result .var ), value );
26052623 }
2624+ if (garbage ) {
2625+ if (GC_DELREF (garbage ) == 0 ) {
2626+ rc_dtor_func (garbage );
2627+ } else {
2628+ gc_check_possible_root_no_ref (garbage );
2629+ }
2630+ }
26062631 } else {
26072632 if (EXPECTED (Z_ISREF_P (object_ptr ))) {
26082633 object_ptr = Z_REFVAL_P (object_ptr );
@@ -2695,9 +2720,22 @@ ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
26952720 value = GET_OP2_ZVAL_PTR (BP_VAR_R );
26962721 variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF (BP_VAR_W );
26972722
2698- value = zend_assign_to_variable (variable_ptr , value , OP2_TYPE , EX_USES_STRICT_TYPES ());
2699- if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
2700- ZVAL_COPY (EX_VAR (opline -> result .var ), value );
2723+ if (!ZEND_VM_SPEC || UNEXPECTED (RETURN_VALUE_USED (opline ))) {
2724+ zend_refcounted * garbage = NULL ;
2725+
2726+ value = zend_assign_to_variable_ex (variable_ptr , value , OP2_TYPE , EX_USES_STRICT_TYPES (), & garbage );
2727+ if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
2728+ ZVAL_COPY (EX_VAR (opline -> result .var ), value );
2729+ }
2730+ if (garbage ) {
2731+ if (GC_DELREF (garbage ) == 0 ) {
2732+ rc_dtor_func (garbage );
2733+ } else {
2734+ gc_check_possible_root_no_ref (garbage );
2735+ }
2736+ }
2737+ } else {
2738+ value = zend_assign_to_variable (variable_ptr , value , OP2_TYPE , EX_USES_STRICT_TYPES ());
27012739 }
27022740 FREE_OP1 ();
27032741 /* zend_assign_to_variable() always takes care of op2, never free it! */
@@ -2710,6 +2748,7 @@ ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
27102748 USE_OPLINE
27112749 zval * variable_ptr ;
27122750 zval * value_ptr ;
2751+ zend_refcounted * garbage = NULL ;
27132752
27142753 SAVE_OPLINE ();
27152754 value_ptr = GET_OP2_ZVAL_PTR_PTR (BP_VAR_W );
@@ -2725,15 +2764,23 @@ ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
27252764 UNEXPECTED (!Z_ISREF_P (value_ptr ))) {
27262765
27272766 variable_ptr = zend_wrong_assign_to_variable_reference (
2728- variable_ptr , value_ptr OPLINE_CC EXECUTE_DATA_CC );
2767+ variable_ptr , value_ptr , & garbage OPLINE_CC EXECUTE_DATA_CC );
27292768 } else {
2730- zend_assign_to_variable_reference (variable_ptr , value_ptr );
2769+ zend_assign_to_variable_reference (variable_ptr , value_ptr , & garbage );
27312770 }
27322771
27332772 if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
27342773 ZVAL_COPY (EX_VAR (opline -> result .var ), variable_ptr );
27352774 }
27362775
2776+ if (garbage ) {
2777+ if (GC_DELREF (garbage ) == 0 ) {
2778+ rc_dtor_func (garbage );
2779+ } else {
2780+ gc_check_possible_root (garbage );
2781+ }
2782+ }
2783+
27372784 FREE_OP2 ();
27382785 FREE_OP1 ();
27392786 ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION ();
@@ -2781,6 +2828,7 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
27812828 USE_OPLINE
27822829 zval * prop , * value_ptr ;
27832830 zend_property_info * prop_info ;
2831+ zend_refcounted * garbage = NULL ;
27842832
27852833 SAVE_OPLINE ();
27862834
@@ -2793,19 +2841,27 @@ ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
27932841 value_ptr = GET_OP_DATA_ZVAL_PTR_PTR (BP_VAR_W );
27942842
27952843 if (OP_DATA_TYPE == IS_VAR && (opline -> extended_value & ZEND_RETURNS_FUNCTION ) && UNEXPECTED (!Z_ISREF_P (value_ptr ))) {
2796- if (UNEXPECTED (!zend_wrong_assign_to_variable_reference (prop , value_ptr OPLINE_CC EXECUTE_DATA_CC ))) {
2844+ if (UNEXPECTED (!zend_wrong_assign_to_variable_reference (prop , value_ptr , & garbage OPLINE_CC EXECUTE_DATA_CC ))) {
27972845 prop = & EG (uninitialized_zval );
27982846 }
27992847 } else if (UNEXPECTED (ZEND_TYPE_IS_SET (prop_info -> type ))) {
2800- prop = zend_assign_to_typed_property_reference (prop_info , prop , value_ptr EXECUTE_DATA_CC );
2848+ prop = zend_assign_to_typed_property_reference (prop_info , prop , value_ptr , & garbage EXECUTE_DATA_CC );
28012849 } else {
2802- zend_assign_to_variable_reference (prop , value_ptr );
2850+ zend_assign_to_variable_reference (prop , value_ptr , & garbage );
28032851 }
28042852
28052853 if (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
28062854 ZVAL_COPY (EX_VAR (opline -> result .var ), prop );
28072855 }
28082856
2857+ if (garbage ) {
2858+ if (GC_DELREF (garbage ) == 0 ) {
2859+ rc_dtor_func (garbage );
2860+ } else {
2861+ gc_check_possible_root (garbage );
2862+ }
2863+ }
2864+
28092865 FREE_OP_DATA ();
28102866 ZEND_VM_NEXT_OPCODE_EX (1 , 2 );
28112867}
0 commit comments