@@ -727,33 +727,27 @@ private LightLambdaExpression CreateFunctionLambda() {
727727
728728#if FEATURE_NET_ASYNC
729729 // Under .NET-async, an `async def` body returns a PythonCoroutine wrapping a Task<object?>.
730- // We pre-allocate a CancellationTokenSource and a StrongBox<Exception?> here
731- // so the same instances are shared with both AsyncExpression, which threads them into AsyncHelpers.DriveAsync
732- // and PythonCoroutine, which uses them to implement coro.throw(exc) on a running coroutine:
733- // write the exception to the box, cancel the CTS, and DriveAsync surfaces that exception in place of OperationCanceledException.
734730 if ( IsAsync) {
735- var cts = MSAst. Expression. Variable( typeof ( CancellationTokenSource) , "$cts") ;
736- var excBox = MSAst. Expression. Variable( typeof ( StrongBox< Exception> ) , "$cancelExc") ;
737- var ctToken = MSAst. Expression. Property( cts, nameof( CancellationTokenSource. Token) ) ;
738731 if ( IsGenerator) {
739732 // Async generator: the body has both `await` and `yield`. Lower it to an
740733 // IAsyncEnumerable<object?> via AsyncEnumerableExpression, sharing the generator label so
741734 // the body's yields and the rewritten awaits land in one generator, then wrap it in a
742735 // PythonAsyncGenerator. The send/throw slots are per-generator StrongBoxes captured by the
743736 // generator (the body's yields read them) AND handed to the wrapper, which writes them
744737 // before each resume — see AsyncSendSlot / AsyncThrowSlot.
738+ var cts = MSAst. Expression. Variable( typeof ( CancellationTokenSource) , "$cts") ;
739+ var ctToken = MSAst. Expression. Property( cts, nameof( CancellationTokenSource. Token) ) ;
745740 var sendSlot = AsyncSendSlot;
746741 var throwSlot = AsyncThrowSlot;
747742 body = MSAst . Expression . Block (
748- [ cts , excBox , sendSlot , throwSlot ] ,
743+ [ cts , sendSlot , throwSlot ] ,
749744 MSAst . Expression . Assign ( cts , MSAst . Expression . New ( typeof ( CancellationTokenSource ) ) ) ,
750- MSAst . Expression . Assign ( excBox , MSAst . Expression . New ( typeof ( StrongBox < Exception > ) ) ) ,
751745 MSAst . Expression . Assign ( sendSlot , MSAst . Expression . New ( typeof ( StrongBox < object > ) ) ) ,
752746 MSAst . Expression . Assign ( throwSlot , MSAst . Expression . New ( typeof ( StrongBox < Exception > ) ) ) ,
753747 Ast . Call (
754748 AstMethods . MakeAsyncGenerator ,
755749 _functionParam ,
756- AstUtils . AsyncEnumerable ( Name , body , GeneratorLabel , ctToken , excBox ) ,
750+ AstUtils . AsyncEnumerable ( Name , body , GeneratorLabel , interrupts : null , ctToken ) ,
757751 sendSlot ,
758752 throwSlot ,
759753 cts ) ) ;
@@ -763,17 +757,18 @@ private LightLambdaExpression CreateFunctionLambda() {
763757 // so the body doesn't execute until the coroutine is first driven (send/AsTask).
764758 // This makes calling an async def side-effect-free (PEP 492) and lets the body's first await capture the driver's SynchronizationContext
765759 // rather than whatever context happened to be current at construction.
760+ // The AsyncInterruptSource is shared by AsyncExpression, which threads it into AsyncHelpers.DriveAsync,
761+ // and PythonCoroutine, which uses it to implement coro.throw(exc).
762+ var interrupts = MSAst. Expression. Variable( typeof ( Microsoft . Scripting . Runtime . AsyncInterruptSource ) , "$interrupts" ) ;
766763 body = MSAst . Expression . Block (
767- [ cts , excBox ] ,
768- MSAst . Expression . Assign ( cts , MSAst . Expression . New ( typeof ( CancellationTokenSource ) ) ) ,
769- MSAst . Expression . Assign ( excBox , MSAst . Expression . New ( typeof ( StrongBox < Exception > ) ) ) ,
764+ [ interrupts ] ,
765+ MSAst . Expression . Assign ( interrupts , MSAst . Expression . New ( typeof ( Microsoft . Scripting . Runtime . AsyncInterruptSource ) ) ) ,
770766 Ast . Call (
771767 AstMethods . MakeAsyncCoroutine ,
772768 _functionParam ,
773769 MSAst . Expression . Lambda < Func < Task < object > > > (
774- AstUtils . Async ( Name , body , ctToken , excBox ) ) ,
775- cts ,
776- excBox ) ) ;
770+ AstUtils . Async ( Name , body , interrupts ) ) ,
771+ interrupts ) ) ;
777772 }
778773 }
779774#endif
0 commit comments