New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Async await prototype #11501
Async await prototype #11501
Conversation
non-async functions, so remove this capability.
…son. The logic seemed wrong here: it was looking through optional types wrapping a function type, but didn't look through the optional injection on the expr side when walking the expr that formed an optional function type.
…bug with the smaem.
Fancy! |
Nice stuff! Welcome back! :-) |
SIL support for this feature (which is needed for it to do anything) is 10x larger and more complicated than the parsing/sema bits in this pull request, and requires significant design work. Y'all might want to hold on to those party hats. |
One approach does. The other approach builds on the LLVM support for coroutines (which would also allow the llvm inliner etc to work on them). If you haven't followed the discussions in the c++ community, it is interesting to note that they landed in a very similar design space to the proposed design. |
It isn't clear to me how LLVM's coroutine transform can do all the work here without any work at the SIL level. We need to at least be able to generate the destructor edge out of every await point to clean up when all references to a suspended coroutine context get released, and it seems like we'd need a new variation of |
Right, I'm not saying there is zero SILGen work, I'm just saying it is a lot less if you build on the coroutine transformation and optimizations that LLVM does already. |
Another approach to get to a prototype stage people can play with might be to not do a coroutine transform at all, and just map begin/suspend to the awful brute-force "allocate a callstack and getcontext/setcontext to move on and off the coroutine stack". That wouldn't give you the efficiency or scalability of the real thing, but could at least get the surface semantics to a point people can experiment building things on top of. |
@jckarter "allocate a callstack and getcontext/setcontext to move on and off the coroutine stack". I'm a bit curious about this topic. This would be similar to Venice coroutines which are built upon libdill coroutines, right? You mentioned before this approach is unsafe for Swift and I believe it even motivated this commit somehow, which marks functions that return twice as unavailable. I know this wouldn't be exactly the same thing because you'd be doing work inside the compiler, so whatever needs to be done to make it safe, you'd do it. I'm just curious about what would have to be done to make this approach safe. |
Using setjmp/longjmp from Swift is not sound because of the returns_twice semantics of setjmp, and because longjmp unwinds the stack and Swift doesn't emit cleanup information. Suspending and resuming contexts shouldn't have that problem (assuming you're not ever trying to resume the same context twice), though there is framework code out there that will break if the stack pointer is not pointing into the kernel-allocated callstack for the current thread. |
Would it be possible to initially implement async/await as simple syntax sugar for callbacks/promises? |
Any news on this? I'd be happy to help. |
I'm borrowing ideas from this for the prototype in #33147, but that gigantic pile of conflicts means it's mostly a rewrite even for things that should be the same. |
Awesome, no worries, I'm thrilled to see your progress thank you Doug! |
This implements parsing and semantic analysis support for the async/await proposal that @jckarter and I are cooking. It doesn't include SILGen support yet, so it isn't ready for merging.