@@ -2967,7 +2967,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29672967 SAVE_OPLINE ();
29682968#endif
29692969
2970- if (EXPECTED ((call_info & (ZEND_CALL_CODE |ZEND_CALL_TOP |ZEND_CALL_HAS_SYMBOL_TABLE |ZEND_CALL_FREE_EXTRA_ARGS |ZEND_CALL_ALLOCATED |ZEND_CALL_HAS_EXTRA_NAMED_PARAMS | ZEND_CALL_DEREF_RESULT )) == 0 )) {
2970+ if (EXPECTED ((call_info & (ZEND_CALL_CODE |ZEND_CALL_TOP |ZEND_CALL_HAS_SYMBOL_TABLE |ZEND_CALL_FREE_EXTRA_ARGS |ZEND_CALL_ALLOCATED |ZEND_CALL_HAS_EXTRA_NAMED_PARAMS )) == 0 )) {
29712971 EG (current_execute_data ) = EX (prev_execute_data );
29722972 i_free_compiled_variables (execute_data );
29732973
@@ -2990,19 +2990,6 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY)
29902990 LOAD_NEXT_OPLINE ();
29912991 ZEND_VM_LEAVE ();
29922992 } else if (EXPECTED ((call_info & (ZEND_CALL_CODE |ZEND_CALL_TOP )) == 0 )) {
2993- if (UNEXPECTED (call_info & ZEND_CALL_DEREF_RESULT )
2994- && EX (return_value )
2995- && Z_TYPE_P (EX (return_value )) == IS_REFERENCE ) {
2996- zval * ret = EX (return_value );
2997- zend_reference * ref = Z_REF_P (ret );
2998- ZVAL_COPY_VALUE (ret , & ref -> val );
2999- if (GC_DELREF (ref ) == 0 ) {
3000- efree_size (ref , sizeof (zend_reference ));
3001- } else {
3002- Z_TRY_ADDREF_P (ret );
3003- }
3004- }
3005-
30062993 EG (current_execute_data ) = EX (prev_execute_data );
30072994 i_free_compiled_variables (execute_data );
30082995
@@ -4202,7 +4189,7 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
42024189 ZEND_VM_ENTER_EX ();
42034190}
42044191
4205- ZEND_VM_HOT_HANDLER (131 , ZEND_DO_FCALL_BY_NAME , ANY , ANY , NUM , SPEC (RETVAL ,OBSERVER ))
4192+ ZEND_VM_HOT_HANDLER (131 , ZEND_DO_FCALL_BY_NAME , ANY , ANY , SPEC (RETVAL ,OBSERVER ))
42064193{
42074194 USE_OPLINE
42084195 zend_execute_data * call = EX (call );
@@ -4238,14 +4225,6 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, NUM, SPEC(RETVAL,OBSER
42384225 ret = EX_VAR (opline -> result .var );
42394226 }
42404227
4241- /* Optimization: ZEND_DO_FCALL_DEREF is the only used flag. */
4242- if (RETURN_VALUE_USED (opline )
4243- && EXPECTED (opline -> extended_value )
4244- && UNEXPECTED (call -> func -> common .fn_flags & ZEND_ACC_RETURN_REFERENCE )) {
4245- ZEND_ASSERT (opline -> extended_value == ZEND_DO_FCALL_DEREF );
4246- ZEND_ADD_CALL_FLAG (call , ZEND_CALL_DEREF_RESULT );
4247- }
4248-
42494228 call -> prev_execute_data = execute_data ;
42504229 execute_data = call ;
42514230 i_init_func_execute_data (& fbc -> op_array , ret , 0 EXECUTE_DATA_CC );
@@ -4284,20 +4263,9 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, NUM, SPEC(RETVAL,OBSER
42844263 ? Z_ISREF_P (ret ) : !Z_ISREF_P (ret ));
42854264 zend_verify_internal_func_info (call -> func , ret );
42864265 }
4266+ ZEND_ASSERT (opline -> result_type != IS_TMP_VAR || !Z_ISREF_P (ret ));
42874267#endif
42884268
4289- /* Optimization: ZEND_DO_FCALL_DEREF is the only used flag. */
4290- if (RETURN_VALUE_USED (opline ) && EXPECTED (opline -> extended_value )) {
4291- ZEND_ASSERT (opline -> extended_value == ZEND_DO_FCALL_DEREF );
4292- if (UNEXPECTED (Z_ISREF_P (ret ))) {
4293- zend_reference * ref = Z_REF_P (ret );
4294- ZVAL_COPY_VALUE (ret , & ref -> val );
4295- if (GC_DELREF (ref ) == 0 ) {
4296- efree_size (ref , sizeof (zend_reference ));
4297- }
4298- }
4299- }
4300-
43014269 ZEND_OBSERVER_FCALL_END (call , EG (exception ) ? NULL : ret );
43024270 ZEND_VM_FCALL_INTERRUPT_CHECK (call );
43034271
@@ -4334,7 +4302,7 @@ ZEND_VM_C_LABEL(fcall_by_name_end):
43344302 ZEND_VM_CONTINUE ();
43354303}
43364304
4337- ZEND_VM_HOT_HANDLER (60 , ZEND_DO_FCALL , ANY , ANY , NUM , SPEC (RETVAL ,OBSERVER ))
4305+ ZEND_VM_HOT_HANDLER (60 , ZEND_DO_FCALL , ANY , ANY , SPEC (RETVAL ,OBSERVER ))
43384306{
43394307 USE_OPLINE
43404308 zend_execute_data * call = EX (call );
@@ -4372,14 +4340,6 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, NUM, SPEC(RETVAL,OBSERVER))
43724340 if (RETURN_VALUE_USED (opline )) {
43734341 ret = EX_VAR (opline -> result .var );
43744342 }
4375-
4376- /* Optimization: ZEND_DO_FCALL_DEREF is the only used flag. */
4377- if (RETURN_VALUE_USED (opline )
4378- && EXPECTED (opline -> extended_value )
4379- && UNEXPECTED (call -> func -> common .fn_flags & ZEND_ACC_RETURN_REFERENCE )) {
4380- ZEND_ASSERT (opline -> extended_value == ZEND_DO_FCALL_DEREF );
4381- ZEND_ADD_CALL_FLAG (call , ZEND_CALL_DEREF_RESULT );
4382- }
43834343
43844344 call -> prev_execute_data = execute_data ;
43854345 execute_data = call ;
@@ -4433,19 +4393,8 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, NUM, SPEC(RETVAL,OBSERVER))
44334393 ? Z_ISREF_P (ret ) : !Z_ISREF_P (ret ));
44344394 zend_verify_internal_func_info (call -> func , ret );
44354395 }
4396+ ZEND_ASSERT (opline -> result_type != IS_TMP_VAR || !Z_ISREF_P (ret ));
44364397#endif
4437-
4438- /* Optimization: ZEND_DO_FCALL_DEREF is the only used flag. */
4439- if (RETURN_VALUE_USED (opline ) && EXPECTED (opline -> extended_value )) {
4440- ZEND_ASSERT (opline -> extended_value == ZEND_DO_FCALL_DEREF );
4441- if (UNEXPECTED (Z_ISREF_P (ret ))) {
4442- zend_reference * ref = Z_REF_P (ret );
4443- ZVAL_COPY_VALUE (ret , & ref -> val );
4444- if (GC_DELREF (ref ) == 0 ) {
4445- efree_size (ref , sizeof (zend_reference ));
4446- }
4447- }
4448- }
44494398
44504399 ZEND_OBSERVER_FCALL_END (call , EG (exception ) ? NULL : ret );
44514400 ZEND_VM_FCALL_INTERRUPT_CHECK (call );
@@ -4696,6 +4645,10 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
46964645
46974646 ZEND_OBSERVER_FCALL_END (execute_data , return_value );
46984647 ZEND_OBSERVER_FREE_RETVAL ();
4648+
4649+ // FIXME: Don't create the ref in the first place?
4650+ zend_return_unwrap_ref (execute_data , return_value );
4651+
46994652 ZEND_VM_DISPATCH_TO_HELPER (zend_leave_helper );
47004653}
47014654
0 commit comments