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"
@@ -637,7 +638,11 @@ static zend_always_inline void zend_fiber_delegate_transfer_result(
637
638
RETURN_THROWS ();
638
639
}
639
640
640
- RETURN_COPY_VALUE (& transfer -> value );
641
+ if (return_value != NULL ) {
642
+ RETURN_COPY_VALUE (& transfer -> value );
643
+ } else {
644
+ zval_ptr_dtor (& transfer -> value );
645
+ }
641
646
}
642
647
643
648
static zend_always_inline zend_fiber_transfer zend_fiber_switch_to (
@@ -665,7 +670,7 @@ static zend_always_inline zend_fiber_transfer zend_fiber_switch_to(
665
670
return transfer ;
666
671
}
667
672
668
- static zend_always_inline zend_fiber_transfer zend_fiber_resume (zend_fiber * fiber , zval * value , bool exception )
673
+ static zend_always_inline zend_fiber_transfer zend_fiber_resume_internal (zend_fiber * fiber , zval * value , bool exception )
669
674
{
670
675
zend_fiber * previous = EG (active_fiber );
671
676
@@ -683,8 +688,10 @@ static zend_always_inline zend_fiber_transfer zend_fiber_resume(zend_fiber *fibe
683
688
return transfer ;
684
689
}
685
690
686
- static zend_always_inline zend_fiber_transfer zend_fiber_suspend (zend_fiber * fiber , zval * value )
691
+ static zend_always_inline zend_fiber_transfer zend_fiber_suspend_internal (zend_fiber * fiber , zval * value )
687
692
{
693
+ ZEND_ASSERT (!(fiber -> flags & ZEND_FIBER_FLAG_DESTROYED ));
694
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_RUNNING || fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED );
688
695
ZEND_ASSERT (fiber -> caller != NULL );
689
696
690
697
zend_fiber_context * caller = fiber -> caller ;
@@ -695,6 +702,54 @@ static zend_always_inline zend_fiber_transfer zend_fiber_suspend(zend_fiber *fib
695
702
return zend_fiber_switch_to (caller , value , false);
696
703
}
697
704
705
+ ZEND_API zend_result zend_fiber_start (zend_fiber * fiber , zval * return_value )
706
+ {
707
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_INIT );
708
+
709
+ if (zend_fiber_init_context (& fiber -> context , zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size )) == FAILURE ) {
710
+ return FAILURE ;
711
+ }
712
+
713
+ fiber -> previous = & fiber -> context ;
714
+
715
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
716
+
717
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
718
+
719
+ return SUCCESS ;
720
+ }
721
+
722
+ ZEND_API void zend_fiber_resume (zend_fiber * fiber , zval * value , zval * return_value )
723
+ {
724
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
725
+
726
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
727
+
728
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , /* exception */ false);
729
+
730
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
731
+ }
732
+
733
+ ZEND_API void zend_fiber_resume_exception (zend_fiber * fiber , zval * exception , zval * return_value )
734
+ {
735
+ ZEND_ASSERT (fiber -> context .status == ZEND_FIBER_STATUS_SUSPENDED && fiber -> caller == NULL );
736
+
737
+ fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
738
+
739
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , /* exception */ true);
740
+
741
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
742
+ }
743
+
744
+ ZEND_API void zend_fiber_suspend (zend_fiber * fiber , zval * value , zval * return_value )
745
+ {
746
+ fiber -> stack_bottom -> prev_execute_data = NULL ;
747
+
748
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
749
+
750
+ zend_fiber_delegate_transfer_result (& transfer , EG (current_execute_data ), return_value );
751
+ }
752
+
698
753
static zend_object * zend_fiber_object_create (zend_class_entry * ce )
699
754
{
700
755
zend_fiber * fiber = emalloc (sizeof (zend_fiber ));
@@ -720,7 +775,7 @@ static void zend_fiber_object_destroy(zend_object *object)
720
775
721
776
fiber -> flags |= ZEND_FIBER_FLAG_DESTROYED ;
722
777
723
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , & graceful_exit , true);
778
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , & graceful_exit , true);
724
779
725
780
zval_ptr_dtor (& graceful_exit );
726
781
@@ -836,7 +891,7 @@ ZEND_METHOD(Fiber, start)
836
891
837
892
fiber -> previous = & fiber -> context ;
838
893
839
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , NULL , false);
894
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , NULL , false);
840
895
841
896
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
842
897
}
@@ -871,7 +926,7 @@ ZEND_METHOD(Fiber, suspend)
871
926
872
927
fiber -> stack_bottom -> prev_execute_data = NULL ;
873
928
874
- zend_fiber_transfer transfer = zend_fiber_suspend (fiber , value );
929
+ zend_fiber_transfer transfer = zend_fiber_suspend_internal (fiber , value );
875
930
876
931
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
877
932
}
@@ -900,7 +955,7 @@ ZEND_METHOD(Fiber, resume)
900
955
901
956
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
902
957
903
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , value , false);
958
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , value , false);
904
959
905
960
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
906
961
}
@@ -928,7 +983,7 @@ ZEND_METHOD(Fiber, throw)
928
983
929
984
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
930
985
931
- zend_fiber_transfer transfer = zend_fiber_resume (fiber , exception , true);
986
+ zend_fiber_transfer transfer = zend_fiber_resume_internal (fiber , exception , true);
932
987
933
988
zend_fiber_delegate_transfer_result (& transfer , INTERNAL_FUNCTION_PARAM_PASSTHRU );
934
989
}
0 commit comments