@@ -2515,6 +2515,67 @@ ZEND_VM_C_LABEL(exit_assign_obj):
25152515	ZEND_VM_NEXT_OPCODE_EX (1 , 2 );
25162516}
25172517
2518+ ZEND_VM_TYPE_SPEC_HANDLER (ZEND_ASSIGN_OBJ , (op -> extended_value  &  1 ) !=  0 , ZEND_ASSIGN_OBJ_CORRECTLY_TYPED , UNUSED |VAR |THIS |CV , CONST , CACHE_SLOT , SPEC (OP_DATA = CONST |TMP |VAR |CV ))
2519+ {
2520+ 	USE_OPLINE 
2521+ 	zval  * object , * value ;
2522+ 	zend_object  * zobj ;
2523+ 	zend_string  * name ;
2524+ 	zend_refcounted  * garbage  =  NULL ;
2525+ 
2526+ 	SAVE_OPLINE ();
2527+ 	object  =  GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF (BP_VAR_W );
2528+ 	value  =  GET_OP_DATA_ZVAL_PTR (BP_VAR_R );
2529+ 
2530+ 	// TODO: get rid of this? 
2531+ 	if  (OP1_TYPE  !=  IS_UNUSED  &&  UNEXPECTED (Z_TYPE_P (object ) !=  IS_OBJECT )) {
2532+ 		if  (Z_ISREF_P (object ) &&  Z_TYPE_P (Z_REFVAL_P (object )) ==  IS_OBJECT ) {
2533+ 			object  =  Z_REFVAL_P (object );
2534+ 			ZEND_VM_C_GOTO (assign_object );
2535+ 		}
2536+ 		zend_throw_non_object_error (object , GET_OP2_ZVAL_PTR (BP_VAR_R ) OPLINE_CC  EXECUTE_DATA_CC );
2537+ 		value  =  & EG (uninitialized_zval );
2538+ 		ZEND_VM_C_GOTO (free_and_exit_assign_obj );
2539+ 	}
2540+ 
2541+ ZEND_VM_C_LABEL (assign_object ):
2542+ 	zobj  =  Z_OBJ_P (object );
2543+ 	if  (EXPECTED (zobj -> ce  ==  CACHED_PTR (opline -> extended_value  &  ~1 ))) {
2544+ 		void  * * cache_slot  =  CACHE_ADDR (opline -> extended_value  &  ~1 );
2545+ 		uintptr_t  prop_offset  =  (uintptr_t )CACHED_PTR_EX (cache_slot  +  1 );
2546+ 		zval  * property_val  =  OBJ_PROP (zobj , prop_offset );
2547+ 
2548+ 		ZEND_ASSERT (IS_VALID_PROPERTY_OFFSET (prop_offset ));
2549+ 
2550+ 		if  (Z_TYPE_P (property_val ) !=  IS_UNDEF ) {
2551+ 			value  =  zend_assign_to_variable_ex (property_val , value , OP_DATA_TYPE , EX_USES_STRICT_TYPES (), & garbage );
2552+ 			if  (UNEXPECTED (RETURN_VALUE_USED (opline ))) {
2553+ 				ZVAL_COPY (EX_VAR (opline -> result .var ), value );
2554+ 			}
2555+ 			ZEND_VM_C_GOTO (exit_assign_obj );
2556+ 		}
2557+ 	}
2558+ 	name  =  Z_STR_P (GET_OP2_ZVAL_PTR (BP_VAR_R ));
2559+ 
2560+ 	ZEND_ASSERT (!Z_ISREF_P (value ));
2561+ 
2562+ 	value  =  zobj -> handlers -> write_property (zobj , name , value , (OP2_TYPE  ==  IS_CONST ) ? CACHE_ADDR (opline -> extended_value  &  ~1 ) : NULL );
2563+ 
2564+ ZEND_VM_C_LABEL (free_and_exit_assign_obj ):
2565+ 	if  (UNEXPECTED (RETURN_VALUE_USED (opline )) &&  value ) {
2566+ 		ZVAL_COPY_DEREF (EX_VAR (opline -> result .var ), value );
2567+ 	}
2568+ 	FREE_OP_DATA ();
2569+ ZEND_VM_C_LABEL (exit_assign_obj ):
2570+ 	if  (garbage ) {
2571+ 		GC_DTOR_NO_REF (garbage );
2572+ 	}
2573+ 	FREE_OP2 ();
2574+ 	FREE_OP1 ();
2575+ 	/* assign_obj has two opcodes! */ 
2576+ 	ZEND_VM_NEXT_OPCODE_EX (1 , 2 );
2577+ }
2578+ 
25182579/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ 
25192580ZEND_VM_HANDLER (25 , ZEND_ASSIGN_STATIC_PROP , ANY , ANY , CACHE_SLOT , SPEC (OP_DATA = CONST |TMP |VAR |CV ))
25202581{
0 commit comments