@@ -183,7 +183,7 @@ static void zend_fiber_stack_free(zend_fiber_stack *stack)
183
183
184
184
static ZEND_NORETURN void zend_fiber_trampoline (transfer_t transfer )
185
185
{
186
- zend_fiber_context * context = EG (current_fiber );
186
+ zend_fiber_context * context = EG (current_fiber_context );
187
187
zend_fiber_context * from = transfer .data ;
188
188
189
189
from -> handle = transfer .context ;
@@ -228,7 +228,7 @@ ZEND_API void zend_fiber_destroy_context(zend_fiber_context *context)
228
228
229
229
ZEND_API zend_fiber_context * zend_fiber_switch_context (zend_fiber_context * to )
230
230
{
231
- zend_fiber_context * from = EG (current_fiber );
231
+ zend_fiber_context * from = EG (current_fiber_context );
232
232
zend_fiber_vm_state state ;
233
233
234
234
ZEND_ASSERT (to && to -> handle && "Invalid fiber context" );
@@ -245,7 +245,7 @@ ZEND_API zend_fiber_context *zend_fiber_switch_context(zend_fiber_context *to)
245
245
from -> status = ZEND_FIBER_STATUS_SUSPENDED ;
246
246
}
247
247
248
- EG (current_fiber ) = to ;
248
+ EG (current_fiber_context ) = to ;
249
249
250
250
#ifdef __SANITIZE_ADDRESS__
251
251
void * fake_stack = NULL ;
@@ -261,7 +261,7 @@ ZEND_API zend_fiber_context *zend_fiber_switch_context(zend_fiber_context *to)
261
261
__sanitizer_finish_switch_fiber (fake_stack , & to -> stack .prior_pointer , & to -> stack .prior_size );
262
262
#endif
263
263
264
- EG (current_fiber ) = from ;
264
+ EG (current_fiber_context ) = from ;
265
265
266
266
zend_fiber_context * previous = transfer .data ;
267
267
previous -> handle = transfer .context ;
@@ -281,7 +281,6 @@ ZEND_API zend_fiber_context *zend_fiber_switch_context(zend_fiber_context *to)
281
281
return previous ;
282
282
}
283
283
284
-
285
284
static zend_always_inline zend_vm_stack zend_fiber_vm_stack_alloc (size_t size )
286
285
{
287
286
zend_vm_stack page = emalloc (size );
@@ -352,6 +351,23 @@ static ZEND_STACK_ALIGNED zend_fiber_context *zend_fiber_execute(zend_fiber_cont
352
351
return caller ;
353
352
}
354
353
354
+ static void zend_fiber_switch_to (zend_fiber * fiber )
355
+ {
356
+ zend_fiber * previous = EG (active_fiber );
357
+ fiber -> caller = EG (current_fiber_context );
358
+ EG (active_fiber ) = fiber ;
359
+ zend_fiber_switch_context (zend_fiber_get_context (fiber ));
360
+ EG (active_fiber ) = previous ;
361
+ }
362
+
363
+ static void zend_fiber_suspend (zend_fiber * fiber )
364
+ {
365
+ zend_fiber_context * caller = fiber -> caller ;
366
+ ZEND_ASSERT (caller != NULL );
367
+ fiber -> caller = NULL ;
368
+ zend_fiber_switch_context (caller );
369
+ }
370
+
355
371
static zend_object * zend_fiber_object_create (zend_class_entry * ce )
356
372
{
357
373
zend_fiber * fiber ;
@@ -376,10 +392,9 @@ static void zend_fiber_object_destroy(zend_object *object)
376
392
zend_object * exception = EG (exception );
377
393
EG (exception ) = NULL ;
378
394
379
- fiber -> caller = EG (current_fiber );
380
395
fiber -> flags |= ZEND_FIBER_FLAG_DESTROYED ;
381
396
382
- zend_fiber_switch_context ( zend_fiber_get_context ( fiber ) );
397
+ zend_fiber_switch_to ( fiber );
383
398
384
399
if (EG (exception )) {
385
400
if (!exception && EG (current_execute_data ) && EG (current_execute_data )-> func
@@ -443,15 +458,11 @@ ZEND_METHOD(Fiber, start)
443
458
fiber -> fci .param_count = param_count ;
444
459
fiber -> fci .named_params = named_params ;
445
460
446
- zend_fiber_context * context = zend_fiber_get_context (fiber );
447
-
448
- if (!zend_fiber_init_context (context , zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size ))) {
461
+ if (!zend_fiber_init_context (zend_fiber_get_context (fiber ), zend_ce_fiber , zend_fiber_execute , EG (fiber_stack_size ))) {
449
462
RETURN_THROWS ();
450
463
}
451
464
452
- fiber -> caller = EG (current_fiber );
453
-
454
- zend_fiber_switch_context (context );
465
+ zend_fiber_switch_to (fiber );
455
466
456
467
if (fiber -> status == ZEND_FIBER_STATUS_DEAD ) {
457
468
RETURN_NULL ();
@@ -470,33 +481,30 @@ ZEND_METHOD(Fiber, suspend)
470
481
Z_PARAM_ZVAL (value );
471
482
ZEND_PARSE_PARAMETERS_END ();
472
483
473
- if (UNEXPECTED (EG (current_fiber )-> kind != zend_ce_fiber )) {
484
+ zend_fiber * fiber = EG (active_fiber );
485
+
486
+ if (!fiber ) {
474
487
zend_throw_error (zend_ce_fiber_error , "Cannot suspend outside of a fiber" );
475
488
RETURN_THROWS ();
476
489
}
477
490
478
- zend_fiber * fiber = zend_fiber_from_context (EG (current_fiber ));
479
- zend_fiber_context * caller = fiber -> caller ;
480
-
481
491
if (UNEXPECTED (fiber -> flags & ZEND_FIBER_FLAG_DESTROYED )) {
482
492
zend_throw_error (zend_ce_fiber_error , "Cannot suspend in a force-closed fiber" );
483
493
RETURN_THROWS ();
484
494
}
485
495
486
496
ZEND_ASSERT (fiber -> status == ZEND_FIBER_STATUS_RUNNING );
487
- ZEND_ASSERT (caller != NULL );
488
497
489
498
if (value ) {
490
499
ZVAL_COPY (& fiber -> value , value );
491
500
} else {
492
501
ZVAL_NULL (& fiber -> value );
493
502
}
494
503
495
- fiber -> caller = NULL ;
496
504
fiber -> execute_data = EG (current_execute_data );
497
505
fiber -> stack_bottom -> prev_execute_data = NULL ;
498
506
499
- zend_fiber_switch_context ( caller );
507
+ zend_fiber_suspend ( fiber );
500
508
501
509
if (fiber -> flags & ZEND_FIBER_FLAG_DESTROYED ) {
502
510
// This occurs when the fiber is GC'ed while suspended.
@@ -539,10 +547,9 @@ ZEND_METHOD(Fiber, resume)
539
547
ZVAL_NULL (& fiber -> value );
540
548
}
541
549
542
- fiber -> caller = EG (current_fiber );
543
550
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
544
551
545
- zend_fiber_switch_context ( zend_fiber_get_context ( fiber ) );
552
+ zend_fiber_switch_to ( fiber );
546
553
547
554
if (fiber -> status == ZEND_FIBER_STATUS_DEAD ) {
548
555
RETURN_NULL ();
@@ -571,10 +578,9 @@ ZEND_METHOD(Fiber, throw)
571
578
Z_ADDREF_P (exception );
572
579
fiber -> exception = exception ;
573
580
574
- fiber -> caller = EG (current_fiber );
575
581
fiber -> stack_bottom -> prev_execute_data = EG (current_execute_data );
576
582
577
- zend_fiber_switch_context ( zend_fiber_get_context ( fiber ) );
583
+ zend_fiber_switch_to ( fiber );
578
584
579
585
if (fiber -> status == ZEND_FIBER_STATUS_DEAD ) {
580
586
RETURN_NULL ();
@@ -659,11 +665,13 @@ ZEND_METHOD(Fiber, this)
659
665
{
660
666
ZEND_PARSE_PARAMETERS_NONE ();
661
667
662
- if (EG (current_fiber )-> kind != zend_ce_fiber ) {
668
+ zend_fiber * fiber = EG (active_fiber );
669
+
670
+ if (!fiber ) {
663
671
RETURN_NULL ();
664
672
}
665
673
666
- RETURN_OBJ_COPY (& zend_fiber_from_context ( EG ( current_fiber )) -> std );
674
+ RETURN_OBJ_COPY (& fiber -> std );
667
675
}
668
676
669
677
ZEND_METHOD (FiberError , __construct )
@@ -698,11 +706,12 @@ void zend_fiber_init(void)
698
706
699
707
context -> status = ZEND_FIBER_STATUS_RUNNING ;
700
708
701
- EG (main_fiber ) = context ;
702
- EG (current_fiber ) = context ;
709
+ EG (main_fiber_context ) = context ;
710
+ EG (current_fiber_context ) = context ;
711
+ EG (active_fiber ) = NULL ;
703
712
}
704
713
705
714
void zend_fiber_shutdown (void )
706
715
{
707
- efree (EG (main_fiber ));
716
+ efree (EG (main_fiber_context ));
708
717
}
0 commit comments