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"
@@ -630,7 +631,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
630
631
RETURN_THROWS ();
631
632
}
632
633
633
- RETURN_COPY_VALUE (& transfer -> value );
634
+ if (return_value != NULL ) {
635
+ RETURN_COPY_VALUE (& transfer -> value );
636
+ } else {
637
+ zval_ptr_dtor (& transfer -> value );
638
+ }
634
639
}
635
640
636
641
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to (
@@ -658,7 +663,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
658
663
return transfer ;
659
664
}
660
665
661
- static zend_always_inline zend_fiber_transfer zend_fiber_resume (zend_fiber * fiber , zval * value , bool exception )
666
+ static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal (zend_fiber * fiber , zval * value , bool exception )
662
667
{
663
668
zend_fiber * previous = EG (active_fiber );
664
669
@@ -676,8 +681,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
676
681
return transfer ;
677
682
}
678
683
679
- static zend_always_inline zend_fiber_transfer zend_fiber_suspend (zend_fiber * fiber , zval * value )
684
+ static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal (zend_fiber * fiber , zval * value )
680
685
{
686
+ ZEND_ASSERT (!(fiber -> flags & ZEND_FIBER_FLAG_DESTROYED ));
687
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_RUNNING || fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED );
681
688
ZEND_ASSERT (fiber -> caller != NULL );
682
689
683
690
zend_fiber_context * caller = fiber -> caller ;
@@ -688,6 +695,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
688
695
return zend_fiber_switch_to (caller , value , false);
689
696
}
690
697
698
+ ZEND_API zend_result zend_fiber_start (zend_fiber * fiber , zval * return_value )
699
+ {
700
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_INIT );
701
+
702
+ if (zend_fiber_init_context (& fiber -> context , zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size )) == FAILURE ) {
703
+ return FAILURE ;
704
+ }
705
+
706
+ fiber -> previous = & fiber -> context ;
707
+
708
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
709
+
710
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
711
+
712
+ return SUCCESS ;
713
+ }
714
+
715
+ ZEND_API void zend_fiber_resume (zend_fiber * fiber , zval * value , zval * return_value )
716
+ {
717
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
718
+
719
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
720
+
721
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , /* exception */ false);
722
+
723
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
724
+ }
725
+
726
+ ZEND_API void zend_fiber_resume_exception (zend_fiber * fiber , zval * exception , zval * return_value )
727
+ {
728
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
729
+
730
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
731
+
732
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , /* exception */ true);
733
+
734
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
735
+ }
736
+
737
+ ZEND_API void zend_fiber_suspend (zend_fiber * fiber , zval * value , zval * return_value )
738
+ {
739
+ fiber -> stack_bottom -> prev_execute_data = NULL ;
740
+
741
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
742
+
743
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
744
+ }
745
+
691
746
static zend_object * zend_fiber_object_create (zend_class_entry * ce )
692
747
{
693
748
zend_fiber * fiber = emalloc (sizeof (zend_fiber ));
@@ -713,7 +768,7 @@ static void zend_fiber_object_destroy(zend_object *object)
713
768
714
769
fiber -> flags |= ZEND_FIBER_FLAG_DESTROYED ;
715
770
716
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , & graceful_exit , true);
771
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , & graceful_exit , true);
717
772
718
773
zval_ptr_dtor (& graceful_exit );
719
774
@@ -829,7 +884,7 @@ ZEND_METHOD(Fiber, start)
829
884
830
885
fiber -> previous = & fiber -> context ;
831
886
832
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , NULL , false);
887
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
833
888
834
889
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
835
890
}
@@ -864,7 +919,7 @@ ZEND_METHOD(Fiber, suspend)
864
919
865
920
fiber -> stack_bottom -> prev_execute_data = NULL ;
866
921
867
- zend_fiber_transfer transfer = zend_fiber_suspend (fiber , value );
922
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
868
923
869
924
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
870
925
}
@@ -893,7 +948,7 @@ ZEND_METHOD(Fiber, resume)
893
948
894
949
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
895
950
896
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , value , false);
951
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , false);
897
952
898
953
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
899
954
}
@@ -921,7 +976,7 @@ ZEND_METHOD(Fiber, throw)
921
976
922
977
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
923
978
924
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , exception , true);
979
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , true);
925
980
926
981
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
927
982
}
0 commit comments