-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Editorial: Change many "abrupt completion" to "throw completion" #2676
Conversation
LGTM other than comments. It's always a bit surprising to me that PerformEval can't Of the remaining abrupt-completion-returning AOs, I believe only
(i.e. the various "Evaluation" AOs used for statements) can actually can produce non-throw abrupt completions. If you don't want to include the remaining cases in this PR I can do it in a followup. Gonna be fun to revert most of this if do expressions ever advances. |
I agree with all of those except But there are also a few missing from your list:
And maybe some others. E.g.
Yeah, I might opt for that, as this PR is playing it safe.
To be clear, you mean most of the "extras", not most of what this PR proposes. (Offhand, I don't think anything in the PR would be affected by do-expressions.) |
Oh geeze, I forgot |
spec.html
Outdated
@@ -20788,7 +20788,7 @@ <h1> | |||
Runtime Semantics: RestDestructuringAssignmentEvaluation ( | |||
_value_: unknown, | |||
_excludedNames_: unknown, | |||
): either a normal completion containing ~unused~ or an abrupt completion | |||
): either a normal completion containing ~unused~ or a throw completion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can produce a return completion, as in
let g = (function* (){ ({ ...{}[yield] } = {}) })();
g.next();
g.return(42);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. (I was avoiding "Evaluation" ops on principle, regardless of what my analysis said, but that one slipped through.)
Alas, let g = (function* (){ var x = class { [yield 1](){} }; })();
g.next();
g.return(42);
Yup, agreed with all of those.
That's how it works, yup. This is used for mainly for cleanup: if you do function* g() {
let resource = lock(thing);
try {
yield 0;
yield 1;
yield 2;
} finally {
unlock(thing);
}
} then the for (let x of g()) {
if (condition) {
break; // executes the `finally` of `g`, by injecting a return completion at whatever `yield` it's paused on
}
}
No, I just didn't initialize realize how few of these were actually evaluating expression. |
Indeed, that list was completely wrong. Reviewing again after remembering how
There's also GetValue and PutValue, which are gross in that they take a completion record as an argument and immediately return it if it's abrupt. If they were refactored to not do that, they'd also not be able to return non-throw abrupt completions. |
(force-pushed to resolve merge conflicts and squash 2 fixups) |
Needs a rebase but otherwise is ready to land. |
(force-pushed to resolve merge conflict from 2719) |
(force-pushed again, to squash to a single commit) |
This is a follow-up to PR #2547, which tagged many operations as returning a normal completion or an abrupt completion. But in most cases, the only abrupt completion possible is a throw completion. So this PR changes lots of "abrupt completion" to the more precise "throw completion".
The first two commits deal with internal methods and host hooks, which the spec explicitly constrains to return normal+throw completions. The third commit deals with ~200 other operations, which I found via static analysis.
Of the ~50 remaining operations that still say "abrupt completion", I think quite a few should likewise change to "throw completion", but it would take more sophisticated analysis to be sure.