Skip to content
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

Closed
wants to merge 8 commits into from
Closed

Async await prototype #11501

wants to merge 8 commits into from

Conversation

lattner
Copy link
Collaborator

@lattner lattner commented Aug 17, 2017

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.

@LuizZak
Copy link
Contributor

LuizZak commented Aug 17, 2017

Fancy!

@practicalswift
Copy link
Contributor

Nice stuff! Welcome back! :-)

@DougGregor
Copy link
Member

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.

@lattner
Copy link
Collaborator Author

lattner commented Aug 24, 2017

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.

@jckarter
Copy link
Member

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 apply/try_apply with a third edge to represent that. It isn't obvious to me that collecting all those destructor edges and putting them together as the heap object destructor for the coroutine context would just fall out of the llvm-level transform either.

@lattner
Copy link
Collaborator Author

lattner commented Aug 25, 2017

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.

@jckarter
Copy link
Member

jckarter commented Aug 25, 2017

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.

@paulofaria
Copy link
Contributor

@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.

@jckarter
Copy link
Member

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.

@tanner0101
Copy link
Contributor

Would it be possible to initially implement async/await as simple syntax sugar for callbacks/promises?

@magyarosibotond
Copy link

magyarosibotond commented Nov 20, 2018

Any news on this?

I'd be happy to help.

@CodaFi CodaFi added the swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review label Nov 17, 2019
@DougGregor
Copy link
Member

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.

@lattner
Copy link
Collaborator Author

lattner commented Jul 29, 2020

Awesome, no worries, I'm thrilled to see your progress thank you Doug!

@lattner lattner closed this Jul 29, 2020
@AnthonyLatsis AnthonyLatsis added swift evolution implemented Flag → feature: A feature that was approved through the Swift evolution process and implemented and removed swift evolution pending discussion Flag → feature: A feature that has a Swift evolution proposal currently in review labels Mar 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
swift evolution implemented Flag → feature: A feature that was approved through the Swift evolution process and implemented
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants