@@ -54,35 +54,59 @@ module CancellablePoolingValueTasks =
5454 let initialResumptionFunc =
5555 CancellableTaskBaseResumptionFunc< 'T, _>( fun sm -> code.Invoke(& sm))
5656
57- let resumptionInfo =
57+ let resumptionInfo () =
58+ let mutable state = InitialYield
59+
5860 { new CancellableTaskBaseResumptionDynamicInfo< 'T, _>( initialResumptionFunc) with
5961 member info.MoveNext ( sm ) =
60- let mutable savedExn = null
61-
62- try
63- sm.ResumptionDynamicInfo.ResumptionData <- null
64- let step = info.ResumptionFunc.Invoke(& sm)
65-
66- if step then
67- MethodBuilder.SetResult(& sm.Data.MethodBuilder, sm.Data.Result)
68- else
69- match sm.ResumptionDynamicInfo.ResumptionData with
70- | : ? ICriticalNotifyCompletion as awaiter ->
71- let mutable awaiter = awaiter
72- // assert not (isNull awaiter)
73- MethodBuilder.AwaitOnCompleted(
74- & sm.Data.MethodBuilder,
75- & awaiter,
76- & sm
77- )
78- | awaiter -> assert not ( isNull awaiter)
79-
80- with exn ->
81- savedExn <- exn
82- // Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
83- match savedExn with
84- | null -> ()
85- | exn -> MethodBuilder.SetException(& sm.Data.MethodBuilder, exn)
62+ let current = state
63+ let mutable continuation = Stop
64+
65+ match current with
66+ | InitialYield ->
67+ state <- Running
68+
69+ continuation <-
70+ if BindContext.CheckWhenIsBind() then Bounce else Immediate
71+ | Running ->
72+ try
73+ let step = info.ResumptionFunc.Invoke(& sm)
74+
75+ if step then
76+ state <- SetResult
77+
78+ continuation <-
79+ if BindContext.Check() then Bounce else Immediate
80+ else
81+ continuation <-
82+ Await( downcast sm.ResumptionDynamicInfo.ResumptionData)
83+ with exn ->
84+ state <- SetException( ExceptionCache.CaptureOrRetrieve exn)
85+ continuation <- if BindContext.Check() then Bounce else Immediate
86+ | SetResult ->
87+ MethodBuilder.SetResult(& sm.Data.MethodBuilder, sm.Data.Result)
88+ | SetException edi ->
89+ MethodBuilder.SetException(& sm.Data.MethodBuilder, edi.SourceException)
90+
91+ let continuation = continuation
92+
93+ match continuation with
94+ | Stop -> ()
95+ | Immediate -> info.MoveNext(& sm)
96+ | Bounce ->
97+ MethodBuilder.AwaitOnCompleted(
98+ & sm.Data.MethodBuilder,
99+ Trampoline.AwaiterRef,
100+ & sm
101+ )
102+ | Await awaiter ->
103+ let mutable awaiter = awaiter
104+
105+ MethodBuilder.AwaitUnsafeOnCompleted(
106+ & sm.Data.MethodBuilder,
107+ & awaiter,
108+ & sm
109+ )
86110
87111 member _.SetStateMachine ( sm , state ) =
88112 MethodBuilder.SetStateMachine(& sm.Data.MethodBuilder, state)
@@ -93,7 +117,7 @@ module CancellablePoolingValueTasks =
93117 ValueTask.FromCanceled<_>( ct)
94118 else
95119 sm.Data.CancellationToken <- ct
96- sm.ResumptionDynamicInfo <- resumptionInfo
120+ sm.ResumptionDynamicInfo <- resumptionInfo ()
97121 sm.Data.MethodBuilder <- PoolingAsyncValueTaskMethodBuilder< 'T>. Create()
98122 sm.Data.MethodBuilder.Start(& sm)
99123 sm.Data.MethodBuilder.Task
@@ -103,22 +127,36 @@ module CancellablePoolingValueTasks =
103127 if __ useResumableCode then
104128 __ stateMachine< CancellableTaskBaseStateMachineData< 'T, _>, CancellableValueTask< 'T>>
105129 ( MoveNextMethodImpl<_>( fun sm ->
106- //-- RESUMABLE CODE START
107130 __ resumeAt sm.ResumptionPoint
108- let mutable __stack_exn = null
109-
110- try
111- let __stack_code_fin = code.Invoke(& sm)
112-
113- if __ stack_ code_ fin then
114- MethodBuilder.SetResult(& sm.Data.MethodBuilder, sm.Data.Result)
115- with exn ->
116- __ stack_ exn <- exn
117- // Run SetException outside the stack unwind, see https://github.com/dotnet/roslyn/issues/26567
118- match __ stack_ exn with
119- | null -> ()
120- | exn -> MethodBuilder.SetException(& sm.Data.MethodBuilder, exn)
121- //-- RESUMABLE CODE END
131+ let mutable error = ValueNone
132+
133+ let __stack_go1 = yieldOnBindLimitWhenIsBind() .Invoke(& sm)
134+
135+ if __ stack_ go1 then
136+ try
137+ let __stack_code_fin = code.Invoke(& sm)
138+
139+ if __ stack_ code_ fin then
140+ let __stack_go2 = yieldOnBindLimit() .Invoke(& sm)
141+
142+ if __ stack_ go2 then
143+ MethodBuilder.SetResult(
144+ & sm.Data.MethodBuilder,
145+ sm.Data.Result
146+ )
147+ with exn ->
148+ error <-
149+ ValueSome
150+ <| ExceptionCache.CaptureOrRetrieve exn
151+
152+ if error.IsSome then
153+ let __stack_go2 = yieldOnBindLimit() .Invoke(& sm)
154+
155+ if __ stack_ go2 then
156+ MethodBuilder.SetException(
157+ & sm.Data.MethodBuilder,
158+ error.Value.SourceException
159+ )
122160 ))
123161 ( SetStateMachineMethodImpl<_>( fun sm state ->
124162 MethodBuilder.SetStateMachine(& sm.Data.MethodBuilder, state)
@@ -148,6 +186,8 @@ module CancellablePoolingValueTasks =
148186 ( [<InlineIfLambda>] x : CancellationToken -> ValueTask < _ >)
149187 : CancellationToken -> Awaiter < ValueTaskAwaiter < _ >, _ > =
150188 fun ct ->
189+ BindContext.SetIsBind()
190+
151191 ( x ct)
152192 |> Awaitable.GetAwaiter
153193
0 commit comments