diff --git a/src/fsharp/FSharp.Core/async.fs b/src/fsharp/FSharp.Core/async.fs index e2f87857f41..2d87a60078a 100644 --- a/src/fsharp/FSharp.Core/async.fs +++ b/src/fsharp/FSharp.Core/async.fs @@ -78,31 +78,25 @@ namespace Microsoft.FSharp.Control [] type Trampoline() = - let unfake FakeUnit = () + let unfake (_ : AsyncReturn) = () [] static let bindLimitBeforeHijack = 300 - [] - [] + [] static val mutable private thisThreadHasTrampoline : bool static member ThisThreadHasTrampoline = Trampoline.thisThreadHasTrampoline let mutable storedCont = None + let mutable storedExnCont = None let mutable bindCount = 0 /// Use this trampoline on the synchronous stack if none exists, and execute /// the given function. The function might write its continuation into the trampoline. + [] member __.Execute (firstAction : unit -> AsyncReturn) = - let rec loop action = - action() |> unfake - match storedCont with - | None -> () - | Some newAction -> - storedCont <- None - loop newAction let thisIsTopTrampoline = if Trampoline.thisThreadHasTrampoline then @@ -111,11 +105,31 @@ namespace Microsoft.FSharp.Control Trampoline.thisThreadHasTrampoline <- true true try - loop firstAction + let mutable keepGoing = true + let mutable action = firstAction + while keepGoing do + try + action() |> unfake + match storedCont with + | None -> + keepGoing <- false + | Some cont -> + storedCont <- None + action <- cont + // Let the exception propagate all the way to the trampoline to get a full .StackTrace entry + with exn -> + match storedExnCont with + | None -> + reraise() + | Some econt -> + storedExnCont <- None + let edi = ExceptionDispatchInfo.RestoreOrCapture exn + action <- (fun () -> econt edi) + finally if thisIsTopTrampoline then Trampoline.thisThreadHasTrampoline <- false - FakeUnit + Unchecked.defaultof /// Increment the counter estimating the size of the synchronous stack and /// return true if time to jump on trampoline. @@ -130,13 +144,16 @@ namespace Microsoft.FSharp.Control bindCount <- 0 storedCont <- Some action | _ -> failwith "Internal error: attempting to install continuation twice" - FakeUnit + Unchecked.defaultof + /// Save the exception continuation during propagation of an exception, or prior to raising an exception + member __.OnExceptionRaised (action: econt) = + storedExnCont <- Some action type TrampolineHolder() as this = let mutable trampoline = null - static let unfake FakeUnit = () + static let unfake (_: AsyncReturn) = () // Preallocate this delegate and keep it in the trampoline holder. let sendOrPostCallbackWithTrampoline = @@ -159,18 +176,19 @@ namespace Microsoft.FSharp.Control #endif /// Execute an async computation after installing a trampoline on its synchronous stack. + [] member __.ExecuteWithTrampoline firstAction = trampoline <- new Trampoline() trampoline.Execute firstAction member this.PostWithTrampoline (syncCtxt: SynchronizationContext) (f : unit -> AsyncReturn) = syncCtxt.Post (sendOrPostCallbackWithTrampoline, state=(f |> box)) - FakeUnit + Unchecked.defaultof member this.QueueWorkItemWithTrampoline (f: unit -> AsyncReturn) = if not (ThreadPool.QueueUserWorkItem(waitCallbackForQueueWorkItemWithTrampoline, f |> box)) then failwith "failed to queue user work item" - FakeUnit + Unchecked.defaultof member this.PostOrQueueWithTrampoline (syncCtxt : SynchronizationContext) f = match syncCtxt with @@ -184,16 +202,20 @@ namespace Microsoft.FSharp.Control this.QueueWorkItemWithTrampoline(f) #else (new Thread((fun _ -> this.Execute f |> unfake), IsBackground=true)).Start() - FakeUnit + Unchecked.defaultof #endif #else // This should be the only call to Thread.Start in this library. We must always install a trampoline. member __.StartThreadWithTrampoline (f : unit -> AsyncReturn) = (new Thread(threadStartCallbackForStartThreadWithTrampoline,IsBackground=true)).Start(f|>box) - FakeUnit + Unchecked.defaultof #endif + /// Save the exception continuation during propagation of an exception, or prior to raising an exception + member inline __.OnExceptionRaised(econt) = + trampoline.OnExceptionRaised econt + /// Call a continuation, but first check if an async computation should trampoline on its synchronous stack. member inline __.HijackCheckThenCall (cont : 'T -> AsyncReturn) res = if trampoline.IncrementBindCount() then @@ -206,26 +228,59 @@ namespace Microsoft.FSharp.Control [] /// Represents rarely changing components of an in-flight async computation type AsyncActivationAux = - { token : CancellationToken + { /// The active cancellation token + token : CancellationToken + /// The exception continuation econt : econt + /// The cancellation continuation ccont : ccont + /// Holds some commonly-allocated callbacks and a mutable location to use for a trampoline trampolineHolder : TrampolineHolder } [] [] - /// Represents an in-flight async computation - type AsyncActivation<'T> = - { cont : cont<'T> + /// Represents context for an in-flight async computation + type AsyncActivationContents<'T> = + { /// The success continuation + cont : cont<'T> + /// The rarely changing components aux : AsyncActivationAux } - member ctxt.IsCancellationRequested = ctxt.aux.token.IsCancellationRequested + /// A struct wrapper around AsyncActivationContents. Using a struct wrapper allows us to change representation of the + /// contents at a later point, e.g. to change the contents to a .NET Task or some other representation. + [] + type AsyncActivation<'T>(contents: AsyncActivationContents<'T>) = + + member ctxt.WithCancellationContinuation ccont = AsyncActivation<_> { contents with aux = { ctxt.aux with ccont = ccont } } + + member ctxt.WithExceptionContinuation econt = AsyncActivation<_> { contents with aux = { ctxt.aux with econt = econt } } + + member ctxt.WithContinuation(cont) = AsyncActivation<_> { cont = cont; aux = contents.aux } + + member ctxt.WithContinuations(cont, econt) = AsyncActivation<_> { cont = cont; aux = { contents.aux with econt = econt } } + + member ctxt.WithContinuations(cont, econt, ccont) = AsyncActivation<_> { contents with cont = cont; aux = { ctxt.aux with econt = econt; ccont = ccont } } + + member ctxt.aux = contents.aux + + member ctxt.cont = contents.cont + + member ctxt.econt = contents.aux.econt + + member ctxt.ccont = contents.aux.ccont + + member ctxt.token = contents.aux.token + + member ctxt.trampolineHolder = contents.aux.trampolineHolder + + member ctxt.IsCancellationRequested = contents.aux.token.IsCancellationRequested /// Call the cancellation continuation of the active computation member ctxt.OnCancellation () = - ctxt.aux.ccont (new OperationCanceledException (ctxt.aux.token)) + contents.aux.ccont (new OperationCanceledException (contents.aux.token)) member inline ctxt.HijackCheckThenCall cont arg = - ctxt.aux.trampolineHolder.HijackCheckThenCall cont arg + contents.aux.trampolineHolder.HijackCheckThenCall cont arg member ctxt.OnSuccess result = if ctxt.IsCancellationRequested then @@ -235,16 +290,25 @@ namespace Microsoft.FSharp.Control /// Call the exception continuation directly member ctxt.CallExceptionContinuation edi = - ctxt.aux.econt edi + contents.aux.econt edi + + /// Save the exception continuation during propagation of an exception, or prior to raising an exception + member ctxt.OnExceptionRaised() = + contents.aux.trampolineHolder.OnExceptionRaised contents.aux.econt + + /// Make an initial async activation. + static member Create cancellationToken trampolineHolder cont econt ccont : AsyncActivation<'T> = + AsyncActivation { cont = cont; aux = { token = cancellationToken; econt = econt; ccont = ccont; trampolineHolder = trampolineHolder } } + member ctxt.QueueContinuationWithTrampoline (result: 'T) = + let ctxt = ctxt ctxt.aux.trampolineHolder.QueueWorkItemWithTrampoline(fun () -> ctxt.cont result) member ctxt.CallContinuation(result: 'T) = ctxt.cont result - [] - [] + [] type Async<'T> = { Invoke : (AsyncActivation<'T> -> AsyncReturn) } @@ -254,14 +318,12 @@ namespace Microsoft.FSharp.Control member __.Proceed = not isStopped member __.Stop() = isStopped <- true - [] - [] + [] type Latch() = let mutable i = 0 member this.Enter() = Interlocked.CompareExchange(&i, 1, 0) = 0 - [] - [] + [] type Once() = let latch = Latch() member this.Do f = @@ -274,6 +336,7 @@ namespace Microsoft.FSharp.Control | Error of ExceptionDispatchInfo | Canceled of OperationCanceledException + [] member res.Commit () = match res with | AsyncResult.Ok res -> res @@ -282,186 +345,230 @@ namespace Microsoft.FSharp.Control module AsyncPrimitives = - let fake () = FakeUnit - let unfake FakeUnit = () + let fake () = Unchecked.defaultof + + let unfake (_: AsyncReturn) = () let mutable defaultCancellationTokenSource = new CancellationTokenSource() - /// Apply userCode to x and call either the continuation or exception continuation depending what happens - let inline ProtectUserCodePlusHijackCheck (trampolineHolder:TrampolineHolder) userCode x econt (cont : 'T -> AsyncReturn) : AsyncReturn = - // This is deliberately written in a allocation-free style, except when the trampoline is taken + /// Primitive to invoke an async computation. + // + // Note: direct calls to this function may end up in user assemblies via inlining + [] + let Invoke (computation: Async<'T>) (ctxt: AsyncActivation<_>) : AsyncReturn = + ctxt.HijackCheckThenCall computation.Invoke ctxt + + /// Apply userCode to x. If no exception is raised then call the normal continuation. Used to implement + /// 'finally' and 'when cancelled'. + [] + let CallThenContinue userCode arg (ctxt: AsyncActivation<_>) : AsyncReturn = let mutable result = Unchecked.defaultof<_> - let mutable edi = null + let mutable ok = false try - result <- userCode x - with exn -> - edi <- ExceptionDispatchInfo.RestoreOrCapture(exn) + result <- userCode arg + ok <- true + finally + if not ok then + ctxt.OnExceptionRaised() - match edi with - | null -> - // NOTE: this must be a tailcall - trampolineHolder.HijackCheckThenCall cont result - | _ -> - // NOTE: this must be a tailcall - trampolineHolder.HijackCheckThenCall econt edi + if ok then + ctxt.HijackCheckThenCall ctxt.cont result + else + Unchecked.defaultof - // Apply userCode to x and call either the continuation or exception continuation depending what happens - let inline ProtectUserCodeThenInvoke userCode x econt (cont : 'T -> AsyncReturn) : AsyncReturn = - // This is deliberately written in a allocation-free style + /// Apply 'part2' to 'result1' and invoke the resulting computation. + // + // Note: direct calls to this function end up in user assemblies via inlining + [] + let CallThenInvoke (ctxt: AsyncActivation<_>) result1 part2 : AsyncReturn = let mutable result = Unchecked.defaultof<_> - let mutable edi = null + let mutable ok = false try - result <- userCode x - with exn -> - edi <- ExceptionDispatchInfo.RestoreOrCapture(exn) + result <- part2 result1 + ok <- true + finally + if not ok then + ctxt.OnExceptionRaised() - match edi with - | null -> - // NOTE: this must be a tailcall - cont result - | exn -> - // NOTE: this must be a tailcall - econt exn + if ok then + Invoke result ctxt + else + Unchecked.defaultof + /// Like `CallThenInvoke` but does not do a hijack check for historical reasons (exact code compat) + [] + let CallThenInvokeNoHijackCheck (ctxt: AsyncActivation<_>) userCode result1 = + let mutable res = Unchecked.defaultof<_> + let mutable ok = false + + try + res <- userCode result1 + ok <- true + finally + if not ok then + ctxt.OnExceptionRaised() + + if ok then + res.Invoke ctxt + else + Unchecked.defaultof + + /// Apply 'catchFilter' to 'arg'. If the result is 'Some' invoke the resulting computation. If the result is 'None' + /// then send 'result1' to the exception continuation. + [] + let CallFilterThenInvoke (ctxt: AsyncActivation<'T>) catchFilter (edi: ExceptionDispatchInfo) : AsyncReturn = + let mutable resOpt = Unchecked.defaultof<_> + let mutable ok = false + + try + resOpt <- catchFilter (edi.GetAssociatedSourceException()) + ok <- true + finally + if not ok then + ctxt.OnExceptionRaised() + + if ok then + match resOpt with + | None -> + ctxt.HijackCheckThenCall ctxt.econt edi + | Some res -> + Invoke res ctxt + else + Unchecked.defaultof + + /// Internal way of making an async from code, for exact code compat. /// Perform a cancellation check and ensure that any exceptions raised by /// the immediate execution of "userCode" are sent to the exception continuation. - let ProtectUserCode (ctxt: AsyncActivation<_>) userCode = + [] + let ProtectedCode (ctxt: AsyncActivation<'T>) userCode = if ctxt.IsCancellationRequested then ctxt.OnCancellation () else + let mutable ok = false try - userCode ctxt - with exn -> - let edi = ExceptionDispatchInfo.RestoreOrCapture(exn) - ctxt.CallExceptionContinuation edi + let res = userCode ctxt + ok <- true + res + finally + if not ok then + ctxt.OnExceptionRaised() - /// Make an initial asyc activation. - [] - let CreateAsyncActivation cancellationToken trampolineHolder cont econt ccont = - { cont = cont; aux = { token = cancellationToken; econt = econt; ccont = ccont; trampolineHolder = trampolineHolder } } - /// Build a primitive without any exception or resync protection + [] let MakeAsync body = { Invoke = body } - // Use this to recover ExceptionDispatchInfo when outside the "with" part of a try/with block. - // This indicates all the places where we lose a stack trace. - // - // Stack trace losses come when interoperating with other code that only provide us with an exception value, - // notably .NET 4.x tasks and user exceptions passed to the exception continuation in Async.FromContinuations. - let MayLoseStackTrace exn = ExceptionDispatchInfo.RestoreOrCapture(exn) - - // Call the exception continuation - let errorT args edi = - args.aux.econt edi + [] + // Note: direct calls to this function end up in user assemblies via inlining + let Bind (ctxt: AsyncActivation<'T>) (part1: Async<'U>) (part2: 'U -> Async<'T>) : AsyncReturn = + if ctxt.IsCancellationRequested then + ctxt.OnCancellation () + else + Invoke part1 (ctxt.WithContinuation(fun result1 -> CallThenInvokeNoHijackCheck ctxt part2 result1 )) - let protectedPrimitiveCore ctxt f = - if ctxt.aux.token.IsCancellationRequested then + [] + /// Re-route all continuations to execute the finally function. + let TryFinally (ctxt: AsyncActivation<'T>) computation finallyFunction = + if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - try - f ctxt - with exn -> - let edi = ExceptionDispatchInfo.RestoreOrCapture(exn) - errorT ctxt edi + // The new continuation runs the finallyFunction and resumes the old continuation + // If an exception is thrown we continue with the previous exception continuation. + let cont result = + CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.cont result)) + // The new exception continuation runs the finallyFunction and then runs the previous exception continuation. + // If an exception is thrown we continue with the previous exception continuation. + let econt exn = + CallThenContinue finallyFunction () (ctxt.WithContinuation(fun () -> ctxt.econt exn)) + // The cancellation continuation runs the finallyFunction and then runs the previous cancellation continuation. + // If an exception is thrown we continue with the previous cancellation continuation (the exception is lost) + let ccont cexn = + CallThenContinue finallyFunction () (ctxt.WithContinuations(cont=(fun () -> ctxt.ccont cexn), econt = (fun _ -> ctxt.ccont cexn))) + let newCtxt = ctxt.WithContinuations(cont=cont, econt=econt, ccont=ccont) + computation.Invoke newCtxt + + /// Re-route the exception continuation to call to catchFunction. If catchFunction returns None then call the exception continuation. + /// If it returns Some, invoke the resulting async. + [] + let TryWith (ctxt: AsyncActivation<'T>) computation catchFunction = + if ctxt.IsCancellationRequested then + ctxt.OnCancellation () + else + let newCtxt = + ctxt.WithExceptionContinuation(fun edi -> + if ctxt.IsCancellationRequested then + ctxt.OnCancellation () + else + CallFilterThenInvoke ctxt catchFunction edi) + computation.Invoke newCtxt - // When run, ensures that any exceptions raised by the immediate execution of "f" are - // sent to the exception continuation. - // + /// Internal way of making an async from code, for exact code compat. + /// When run, ensures that any exceptions raised by the immediate execution of "f" are + /// sent to the exception continuation. let CreateProtectedAsync f = - MakeAsync (fun ctxt -> ProtectUserCode ctxt f) + MakeAsync (fun ctxt -> ProtectedCode ctxt f) + /// Internal way of making an async from result, for exact code compat. let CreateAsyncResultAsync res = MakeAsync (fun ctxt -> match res with | AsyncResult.Ok r -> ctxt.cont r | AsyncResult.Error edi -> ctxt.CallExceptionContinuation edi - | AsyncResult.Canceled oce -> ctxt.aux.ccont oce) + | AsyncResult.Canceled oce -> ctxt.ccont oce) // Generate async computation which calls its continuation with the given result - let CreateReturnAsync x = - MakeAsync (fun ctxt -> - if ctxt.IsCancellationRequested then - ctxt.OnCancellation () - else - ctxt.HijackCheckThenCall ctxt.cont x) - + let inline CreateReturnAsync res = + // Note: this code ends up in user assemblies via inlining + MakeAsync (fun ctxt -> ctxt.OnSuccess res) + // The primitive bind operation. Generate a process that runs the first process, takes // its result, applies f and then runs the new process produced. Hijack if necessary and // run 'f' with exception protection - let CreateBindAsync p1 f = - MakeAsync (fun ctxt -> - if ctxt.IsCancellationRequested then - ctxt.OnCancellation () - else - - let ctxt = - let cont a = ProtectUserCodeThenInvoke f a ctxt.aux.econt (fun p2 -> p2.Invoke ctxt) - { cont=cont; - aux = ctxt.aux - } - // Trampoline the continuation onto a new work item every so often - ctxt.HijackCheckThenCall p1.Invoke ctxt) + let inline CreateBindAsync part1 part2 = + // Note: this code ends up in user assemblies via inlining + MakeAsync (fun ctxt -> + Bind ctxt part1 part2) // Call the given function with exception protection, but first // check for cancellation. - let CreateCallAsync f x = - MakeAsync (fun ctxt -> - if ctxt.aux.token.IsCancellationRequested then + let inline CreateCallAsync part2 result1 = + // Note: this code ends up in user assemblies via inlining + MakeAsync (fun ctxt -> + if ctxt.IsCancellationRequested then ctxt.OnCancellation () else - ProtectUserCodePlusHijackCheck ctxt.aux.trampolineHolder f x ctxt.aux.econt (fun p2 -> p2.Invoke ctxt) - ) + CallThenInvoke ctxt result1 part2) - let CreateDelayAsync f = CreateCallAsync f () + let inline CreateDelayAsync computation = + // Note: this code ends up in user assemblies via inlining + CreateCallAsync computation () - let CreateSequentialAsync p1 p2 = - CreateBindAsync p1 (fun () -> p2) + /// Implements the sequencing construct of async computation expressions + let inline CreateSequentialAsync part1 part2 = + // Note: this code ends up in user assemblies via inlining + CreateBindAsync part1 (fun () -> part2) - // Call p but augment the normal, exception and cancel continuations with a call to finallyFunction. - // If the finallyFunction raises an exception then call the original exception continuation - // with the new exception. If exception is raised after a cancellation, exception is ignored - // and cancel continuation is called. - let CreateTryFinallyAsync finallyFunction computation = - MakeAsync (fun ctxt -> - if ctxt.aux.token.IsCancellationRequested then - ctxt.OnCancellation () - else - let trampolineHolder = ctxt.aux.trampolineHolder - // The new continuation runs the finallyFunction and resumes the old continuation - // If an exception is thrown we continue with the previous exception continuation. - let cont b = ProtectUserCodePlusHijackCheck trampolineHolder finallyFunction () ctxt.aux.econt (fun () -> ctxt.cont b) - // The new exception continuation runs the finallyFunction and then runs the previous exception continuation. - // If an exception is thrown we continue with the previous exception continuation. - let econt exn = ProtectUserCodePlusHijackCheck trampolineHolder finallyFunction () ctxt.aux.econt (fun () -> ctxt.aux.econt exn) - // The cancellation continuation runs the finallyFunction and then runs the previous cancellation continuation. - // If an exception is thrown we continue with the previous cancellation continuation (the exception is lost) - let ccont cexn = ProtectUserCodePlusHijackCheck trampolineHolder finallyFunction () (fun _ -> ctxt.aux.ccont cexn) (fun () -> ctxt.aux.ccont cexn) - computation.Invoke { ctxt with cont = cont; aux = { ctxt.aux with econt = econt; ccont = ccont } }) - - // Re-route the exception continuation to call to catchFunction. If catchFunction or the new process fail - // then call the original exception continuation with the failure. - let CreateTryWithDispatchInfoAsync catchFunction computation = - MakeAsync (fun ctxt -> - if ctxt.aux.token.IsCancellationRequested then - ctxt.OnCancellation () - else - let econt (edi: ExceptionDispatchInfo) = - let ecomputation = CreateCallAsync catchFunction edi - ecomputation.Invoke ctxt - let newCtxt = { ctxt with aux = { ctxt.aux with econt = econt } } - computation.Invoke newCtxt) + /// Create an async for a try/finally + let inline CreateTryFinallyAsync finallyFunction computation = + MakeAsync (fun ctxt -> TryFinally ctxt computation finallyFunction) - let CreateTryWithAsync catchFunction computation = - computation |> CreateTryWithDispatchInfoAsync (fun edi -> catchFunction (edi.GetAssociatedSourceException())) + /// Create an async for a try/with filtering exceptions through a pattern match + let inline CreateTryWithFilterAsync catchFunction computation = + MakeAsync (fun ctxt -> TryWith ctxt computation (fun edi -> catchFunction edi)) - /// Call the finallyFunction if the computation results in a cancellation + /// Create an async for a try/with filtering + let inline CreateTryWithAsync catchFunction computation = + CreateTryWithFilterAsync (fun exn -> Some (catchFunction exn)) computation + + /// Call the finallyFunction if the computation results in a cancellation, and then continue with cancellation. + /// If the finally function gives an exception then continue with cancellation regardless. let CreateWhenCancelledAsync (finallyFunction : OperationCanceledException -> unit) computation = MakeAsync (fun ctxt -> - let aux = ctxt.aux - let ccont exn = ProtectUserCodePlusHijackCheck aux.trampolineHolder finallyFunction exn (fun _ -> aux.ccont exn) (fun _ -> aux.ccont exn) - let newCtxt = { ctxt with aux = { aux with ccont = ccont } } + let ccont = ctxt.ccont + let newCtxt = + ctxt.WithCancellationContinuation(fun exn -> + CallThenContinue finallyFunction exn (ctxt.WithContinuations(cont = (fun _ -> ccont exn), econt = (fun _ -> ccont exn)))) computation.Invoke newCtxt) /// A single pre-allocated computation that fetched the current cancellation token @@ -480,18 +587,20 @@ namespace Microsoft.FSharp.Control Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicFunctions.Dispose resource CreateTryFinallyAsync disposeFunction (CreateCallAsync computation resource) |> CreateWhenCancelledAsync disposeFunction - let CreateIgnoreAsync computation = + let inline CreateIgnoreAsync computation = CreateBindAsync computation (fun _ -> unitAsync) - /// Implement the while loop construct of async commputation expressions - let rec CreateWhileAsync guardFunc computation = + /// Implement the while loop construct of async computation expressions + let CreateWhileAsync guardFunc computation = if guardFunc() then - CreateBindAsync computation (fun () -> CreateWhileAsync guardFunc computation) + let mutable whileAsync = Unchecked.defaultof<_> + whileAsync <- CreateBindAsync computation (fun () -> if guardFunc() then whileAsync else unitAsync) + whileAsync else unitAsync /// Implement the for loop construct of async commputation expressions - let rec CreateForLoopAsync (source: seq<_>) computation = + let CreateForLoopAsync (source: seq<_>) computation = CreateUsingAsync (source.GetEnumerator()) (fun ie -> CreateWhileAsync (fun () -> ie.MoveNext()) @@ -499,33 +608,29 @@ namespace Microsoft.FSharp.Control let CreateSwitchToAsync (syncCtxt: SynchronizationContext) = CreateProtectedAsync (fun ctxt -> - ctxt.aux.trampolineHolder.PostWithTrampoline syncCtxt ctxt.cont) + ctxt.trampolineHolder.PostWithTrampoline syncCtxt ctxt.cont) let CreateSwitchToNewThreadAsync() = CreateProtectedAsync (fun ctxt -> - ctxt.aux.trampolineHolder.StartThreadWithTrampoline ctxt.cont) + ctxt.trampolineHolder.StartThreadWithTrampoline ctxt.cont) let CreateSwitchToThreadPoolAsync() = CreateProtectedAsync (fun ctxt -> - ctxt.aux.trampolineHolder.QueueWorkItemWithTrampoline ctxt.cont) + ctxt.trampolineHolder.QueueWorkItemWithTrampoline ctxt.cont) - let delimitSyncContext ctxt = + /// Post back to the sync context regardless of which continuation is taken + let DelimitSyncContext (ctxt: AsyncActivation<_>) = match SynchronizationContext.Current with | null -> ctxt | syncCtxt -> - let aux = ctxt.aux - let trampolineHolder = aux.trampolineHolder - { ctxt with - cont = (fun x -> trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.cont x)) - aux = { aux with - econt = (fun x -> trampolineHolder.PostWithTrampoline syncCtxt (fun () -> aux.econt x)) - ccont = (fun x -> trampolineHolder.PostWithTrampoline syncCtxt (fun () -> aux.ccont x)) } - } + ctxt.WithContinuations(cont = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.cont x)), + econt = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.econt x)), + ccont = (fun x -> ctxt.trampolineHolder.PostWithTrampoline syncCtxt (fun () -> ctxt.ccont x))) // When run, ensures that each of the continuations of the process are run in the same synchronization context. let CreateDelimitedUserCodeAsync f = CreateProtectedAsync (fun ctxt -> - let ctxtWithSync = delimitSyncContext ctxt + let ctxtWithSync = DelimitSyncContext ctxt f ctxtWithSync) [] @@ -539,7 +644,7 @@ namespace Microsoft.FSharp.Control | null -> null // saving a thread-local access | _ -> Thread.CurrentThread - let trampolineHolder = ctxt.aux.trampolineHolder + let trampolineHolder = ctxt.trampolineHolder member __.ContinueImmediate res = let action () = ctxt.cont res @@ -608,7 +713,7 @@ namespace Microsoft.FSharp.Control resEvent <- null) interface IDisposable with - member x.Dispose() = x.Close() // ; System.GC.SuppressFinalize(x) + member x.Dispose() = x.Close() member x.GrabResult() = match result with @@ -641,7 +746,7 @@ namespace Microsoft.FSharp.Control // Run the action outside the lock match grabbedConts with - | [] -> FakeUnit + | [] -> Unchecked.defaultof | [cont] -> if reuseThread then cont.ContinueImmediate(res) @@ -673,7 +778,7 @@ namespace Microsoft.FSharp.Control ) match resOpt with | Some res -> ctxt.cont res - | None -> FakeUnit + | None -> Unchecked.defaultof ) member x.TryWaitForResultSynchronously (?timeout) : 'T option = @@ -717,13 +822,15 @@ namespace Microsoft.FSharp.Control let invokeMeth = (typeof>).GetMethod("Invoke", BindingFlags.Public ||| BindingFlags.NonPublic ||| BindingFlags.Instance) System.Delegate.CreateDelegate(typeof<'Delegate>, obj, invokeMeth) :?> 'Delegate + [] let QueueAsync cancellationToken cont econt ccont computation = let trampolineHolder = new TrampolineHolder() trampolineHolder.QueueWorkItemWithTrampoline (fun () -> - let ctxt = CreateAsyncActivation cancellationToken trampolineHolder cont econt ccont + let ctxt = AsyncActivation.Create cancellationToken trampolineHolder cont econt ccont computation.Invoke ctxt) /// Run the asynchronous workflow and wait for its result. + [] let RunSynchronouslyInAnotherThread (token:CancellationToken,computation,timeout) = let token,innerCTS = // If timeout is provided, we govern the async by our own CTS, to cancel @@ -759,14 +866,15 @@ namespace Microsoft.FSharp.Control | None -> () res.Commit() - let RunSynchronouslyInCurrentThread (token:CancellationToken,computation) = + [] + let RunSynchronouslyInCurrentThread (cancellationToken:CancellationToken,computation) = use resultCell = new ResultCell>() - let trampolineHolder = TrampolineHolder() + let trampolineHolder = new TrampolineHolder() trampolineHolder.ExecuteWithTrampoline (fun () -> let ctxt = - CreateAsyncActivation - token + AsyncActivation.Create + cancellationToken trampolineHolder (fun res -> resultCell.RegisterResult(AsyncResult.Ok(res),reuseThread=true)) (fun edi -> resultCell.RegisterResult(AsyncResult.Error(edi),reuseThread=true)) @@ -777,6 +885,7 @@ namespace Microsoft.FSharp.Control let res = resultCell.TryWaitForResultSynchronously().Value res.Commit() + [] let RunSynchronously cancellationToken (computation: Async<'T>) timeout = // Reuse the current ThreadPool thread if possible. Unfortunately // Thread.IsThreadPoolThread isn't available on all profiles so @@ -794,23 +903,26 @@ namespace Microsoft.FSharp.Control // for the cancellation and run the computation in another thread. | _ -> RunSynchronouslyInAnotherThread (cancellationToken, computation, timeout) - let Start cancellationToken computation = + [] + let Start cancellationToken (computation:Async) = QueueAsync cancellationToken - (fun () -> FakeUnit) // nothing to do on success + (fun () -> Unchecked.defaultof) // nothing to do on success (fun edi -> edi.ThrowAny()) // raise exception in child - (fun _ -> FakeUnit) // ignore cancellation in child + (fun _ -> Unchecked.defaultof) // ignore cancellation in child computation |> unfake + [] let StartWithContinuations cancellationToken (computation:Async<'T>) cont econt ccont = let trampolineHolder = new TrampolineHolder() trampolineHolder.ExecuteWithTrampoline (fun () -> - let ctxt = CreateAsyncActivation cancellationToken trampolineHolder (cont >> fake) (econt >> fake) (ccont >> fake) + let ctxt = AsyncActivation.Create cancellationToken trampolineHolder (cont >> fake) (econt >> fake) (ccont >> fake) computation.Invoke ctxt) |> unfake - - let StartAsTask cancellationToken computation taskCreationOptions = + + [] + let StartAsTask cancellationToken (computation:Async<'T>) taskCreationOptions = let taskCreationOptions = defaultArg taskCreationOptions TaskCreationOptions.None let tcs = new TaskCompletionSource<_>(taskCreationOptions) @@ -828,11 +940,10 @@ namespace Microsoft.FSharp.Control task // Helper to attach continuation to the given task. - // Should be invoked as a part of CreateProtectedAsync(withResync) call - let taskContinueWith (task : Task<'T>) ctxt useCcontForTaskCancellation = + let taskContinueWith (task : Task<'T>) (ctxt: AsyncActivation<'T>) useCcontForTaskCancellation = let continuation (completedTask: Task<_>) : unit = - ctxt.aux.trampolineHolder.ExecuteWithTrampoline (fun () -> + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation then ctxt.OnCancellation () @@ -840,17 +951,18 @@ namespace Microsoft.FSharp.Control let edi = ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask)) ctxt.CallExceptionContinuation edi elif completedTask.IsFaulted then - let edi = MayLoseStackTrace(completedTask.Exception) + let edi = ExceptionDispatchInfo.RestoreOrCapture(completedTask.Exception) ctxt.CallExceptionContinuation edi else ctxt.cont completedTask.Result) |> unfake task.ContinueWith(Action>(continuation)) |> ignore |> fake - let taskContinueWithUnit (task: Task) ctxt useCcontForTaskCancellation = + [] + let taskContinueWithUnit (task: Task) (ctxt: AsyncActivation) useCcontForTaskCancellation = let continuation (completedTask: Task) : unit = - ctxt.aux.trampolineHolder.ExecuteWithTrampoline (fun () -> + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> if completedTask.IsCanceled then if useCcontForTaskCancellation then ctxt.OnCancellation () @@ -858,7 +970,7 @@ namespace Microsoft.FSharp.Control let edi = ExceptionDispatchInfo.Capture(new TaskCanceledException(completedTask)) ctxt.CallExceptionContinuation edi elif completedTask.IsFaulted then - let edi = MayLoseStackTrace(completedTask.Exception) + let edi = ExceptionDispatchInfo.RestoreOrCapture(completedTask.Exception) ctxt.CallExceptionContinuation edi else ctxt.cont ()) |> unfake @@ -956,11 +1068,11 @@ namespace Microsoft.FSharp.Control member __.Delay generator = CreateDelayAsync generator - member __.Return value = CreateReturnAsync value + member inline __.Return value = CreateReturnAsync value - member __.ReturnFrom (computation: Async<_>) = computation + member inline __.ReturnFrom (computation:Async<_>) = computation - member __.Bind (computation, binder) = CreateBindAsync computation binder + member inline __.Bind (computation, binder) = CreateBindAsync computation binder member __.Using (resource, binder) = CreateUsingAsync resource binder @@ -968,17 +1080,18 @@ namespace Microsoft.FSharp.Control member __.For (sequence, body) = CreateForLoopAsync sequence body - member __.Combine (computation1, computation2) = CreateSequentialAsync computation1 computation2 + member inline __.Combine (computation1, computation2) = CreateSequentialAsync computation1 computation2 - member __.TryFinally (computation, compensation) = CreateTryFinallyAsync compensation computation + member inline __.TryFinally (computation, compensation) = CreateTryFinallyAsync compensation computation - member __.TryWith (computation, catchHandler) = CreateTryWithAsync catchHandler computation + member inline __.TryWith (computation, catchHandler) = CreateTryWithAsync catchHandler computation - module AsyncImpl = + // member inline __.TryWithFilter (computation, catchHandler) = CreateTryWithFilterAsync catchHandler computation + + [] + module AsyncBuilderImpl = let async = AsyncBuilder() - open AsyncImpl - [] [] type Async = @@ -996,28 +1109,27 @@ namespace Microsoft.FSharp.Control let mutable contToTailCall = None let thread = Thread.CurrentThread let latch = Latch() - let aux = ctxt.aux let once cont x = if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) if Thread.CurrentThread.Equals(thread) && underCurrentThreadStack then contToTailCall <- Some(fun () -> cont x) else if Trampoline.ThisThreadHasTrampoline then let syncCtxt = SynchronizationContext.Current - aux.trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> cont x) |> unfake + ctxt.trampolineHolder.PostOrQueueWithTrampoline syncCtxt (fun () -> cont x) |> unfake else - aux.trampolineHolder.ExecuteWithTrampoline (fun () -> cont x ) |> unfake + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont x ) |> unfake try - callback (once ctxt.cont, (fun exn -> once aux.econt (MayLoseStackTrace(exn))), once aux.ccont) + callback (once ctxt.cont, (fun exn -> once ctxt.econt (ExceptionDispatchInfo.RestoreOrCapture(exn))), once ctxt.ccont) with exn -> if not(latch.Enter()) then invalidOp(SR.GetString(SR.controlContinuationInvokedMultipleTimes)) let edi = ExceptionDispatchInfo.RestoreOrCapture(exn) - aux.econt edi |> unfake + ctxt.econt edi |> unfake underCurrentThreadStack <- false match contToTailCall with | Some k -> k() - | _ -> FakeUnit) + | _ -> Unchecked.defaultof) static member DefaultCancellationToken = defaultCancellationTokenSource.Token @@ -1034,10 +1146,10 @@ namespace Microsoft.FSharp.Control static member Catch (computation: Async<'T>) = MakeAsync (fun ctxt -> - let cont = (Choice1Of2 >> ctxt.cont) - let econt (edi: ExceptionDispatchInfo) = ctxt.cont (Choice2Of2 (edi.GetAssociatedSourceException())) - let ctxt = { cont = cont; aux = { ctxt.aux with econt = econt } } - computation.Invoke ctxt) + // Turn the success or exception into data + let newCtxt = ctxt.WithContinuations(cont = (fun res -> ctxt.cont (Choice1Of2 res)), + econt = (fun edi -> ctxt.cont (Choice2Of2 (edi.GetAssociatedSourceException())))) + computation.Invoke newCtxt) static member RunSynchronously (computation: Async<'T>,?timeout,?cancellationToken:CancellationToken) = let timeout, cancellationToken = @@ -1071,49 +1183,48 @@ namespace Microsoft.FSharp.Control match result with | Some r -> r | None -> - if tasks.Length = 0 then - ctxt.cont [| |] - else // must not be in a 'protect' if we call cont explicitly; if cont throws, it should unwind the stack, preserving Dev10 behavior - ProtectUserCode ctxt (fun ctxt -> - let ctxtWithSync = delimitSyncContext ctxt // manually resync - let aux = ctxtWithSync.aux - let count = ref tasks.Length - let firstExn = ref None + if tasks.Length = 0 then + // must not be in a 'protect' if we call cont explicitly; if cont throws, it should unwind the stack, preserving Dev10 behavior + ctxt.cont [| |] + else + ProtectedCode ctxt (fun ctxt -> + let ctxtWithSync = DelimitSyncContext ctxt // manually resync + let mutable count = tasks.Length + let mutable firstExn = None let results = Array.zeroCreate tasks.Length // Attempt to cancel the individual operations if an exception happens on any of the other threads - let innerCTS = new LinkedSubSource(aux.token) - let trampolineHolder = aux.trampolineHolder + let innerCTS = new LinkedSubSource(ctxtWithSync.token) let finishTask(remaining) = if (remaining = 0) then innerCTS.Dispose() - match (!firstExn) with - | None -> trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont results) - | Some (Choice1Of2 exn) -> trampolineHolder.ExecuteWithTrampoline (fun () -> aux.econt exn) - | Some (Choice2Of2 cexn) -> trampolineHolder.ExecuteWithTrampoline (fun () -> aux.ccont cexn) + match firstExn with + | None -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont results) + | Some (Choice1Of2 exn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) + | Some (Choice2Of2 cexn) -> ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont cexn) else - FakeUnit + Unchecked.defaultof // recordSuccess and recordFailure between them decrement count to 0 and // as soon as 0 is reached dispose innerCancellationSource let recordSuccess i res = - results.[i] <- res; - finishTask(Interlocked.Decrement count) + results.[i] <- res + finishTask(Interlocked.Decrement &count) let recordFailure exn = // capture first exception and then decrement the counter to avoid race when // - thread 1 decremented counter and preempted by the scheduler // - thread 2 decremented counter and called finishTask // since exception is not yet captured - finishtask will fall into success branch - match Interlocked.CompareExchange(firstExn, Some exn, None) with + match Interlocked.CompareExchange(&firstExn, Some exn, None) with | None -> // signal cancellation before decrementing the counter - this guarantees that no other thread can sneak to finishTask and dispose innerCTS // NOTE: Cancel may introduce reentrancy - i.e. when handler registered for the cancellation token invokes cancel continuation that will call 'recordFailure' // to correctly handle this we need to return decremented value, not the current value of 'count' otherwise we may invoke finishTask with value '0' several times innerCTS.Cancel() | _ -> () - finishTask(Interlocked.Decrement count) + finishTask(Interlocked.Decrement &count) tasks |> Array.iteri (fun i p -> QueueAsync @@ -1125,8 +1236,8 @@ namespace Microsoft.FSharp.Control // on cancellation... (fun cexn -> recordFailure (Choice2Of2 cexn)) p - |> unfake); - FakeUnit)) + |> unfake) + Unchecked.defaultof)) static member Choice(computations : Async<'T option> seq) : Async<'T option> = MakeAsync (fun ctxt -> @@ -1138,44 +1249,42 @@ namespace Microsoft.FSharp.Control | Choice2Of2 edi -> ctxt.CallExceptionContinuation edi | Choice1Of2 [||] -> ctxt.cont None | Choice1Of2 computations -> - ProtectUserCode ctxt (fun ctxt -> - let ctxtWithSync = delimitSyncContext ctxt - let aux = ctxtWithSync.aux + ProtectedCode ctxt (fun ctxt -> + let ctxtWithSync = DelimitSyncContext ctxt let noneCount = ref 0 let exnCount = ref 0 - let innerCts = new LinkedSubSource(aux.token) - let trampolineHolder = aux.trampolineHolder + let innerCts = new LinkedSubSource(ctxtWithSync.token) let scont (result : 'T option) = match result with | Some _ -> if Interlocked.Increment exnCount = 1 then - innerCts.Cancel(); trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont result) + innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont result) else - FakeUnit + Unchecked.defaultof | None -> if Interlocked.Increment noneCount = computations.Length then - innerCts.Cancel(); trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont None) + innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.cont None) else - FakeUnit + Unchecked.defaultof let econt (exn : ExceptionDispatchInfo) = if Interlocked.Increment exnCount = 1 then - innerCts.Cancel(); trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.aux.econt exn) + innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.econt exn) else - FakeUnit + Unchecked.defaultof let ccont (exn : OperationCanceledException) = if Interlocked.Increment exnCount = 1 then - innerCts.Cancel(); trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.aux.ccont exn) + innerCts.Cancel(); ctxtWithSync.trampolineHolder.ExecuteWithTrampoline (fun () -> ctxtWithSync.ccont exn) else - FakeUnit + Unchecked.defaultof for c in computations do QueueAsync innerCts.Token scont econt ccont c |> unfake - FakeUnit)) + Unchecked.defaultof)) type Async with @@ -1193,8 +1302,8 @@ namespace Microsoft.FSharp.Control let task = ts.Task Async.StartWithContinuations( computation, - (fun (k) -> ts.SetResult(k)), - (fun exn -> ts.SetException(exn)), + (fun k -> ts.SetResult k), + (fun exn -> ts.SetException exn), (fun _ -> ts.SetCanceled()), cancellationToken) task @@ -1205,50 +1314,48 @@ namespace Microsoft.FSharp.Control static member Sleep(millisecondsDueTime) : Async = CreateDelimitedUserCodeAsync (fun ctxt -> - let aux = ctxt.aux - let timer = ref (None : Timer option) - let savedCont = ctxt.cont - let savedCCont = aux.ccont + let mutable timer = None : Timer option + let cont = ctxt.cont + let ccont = ctxt.ccont let latch = new Latch() let registration = - aux.token.Register( + ctxt.token.Register( (fun _ -> if latch.Enter() then - match !timer with + match timer with | None -> () | Some t -> t.Dispose() - aux.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCCont(new OperationCanceledException(aux.token))) |> unfake - ), + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> ccont(new OperationCanceledException(ctxt.token))) |> unfake), null) let mutable edi = null try - timer := new Timer((fun _ -> + timer <- new Timer((fun _ -> if latch.Enter() then // NOTE: If the CTS for the token would have been disposed, disposal of the registration would throw // However, our contract is that until async computation ceases execution (and invokes ccont) // the CTS will not be disposed. Execution of savedCCont is guarded by latch, so we are safe unless // user violates the contract. registration.Dispose() - // Try to Dispose of the TImer. + // Try to Dispose of the Timer. // Note: there is a race here: the Timer time very occasionally // calls the callback _before_ the timer object has been recorded anywhere. This makes it difficult to dispose the // timer in this situation. In this case we just let the timer be collected by finalization. - match !timer with + match timer with | None -> () | Some t -> t.Dispose() // Now we're done, so call the continuation - aux.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCont()) |> unfake), + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> cont()) |> unfake), null, dueTime=millisecondsDueTime, period = -1) |> Some with exn -> if latch.Enter() then - edi <- ExceptionDispatchInfo.RestoreOrCapture(exn) // post exception to econt only if we successfully enter the latch (no other continuations were called) + // post exception to econt only if we successfully enter the latch (no other continuations were called) + edi <- ExceptionDispatchInfo.RestoreOrCapture(exn) match edi with | null -> - FakeUnit + Unchecked.defaultof | _ -> - aux.econt edi - ) + ctxt.econt edi) /// Wait for a wait handle. Both timeout and cancellation are supported static member AwaitWaitHandle(waitHandle: WaitHandle, ?millisecondsTimeout:int) = @@ -1279,7 +1386,7 @@ namespace Microsoft.FSharp.Control match !rwh with | None -> () | Some rwh -> rwh.Unregister(null) |> ignore) - Async.Start (async { do (aux.ccont (OperationCanceledException(aux.token)) |> unfake) })) + Async.Start (async { do (ctxt.ccont (OperationCanceledException(aux.token)) |> unfake) })) and registration : CancellationTokenRegistration = aux.token.Register(cancelHandler, null) @@ -1293,17 +1400,17 @@ namespace Microsoft.FSharp.Control lock rwh (fun () -> rwh.Value.Value.Unregister(null) |> ignore) rwh := None registration.Dispose() - aux.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCont (not timeOut)) |> unfake), + ctxt.trampolineHolder.ExecuteWithTrampoline (fun () -> savedCont (not timeOut)) |> unfake), state=null, millisecondsTimeOutInterval=millisecondsTimeout, executeOnlyOnce=true)); - FakeUnit) + Unchecked.defaultof) with _ -> if latch.Enter() then registration.Dispose() reraise() // reraise exception only if we successfully enter the latch (no other continuations were called) else - FakeUnit + Unchecked.defaultof ) static member AwaitIAsyncResult(iar: IAsyncResult, ?millisecondsTimeout): Async = @@ -1319,7 +1426,7 @@ namespace Microsoft.FSharp.Control (match result with | Ok v -> ctxt.cont v | Error exn -> ctxt.CallExceptionContinuation exn - | Canceled exn -> ctxt.aux.ccont exn) ) + | Canceled exn -> ctxt.ccont exn) ) /// Await and use the result of a result cell. The resulting async doesn't support cancellation /// or timeout directly, rather the underlying computation must fill the result if cancellation @@ -1603,18 +1710,18 @@ namespace Microsoft.FSharp.Control let canceled = ref false // WebException with Status = WebExceptionStatus.RequestCanceled can be raised in other situations except cancellation, use flag to filter out false positives - // Use CreateTryWithDispatchInfoAsync to allow propagation of ExceptionDispatchInfo + // Use CreateTryWithFilterAsync to allow propagation of exception without losing stack Async.FromBeginEnd(beginAction=req.BeginGetResponse, endAction = req.EndGetResponse, cancelAction = fun() -> canceled := true; req.Abort()) - |> CreateTryWithDispatchInfoAsync (fun edi -> - match edi.SourceException with + |> CreateTryWithFilterAsync (fun exn -> + match exn with | :? System.Net.WebException as webExn when webExn.Status = System.Net.WebExceptionStatus.RequestCanceled && !canceled -> - Async.BindResult(AsyncResult.Canceled (OperationCanceledException webExn.Message)) + Some (Async.BindResult(AsyncResult.Canceled (OperationCanceledException webExn.Message))) | _ -> - edi.ThrowAny()) + None) #if !FX_NO_WEB_CLIENT diff --git a/src/fsharp/FSharp.Core/async.fsi b/src/fsharp/FSharp.Core/async.fsi index 9ce73b10cc2..53f68776288 100644 --- a/src/fsharp/FSharp.Core/async.fsi +++ b/src/fsharp/FSharp.Core/async.fsi @@ -25,9 +25,7 @@ namespace Microsoft.FSharp.Control /// computation expressions can check the cancellation condition regularly. Synchronous /// computations within an asynchronous computation do not automatically check this condition. - [] - [] - [] + [] type Async<'T> /// This static class holds members for creating and manipulating asynchronous computations. @@ -417,7 +415,6 @@ namespace Microsoft.FSharp.Control static member StartImmediate: computation:Async * ?cancellationToken:CancellationToken-> unit - /// Runs an asynchronous computation, starting immediately on the current operating system, /// but also returns the execution as System.Threading.Tasks.Task /// @@ -435,6 +432,112 @@ namespace Microsoft.FSharp.Control computation:Async<'T> * ?cancellationToken:CancellationToken-> Task<'T> + /// The F# compiler emits references to this type to implement F# async expressions. + type AsyncReturn + + /// The F# compiler emits references to this type to implement F# async expressions. + [] + type AsyncActivation<'T> = + + /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// A value indicating asynchronous execution. + member IsCancellationRequested: bool + + /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// A value indicating asynchronous execution. + member OnSuccess: 'T -> AsyncReturn + + /// The F# compiler emits calls to this function to implement F# async expressions. + member OnExceptionRaised: unit -> unit + + /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// A value indicating asynchronous execution. + member OnCancellation: unit -> AsyncReturn + + /// Used by MailboxProcessor + member internal QueueContinuationWithTrampoline: 'T -> AsyncReturn + /// Used by MailboxProcessor + member internal CallContinuation: 'T -> AsyncReturn + + [] + // Internals used by MailboxProcessor + type internal AsyncResult<'T> = + | Ok of 'T + | Error of ExceptionDispatchInfo + | Canceled of OperationCanceledException + + [] + /// Entry points for generated code + module AsyncPrimitives = + + /// The F# compiler emits calls to this function to implement F# async expressions. + /// + /// The body of the async computation. + /// + /// The async computation. + val MakeAsync: body:(AsyncActivation<'T> -> AsyncReturn) -> Async<'T> + + /// The F# compiler emits calls to this function to implement constructs for F# async expressions. + /// + /// The async computation. + /// The async activation. + /// + /// A value indicating asynchronous execution. + val Invoke: computation: Async<'T> -> ctxt:AsyncActivation<'T> -> AsyncReturn + + /// The F# compiler emits calls to this function to implement constructs for F# async expressions. + /// + /// The async activation. + /// The result of the first part of the computation. + /// A function returning the second part of the computation. + /// + /// A value indicating asynchronous execution. + val CallThenInvoke: ctxt:AsyncActivation<'T> -> result1:'U -> part2:('U -> Async<'T>) -> AsyncReturn + + /// The F# compiler emits calls to this function to implement the let! construct for F# async expressions. + /// + /// The async activation. + /// A function returning the second part of the computation. + /// + /// An async activation suitable for running part1 of the asynchronous execution. + val Bind: ctxt:AsyncActivation<'T> -> part1:Async<'U> -> part2:('U -> Async<'T>) -> AsyncReturn + + /// The F# compiler emits calls to this function to implement the try/finally construct for F# async expressions. + /// + /// The async activation. + /// The computation to protect. + /// The finally code. + /// + /// A value indicating asynchronous execution. + val TryFinally: ctxt:AsyncActivation<'T> -> computation: Async<'T> -> finallyFunction: (unit -> unit) -> AsyncReturn + + /// The F# compiler emits calls to this function to implement the try/with construct for F# async expressions. + /// + /// The async activation. + /// The computation to protect. + /// The exception filter. + /// + /// A value indicating asynchronous execution. + val TryWith: ctxt:AsyncActivation<'T> -> computation: Async<'T> -> catchFunction: (Exception -> Async<'T> option) -> AsyncReturn + + [] + // Internals used by MailboxProcessor + type internal ResultCell<'T> = + new : unit -> ResultCell<'T> + member GetWaitHandle: unit -> WaitHandle + member Close: unit -> unit + interface IDisposable + member RegisterResult: 'T * reuseThread: bool -> AsyncReturn + member GrabResult: unit -> 'T + member ResultAvailable : bool + member AwaitResult_NoDirectCancelOrTimeout : Async<'T> + member TryWaitForResultSynchronously: ?timeout: int -> 'T option + + // Internals used by MailboxProcessor + val internal CreateAsyncResultAsync : AsyncResult<'T> -> Async<'T> [] [] @@ -473,7 +576,7 @@ namespace Microsoft.FSharp.Control /// The first part of the sequenced computation. /// The second part of the sequenced computation. /// An asynchronous computation that runs both of the computations sequentially. - member Combine : computation1:Async * computation2:Async<'T> -> Async<'T> + member inline Combine : computation1:Async * computation2:Async<'T> -> Async<'T> /// Creates an asynchronous computation that runs computation repeatedly /// until guard() becomes false. @@ -496,7 +599,7 @@ namespace Microsoft.FSharp.Control /// async { ... } computation expression syntax. /// The value to return from the computation. /// An asynchronous computation that returns value when executed. - member Return : value:'T -> Async<'T> + member inline Return : value:'T -> Async<'T> /// Delegates to the input computation. /// @@ -504,7 +607,7 @@ namespace Microsoft.FSharp.Control /// async { ... } computation expression syntax. /// The input computation. /// The input computation. - member ReturnFrom : computation:Async<'T> -> Async<'T> + member inline ReturnFrom : computation:Async<'T> -> Async<'T> /// Creates an asynchronous computation that runs generator. /// @@ -538,7 +641,7 @@ namespace Microsoft.FSharp.Control /// The function to bind the result of computation. /// An asynchronous computation that performs a monadic bind on the result /// of computation. - member Bind: computation: Async<'T> * binder: ('T -> Async<'U>) -> Async<'U> + member inline Bind: computation: Async<'T> * binder: ('T -> Async<'U>) -> Async<'U> /// Creates an asynchronous computation that runs computation. The action compensation is executed /// after computation completes, whether computation exits normally or by an exception. If compensation raises an exception itself @@ -553,7 +656,7 @@ namespace Microsoft.FSharp.Control /// exception (including cancellation). /// An asynchronous computation that executes computation and compensation afterwards or /// when an exception is raised. - member TryFinally : computation:Async<'T> * compensation:(unit -> unit) -> Async<'T> + member inline TryFinally : computation:Async<'T> * compensation:(unit -> unit) -> Async<'T> /// Creates an asynchronous computation that runs computation and returns its result. /// If an exception happens then catchHandler(exn) is called and the resulting computation executed instead. @@ -562,11 +665,14 @@ namespace Microsoft.FSharp.Control /// /// The existence of this method permits the use of try/with in the /// async { ... } computation expression syntax. + /// /// The input computation. /// The function to run when computation throws an exception. /// An asynchronous computation that executes computation and calls catchHandler if an /// exception is thrown. - member TryWith : computation:Async<'T> * catchHandler:(exn -> Async<'T>) -> Async<'T> + member inline TryWith : computation:Async<'T> * catchHandler:(exn -> Async<'T>) -> Async<'T> + + // member inline TryWithFilter : computation:Async<'T> * catchHandler:(exn -> Async<'T> option) -> Async<'T> /// Generate an object used to build asynchronous computations using F# computation expressions. The value /// 'async' is a pre-defined instance of this type. @@ -659,41 +765,6 @@ namespace Microsoft.FSharp.Control #endif // Internals used by MailboxProcessor - module internal AsyncImpl = + module internal AsyncBuilderImpl = val async : AsyncBuilder - [] - // Internals used by MailboxProcessor - type internal AsyncReturn - - [] - // Internals used by MailboxProcessor - type internal AsyncActivation<'T> = - member QueueContinuationWithTrampoline: 'T -> AsyncReturn - member CallContinuation: 'T -> AsyncReturn - - [] - // Internals used by MailboxProcessor - type internal AsyncResult<'T> = - | Ok of 'T - | Error of ExceptionDispatchInfo - | Canceled of OperationCanceledException - - // Internals used by MailboxProcessor - module internal AsyncPrimitives = - - [] - type internal ResultCell<'T> = - new : unit -> ResultCell<'T> - member GetWaitHandle: unit -> WaitHandle - member Close: unit -> unit - interface IDisposable - member RegisterResult: 'T * reuseThread: bool -> AsyncReturn - member GrabResult: unit -> 'T - member ResultAvailable : bool - member AwaitResult_NoDirectCancelOrTimeout : Async<'T> - member TryWaitForResultSynchronously: ?timeout: int -> 'T option - - val CreateAsyncResultAsync : AsyncResult<'T> -> Async<'T> - - val MakeAsync : (AsyncActivation<'T> -> AsyncReturn) -> Async<'T> diff --git a/src/fsharp/FSharp.Core/mailbox.fs b/src/fsharp/FSharp.Core/mailbox.fs index c83bc49e5fb..f58a94b6f12 100644 --- a/src/fsharp/FSharp.Core/mailbox.fs +++ b/src/fsharp/FSharp.Core/mailbox.fs @@ -7,7 +7,7 @@ namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators open Microsoft.FSharp.Control - open Microsoft.FSharp.Control.AsyncImpl + open Microsoft.FSharp.Control.AsyncBuilderImpl open Microsoft.FSharp.Control.AsyncPrimitives open Microsoft.FSharp.Collections diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index bb79e0f84d7..34b7e82beae 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -2764,17 +2764,17 @@ namespace Microsoft.FSharp.Core // Function Values [] - type FSharpTypeFunc() = + type FSharpTypeFunc [] () = abstract Specialize<'T> : unit -> obj [] - type FSharpFunc<'T,'Res>() = + type FSharpFunc<'T,'Res> [] () = abstract Invoke : 'T -> 'Res module OptimizedClosures = [] - type FSharpFunc<'T,'U,'V>() = + type FSharpFunc<'T,'U,'V> [] () = inherit FSharpFunc<'T,('U -> 'V)>() abstract Invoke : 'T * 'U -> 'V override f.Invoke(t) = (fun u -> f.Invoke(t,u)) @@ -2787,7 +2787,7 @@ namespace Microsoft.FSharp.Core member x.Invoke(t,u) = (retype func : FSharpFunc<'T,FSharpFunc<'U,'V>>).Invoke(t).Invoke(u) } [] - type FSharpFunc<'T,'U,'V,'W>() = + type FSharpFunc<'T,'U,'V,'W> [] () = inherit FSharpFunc<'T,('U -> 'V -> 'W)>() abstract Invoke : 'T * 'U * 'V -> 'W override f.Invoke(t) = (fun u v -> f.Invoke(t,u,v)) @@ -2805,7 +2805,7 @@ namespace Microsoft.FSharp.Core member x.Invoke(t,u,v) = (retype func : FSharpFunc<'T,('U -> 'V -> 'W)>).Invoke(t) u v } [] - type FSharpFunc<'T,'U,'V,'W,'X>() = + type FSharpFunc<'T,'U,'V,'W,'X> [] () = inherit FSharpFunc<'T,('U -> 'V -> 'W -> 'X)>() abstract Invoke : 'T * 'U * 'V * 'W -> 'X static member Adapt(func : 'T -> 'U -> 'V -> 'W -> 'X) = @@ -2828,7 +2828,7 @@ namespace Microsoft.FSharp.Core override f.Invoke(t) = (fun u v w -> f.Invoke(t,u,v,w)) [] - type FSharpFunc<'T,'U,'V,'W,'X,'Y>() = + type FSharpFunc<'T,'U,'V,'W,'X,'Y> [] () = inherit FSharpFunc<'T,('U -> 'V -> 'W -> 'X -> 'Y)>() abstract Invoke : 'T * 'U * 'V * 'W * 'X -> 'Y override f.Invoke(t) = (fun u v w x -> f.Invoke(t,u,v,w,x)) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index c9738c1b8ba..e0373b38de1 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -567,6 +567,29 @@ Microsoft.FSharp.Collections.SetModule: TState FoldBack[T,TState](Microsoft.FSha Microsoft.FSharp.Collections.SetModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpSet`1[T]) Microsoft.FSharp.Collections.SetModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) Microsoft.FSharp.Collections.SetModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean IsCancellationRequested +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean get_IsCancellationRequested() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnCancellation() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Void OnExceptionRaised() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnSuccess(T) +Microsoft.FSharp.Control.AsyncActivation`1[T]: System.String ToString() +Microsoft.FSharp.Control.AsyncActivation`1[T]: System.Type GetType() +Microsoft.FSharp.Control.AsyncPrimitives: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncPrimitives: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Bind[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn CallThenInvoke[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], TResult, Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Invoke[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Control.AsyncActivation`1[T]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryFinally[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryWith[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.FSharpAsync`1[T] MakeAsync[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.AsyncActivation`1[T],Microsoft.FSharp.Control.AsyncReturn]) +Microsoft.FSharp.Control.AsyncPrimitives: System.String ToString() +Microsoft.FSharp.Control.AsyncPrimitives: System.Type GetType() +Microsoft.FSharp.Control.AsyncReturn: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncReturn: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncReturn: System.String ToString() +Microsoft.FSharp.Control.AsyncReturn: System.Type GetType() Microsoft.FSharp.Control.CommonExtensions: Boolean Equals(System.Object) Microsoft.FSharp.Control.CommonExtensions: Int32 GetHashCode() Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncWrite(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 27527ff429a..3608ab710fd 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -554,6 +554,29 @@ Microsoft.FSharp.Collections.SetModule: TState FoldBack[T,TState](Microsoft.FSha Microsoft.FSharp.Collections.SetModule: TState Fold[T,TState](Microsoft.FSharp.Core.FSharpFunc`2[TState,Microsoft.FSharp.Core.FSharpFunc`2[T,TState]], TState, Microsoft.FSharp.Collections.FSharpSet`1[T]) Microsoft.FSharp.Collections.SetModule: T[] ToArray[T](Microsoft.FSharp.Collections.FSharpSet`1[T]) Microsoft.FSharp.Collections.SetModule: Void Iterate[T](Microsoft.FSharp.Core.FSharpFunc`2[T,Microsoft.FSharp.Core.Unit], Microsoft.FSharp.Collections.FSharpSet`1[T]) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean IsCancellationRequested +Microsoft.FSharp.Control.AsyncActivation`1[T]: Boolean get_IsCancellationRequested() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnCancellation() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Void OnExceptionRaised() +Microsoft.FSharp.Control.AsyncActivation`1[T]: Microsoft.FSharp.Control.AsyncReturn OnSuccess(T) +Microsoft.FSharp.Control.AsyncActivation`1[T]: System.String ToString() +Microsoft.FSharp.Control.AsyncActivation`1[T]: System.Type GetType() +Microsoft.FSharp.Control.AsyncPrimitives: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncPrimitives: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Bind[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[TResult], Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn CallThenInvoke[T,TResult](Microsoft.FSharp.Control.AsyncActivation`1[T], TResult, Microsoft.FSharp.Core.FSharpFunc`2[TResult,Microsoft.FSharp.Control.FSharpAsync`1[T]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn Invoke[T](Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Control.AsyncActivation`1[T]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryFinally[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,Microsoft.FSharp.Core.Unit]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.AsyncReturn TryWith[T](Microsoft.FSharp.Control.AsyncActivation`1[T], Microsoft.FSharp.Control.FSharpAsync`1[T], Microsoft.FSharp.Core.FSharpFunc`2[System.Exception,Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Control.FSharpAsync`1[T]]]) +Microsoft.FSharp.Control.AsyncPrimitives: Microsoft.FSharp.Control.FSharpAsync`1[T] MakeAsync[T](Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Control.AsyncActivation`1[T],Microsoft.FSharp.Control.AsyncReturn]) +Microsoft.FSharp.Control.AsyncPrimitives: System.String ToString() +Microsoft.FSharp.Control.AsyncPrimitives: System.Type GetType() +Microsoft.FSharp.Control.AsyncReturn: Boolean Equals(System.Object) +Microsoft.FSharp.Control.AsyncReturn: Int32 GetHashCode() +Microsoft.FSharp.Control.AsyncReturn: System.String ToString() +Microsoft.FSharp.Control.AsyncReturn: System.Type GetType() Microsoft.FSharp.Control.CommonExtensions: Boolean Equals(System.Object) Microsoft.FSharp.Control.CommonExtensions: Int32 GetHashCode() Microsoft.FSharp.Control.CommonExtensions: Microsoft.FSharp.Control.FSharpAsync`1[Microsoft.FSharp.Core.Unit] AsyncWrite(System.IO.Stream, Byte[], Microsoft.FSharp.Core.FSharpOption`1[System.Int32], Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) diff --git a/tests/fsharp/TypeProviderTests.fs b/tests/fsharp/TypeProviderTests.fs index 00633234ea3..3055e5c192f 100644 --- a/tests/fsharp/TypeProviderTests.fs +++ b/tests/fsharp/TypeProviderTests.fs @@ -30,6 +30,7 @@ let FSI_BASIC = FSI_FILE let FSIANYCPU_BASIC = FSIANYCPU_FILE #endif +(* [] let diamondAssembly () = let cfg = testConfig "typeProviders/diamondAssembly" @@ -356,3 +357,4 @@ let wedgeAssembly () = peverify cfg "test3.exe" exec cfg ("." ++ "test3.exe") "" +*) diff --git a/tests/fsharp/core/asyncStackTraces/test.fsx b/tests/fsharp/core/asyncStackTraces/test.fsx new file mode 100644 index 00000000000..56b3810bf55 --- /dev/null +++ b/tests/fsharp/core/asyncStackTraces/test.fsx @@ -0,0 +1,170 @@ + +// Tests that async stack traces contain certain method names + +// See https://github.com/Microsoft/visualfsharp/pull/4867 + +// The focus of the tests is on the synchronous parts of async execution, and on exceptions. + +let mutable failures = [] +let syncObj = new obj() +let report_failure s = + stderr.WriteLine " NO"; + lock syncObj (fun () -> + failures <- s :: failures; + printfn "FAILURE: %s failed" s + ) + +let test s b = stderr.Write(s:string); if b then stderr.WriteLine " OK" else report_failure s + +let checkQuiet s x1 x2 = + if x1 <> x2 then + (test s false; + printfn "expected: %A, got %A" x2 x1) + +let check s x1 x2 = + if x1 = x2 then test s true + else (test s false; printfn "expected: %A, got %A" x2 x1) + + +let rec async_syncLoopViaTailCallFail(n) = async { + if n > 10 then + let! res = failwith "fail" + return res + else + return! async_syncLoopViaTailCallFail(n+1) +} + +let rec async_syncLoopViaNonTailCallFail(n) = async { + if n > 10 then + let! res = failwith "fail" + return Unchecked.defaultof<_> + else + let! n2 = async_syncLoopViaNonTailCallFail(n+1) + return n2 +} + +let rec async_syncWhileLoopFail() = async { + let mutable n = 0 + while true do + if n > 10 then + let! res = failwith "fail" + return res + else + n <- n + 1 +} + +let rec async_syncTryFinallyFail() = async { + try + failwith "fail" + finally + () +} + +// Raising an exception counts as an "asynchronous action" which wipes out the stack. +// +// This is because of a limitation in the .NET exception mechanism where stack traces are only populated +// up to the point where they are caught, so we need to catch them in the trampoline handler to get a good stack. +// +// This means that re-raising that exception (e.g. in a failed pattern match for a try-with) +// or throwing an exception from the "with" handler will not get a good stack. +// There is not yet any good workaround for this. +// +//let rec async_syncTryWithFail() = async { +// try +// failwith "fail" +// with _ -> () +//} + +let rec async_syncPreAsyncSleepFail() = async { + let! x = failwith "fail" // failure is in synchronous part of code + do! Async.Sleep 10 + return Unchecked.defaultof<_> +} + +let rec async_syncFail() = async { + failwith "fail" +} + +let asyncCheckEnvironmentStackTracesBottom() = async { + let stack = System.Diagnostics.StackTrace(true).ToString() + //test "vwerv0re0reer: stack = %s", stack); + test "clncw09ew09c1" (stack.Contains("asyncCheckEnvironmentStackTracesBottom")) + test "clncw09ew09c2" (stack.Contains(string (int __LINE__ - 3))) + test "clncw09ew09d3" (stack.Contains("asyncCheckEnvironmentStackTracesMid")) + test "clncw09ew09e4" (stack.Contains("asyncCheckEnvironmentStackTracesTop")) + return 1 +} + +let asyncCheckEnvironmentStackTracesMid() = async { + let! res = asyncCheckEnvironmentStackTracesBottom() + let stack = System.Diagnostics.StackTrace(true).ToString() + test "clncw09ew09d2" (stack.Contains("asyncCheckEnvironmentStackTracesMid")) + test "clncw09ew09c" (stack.Contains(string (int __LINE__ - 2))) + test "clncw09ew09e2" (stack.Contains("asyncCheckEnvironmentStackTracesTop")) + return res +} + +let asyncCheckEnvironmentStackTracesTop() = async { + let! res = asyncCheckEnvironmentStackTracesMid() + let stack = System.Diagnostics.StackTrace(true).ToString() + test "clncw09ew09f" (stack.Contains("asyncCheckEnvironmentStackTracesTop")) + test "clncw09ew09c" (stack.Contains(string (int __LINE__ - 2))) + + do! Async.Sleep 10 + let stack = System.Diagnostics.StackTrace(true).ToString() + test "clncw09ew09f" (stack.Contains("asyncCheckEnvironmentStackTracesTop")) + test "clncw09ew09c" (stack.Contains(string (int __LINE__ - 2))) + +} + +let asyncMid(f) = async { + + let! res = f() + () +} +let asyncTop2(f) = async { + + let! res = asyncMid(f) + return () +} + +let asyncTop3(f) = async { + + do! Async.Sleep 10 + let! res = asyncMid(f) + return () +} + + + +asyncCheckEnvironmentStackTracesTop() |> Async.RunSynchronously + +let testCasesThatRaiseExceptions = + [ ("async_syncFail", async_syncFail) + ("async_syncLoopViaTailCallFail", (fun () -> async_syncLoopViaTailCallFail(0))) + ("async_syncLoopViaNonTailCallFail", (fun () -> async_syncLoopViaNonTailCallFail(0))) + ("async_syncWhileLoopFail", async_syncWhileLoopFail) + ("async_syncTryFinallyFail", async_syncTryFinallyFail) + ("async_syncPreAsyncSleepFail", async_syncPreAsyncSleepFail) ] + +for (asyncTopName, asyncTop) in [("asyncTop2", asyncTop2); ("asyncTop3", asyncTop3) ] do + for functionName, asyncFunction in testCasesThatRaiseExceptions do + try + asyncTop(asyncFunction) |> Async.RunSynchronously |> ignore + failwith "should have raised exception" + with e -> + let stack = e.StackTrace + test (sprintf "case %s: clncw09ew09m0" functionName) (not (stack.Contains("line 0"))) + test (sprintf "case %s: clncw09ew09m1" functionName) (stack.Contains(functionName)) + test (sprintf "case %s: clncw09ew09n2" functionName) (stack.Contains("asyncMid")) + test (sprintf "case %s: clncw09ew09n3" functionName) (stack.Contains(asyncTopName)) + +let aa = + if not failures.IsEmpty then + stdout.WriteLine "Test Failed" + exit 1 + else + stdout.WriteLine "Test Passed" + System.IO.File.WriteAllText("test.ok","ok") + exit 0 + diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 15fcd5b8e65..bddb9bbe594 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -170,9 +170,7 @@ module CoreTests = [] let ``attributes-FSI_BASIC`` () = singleTestBuildAndRun "core/attributes" FSI_BASIC -#endif -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS [] let byrefs () = @@ -189,6 +187,19 @@ module CoreTests = fsi cfg "" ["test.fsx"] testOkFile.CheckExists() + + [] + let asyncStackTraces () = + let cfg = testConfig "core/asyncStackTraces" + + use testOkFile = fileguard cfg "test.ok" + + fsc cfg "%s -o:test.exe -g --tailcalls- --optimize-" cfg.fsc_flags ["test.fsx"] + + exec cfg ("." ++ "test.exe") "" + + testOkFile.CheckExists() + #endif [] diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl index ec794be06a1..3e69ae4967f 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest1.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest1 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest1 { - // Offset: 0x00000000 Length: 0x0000024A + // Offset: 0x00000000 Length: 0x0000026C } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest1 { - // Offset: 0x00000250 Length: 0x000000B1 + // Offset: 0x00000270 Length: 0x000000B1 } .module AsyncExpressionSteppingTest1.dll -// MVID: {5A1F62A7-6394-B5D4-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-B5D4-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x05190000 +// Image base: 0x02880000 // =============== CLASS MEMBERS DECLARATION =================== @@ -83,7 +83,7 @@ // Code size 62 (0x3e) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 17,32 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs' + .line 6,6 : 17,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs' IL_0000: ldstr "hello" IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5::.ctor(string) IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl index 6a87f0671a8..7bdb6a074c0 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest2.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest2 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest2 { - // Offset: 0x00000000 Length: 0x0000024A + // Offset: 0x00000000 Length: 0x0000026C } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest2 { - // Offset: 0x00000250 Length: 0x000000B1 + // Offset: 0x00000270 Length: 0x000000B1 } .module AsyncExpressionSteppingTest2.dll -// MVID: {5A1F62A7-6394-D499-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-D499-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00F10000 +// Image base: 0x04520000 // =============== CLASS MEMBERS DECLARATION =================== @@ -80,7 +80,7 @@ // Code size 15 (0xf) .maxstack 8 .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 23,29 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs' + .line 6,6 : 23,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs' IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest2/AsyncExpressionSteppingTest2/'f2@6-1'::x IL_0006: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl index 83b7070f112..6dfebd88b1e 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest3.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest3 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest3 { - // Offset: 0x00000000 Length: 0x00000255 + // Offset: 0x00000000 Length: 0x00000277 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest3 { - // Offset: 0x00000260 Length: 0x000000B1 + // Offset: 0x00000280 Length: 0x000000B1 } .module AsyncExpressionSteppingTest3.dll -// MVID: {5A1F62A7-6394-F35E-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-F35E-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x01210000 +// Image base: 0x04650000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,6 +55,44 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@10-1' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public int32 'value' + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/'f3@10-1'::'value' + IL_000d: ret + } // end of method 'f3@10-1'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest3.fs' + IL_0000: ldarga.s ctxt + IL_0002: ldarg.0 + IL_0003: ldfld int32 AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/'f3@10-1'::'value' + IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) + IL_000d: ret + } // end of method 'f3@10-1'::Invoke + + } // end of class 'f3@10-1' + .class auto ansi serializable sealed nested assembly beforefieldinit f3@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -80,13 +118,14 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 57 (0x39) + // Code size 67 (0x43) .maxstack 6 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, - [2] int32 z) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 17,30 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest3.fs' + [2] int32 z, + [3] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, + [4] int32 V_4) + .line 5,5 : 17,30 '' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -112,10 +151,14 @@ .line 10,10 : 17,25 '' IL_002a: ldarg.0 IL_002b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/f3@5::builder@ - IL_0030: ldloc.2 - IL_0031: tail. - IL_0033: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) - IL_0038: ret + IL_0030: stloc.3 + IL_0031: ldloc.2 + IL_0032: stloc.s V_4 + IL_0034: ldloc.s V_4 + IL_0036: newobj instance void AsyncExpressionSteppingTest3/AsyncExpressionSteppingTest3/'f3@10-1'::.ctor(int32) + IL_003b: tail. + IL_003d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0042: ret } // end of method f3@5::Invoke } // end of class f3@5 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl index 02e29ae2280..ce54bd4945d 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest4.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest4 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest4 { - // Offset: 0x00000000 Length: 0x00000255 + // Offset: 0x00000000 Length: 0x00000277 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest4 { - // Offset: 0x00000260 Length: 0x000000B1 + // Offset: 0x00000280 Length: 0x000000B1 } .module AsyncExpressionSteppingTest4.dll -// MVID: {5A1F62A7-6394-6D4B-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-6D4B-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x038C0000 +// Image base: 0x028F0000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,6 +55,44 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@10-2' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public int32 'value' + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@10-2'::'value' + IL_000d: ret + } // end of method 'f4@10-2'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 10,10 : 21,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest4.fs' + IL_0000: ldarga.s ctxt + IL_0002: ldarg.0 + IL_0003: ldfld int32 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@10-2'::'value' + IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) + IL_000d: ret + } // end of method 'f4@10-2'::Invoke + + } // end of class 'f4@10-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@7-1' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -85,12 +123,13 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 48 (0x30) + // Code size 56 (0x38) .maxstack 6 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, - [1] int32 z) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 7,7 : 21,34 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest4.fs' + [1] int32 z, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, + [3] int32 V_3) + .line 7,7 : 21,34 '' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -109,15 +148,19 @@ .line 10,10 : 21,29 '' IL_0021: ldarg.0 IL_0022: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@7-1'::builder@ - IL_0027: ldloc.1 - IL_0028: tail. - IL_002a: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) - IL_002f: ret + IL_0027: stloc.2 + IL_0028: ldloc.1 + IL_0029: stloc.3 + IL_002a: ldloc.3 + IL_002b: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@10-2'::.ctor(int32) + IL_0030: tail. + IL_0032: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0037: ret } // end of method 'f4@7-1'::Invoke } // end of class 'f4@7-1' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@12-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 { .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x @@ -132,9 +175,9 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-2'::x + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-3'::x IL_000d: ret - } // end of method 'f4@12-2'::.ctor + } // end of method 'f4@12-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed @@ -143,7 +186,7 @@ .maxstack 8 .line 12,12 : 20,26 '' IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-2'::x + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-3'::x IL_0006: call void [FSharp.Core]Microsoft.FSharp.Core.Operators::Increment(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) IL_000b: nop .line 13,13 : 20,34 '' @@ -152,9 +195,59 @@ IL_0016: tail. IL_0018: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4) IL_001d: ret - } // end of method 'f4@12-2'::Invoke + } // end of method 'f4@12-3'::Invoke - } // end of class 'f4@12-2' + } // end of class 'f4@12-3' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f4@6-4' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 compensation) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@6-4'::computation + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@6-4'::compensation + IL_0014: ret + } // end of method 'f4@6-4'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 6,6 : 17,20 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@6-4'::computation + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@6-4'::compensation + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::TryFinally(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_0014: ret + } // end of method 'f4@6-4'::Invoke + + } // end of class 'f4@6-4' .class auto ansi serializable sealed nested assembly beforefieldinit f4@5 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> @@ -181,9 +274,12 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 50 (0x32) - .maxstack 8 - .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x) + // Code size 60 (0x3c) + .maxstack 7 + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 V_3) .line 5,5 : 17,30 '' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) @@ -191,20 +287,26 @@ .line 6,6 : 17,20 '' IL_0007: ldarg.0 IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/f4@5::builder@ - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/f4@5::builder@ - IL_0013: ldarg.0 - IL_0014: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/f4@5::builder@ - IL_0019: ldloc.0 - IL_001a: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_000d: stloc.1 + IL_000e: ldarg.0 + IL_000f: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/f4@5::builder@ + IL_0014: ldarg.0 + IL_0015: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/f4@5::builder@ + IL_001a: ldloc.0 + IL_001b: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@7-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_001f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0024: ldloc.0 - IL_0025: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002a: tail. - IL_002c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::TryFinally(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) - IL_0031: ret + IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0025: stloc.2 + IL_0026: ldloc.0 + IL_0027: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@12-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) + IL_002c: stloc.3 + IL_002d: ldloc.2 + IL_002e: ldloc.3 + IL_002f: newobj instance void AsyncExpressionSteppingTest4/AsyncExpressionSteppingTest4/'f4@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2) + IL_0034: tail. + IL_0036: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_003b: ret } // end of method f4@5::Invoke } // end of class f4@5 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl index 50407f757c2..da554a3adf4 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest5.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest5 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest5 { - // Offset: 0x00000000 Length: 0x00000296 + // Offset: 0x00000000 Length: 0x000002B8 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest5 { - // Offset: 0x000002A0 Length: 0x000000BE + // Offset: 0x000002C0 Length: 0x000000BE } .module AsyncExpressionSteppingTest5.dll -// MVID: {5A1F62A7-6394-30E8-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-30E8-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x00C60000 +// Image base: 0x04430000 // =============== CLASS MEMBERS DECLARATION =================== @@ -84,7 +84,7 @@ .maxstack 5 .locals init ([0] int32 x) .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 6,6 : 17,31 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest5.fs' + .line 6,6 : 17,31 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest5.fs' IL_0000: ldarg.1 IL_0001: stloc.0 .line 7,7 : 20,35 '' @@ -198,6 +198,91 @@ } // end of class 'f7@9-2' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-4' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2 + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation2) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-4'::computation2 + IL_000d: ret + } // end of method 'f7@6-4'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 + Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar0) cil managed + { + // Code size 7 (0x7) + .maxstack 8 + .line 6,6 : 17,31 '' + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-4'::computation2 + IL_0006: ret + } // end of method 'f7@6-4'::Invoke + + } // end of class 'f7@6-4' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f7@6-5' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1 + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2 + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> part2) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-5'::computation1 + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-5'::part2 + IL_0014: ret + } // end of method 'f7@6-5'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 6,6 : 17,31 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-5'::computation1 + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-5'::part2 + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0014: ret + } // end of method 'f7@6-5'::Invoke + + } // end of class 'f7@6-5' + .class auto ansi serializable sealed nested assembly beforefieldinit f7@6 extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -223,29 +308,42 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 63 (0x3f) - .maxstack 8 + // Code size 80 (0x50) + .maxstack 7 + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) .line 6,6 : 17,31 '' IL_0000: ldarg.0 IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ - IL_0006: ldarg.0 - IL_0007: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ - IL_000c: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5::get_es() - IL_0011: ldarg.0 - IL_0012: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ - IL_0017: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_001c: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [mscorlib]System.Collections.Generic.IEnumerable`1, + IL_0006: stloc.0 + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ + IL_000d: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5::get_es() + IL_0012: ldarg.0 + IL_0013: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ + IL_0018: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_001d: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::For(class [mscorlib]System.Collections.Generic.IEnumerable`1, class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0021: ldarg.0 - IL_0022: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ - IL_0027: ldarg.0 - IL_0028: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ - IL_002d: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0032: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0037: tail. - IL_0039: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Combine(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) - IL_003e: ret + IL_0022: stloc.1 + IL_0023: ldarg.0 + IL_0024: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ + IL_0029: ldarg.0 + IL_002a: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/f7@6::builder@ + IL_002f: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@9-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0034: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0039: stloc.2 + IL_003a: ldloc.2 + IL_003b: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1) + IL_0040: stloc.3 + IL_0041: ldloc.1 + IL_0042: ldloc.3 + IL_0043: newobj instance void AsyncExpressionSteppingTest5/AsyncExpressionSteppingTest5/'f7@6-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0048: tail. + IL_004a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_004f: ret } // end of method f7@6::Invoke } // end of class f7@6 diff --git a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl index e027d172025..379ad6bbe7c 100644 --- a/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl +++ b/tests/fsharpqa/Source/CodeGen/EmittedIL/AsyncExpressionStepping/AsyncExpressionSteppingTest6.il.bsl @@ -13,7 +13,7 @@ .assembly extern FSharp.Core { .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: - .ver 4:4:1:0 + .ver 4:4:3:0 } .assembly AsyncExpressionSteppingTest6 { @@ -29,20 +29,20 @@ } .mresource public FSharpSignatureData.AsyncExpressionSteppingTest6 { - // Offset: 0x00000000 Length: 0x00000281 + // Offset: 0x00000000 Length: 0x000002A3 } .mresource public FSharpOptimizationData.AsyncExpressionSteppingTest6 { - // Offset: 0x00000288 Length: 0x000000BE + // Offset: 0x000002A8 Length: 0x000000BE } .module AsyncExpressionSteppingTest6.dll -// MVID: {5A1F62A7-6394-4FAD-A745-0383A7621F5A} +// MVID: {5AF5DDAE-6394-4FAD-A745-0383AEDDF55A} .imagebase 0x00400000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY -// Image base: 0x03740000 +// Image base: 0x04C40000 // =============== CLASS MEMBERS DECLARATION =================== @@ -55,6 +55,44 @@ extends [mscorlib]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@10-4' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public int32 'value' + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::'value' + IL_000d: ret + } // end of method 'f2@10-4'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' + .line 10,10 : 17,25 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest6.fs' + IL_0000: ldarga.s ctxt + IL_0002: ldarg.0 + IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::'value' + IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) + IL_000d: ret + } // end of method 'f2@10-4'::Invoke + + } // end of class 'f2@10-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f2@5-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { @@ -80,13 +118,14 @@ .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 57 (0x39) + // Code size 67 (0x43) .maxstack 6 .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 x, [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, - [2] int32 z) - .language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}' - .line 5,5 : 17,30 'C:\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest6.fs' + [2] int32 z, + [3] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_3, + [4] int32 V_4) + .line 5,5 : 17,30 '' IL_0000: ldc.i4.0 IL_0001: call class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 [FSharp.Core]Microsoft.FSharp.Core.Operators::Ref(!!0) IL_0006: stloc.0 @@ -112,15 +151,56 @@ .line 10,10 : 17,25 '' IL_002a: ldarg.0 IL_002b: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@5-3'::builder@ - IL_0030: ldloc.2 - IL_0031: tail. - IL_0033: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) - IL_0038: ret + IL_0030: stloc.3 + IL_0031: ldloc.2 + IL_0032: stloc.s V_4 + IL_0034: ldloc.s V_4 + IL_0036: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f2@10-4'::.ctor(int32) + IL_003b: tail. + IL_003d: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0042: ret } // end of method 'f2@5-3'::Invoke } // end of class 'f2@5-3' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-5' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@20-7' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public int32 'value' + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(int32 'value') cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 14 (0xe) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::'value' + IL_000d: ret + } // end of method 'f3@20-7'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 14 (0xe) + .maxstack 8 + .line 20,20 : 17,25 '' + IL_0000: ldarga.s ctxt + IL_0002: ldarg.0 + IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::'value' + IL_0008: call instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1::OnSuccess(!0) + IL_000d: ret + } // end of method 'f3@20-7'::Invoke + + } // end of class 'f3@20-7' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@19-6' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -142,31 +222,33 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::x1 IL_0014: ldarg.0 IL_0015: ldarg.3 - IL_0016: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::y + IL_0016: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::y IL_001b: ret - } // end of method 'f3@19-5'::.ctor + } // end of method 'f3@19-6'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg4) cil managed { - // Code size 38 (0x26) + // Code size 46 (0x2e) .maxstack 6 .locals init ([0] int32 x4, - [1] int32 z) + [1] int32 z, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, + [3] int32 V_3) .line 18,18 : 17,31 '' IL_0000: ldarg.1 IL_0001: stloc.0 .line 19,19 : 17,37 '' IL_0002: ldarg.0 - IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::x1 + IL_0003: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::x1 IL_0008: ldarg.0 - IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::y + IL_0009: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::y IL_000e: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) IL_0013: add IL_0014: ldloc.0 @@ -174,16 +256,70 @@ IL_0016: stloc.1 .line 20,20 : 17,25 '' IL_0017: ldarg.0 - IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::builder@ - IL_001d: ldloc.1 - IL_001e: tail. - IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Return(!!0) - IL_0025: ret - } // end of method 'f3@19-5'::Invoke + IL_0018: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::builder@ + IL_001d: stloc.2 + IL_001e: ldloc.1 + IL_001f: stloc.3 + IL_0020: ldloc.3 + IL_0021: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@20-7'::.ctor(int32) + IL_0026: tail. + IL_0028: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_002d: ret + } // end of method 'f3@19-6'::Invoke + + } // end of class 'f3@19-6' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@18-8' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::computation + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::binder + IL_0014: ret + } // end of method 'f3@18-8'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 18,18 : 17,31 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::computation + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::binder + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0014: ret + } // end of method 'f3@18-8'::Invoke - } // end of class 'f3@19-5' + } // end of class 'f3@18-8' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-4' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@16-5' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -203,20 +339,23 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::x1 IL_0014: ret - } // end of method 'f3@16-4'::.ctor + } // end of method 'f3@16-5'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg3) cil managed { - // Code size 53 (0x35) - .maxstack 9 + // Code size 65 (0x41) + .maxstack 7 .locals init ([0] int32 x3, - [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y) + [1] class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1 y, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_3, + [4] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_4) .line 15,15 : 17,31 '' IL_0000: ldarg.1 IL_0001: stloc.0 @@ -230,25 +369,81 @@ IL_000f: nop .line 18,18 : 17,31 '' IL_0010: ldarg.0 - IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::builder@ - IL_0016: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() - IL_001b: ldarg.0 - IL_001c: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::builder@ - IL_0021: ldarg.0 - IL_0022: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::x1 - IL_0027: ldloc.1 - IL_0028: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_0011: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ + IL_0016: stloc.2 + IL_0017: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() + IL_001c: stloc.3 + IL_001d: ldarg.0 + IL_001e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::builder@ + IL_0023: ldarg.0 + IL_0024: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::x1 + IL_0029: ldloc.1 + IL_002a: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@19-6'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32, class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1) - IL_002d: tail. - IL_002f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0034: ret - } // end of method 'f3@16-4'::Invoke + IL_002f: stloc.s V_4 + IL_0031: ldloc.3 + IL_0032: ldloc.s V_4 + IL_0034: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@18-8'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0039: tail. + IL_003b: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0040: ret + } // end of method 'f3@16-5'::Invoke + + } // end of class 'f3@16-5' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-9' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::computation + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::binder + IL_0014: ret + } // end of method 'f3@15-9'::.ctor - } // end of class 'f3@16-4' + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 15,15 : 17,31 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::computation + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::binder + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0014: ret + } // end of method 'f3@15-9'::Invoke + + } // end of class 'f3@15-9' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-3' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@15-4' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -268,41 +463,100 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ IL_000d: ldarg.0 IL_000e: ldarg.2 - IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::x1 + IL_000f: stfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::x1 IL_0014: ret - } // end of method 'f3@15-3'::.ctor + } // end of method 'f3@15-4'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg2) cil managed { - // Code size 38 (0x26) - .maxstack 8 - .locals init ([0] int32 x2) + // Code size 48 (0x30) + .maxstack 6 + .locals init ([0] int32 x2, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) .line 14,14 : 17,31 '' IL_0000: ldarg.1 IL_0001: stloc.0 .line 15,15 : 17,31 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::builder@ - IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::builder@ - IL_0013: ldarg.0 - IL_0014: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::x1 - IL_0019: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ + IL_0008: stloc.1 + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() + IL_000e: stloc.2 + IL_000f: ldarg.0 + IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::builder@ + IL_0015: ldarg.0 + IL_0016: ldfld int32 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::x1 + IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@16-5'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32) - IL_001e: tail. - IL_0020: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0025: ret - } // end of method 'f3@15-3'::Invoke + IL_0020: stloc.3 + IL_0021: ldloc.2 + IL_0022: ldloc.3 + IL_0023: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-9'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0028: tail. + IL_002a: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_002f: ret + } // end of method 'f3@15-4'::Invoke + + } // end of class 'f3@15-4' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-10' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::computation + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::binder + IL_0014: ret + } // end of method 'f3@14-10'::.ctor - } // end of class 'f3@15-3' + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 14,14 : 17,31 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::computation + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::binder + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0014: ret + } // end of method 'f3@14-10'::Invoke - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-2' + } // end of class 'f3@14-10' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@14-3' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -320,37 +574,96 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-2'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ IL_000d: ret - } // end of method 'f3@14-2'::.ctor + } // end of method 'f3@14-3'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(int32 _arg1) cil managed { - // Code size 33 (0x21) - .maxstack 8 - .locals init ([0] int32 x1) + // Code size 43 (0x2b) + .maxstack 6 + .locals init ([0] int32 x1, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_1, + [2] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_2, + [3] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_3) .line 13,13 : 17,31 '' IL_0000: ldarg.1 IL_0001: stloc.0 .line 14,14 : 17,31 '' IL_0002: ldarg.0 - IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-2'::builder@ - IL_0008: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() - IL_000d: ldarg.0 - IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-2'::builder@ - IL_0013: ldloc.0 - IL_0014: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, + IL_0003: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ + IL_0008: stloc.1 + IL_0009: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() + IL_000e: stloc.2 + IL_000f: ldarg.0 + IL_0010: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::builder@ + IL_0015: ldloc.0 + IL_0016: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@15-4'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder, int32) - IL_0019: tail. - IL_001b: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_0020: ret - } // end of method 'f3@14-2'::Invoke + IL_001b: stloc.3 + IL_001c: ldloc.2 + IL_001d: ldloc.3 + IL_001e: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-10'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0023: tail. + IL_0025: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_002a: ret + } // end of method 'f3@14-3'::Invoke + + } // end of class 'f3@14-3' + + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-11' + extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn> + { + .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder + .custom instance void [mscorlib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + .method assembly specialname rtspecialname + instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 computation, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> binder) cil managed + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) + // Code size 21 (0x15) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>::.ctor() + IL_0006: ldarg.0 + IL_0007: ldarg.1 + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::computation + IL_000d: ldarg.0 + IL_000e: ldarg.2 + IL_000f: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::binder + IL_0014: ret + } // end of method 'f3@13-11'::.ctor + + .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn + Invoke(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1 ctxt) cil managed + { + // Code size 21 (0x15) + .maxstack 8 + .line 13,13 : 17,31 '' + IL_0000: ldarg.1 + IL_0001: ldarg.0 + IL_0002: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::computation + IL_0007: ldarg.0 + IL_0008: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::binder + IL_000d: tail. + IL_000f: call class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::Bind(valuetype [FSharp.Core]Microsoft.FSharp.Control.AsyncActivation`1, + class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0014: ret + } // end of method 'f3@13-11'::Invoke - } // end of class 'f3@14-2' + } // end of class 'f3@13-11' - .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-1' + .class auto ansi serializable sealed nested assembly beforefieldinit 'f3@13-2' extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> { .field public class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder builder@ @@ -368,29 +681,38 @@ IL_0001: call instance void class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>::.ctor() IL_0006: ldarg.0 IL_0007: ldarg.1 - IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-1'::builder@ + IL_0008: stfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ IL_000d: ret - } // end of method 'f3@13-1'::.ctor + } // end of method 'f3@13-2'::.ctor .method public strict virtual instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit unitVar) cil managed { - // Code size 30 (0x1e) - .maxstack 8 + // Code size 40 (0x28) + .maxstack 6 + .locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder V_0, + [1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 V_1, + [2] class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> V_2) .line 13,13 : 17,31 '' IL_0000: ldarg.0 - IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-1'::builder@ - IL_0006: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() - IL_000b: ldarg.0 - IL_000c: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-1'::builder@ - IL_0011: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) - IL_0016: tail. - IL_0018: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Bind(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, - class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) - IL_001d: ret - } // end of method 'f3@13-1'::Invoke - - } // end of class 'f3@13-1' + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ + IL_0006: stloc.0 + IL_0007: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6::f2() + IL_000c: stloc.1 + IL_000d: ldarg.0 + IL_000e: ldfld class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::builder@ + IL_0013: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@14-3'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0018: stloc.2 + IL_0019: ldloc.1 + IL_001a: ldloc.2 + IL_001b: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-11'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1, + class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0020: tail. + IL_0022: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.AsyncPrimitives::MakeAsync(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,class [FSharp.Core]Microsoft.FSharp.Control.AsyncReturn>) + IL_0027: ret + } // end of method 'f3@13-2'::Invoke + + } // end of class 'f3@13-2' .method public static class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 f2() cil managed @@ -420,7 +742,7 @@ IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: ldloc.0 - IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-1'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) + IL_0008: newobj instance void AsyncExpressionSteppingTest6/AsyncExpressionSteppingTest6/'f3@13-2'::.ctor(class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder) IL_000d: tail. IL_000f: callvirt instance class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1 [FSharp.Core]Microsoft.FSharp.Control.FSharpAsyncBuilder::Delay(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) IL_0014: ret