@@ -266,7 +266,7 @@ ZEND_API void zend_fiber_suspend_context(zend_fiber_context *current)
266
266
current -> caller = transfer .context ;
267
267
}
268
268
269
- static void zend_fiber_suspend (zend_fiber * fiber )
269
+ static void zend_fiber_suspend_from (zend_fiber * fiber )
270
270
{
271
271
zend_vm_stack stack ;
272
272
size_t stack_page_size ;
@@ -445,6 +445,18 @@ static void zend_fiber_object_free(zend_object *object)
445
445
zend_object_std_dtor (& fiber -> std );
446
446
}
447
447
448
+ ZEND_API zend_fiber * zend_fiber_create (const zend_fcall_info * fci , const zend_fcall_info_cache * fci_cache )
449
+ {
450
+ zend_fiber * fiber = (zend_fiber * ) zend_fiber_object_create (zend_ce_fiber );
451
+
452
+ fiber -> fci = * fci ;
453
+ fiber -> fci_cache = * fci_cache ;
454
+
455
+ Z_TRY_ADDREF (fiber -> fci .function_name );
456
+
457
+ return fiber ;
458
+ }
459
+
448
460
ZEND_METHOD (Fiber , __construct )
449
461
{
450
462
zend_fiber * fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
@@ -457,17 +469,8 @@ ZEND_METHOD(Fiber, __construct)
457
469
Z_TRY_ADDREF (fiber -> fci .function_name );
458
470
}
459
471
460
- ZEND_METHOD ( Fiber , start )
472
+ ZEND_API void zend_fiber_start ( zend_fiber * fiber , zval * params , uint32_t param_count , zend_array * named_params , zval * return_value )
461
473
{
462
- zend_fiber * fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
463
- zval * params ;
464
- uint32_t param_count ;
465
- zend_array * named_params ;
466
-
467
- ZEND_PARSE_PARAMETERS_START (0 , -1 )
468
- Z_PARAM_VARIADIC_WITH_NAMED (params , param_count , named_params );
469
- ZEND_PARSE_PARAMETERS_END ();
470
-
471
474
if (fiber -> status != ZEND_FIBER_STATUS_INIT ) {
472
475
zend_throw_error (zend_ce_fiber_error , "Cannot start a fiber that has already been started" );
473
476
RETURN_THROWS ();
@@ -492,16 +495,24 @@ ZEND_METHOD(Fiber, start)
492
495
ZVAL_UNDEF (& fiber -> value );
493
496
}
494
497
495
- ZEND_METHOD (Fiber , suspend )
498
+ ZEND_METHOD (Fiber , start )
496
499
{
497
- zend_fiber * fiber = EG (current_fiber );
498
- zval * exception , * value = NULL ;
500
+ zend_fiber * fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
501
+ zval * params ;
502
+ uint32_t param_count ;
503
+ zend_array * named_params ;
499
504
500
- ZEND_PARSE_PARAMETERS_START (0 , 1 )
501
- Z_PARAM_OPTIONAL
502
- Z_PARAM_ZVAL (value );
505
+ ZEND_PARSE_PARAMETERS_START (0 , -1 )
506
+ Z_PARAM_VARIADIC_WITH_NAMED (params , param_count , named_params );
503
507
ZEND_PARSE_PARAMETERS_END ();
504
508
509
+ zend_fiber_start (fiber , params , param_count , named_params , return_value );
510
+ }
511
+
512
+ ZEND_API void zend_fiber_suspend (zval * value , zval * return_value )
513
+ {
514
+ zend_fiber * fiber = EG (current_fiber );
515
+
505
516
if (UNEXPECTED (!fiber )) {
506
517
zend_throw_error (zend_ce_fiber_error , "Cannot suspend outside of a fiber" );
507
518
RETURN_THROWS ();
@@ -520,11 +531,11 @@ ZEND_METHOD(Fiber, suspend)
520
531
ZVAL_NULL (& fiber -> value );
521
532
}
522
533
523
- fiber -> execute_data = execute_data ;
534
+ fiber -> execute_data = EG ( current_execute_data ) ;
524
535
fiber -> status = ZEND_FIBER_STATUS_SUSPENDED ;
525
536
fiber -> stack_bottom -> prev_execute_data = NULL ;
526
537
527
- zend_fiber_suspend (fiber );
538
+ zend_fiber_suspend_from (fiber );
528
539
529
540
if (fiber -> status == ZEND_FIBER_STATUS_SHUTDOWN ) {
530
541
// This occurs when the fiber is GC'ed while suspended.
@@ -535,7 +546,7 @@ ZEND_METHOD(Fiber, suspend)
535
546
fiber -> status = ZEND_FIBER_STATUS_RUNNING ;
536
547
537
548
if (fiber -> exception ) {
538
- exception = fiber -> exception ;
549
+ zval * exception = fiber -> exception ;
539
550
fiber -> exception = NULL ;
540
551
541
552
zend_throw_exception_object (exception );
@@ -546,18 +557,20 @@ ZEND_METHOD(Fiber, suspend)
546
557
ZVAL_UNDEF (& fiber -> value );
547
558
}
548
559
549
- ZEND_METHOD (Fiber , resume )
560
+ ZEND_METHOD (Fiber , suspend )
550
561
{
551
- zend_fiber * fiber ;
552
562
zval * value = NULL ;
553
563
554
564
ZEND_PARSE_PARAMETERS_START (0 , 1 )
555
565
Z_PARAM_OPTIONAL
556
566
Z_PARAM_ZVAL (value );
557
567
ZEND_PARSE_PARAMETERS_END ();
558
568
559
- fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
569
+ zend_fiber_suspend (value , return_value );
570
+ }
560
571
572
+ ZEND_API void zend_fiber_resume (zend_fiber * fiber , zval * value , zval * return_value )
573
+ {
561
574
if (UNEXPECTED (fiber -> status != ZEND_FIBER_STATUS_SUSPENDED )) {
562
575
zend_throw_error (zend_ce_fiber_error , "Cannot resume a fiber that is not suspended" );
563
576
RETURN_THROWS ();
@@ -570,7 +583,7 @@ ZEND_METHOD(Fiber, resume)
570
583
}
571
584
572
585
fiber -> status = ZEND_FIBER_STATUS_RUNNING ;
573
- fiber -> stack_bottom -> prev_execute_data = execute_data ;
586
+ fiber -> stack_bottom -> prev_execute_data = EG ( current_execute_data ) ;
574
587
575
588
zend_fiber_switch_to (fiber );
576
589
@@ -582,17 +595,23 @@ ZEND_METHOD(Fiber, resume)
582
595
ZVAL_UNDEF (& fiber -> value );
583
596
}
584
597
585
- ZEND_METHOD (Fiber , throw )
598
+ ZEND_METHOD (Fiber , resume )
586
599
{
587
600
zend_fiber * fiber ;
588
- zval * exception ;
601
+ zval * value = NULL ;
589
602
590
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
591
- Z_PARAM_OBJECT_OF_CLASS (exception , zend_ce_throwable )
603
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
604
+ Z_PARAM_OPTIONAL
605
+ Z_PARAM_ZVAL (value );
592
606
ZEND_PARSE_PARAMETERS_END ();
593
607
594
608
fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
595
609
610
+ zend_fiber_resume (fiber , value , return_value );
611
+ }
612
+
613
+ ZEND_API void zend_fiber_throw (zend_fiber * fiber , zval * exception , zval * return_value )
614
+ {
596
615
if (UNEXPECTED (fiber -> status != ZEND_FIBER_STATUS_SUSPENDED )) {
597
616
zend_throw_error (zend_ce_fiber_error , "Cannot resume a fiber that is not suspended" );
598
617
RETURN_THROWS ();
@@ -602,7 +621,7 @@ ZEND_METHOD(Fiber, throw)
602
621
fiber -> exception = exception ;
603
622
604
623
fiber -> status = ZEND_FIBER_STATUS_RUNNING ;
605
- fiber -> stack_bottom -> prev_execute_data = execute_data ;
624
+ fiber -> stack_bottom -> prev_execute_data = EG ( current_execute_data ) ;
606
625
607
626
zend_fiber_switch_to (fiber );
608
627
@@ -614,6 +633,20 @@ ZEND_METHOD(Fiber, throw)
614
633
ZVAL_UNDEF (& fiber -> value );
615
634
}
616
635
636
+ ZEND_METHOD (Fiber , throw )
637
+ {
638
+ zend_fiber * fiber ;
639
+ zval * exception ;
640
+
641
+ ZEND_PARSE_PARAMETERS_START (1 , 1 )
642
+ Z_PARAM_OBJECT_OF_CLASS (exception , zend_ce_throwable )
643
+ ZEND_PARSE_PARAMETERS_END ();
644
+
645
+ fiber = (zend_fiber * ) Z_OBJ_P (getThis ());
646
+
647
+ zend_fiber_throw (fiber , exception , return_value );
648
+ }
649
+
617
650
ZEND_METHOD (Fiber , isStarted )
618
651
{
619
652
zend_fiber * fiber ;
0 commit comments