20
20
#include "zend.h"
21
21
#include "zend_API.h"
22
22
#include "zend_ini.h"
23
+ #include "zend_variables.h"
23
24
#include "zend_vm.h"
24
25
#include "zend_exceptions.h"
25
26
#include "zend_builtin_functions.h"
@@ -624,7 +625,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
624
625
RETURN_THROWS ();
625
626
}
626
627
627
- RETURN_COPY_VALUE (& transfer -> value );
628
+ if (return_value != NULL ) {
629
+ RETURN_COPY_VALUE (& transfer -> value );
630
+ } else {
631
+ zval_ptr_dtor (& transfer -> value );
632
+ }
628
633
}
629
634
630
635
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to (
@@ -652,7 +657,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
652
657
return transfer ;
653
658
}
654
659
655
- static zend_always_inline zend_fiber_transfer zend_fiber_resume (zend_fiber * fiber , zval * value , bool exception )
660
+ static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal (zend_fiber * fiber , zval * value , bool exception )
656
661
{
657
662
zend_fiber * previous = EG (active_fiber );
658
663
@@ -670,8 +675,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
670
675
return transfer ;
671
676
}
672
677
673
- static zend_always_inline zend_fiber_transfer zend_fiber_suspend (zend_fiber * fiber , zval * value )
678
+ static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal (zend_fiber * fiber , zval * value )
674
679
{
680
+ ZEND_ASSERT (!(fiber -> flags & ZEND_FIBER_FLAG_DESTROYED ));
681
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_RUNNING || fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED );
675
682
ZEND_ASSERT (fiber -> caller != NULL );
676
683
677
684
zend_fiber_context * caller = fiber -> caller ;
@@ -682,6 +689,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
682
689
return zend_fiber_switch_to (caller , value , false);
683
690
}
684
691
692
+ ZEND_API zend_result zend_fiber_start (zend_fiber * fiber , zval * return_value )
693
+ {
694
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_INIT );
695
+
696
+ if (zend_fiber_init_context (& fiber -> context , zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size )) == FAILURE ) {
697
+ return FAILURE ;
698
+ }
699
+
700
+ fiber -> previous = & fiber -> context ;
701
+
702
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
703
+
704
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
705
+
706
+ return SUCCESS ;
707
+ }
708
+
709
+ ZEND_API void zend_fiber_resume (zend_fiber * fiber , zval * value , zval * return_value )
710
+ {
711
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
712
+
713
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
714
+
715
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , /* exception */ false);
716
+
717
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
718
+ }
719
+
720
+ ZEND_API void zend_fiber_resume_exception (zend_fiber * fiber , zval * exception , zval * return_value )
721
+ {
722
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
723
+
724
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
725
+
726
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , /* exception */ true);
727
+
728
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
729
+ }
730
+
731
+ ZEND_API void zend_fiber_suspend (zend_fiber * fiber , zval * value , zval * return_value )
732
+ {
733
+ fiber -> stack_bottom -> prev_execute_data = NULL ;
734
+
735
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
736
+
737
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
738
+ }
739
+
685
740
static zend_object * zend_fiber_object_create (zend_class_entry * ce )
686
741
{
687
742
zend_fiber * fiber = emalloc (sizeof (zend_fiber ));
@@ -707,7 +762,7 @@ static void zend_fiber_object_destroy(zend_object *object)
707
762
708
763
fiber -> flags |= ZEND_FIBER_FLAG_DESTROYED ;
709
764
710
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , & graceful_exit , true);
765
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , & graceful_exit , true);
711
766
712
767
zval_ptr_dtor (& graceful_exit );
713
768
@@ -823,7 +878,7 @@ ZEND_METHOD(Fiber, start)
823
878
824
879
fiber -> previous = & fiber -> context ;
825
880
826
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , NULL , false);
881
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
827
882
828
883
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
829
884
}
@@ -858,7 +913,7 @@ ZEND_METHOD(Fiber, suspend)
858
913
859
914
fiber -> stack_bottom -> prev_execute_data = NULL ;
860
915
861
- zend_fiber_transfer transfer = zend_fiber_suspend (fiber , value );
916
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
862
917
863
918
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
864
919
}
@@ -887,7 +942,7 @@ ZEND_METHOD(Fiber, resume)
887
942
888
943
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
889
944
890
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , value , false);
945
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , false);
891
946
892
947
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
893
948
}
@@ -915,7 +970,7 @@ ZEND_METHOD(Fiber, throw)
915
970
916
971
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
917
972
918
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , exception , true);
973
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , true);
919
974
920
975
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
921
976
}
0 commit comments