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

Implement Async Functions #692

Merged
merged 42 commits into from
Nov 11, 2016
Merged

Implement Async Functions #692

merged 42 commits into from
Nov 11, 2016

Conversation

bterlson
Copy link
Member

@bterlson bterlson commented Sep 15, 2016

This PR implements async functions as specified in the Async Functions Proposal with minor modifications. This is a big PR with lots of fiddly pieces. As such, I'm sure there are minor editorial and likely technical issues.

To aid in reviewing, I've published a build of the spec with async funtions. Below is a list of changes with deep links. Please help me review this!

  • Updates to Table 7 to add %AsyncFunction% and %AsyncFunctionPrototype%. Table 7
  • Updated note in 10.2 about types of source code 10.2
  • await is a new keyword 11.6.2.1
  • await added as alternative for various Identifier kinds 12.1 and appropriate early errors 12.1.1.
  • New language for applying supplemental grammars that doesn't require permuting the various combinations of parameter values 12.2.1.1 and other examples.
  • Xref for async function expression 12.2.7
  • Add cover grammar for CallExpression
  • New supplemental syntax for CallExpression: CallMemberExpression
  • Static semantics for pulling out the covered call member expression: 12.3.1.1
  • Updated function call evaluation semantics to apply cover grammar: 12.3.4.1
  • Updated assignment expression static semantics IsFunctionDefinition: 12.15.2
  • AsyncFunctionDeclaration to HoistableDeclaration (plus static semantics for same)
  • New lookahead for ExpressionStatement
  • New Early Error for arrow parameters to always disallow await 14.2.1
  • New clause Async Function Definitions.
  • New expression positions to the tail position calls spec 14.8.2.2
  • New lookahead in export default 15.2.3
  • Updates to CreateDynamicFunction to allow dynamic creation of async functions 19.2.1.1.1.
  • New clause Async Function Objects
  • New productions added to Annex A.2 and A.3

Additionally, any production of the grammar that took a yield parameter now also takes an await parameter. An RHS non-terminal that previously passed a ?Yield parameter now also pass ?Await. RHSes that passed +Yield or Yield were updated to pass +//?Await as appropriate.

@bterlson
Copy link
Member Author

Accidentally submitted (still working on the TOC)...

@bterlson
Copy link
Member Author

Ok good to go!

@bterlson
Copy link
Member Author

bterlson commented Sep 15, 2016

Added changes to evalute body: removed first steps from https://bterlson.github.io/ecma262/#sec-ordinarycallevaluatebody and moved to corresponding EvaluateBodys (eg. https://bterlson.github.io/ecma262/#sec-function-definitions-runtime-semantics-evaluatebody). Rationale in this note.

@domenic
Copy link
Member

domenic commented Sep 15, 2016

Consider moving CreateDynamicFunction somewhere else, as it's now being used from multiple places and it's less appropriate to nest it under Function. On the other hand, I can't find any good place to put it.

I think the section "Async Function Objects" should be consistent with "GeneratorFunction Objects", i.e. space or no space.

@domenic
Copy link
Member

domenic commented Sep 15, 2016

"Note: Async functions are not constructable and do not have a prototype property." seems to contradict the line above it where you say "Else [if not a generator], perform MakeConstructor(F)".

@domenic
Copy link
Member

domenic commented Sep 15, 2016

The note below also would need adjusting: "A prototype property is automatically created for every function created using CreateDynamicFunction, to provide for the possibility that the function will be used as a constructor."

@bterlson
Copy link
Member Author

"Note: Async functions are not constructable and do not have a prototype property." seems to contradict the line above it where you say "Else [if not a generator], perform MakeConstructor(F)".

Indeed! I put the note but didn't fix up the else leg. Will fix that plus the note.

@littledan
Copy link
Member

Minor issue I noticed in debugging our async/await implementation: in https://bterlson.github.io/ecma262/#abstract-ops-async-function-await , you have to set throwawayCapability.[[Promise]].[[PromiseIsHandled]] to true.

@domenic
Copy link
Member

domenic commented Sep 16, 2016

It would be really nice if you could factor out a version of PerformPromiseThen which did not need to deal with the throwawayCapability business. It's shown up in multiple specs now. I think the idea would be to let the [[Capability]] field of PromiseReaction be undefined (noting that this is for spec-internal situations), add a check in PromiseReactionJob, and tweak PerformPromiseThen so that promiseCapability is an optional argument that defaults to undefined (i.e. change the assert and return value).

@littledan
Copy link
Member

@domenic I think such a refactoring could be left to a later patch.

@bterlson
Copy link
Member Author

@domenic yeah I'm leaning toward a separate refactoring patch for that. Can you open an issue on it (hopefully with an example I can take a look at)?

@domenic
Copy link
Member

domenic commented Sep 16, 2016

<a href="#async-function-definitions-awaited-fulfilled">AsyncFunction Awaited Fulfilled</a>

this should use emu-xref instead like the other closures do.

@domenic
Copy link
Member

domenic commented Sep 16, 2016

Function _F_ is called with the parameter _value_.

this is very terse compared to existing closure declarations, and should probably be expanded to be more like those (intro paragraph, internal slot list, when called, length specifier).

@domenic
Copy link
Member

domenic commented Sep 16, 2016

Also the section header should include "Functions"

@domenic
Copy link
Member

domenic commented Sep 16, 2016

Let _asyncContext_ be the value of _F_'s [[AsyncContext]] internal slot.

per recent changes, should be "Let asyncContext be F.[[AsyncContext]]". I'd suggest doing a search for "the value of" to find other instances.

@domenic
Copy link
Member

domenic commented Sep 16, 2016

In reviewing this further, I think the last steps of AsyncFunction Awaited Fulfilled/Rejected, where it returns the completion value, do not make much sense. It's not returning to anyone interesting; it would only impact the throwawayCapability.[[Promise]], which is, well, a throwaway.

@bterlson
Copy link
Member Author

Note to self: I also need to define the [[AsyncContext]] internal slot somewhere.

@domenic
Copy link
Member

domenic commented Sep 16, 2016

This spec has not been updated for the great uppercasing of record fields. In particular completion record [[value]], [[target]], and [[type]] are all now uppercase.

kisg pushed a commit to paul99/v8mips that referenced this pull request Sep 16, 2016
…romises

This patch implements a bug fix to the async/await specification described
at tc39/ecma262#692 (comment)
Namely, the intermediate values of Promises may be rejected, and they do
not have .then called on them anymore (now that the memory leak is fixed),
but they do not correspond do unhandled rejections. This change has been
tested manually with integration with Blink; once it is checked in and
rolled, then further tests can be added on the Blink side for the uncaught
rejection handler and async/await.

BUG=v8:4483

Review-Url: https://codereview.chromium.org/2338273007
Cr-Commit-Position: refs/heads/master@{#39480}
Copy link
Collaborator

@jmdyck jmdyck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have editorial tweaks, but I don't know how to submit a PR to a PR.

@bterlson
Copy link
Member Author

@jmdyck: send the PR to this repo + branch: https://github.com/bterlson/ecma262/tree/async-functions. Then once the PR is accepted there it will show up here.

@bterlson
Copy link
Member Author

Alternatively you can just push your fixes someplace and I can pull them in outside of the GitHub interface. Whichever is easiest for you!

@bterlson
Copy link
Member Author

@jmdyck are your commits already ready to go? If so I can wait a bit before making further changes so as not to create rebase headaches...

@jmdyck
Copy link
Collaborator

jmdyck commented Sep 17, 2016

I've just finished making all the changes on my local branch, but I haven't started doing any commits yet. If you've got stuff ready to push, you should probably just push it, and I'll deal with the headaches.

In order to submit a PR against your repo, I'd have to have a fork of it on github, right? But jmdyck/ecma262 already exists as a fork of tc39/ecma262, so I'm not sure how I could have another fork of ecma262.

@bterlson
Copy link
Member Author

bterlson commented Sep 17, 2016

I also don't have commits yet, just started on the rest of Domenic's issues. I'll probably want to push something later today.

If you already have a fork, easiest way using the GitHub UI is to push your commits and hit the pull request button on your repo. On the next screen you can change the "base fork" to bterlson/ecma262 and base branch to async-functions, then create the PR.

@jmdyck
Copy link
Collaborator

jmdyck commented Sep 17, 2016

Okay, I've finished all my commits. I'll see if I can make a PR.

@bterlson
Copy link
Member Author

@littledan Right, added that plus the definition of [[AsyncContext]].

@littledan
Copy link
Member

LGTM (AFAICT!)

@not-an-aardvark
Copy link
Contributor

Editorial nit: I think section 19.2.1 will no longer be accurate after this is merged.

There is no syntactic means to create instances of Function subclasses except for the built-in GeneratorFunction subclass.

Maybe that section should mention AsyncFunction as well.

@bterlson
Copy link
Member Author

@not-an-aardvark you are correct, I will fix that up!

@bterlson
Copy link
Member Author

Alright, gonna pull this in now. We can of course make further updates up 'til we freeze for ES2017.

@bterlson bterlson merged commit 869f1c6 into tc39:master Nov 11, 2016
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jan 14, 2021
The nonterminals:
- FunctionExpression
- ClassExpression
- GeneratorExpression
- AsyncGeneratorExpression

are all defined with a single RHS involving an optional BindingIdentifier.

But AsyncFunctionExpression is defined with two RHSs,
one with a BindingIdentifier and one without.
(It's been that way since it was introduced in PR tc39#692.)
I can't see any reason for it to be not like the others.
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jan 16, 2021
The nonterminals:
- FunctionExpression
- ClassExpression
- GeneratorExpression
- AsyncGeneratorExpression

are all defined with a single RHS involving an optional BindingIdentifier.

But AsyncFunctionExpression is defined with two RHSs,
one with a BindingIdentifier and one without.
(It's been that way since it was introduced in PR tc39#692.)
I can't see any reason for it to be not like the others.
ljharb pushed a commit to jmdyck/ecma262 that referenced this pull request Jan 25, 2021
The nonterminals:
- FunctionExpression
- ClassExpression
- GeneratorExpression
- AsyncGeneratorExpression

are all defined with a single RHS involving an optional BindingIdentifier.

But AsyncFunctionExpression is defined with two RHSs, one with a BindingIdentifier and one without.
(It's been that way since it was introduced in PR tc39#692)
I can't see any reason for it to be not like the others.
@alkthegit
Copy link

alkthegit commented May 7, 2024

Hi there,

I'm curious about why the link up there is not working anymore: https://tc39.github.io/ecmascript-asyncawait

Hope that doesn't mean the proposal was somehow reverted from the ES spec :)
So, where can I read the text of that original proposal for the purpose of learning?

@ctcpip
Copy link
Member

ctcpip commented May 7, 2024

@alkthegit
Copy link

Thanks, but I've already been there and the page also contains the same broken link.

What I was hoping to find is a kind of a "long explaner", with an example being here on the pipe operator:
https://github.com/tc39/proposal-pipeline-operator

Thought it was moved to the resource under the broken link but maybe it just never existed?

@ljharb
Copy link
Member

ljharb commented May 7, 2024

Indeed the proposal repo, and https://tc39.es/proposal-async-await/, are all that exists. Not every proposal chooses the same ways to explain itself.

@alkthegit
Copy link

Ok, got it.
Seems like maybe there is little to be "long explained" :).

@alkthegit
Copy link

Thanks, Chris!
I'll take a glance at it.
Can't see your link here but received it via email notify.

@ctcpip
Copy link
Member

ctcpip commented May 7, 2024

it was the wrong link. updated above. there are others, at least one more, but that's what I was able to find quickly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants