1111use PHPStan \Analyser \Scope ;
1212use PHPStan \DependencyInjection \AutowiredService ;
1313use PHPStan \ShouldNotHappenException ;
14+ use function array_pop ;
15+ use function count ;
1416use function get_debug_type ;
1517
1618#[AutowiredService(as: FiberNodeScopeResolver::class)]
@@ -31,20 +33,28 @@ protected function callNodeCallback(
3133 $ nodeCallback ($ node , $ scope ->toFiberScope ());
3234 return ;
3335 }
34- $ fiber = new Fiber (static function () use ($ node , $ scope , $ nodeCallback ) {
35- $ nodeCallback ($ node , $ scope ->toFiberScope ());
36- });
37- $ request = $ fiber ->start ();
36+ if (count ($ storage ->parkedFibers ) > 0 ) {
37+ $ fiber = array_pop ($ storage ->parkedFibers );
38+ $ request = $ fiber ->resume ([$ nodeCallback , $ node , $ scope ]);
39+ } else {
40+ $ fiber = new Fiber (static function () use ($ node , $ scope , $ nodeCallback ) {
41+ while (true ) { // @phpstan-ignore while.alwaysTrue
42+ $ nodeCallback ($ node , $ scope ->toFiberScope ());
43+ [$ nodeCallback , $ node , $ scope ] = Fiber::suspend (new ParkFiberRequest ());
44+ }
45+ });
46+ $ request = $ fiber ->start ();
47+ }
3848 $ this ->runFiberForNodeCallback ($ storage , $ fiber , $ request );
3949 }
4050
4151 /**
42- * @param Fiber<mixed, Scope, null, BeforeScopeForExprRequest> $fiber
52+ * @param Fiber<mixed, Scope|array{callable(Node $node, Scope $scope): void, Node, Scope}, null, BeforeScopeForExprRequest|ParkFiberRequest > $fiber
4353 */
4454 private function runFiberForNodeCallback (
4555 ExpressionResultStorage $ storage ,
4656 Fiber $ fiber ,
47- ? BeforeScopeForExprRequest $ request ,
57+ BeforeScopeForExprRequest | ParkFiberRequest | null $ request ,
4858 ): void
4959 {
5060 while (!$ fiber ->isTerminated ()) {
@@ -61,6 +71,10 @@ private function runFiberForNodeCallback(
6171 ];
6272 return ;
6373 }
74+ if ($ request instanceof ParkFiberRequest) {
75+ $ storage ->parkedFibers [] = $ fiber ;
76+ return ;
77+ }
6478
6579 throw new ShouldNotHappenException (
6680 'Unknown fiber suspension: ' . get_debug_type ($ request ),
0 commit comments